blob: 83c7b8a79c8dfbc359a442b35ab7aa7910bb0fab [file] [log] [blame]
Brian Paul9abbeda2009-09-16 19:33:01 -06001/*
2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22/**
23 * OpenGL/GLUT common code for perf programs.
24 * Brian Paul
25 * 15 Sep 2009
26 */
27
28
Brian Paul05bce082009-09-21 11:58:03 -060029#include <stdio.h>
Brian Paul9abbeda2009-09-16 19:33:01 -060030#include "glmain.h"
31#include <GL/glut.h>
32
33
34static int Win;
35static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
36static GLboolean Anim = GL_FALSE;
37
38
39/** Return time in seconds */
40double
41PerfGetTime(void)
42{
43 return glutGet(GLUT_ELAPSED_TIME) * 0.001;
44}
45
46
47void
48PerfSwapBuffers(void)
49{
50 glutSwapBuffers();
51}
52
53
Brian Paul05bce082009-09-21 11:58:03 -060054/** make simple checkerboard texture object */
55GLuint
56PerfCheckerTexture(GLsizei width, GLsizei height)
57{
58 const GLenum filter = GL_NEAREST;
59 GLubyte *img = (GLubyte *) malloc(width * height * 4);
60 GLint i, j, k;
61 GLuint obj;
62
63 k = 0;
64 for (i = 0; i < height; i++) {
65 for (j = 0; j < width; j++) {
66 GLubyte color;
67 if (((i / 8) ^ (j / 8)) & 1) {
68 color = 0xff;
69 }
70 else {
71 color = 0x0;
72 }
73 img[k++] = color;
74 img[k++] = color;
75 img[k++] = color;
76 img[k++] = color;
77 }
78 }
79
80 glGenTextures(1, &obj);
81 glBindTexture(GL_TEXTURE_2D, obj);
82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
84 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
85 GL_RGBA, GL_UNSIGNED_BYTE, img);
86 free(img);
87
88 return obj;
89}
90
91
92static GLuint
93CompileShader(GLenum type, const char *shader)
94{
95 GLuint sh;
96 GLint stat;
97
98 sh = glCreateShader(type);
99 glShaderSource(sh, 1, (const GLchar **) &shader, NULL);
100
101 glCompileShader(sh);
102
103 glGetShaderiv(sh, GL_COMPILE_STATUS, &stat);
104 if (!stat) {
105 GLchar log[1000];
106 GLsizei len;
107 glGetShaderInfoLog(sh, 1000, &len, log);
108 fprintf(stderr, "Error: problem compiling shader: %s\n", log);
109 exit(1);
110 }
111
112 return sh;
113}
114
115
116/** Make shader program from given vert/frag shader text */
117GLuint
118PerfShaderProgram(const char *vertShader, const char *fragShader)
119{
120 GLuint prog;
121 GLint stat;
122
123 {
124 const char *version = (const char *) glGetString(GL_VERSION);
125 if (version[0] != '2' || version[1] != '.') {
126 fprintf(stderr, "Error: GL version 2.x required\n");
127 exit(1);
128 }
129 }
130
131 prog = glCreateProgram();
132
133 if (vertShader) {
134 GLuint vs = CompileShader(GL_VERTEX_SHADER, vertShader);
135 glAttachShader(prog, vs);
136 }
137 if (fragShader) {
138 GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);
139 glAttachShader(prog, fs);
140 }
141
142 glLinkProgram(prog);
143 glGetProgramiv(prog, GL_LINK_STATUS, &stat);
144 if (!stat) {
145 GLchar log[1000];
146 GLsizei len;
147 glGetProgramInfoLog(prog, 1000, &len, log);
148 fprintf(stderr, "Shader link error:\n%s\n", log);
149 exit(1);
150 }
151
152 return prog;
153}
154
155
Brian Paul9abbeda2009-09-16 19:33:01 -0600156static void
157Idle(void)
158{
159 Xrot += 3.0;
160 Yrot += 4.0;
161 Zrot += 2.0;
162 glutPostRedisplay();
163}
164
165
166static void
167Draw(void)
168{
169 PerfDraw();
170 glutSwapBuffers();
171}
172
173
174static void
175Reshape(int width, int height)
176{
177 WinWidth = width;
178 WinHeight = height;
179 glViewport(0, 0, width, height);
180 glMatrixMode(GL_PROJECTION);
181 glLoadIdentity();
182 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
183 glMatrixMode(GL_MODELVIEW);
184 glLoadIdentity();
185 glTranslatef(0.0, 0.0, -15.0);
186}
187
188
189static void
190Key(unsigned char key, int x, int y)
191{
192 const GLfloat step = 3.0;
193 (void) x;
194 (void) y;
195 switch (key) {
196 case 'a':
197 Anim = !Anim;
198 if (Anim)
199 glutIdleFunc(Idle);
200 else
201 glutIdleFunc(NULL);
202 break;
203 case 'z':
204 Zrot -= step;
205 break;
206 case 'Z':
207 Zrot += step;
208 break;
209 case 27:
210 glutDestroyWindow(Win);
211 exit(0);
212 break;
213 }
214 glutPostRedisplay();
215}
216
217
218static void
219SpecialKey(int key, int x, int y)
220{
221 const GLfloat step = 3.0;
222 (void) x;
223 (void) y;
224 switch (key) {
225 case GLUT_KEY_UP:
226 Xrot -= step;
227 break;
228 case GLUT_KEY_DOWN:
229 Xrot += step;
230 break;
231 case GLUT_KEY_LEFT:
232 Yrot -= step;
233 break;
234 case GLUT_KEY_RIGHT:
235 Yrot += step;
236 break;
237 }
238 glutPostRedisplay();
239}
240
241
242int
243main(int argc, char *argv[])
244{
245 glutInit(&argc, argv);
246 glutInitWindowSize(WinWidth, WinHeight);
247 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
248 Win = glutCreateWindow(argv[0]);
249 glewInit();
250 glutReshapeFunc(Reshape);
251 glutKeyboardFunc(Key);
252 glutSpecialFunc(SpecialKey);
253 glutDisplayFunc(Draw);
254 if (Anim)
255 glutIdleFunc(Idle);
256 PerfInit();
257 glutMainLoop();
258 return 0;
259}