~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to progs/demos/fslight.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
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>
 
23
#include "extfuncs.h"
 
24
 
 
25
 
 
26
#define TEXTURE 0
 
27
 
 
28
static GLint CoordAttrib = 0;
 
29
 
 
30
static char *FragProgFile = NULL;
 
31
static char *VertProgFile = NULL;
 
32
 
 
33
static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
 
34
static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
 
35
static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f };
 
36
static GLfloat delta = 1.0f;
 
37
 
 
38
static GLuint fragShader;
 
39
static GLuint vertShader;
 
40
static GLuint program;
 
41
 
 
42
static GLint uDiffuse;
 
43
static GLint uSpecular;
 
44
static GLint uTexture;
 
45
 
 
46
static GLuint SphereList, RectList, CurList;
 
47
static GLint win = 0;
 
48
static GLboolean anim = GL_TRUE;
 
49
static GLboolean wire = GL_FALSE;
 
50
static GLboolean pixelLight = GL_TRUE;
 
51
 
 
52
static GLint t0 = 0;
 
53
static GLint frames = 0;
 
54
 
 
55
static GLfloat xRot = 90.0f, yRot = 0.0f;
 
56
 
 
57
 
 
58
static void
 
59
normalize(GLfloat *dst, const GLfloat *src)
 
60
{
 
61
   GLfloat len = sqrt(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
 
62
   dst[0] = src[0] / len;
 
63
   dst[1] = src[1] / len;
 
64
   dst[2] = src[2] / len;
 
65
   dst[3] = src[3];
 
66
}
 
67
 
 
68
 
 
69
static void
 
70
Redisplay(void)
 
71
{
 
72
   GLfloat vec[4];
 
73
 
 
74
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
75
 
 
76
   /* update light position */
 
77
   normalize(vec, lightPos);
 
78
   glLightfv(GL_LIGHT0, GL_POSITION, vec);
 
79
   
 
80
   if (pixelLight) {
 
81
      glUseProgram_func(program);
 
82
      glDisable(GL_LIGHTING);
 
83
   }
 
84
   else {
 
85
      glUseProgram_func(0);
 
86
      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);
 
92
   /*
 
93
   glutSolidSphere(2.0, 10, 5);
 
94
   */
 
95
   glCallList(CurList);
 
96
   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
 
 
115
static void
 
116
Idle(void)
 
117
{
 
118
   lightPos[0] += delta;
 
119
   if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
 
120
      delta = -delta;
 
121
   glutPostRedisplay();
 
122
}
 
123
 
 
124
 
 
125
static void
 
126
Reshape(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
 
 
138
static void
 
139
CleanUp(void)
 
140
{
 
141
   glDeleteShader_func(fragShader);
 
142
   glDeleteShader_func(vertShader);
 
143
   glDeleteProgram_func(program);
 
144
   glutDestroyWindow(win);
 
145
}
 
146
 
 
147
 
 
148
static void
 
149
Key(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;
 
176
   case 'o':
 
177
      if (CurList == SphereList)
 
178
         CurList = RectList;
 
179
      else
 
180
         CurList = SphereList;
 
181
      break;
 
182
   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
 
 
198
static void
 
199
SpecialKey(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
 
 
224
static void
 
225
TestFunctions(void)
 
226
{
 
227
   printf("Error 0x%x at line %d\n", glGetError(), __LINE__);
 
228
   {
 
229
      GLfloat pos[3];
 
230
      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
 
 
286
#if TEXTURE
 
287
static void
 
288
MakeTexture(void)
 
289
{
 
290
#define SZ0 64
 
291
#define SZ1 32
 
292
   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
}
 
354
#endif
 
355
 
 
356
 
 
357
static void
 
358
MakeSphere(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
 
 
368
static void
 
369
VertAttrib(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
 
 
378
static void
 
379
MakeRect(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
 
 
395
static void
 
396
LoadAndCompileShader(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);
 
409
      fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
 
410
      exit(1);
 
411
   }
 
412
}
 
413
 
 
414
 
 
415
/**
 
416
 * Read a shader from a file.
 
417
 */
 
418
static void
 
419
ReadShader(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) {
 
426
      fprintf(stderr, "fslight: Unable to open shader file %s\n", filename);
 
427
      exit(1);
 
428
   }
 
429
 
 
430
   n = fread(buffer, 1, max, f);
 
431
   printf("fslight: read %d bytes from shader file %s\n", n, filename);
 
432
   if (n > 0) {
 
433
      buffer[n] = 0;
 
434
      LoadAndCompileShader(shader, buffer);
 
435
   }
 
436
 
 
437
   fclose(f);
 
438
   free(buffer);
 
439
}
 
440
 
 
441
 
 
442
static void
 
443
CheckLink(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
 
 
456
static void
 
457
Init(void)
 
458
{
 
459
   static const char *fragShaderText =
 
460
      "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"
 
465
      "   float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
 
466
      "                           normalize(normal)), 0.0);\n"
 
467
      "   // 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";
 
476
   const char *version;
 
477
 
 
478
   version = (const char *) glGetString(GL_VERSION);
 
479
   if (version[0] != '2' || version[1] != '.') {
 
480
      printf("This program requires OpenGL 2.x, found %s\n", version);
 
481
      exit(1);
 
482
   }
 
483
 
 
484
   GetExtensionFuncs();
 
485
 
 
486
   fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
 
487
   if (FragProgFile)
 
488
      ReadShader(fragShader, FragProgFile);
 
489
   else
 
490
      LoadAndCompileShader(fragShader, fragShaderText);
 
491
 
 
492
 
 
493
   vertShader = glCreateShader_func(GL_VERTEX_SHADER);
 
494
   if (VertProgFile)
 
495
      ReadShader(vertShader, VertProgFile);
 
496
   else
 
497
      LoadAndCompileShader(vertShader, vertShaderText);
 
498
 
 
499
   program = glCreateProgram_func();
 
500
   glAttachShader_func(program, fragShader);
 
501
   glAttachShader_func(program, vertShader);
 
502
   glLinkProgram_func(program);
 
503
   CheckLink(program);
 
504
   glUseProgram_func(program);
 
505
 
 
506
   uDiffuse = glGetUniformLocation_func(program, "diffuse");
 
507
   uSpecular = glGetUniformLocation_func(program, "specular");
 
508
   uTexture = glGetUniformLocation_func(program, "texture");
 
509
   printf("DiffusePos %d  SpecularPos %d  TexturePos %d\n",
 
510
          uDiffuse, uSpecular, uTexture);
 
511
 
 
512
   glUniform4fv_func(uDiffuse, 1, diffuse);
 
513
   glUniform4fv_func(uSpecular, 1, specular);
 
514
   /*   assert(glGetError() == 0);*/
 
515
   glUniform1i_func(uTexture, 2);  /* use texture unit 2 */
 
516
   /*assert(glGetError() == 0);*/
 
517
 
 
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);*/
 
533
 
 
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
 
 
542
   MakeSphere();
 
543
   MakeRect();
 
544
 
 
545
   CurList = SphereList;
 
546
 
 
547
#if TEXTURE
 
548
   MakeTexture();
 
549
#endif
 
550
 
 
551
   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() */
 
555
   if (0) {
 
556
      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));
 
569
 
 
570
   glColor3f(1, 0, 0);
 
571
 
 
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
 
 
580
#if 0
 
581
   TestFunctions();
 
582
#else
 
583
   (void) TestFunctions;
 
584
#endif
 
585
}
 
586
 
 
587
 
 
588
static void
 
589
ParseOptions(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
   }
 
600
}
 
601
 
 
602
 
 
603
int
 
604
main(int argc, char *argv[])
 
605
{
 
606
   glutInit(&argc, argv);
 
607
   glutInitWindowPosition( 0, 0);
 
608
   glutInitWindowSize(200, 200);
 
609
   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);
 
617
   ParseOptions(argc, argv);
 
618
   Init();
 
619
   glutMainLoop();
 
620
   return 0;
 
621
}
 
622
 
 
623