blob: e6d83bf8fb325d4dc7806acc4c2caf3f0df963b3 [file] [log] [blame]
Brian Paul24ea2c22006-11-03 00:04:06 +00001/**
2 * Test OpenGL 2.0 vertex/fragment shaders.
3 * Brian Paul
4 * 1 November 2006
5 *
6 * Based on ARB version by:
7 * Michal Krol
8 * 20 February 2006
9 *
10 * Based on the original demo by:
11 * Brian Paul
12 * 17 April 2003
13 */
14
15#include <assert.h>
16#include <string.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <math.h>
20#include <GL/gl.h>
21#include <GL/glut.h>
22#include <GL/glext.h>
Brianbecb3932006-12-15 09:31:14 -070023#include "extfuncs.h"
24
Brian46a92412007-01-17 10:25:44 -070025
Brian0420d852007-03-27 16:06:20 -060026#define TEXTURE 0
27
Brian46a92412007-01-17 10:25:44 -070028static GLint CoordAttrib = 0;
29
Brianbecb3932006-12-15 09:31:14 -070030static char *FragProgFile = NULL;
31static char *VertProgFile = NULL;
Brian Paul24ea2c22006-11-03 00:04:06 +000032
33static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
34static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
Brian917a5082007-02-21 15:57:55 -070035static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };
Brian Paul24ea2c22006-11-03 00:04:06 +000036static GLfloat delta = 1.0f;
37
38static GLuint fragShader;
39static GLuint vertShader;
40static GLuint program;
41
Brian Paul24ea2c22006-11-03 00:04:06 +000042static GLint uDiffuse;
43static GLint uSpecular;
Brian46a92412007-01-17 10:25:44 -070044static GLint uTexture;
Brian Paul24ea2c22006-11-03 00:04:06 +000045
Brian46a92412007-01-17 10:25:44 -070046static GLuint SphereList, RectList, CurList;
Brian Paul24ea2c22006-11-03 00:04:06 +000047static GLint win = 0;
Brianbf287352007-04-11 14:09:32 -060048static GLboolean anim = GL_TRUE;
Brian Paul24ea2c22006-11-03 00:04:06 +000049static GLboolean wire = GL_FALSE;
50static GLboolean pixelLight = GL_TRUE;
51
52static GLint t0 = 0;
53static GLint frames = 0;
54
Brian46a92412007-01-17 10:25:44 -070055static GLfloat xRot = 90.0f, yRot = 0.0f;
Brian Paul24ea2c22006-11-03 00:04:06 +000056
Brian Paul24ea2c22006-11-03 00:04:06 +000057
58static void
59normalize(GLfloat *dst, const GLfloat *src)
60{
Brian4a285482007-04-26 07:46:38 -060061 GLfloat len = sqrt(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
Brian Paul24ea2c22006-11-03 00:04:06 +000062 dst[0] = src[0] / len;
63 dst[1] = src[1] / len;
64 dst[2] = src[2] / len;
Brian917a5082007-02-21 15:57:55 -070065 dst[3] = src[3];
Brian Paul24ea2c22006-11-03 00:04:06 +000066}
67
68
69static void
70Redisplay(void)
71{
Brian917a5082007-02-21 15:57:55 -070072 GLfloat vec[4];
73
Brian Paul24ea2c22006-11-03 00:04:06 +000074 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Brian917a5082007-02-21 15:57:55 -070075
76 /* update light position */
77 normalize(vec, lightPos);
78 glLightfv(GL_LIGHT0, GL_POSITION, vec);
Brian Paul24ea2c22006-11-03 00:04:06 +000079
80 if (pixelLight) {
Brian Paul24ea2c22006-11-03 00:04:06 +000081 glUseProgram_func(program);
Brian Paul24ea2c22006-11-03 00:04:06 +000082 glDisable(GL_LIGHTING);
83 }
84 else {
85 glUseProgram_func(0);
Brian Paul24ea2c22006-11-03 00:04:06 +000086 glEnable(GL_LIGHTING);
87 }
88
89 glPushMatrix();
90 glRotatef(xRot, 1.0f, 0.0f, 0.0f);
91 glRotatef(yRot, 0.0f, 1.0f, 0.0f);
Brian46a92412007-01-17 10:25:44 -070092 /*
Brian Paul24ea2c22006-11-03 00:04:06 +000093 glutSolidSphere(2.0, 10, 5);
Brian46a92412007-01-17 10:25:44 -070094 */
95 glCallList(CurList);
Brian Paul24ea2c22006-11-03 00:04:06 +000096 glPopMatrix();
97
98 glutSwapBuffers();
99 frames++;
100
101 if (anim) {
102 GLint t = glutGet(GLUT_ELAPSED_TIME);
103 if (t - t0 >= 5000) {
104 GLfloat seconds =(GLfloat)(t - t0) / 1000.0f;
105 GLfloat fps = frames / seconds;
106 printf("%d frames in %6.3f seconds = %6.3f FPS\n",
107 frames, seconds, fps);
108 t0 = t;
109 frames = 0;
110 }
111 }
112}
113
114
115static void
116Idle(void)
117{
118 lightPos[0] += delta;
119 if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
120 delta = -delta;
121 glutPostRedisplay();
122}
123
124
125static void
126Reshape(int width, int height)
127{
128 glViewport(0, 0, width, height);
129 glMatrixMode(GL_PROJECTION);
130 glLoadIdentity();
131 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
132 glMatrixMode(GL_MODELVIEW);
133 glLoadIdentity();
134 glTranslatef(0.0f, 0.0f, -15.0f);
135}
136
137
138static void
139CleanUp(void)
140{
141 glDeleteShader_func(fragShader);
142 glDeleteShader_func(vertShader);
143 glDeleteProgram_func(program);
144 glutDestroyWindow(win);
145}
146
147
148static void
149Key(unsigned char key, int x, int y)
150{
151 (void) x;
152 (void) y;
153
154 switch(key) {
155 case ' ':
156 case 'a':
157 anim = !anim;
158 if (anim)
159 glutIdleFunc(Idle);
160 else
161 glutIdleFunc(NULL);
162 break;
163 case 'x':
164 lightPos[0] -= 1.0f;
165 break;
166 case 'X':
167 lightPos[0] += 1.0f;
168 break;
169 case 'w':
170 wire = !wire;
171 if (wire)
172 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
173 else
174 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
175 break;
Brian46a92412007-01-17 10:25:44 -0700176 case 'o':
177 if (CurList == SphereList)
178 CurList = RectList;
179 else
180 CurList = SphereList;
181 break;
Brian Paul24ea2c22006-11-03 00:04:06 +0000182 case 'p':
183 pixelLight = !pixelLight;
184 if (pixelLight)
185 printf("Per-pixel lighting\n");
186 else
187 printf("Conventional lighting\n");
188 break;
189 case 27:
190 CleanUp();
191 exit(0);
192 break;
193 }
194 glutPostRedisplay();
195}
196
197
198static void
199SpecialKey(int key, int x, int y)
200{
201 const GLfloat step = 3.0f;
202
203 (void) x;
204 (void) y;
205
206 switch(key) {
207 case GLUT_KEY_UP:
208 xRot -= step;
209 break;
210 case GLUT_KEY_DOWN:
211 xRot += step;
212 break;
213 case GLUT_KEY_LEFT:
214 yRot -= step;
215 break;
216 case GLUT_KEY_RIGHT:
217 yRot += step;
218 break;
219 }
220 glutPostRedisplay();
221}
222
223
224static void
Brianbecb3932006-12-15 09:31:14 -0700225TestFunctions(void)
226{
227 printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
228 {
229 GLfloat pos[3];
Brianbecb3932006-12-15 09:31:14 -0700230 printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
231 printf("Light pos %g %g %g\n", pos[0], pos[1], pos[2]);
232 }
233
234
235 {
236 GLfloat m[16], result[16];
237 GLint mPos;
238 int i;
239
240 for (i = 0; i < 16; i++)
241 m[i] = (float) i;
242
243 mPos = glGetUniformLocation_func(program, "m");
244 printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
245 glUniformMatrix4fv_func(mPos, 1, GL_FALSE, m);
246 printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
247
248 glGetUniformfv_func(program, mPos, result);
249 printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
250
251 for (i = 0; i < 16; i++) {
252 printf("%8g %8g\n", m[i], result[i]);
253 }
254 }
255
256 assert(glIsProgram_func(program));
257 assert(glIsShader_func(fragShader));
258 assert(glIsShader_func(vertShader));
259
260 /* attached shaders */
261 {
262 GLuint shaders[20];
263 GLsizei count;
264 int i;
265 glGetAttachedShaders_func(program, 20, &count, shaders);
266 for (i = 0; i < count; i++) {
267 printf("Attached: %u\n", shaders[i]);
268 assert(shaders[i] == fragShader ||
269 shaders[i] == vertShader);
270 }
271 }
272
273 {
274 GLchar log[1000];
275 GLsizei len;
276 glGetShaderInfoLog_func(vertShader, 1000, &len, log);
277 printf("Vert Shader Info Log: %s\n", log);
278 glGetShaderInfoLog_func(fragShader, 1000, &len, log);
279 printf("Frag Shader Info Log: %s\n", log);
280 glGetProgramInfoLog_func(program, 1000, &len, log);
281 printf("Program Info Log: %s\n", log);
282 }
283}
284
285
Brian0420d852007-03-27 16:06:20 -0600286#if TEXTURE
Brianbecb3932006-12-15 09:31:14 -0700287static void
Brian46a92412007-01-17 10:25:44 -0700288MakeTexture(void)
289{
Brian0420d852007-03-27 16:06:20 -0600290#define SZ0 64
291#define SZ1 32
Brian46a92412007-01-17 10:25:44 -0700292 GLubyte image0[SZ0][SZ0][SZ0][4];
293 GLubyte image1[SZ1][SZ1][SZ1][4];
294 GLuint i, j, k;
295
296 /* level 0: two-tone gray checkboard */
297 for (i = 0; i < SZ0; i++) {
298 for (j = 0; j < SZ0; j++) {
299 for (k = 0; k < SZ0; k++) {
300 if ((i/8 + j/8 + k/8) & 1) {
301 image0[i][j][k][0] =
302 image0[i][j][k][1] =
303 image0[i][j][k][2] = 200;
304 }
305 else {
306 image0[i][j][k][0] =
307 image0[i][j][k][1] =
308 image0[i][j][k][2] = 100;
309 }
310 image0[i][j][k][3] = 255;
311 }
312 }
313 }
314
315 /* level 1: two-tone green checkboard */
316 for (i = 0; i < SZ1; i++) {
317 for (j = 0; j < SZ1; j++) {
318 for (k = 0; k < SZ1; k++) {
319 if ((i/8 + j/8 + k/8) & 1) {
320 image1[i][j][k][0] = 0;
321 image1[i][j][k][1] = 250;
322 image1[i][j][k][2] = 0;
323 }
324 else {
325 image1[i][j][k][0] = 0;
326 image1[i][j][k][1] = 200;
327 image1[i][j][k][2] = 0;
328 }
329 image1[i][j][k][3] = 255;
330 }
331 }
332 }
333
334 glActiveTexture(GL_TEXTURE2); /* unit 2 */
335 glBindTexture(GL_TEXTURE_2D, 42);
336 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ0, SZ0, 0,
337 GL_RGBA, GL_UNSIGNED_BYTE, image0);
338 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, SZ1, SZ1, 0,
339 GL_RGBA, GL_UNSIGNED_BYTE, image1);
340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
342 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
343
344 glActiveTexture(GL_TEXTURE4); /* unit 4 */
345 glBindTexture(GL_TEXTURE_3D, 43);
346 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, SZ0, SZ0, SZ0, 0,
347 GL_RGBA, GL_UNSIGNED_BYTE, image0);
348 glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, SZ1, SZ1, SZ1, 0,
349 GL_RGBA, GL_UNSIGNED_BYTE, image1);
350 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1);
351 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
352 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
353}
Brian0420d852007-03-27 16:06:20 -0600354#endif
Brian46a92412007-01-17 10:25:44 -0700355
356
357static void
358MakeSphere(void)
359{
360 GLUquadricObj *obj = gluNewQuadric();
361 SphereList = glGenLists(1);
362 gluQuadricTexture(obj, GL_TRUE);
363 glNewList(SphereList, GL_COMPILE);
364 gluSphere(obj, 2.0f, 10, 5);
365 glEndList();
366}
367
368static void
369VertAttrib(GLint index, float x, float y)
370{
371#if 1
372 glVertexAttrib2f_func(index, x, y);
373#else
374 glTexCoord2f(x, y);
375#endif
376}
377
378static void
379MakeRect(void)
380{
381 RectList = glGenLists(1);
382 glNewList(RectList, GL_COMPILE);
383 glNormal3f(0, 0, 1);
384 glBegin(GL_POLYGON);
385 VertAttrib(CoordAttrib, 0, 0); glVertex2f(-2, -2);
386 VertAttrib(CoordAttrib, 1, 0); glVertex2f( 2, -2);
387 VertAttrib(CoordAttrib, 1, 1); glVertex2f( 2, 2);
388 VertAttrib(CoordAttrib, 0, 1); glVertex2f(-2, 2);
389 glEnd(); /* XXX omit this and crash! */
390 glEndList();
391}
392
393
394
395static void
Brianbecb3932006-12-15 09:31:14 -0700396LoadAndCompileShader(GLuint shader, const char *text)
397{
398 GLint stat;
399
400 glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
401
402 glCompileShader_func(shader);
403
404 glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
405 if (!stat) {
406 GLchar log[1000];
407 GLsizei len;
408 glGetShaderInfoLog_func(shader, 1000, &len, log);
Brianf4e345c2007-01-17 16:30:11 -0700409 fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
Brianbecb3932006-12-15 09:31:14 -0700410 exit(1);
411 }
412}
413
414
415/**
416 * Read a shader from a file.
417 */
418static void
419ReadShader(GLuint shader, const char *filename)
420{
421 const int max = 100*1000;
422 int n;
423 char *buffer = (char*) malloc(max);
424 FILE *f = fopen(filename, "r");
425 if (!f) {
Brian46a92412007-01-17 10:25:44 -0700426 fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
Brianbecb3932006-12-15 09:31:14 -0700427 exit(1);
428 }
429
430 n = fread(buffer, 1, max, f);
Brian46a92412007-01-17 10:25:44 -0700431 printf("fslight: read %d bytes from shader file %s\n", n, filename);
Brianbecb3932006-12-15 09:31:14 -0700432 if (n > 0) {
433 buffer[n] = 0;
434 LoadAndCompileShader(shader, buffer);
435 }
436
437 fclose(f);
438 free(buffer);
439}
440
441
442static void
443CheckLink(GLuint prog)
444{
445 GLint stat;
446 glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
447 if (!stat) {
448 GLchar log[1000];
449 GLsizei len;
450 glGetProgramInfoLog_func(prog, 1000, &len, log);
451 fprintf(stderr, "Linker error:\n%s\n", log);
452 }
453}
454
455
456static void
Brian Paul24ea2c22006-11-03 00:04:06 +0000457Init(void)
458{
459 static const char *fragShaderText =
Brian Paul24ea2c22006-11-03 00:04:06 +0000460 "uniform vec4 diffuse;\n"
461 "uniform vec4 specular;\n"
462 "varying vec3 normal;\n"
463 "void main() {\n"
464 " // Compute dot product of light direction and normal vector\n"
Brian917a5082007-02-21 15:57:55 -0700465 " float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
466 " normalize(normal)), 0.0);\n"
Brian Paul24ea2c22006-11-03 00:04:06 +0000467 " // Compute diffuse and specular contributions\n"
468 " gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"
469 "}\n";
470 static const char *vertShaderText =
471 "varying vec3 normal;\n"
472 "void main() {\n"
473 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
474 " normal = gl_NormalMatrix * gl_Normal;\n"
475 "}\n";
Brian Paul24ea2c22006-11-03 00:04:06 +0000476 const char *version;
477
478 version = (const char *) glGetString(GL_VERSION);
479 if (version[0] != '2' || version[1] != '.') {
Brianbf287352007-04-11 14:09:32 -0600480 printf("This program requires OpenGL 2.x, found %s\n", version);
481 exit(1);
Brian Paul24ea2c22006-11-03 00:04:06 +0000482 }
483
Brianbecb3932006-12-15 09:31:14 -0700484 GetExtensionFuncs();
Brian Paul24ea2c22006-11-03 00:04:06 +0000485
486 fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
Brianbecb3932006-12-15 09:31:14 -0700487 if (FragProgFile)
488 ReadShader(fragShader, FragProgFile);
489 else
490 LoadAndCompileShader(fragShader, fragShaderText);
491
Brian Paul24ea2c22006-11-03 00:04:06 +0000492
493 vertShader = glCreateShader_func(GL_VERTEX_SHADER);
Brianbecb3932006-12-15 09:31:14 -0700494 if (VertProgFile)
495 ReadShader(vertShader, VertProgFile);
496 else
497 LoadAndCompileShader(vertShader, vertShaderText);
Brian Paul24ea2c22006-11-03 00:04:06 +0000498
499 program = glCreateProgram_func();
500 glAttachShader_func(program, fragShader);
501 glAttachShader_func(program, vertShader);
502 glLinkProgram_func(program);
Brianbecb3932006-12-15 09:31:14 -0700503 CheckLink(program);
Brian Paul24ea2c22006-11-03 00:04:06 +0000504 glUseProgram_func(program);
505
Brian Paul24ea2c22006-11-03 00:04:06 +0000506 uDiffuse = glGetUniformLocation_func(program, "diffuse");
507 uSpecular = glGetUniformLocation_func(program, "specular");
Brian46a92412007-01-17 10:25:44 -0700508 uTexture = glGetUniformLocation_func(program, "texture");
Brian917a5082007-02-21 15:57:55 -0700509 printf("DiffusePos %d SpecularPos %d TexturePos %d\n",
510 uDiffuse, uSpecular, uTexture);
Brian Paul24ea2c22006-11-03 00:04:06 +0000511
512 glUniform4fv_func(uDiffuse, 1, diffuse);
513 glUniform4fv_func(uSpecular, 1, specular);
Brian180cc2f2007-03-21 11:41:41 -0600514 /* assert(glGetError() == 0);*/
Brian46a92412007-01-17 10:25:44 -0700515 glUniform1i_func(uTexture, 2); /* use texture unit 2 */
Brian917a5082007-02-21 15:57:55 -0700516 /*assert(glGetError() == 0);*/
Brian46a92412007-01-17 10:25:44 -0700517
518 if (CoordAttrib) {
519 int i;
520 glBindAttribLocation_func(program, CoordAttrib, "coord");
521 i = glGetAttribLocation_func(program, "coord");
522 assert(i >= 0);
523 if (i != CoordAttrib) {
524 printf("Hmmm, NVIDIA bug?\n");
525 CoordAttrib = i;
526 }
527 else {
528 printf("Mesa bind attrib: coord = %d\n", i);
529 }
530 }
531
532 /*assert(glGetError() == 0);*/
Brian Paul24ea2c22006-11-03 00:04:06 +0000533
534 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
535 glEnable(GL_DEPTH_TEST);
536 glEnable(GL_LIGHT0);
537 glEnable(GL_LIGHTING);
538 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
539 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
540 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
541
Brian46a92412007-01-17 10:25:44 -0700542 MakeSphere();
543 MakeRect();
544
545 CurList = SphereList;
546
Brian0420d852007-03-27 16:06:20 -0600547#if TEXTURE
Brian46a92412007-01-17 10:25:44 -0700548 MakeTexture();
Brian0420d852007-03-27 16:06:20 -0600549#endif
Brian46a92412007-01-17 10:25:44 -0700550
Brian Paul24ea2c22006-11-03 00:04:06 +0000551 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
552 printf("Press p to toggle between per-pixel and per-vertex lighting\n");
553
554 /* test glGetShaderSource() */
Brianbecb3932006-12-15 09:31:14 -0700555 if (0) {
Brian Paul24ea2c22006-11-03 00:04:06 +0000556 GLsizei len = strlen(fragShaderText) + 1;
557 GLsizei lenOut;
558 GLchar *src =(GLchar *) malloc(len * sizeof(GLchar));
559 glGetShaderSource_func(fragShader, 0, NULL, src);
560 glGetShaderSource_func(fragShader, len, &lenOut, src);
561 assert(len == lenOut + 1);
562 assert(strcmp(src, fragShaderText) == 0);
563 free(src);
564 }
565
566 assert(glIsProgram_func(program));
567 assert(glIsShader_func(fragShader));
568 assert(glIsShader_func(vertShader));
Brianbecb3932006-12-15 09:31:14 -0700569
570 glColor3f(1, 0, 0);
Brian917a5082007-02-21 15:57:55 -0700571
572 /* for testing state vars */
573 {
574 static GLfloat fc[4] = { 1, 1, 0, 0 };
575 static GLfloat amb[4] = { 1, 0, 1, 0 };
576 glFogfv(GL_FOG_COLOR, fc);
577 glLightfv(GL_LIGHT1, GL_AMBIENT, amb);
578 }
579
Brianbecb3932006-12-15 09:31:14 -0700580#if 0
581 TestFunctions();
Brianbf287352007-04-11 14:09:32 -0600582#else
583 (void) TestFunctions;
Brianbecb3932006-12-15 09:31:14 -0700584#endif
585}
586
587
588static void
589ParseOptions(int argc, char *argv[])
590{
591 int i;
592 for (i = 1; i < argc; i++) {
593 if (strcmp(argv[i], "-fs") == 0) {
594 FragProgFile = argv[i+1];
595 }
596 else if (strcmp(argv[i], "-vs") == 0) {
597 VertProgFile = argv[i+1];
598 }
599 }
Brian Paul24ea2c22006-11-03 00:04:06 +0000600}
601
602
603int
604main(int argc, char *argv[])
605{
606 glutInit(&argc, argv);
607 glutInitWindowPosition( 0, 0);
Brianbf287352007-04-11 14:09:32 -0600608 glutInitWindowSize(200, 200);
Brian Paul24ea2c22006-11-03 00:04:06 +0000609 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
610 win = glutCreateWindow(argv[0]);
611 glutReshapeFunc(Reshape);
612 glutKeyboardFunc(Key);
613 glutSpecialFunc(SpecialKey);
614 glutDisplayFunc(Redisplay);
615 if (anim)
616 glutIdleFunc(Idle);
Brianbecb3932006-12-15 09:31:14 -0700617 ParseOptions(argc, argv);
Brian Paul24ea2c22006-11-03 00:04:06 +0000618 Init();
619 glutMainLoop();
620 return 0;
621}
622
Brian917a5082007-02-21 15:57:55 -0700623