1
2/*
3 * Demonstrates mixed texgen/non-texgen texture coordinates.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <GL/glew.h>
10#include "glut_wrap.h"
11
12#undef max
13#undef min
14#define max( a, b )	((a) >= (b) ? (a) : (b))
15#define min( a, b )	((a) <= (b) ? (a) : (b))
16
17GLfloat labelColor0[4] = { 1.0, 1.0, 1.0, 1.0 };
18GLfloat labelColor1[4] = { 1.0, 1.0, 0.4, 1.0 };
19GLfloat *labelInfoColor = labelColor0;
20
21GLboolean doubleBuffered = GL_TRUE;
22GLboolean drawTextured = GL_TRUE;
23
24int textureWidth = 64;
25int textureHeight = 64;
26
27int winWidth = 580, winHeight = 720;
28
29const GLfloat texmat_swap_rq[16] = { 1.0, 0.0, 0.0, 0.0,
30                                     0.0, 1.0, 0.0, 0.0,
31                                     0.0, 0.0, 0.0, 1.0,
32                                     0.0, 0.0, 1.0, 0.0};
33
34const GLfloat nullPlane[4] = { 0.0, 0.0, 0.0, 0.0 };
35const GLfloat ObjPlaneS1[4] = { 1.0, 0.0, 1.0, 0.0 };
36const GLfloat ObjPlaneS2[4] = { 0.5, 0.0, 0.0, 0.0 };
37const GLfloat ObjPlaneS3[4] = { 1.0, 0.0, 0.0, 0.0 };
38const GLfloat ObjPlaneT[4] = { 0.0, 1.0, 0.0, 0.0 };
39const GLfloat ObjPlaneT2[4] = { 0.0, 0.5, 0.0, 0.0 };
40const GLfloat ObjPlaneT3[4] = { 0.0, 1.0, 0.0, 0.0 };
41const GLfloat ObjPlaneR[4] = { 0.0, 0.0, 1.0, 0.0 };
42const GLfloat ObjPlaneQ[4] = { 0.0, 0.0, 0.0, 0.5 };
43
44
45static void checkErrors( void )
46{
47   GLenum error;
48
49   while ( (error = glGetError()) != GL_NO_ERROR ) {
50      fprintf( stderr, "Error: %s\n", (char *) gluErrorString( error ) );
51   }
52}
53
54static void drawString( const char *string, GLfloat x, GLfloat y,
55                        const GLfloat color[4] )
56{
57   glColor4fv( color );
58   glRasterPos2f( x, y );
59
60   while ( *string ) {
61      glutBitmapCharacter( GLUT_BITMAP_TIMES_ROMAN_10, *string );
62      string++;
63   }
64}
65
66static void begin2D( int width, int height )
67{
68   glMatrixMode( GL_PROJECTION );
69
70   glPushMatrix();
71   glLoadIdentity();
72
73   glOrtho( 0, width, 0, height, -1, 1 );
74   glMatrixMode( GL_MODELVIEW );
75
76   glPushMatrix();
77   glLoadIdentity();
78}
79
80static void end2D( void )
81{
82   glMatrixMode( GL_PROJECTION );
83   glPopMatrix();
84   glMatrixMode( GL_MODELVIEW );
85   glPopMatrix();
86}
87
88static void initialize( void )
89{
90   glMatrixMode( GL_PROJECTION );
91   glLoadIdentity();
92
93   glOrtho( -1.5, 1.5, -1.5, 1.5, -1.5, 1.5 );
94
95   glMatrixMode(GL_MODELVIEW);
96   glLoadIdentity();
97
98   glShadeModel( GL_FLAT );
99}
100
101/* ARGSUSED1 */
102static void keyboard( unsigned char c, int x, int y )
103{
104   switch ( c ) {
105   case 't':
106      drawTextured = !drawTextured;
107      break;
108   case 27:             /* Escape key should force exit. */
109      exit(0);
110      break;
111   default:
112      break;
113   }
114   glutPostRedisplay();
115}
116
117/* ARGSUSED1 */
118static void special( int key, int x, int y )
119{
120   switch ( key ) {
121   case GLUT_KEY_DOWN:
122      break;
123   case GLUT_KEY_UP:
124      break;
125   case GLUT_KEY_LEFT:
126      break;
127   case GLUT_KEY_RIGHT:
128      break;
129   default:
130      break;
131   }
132   glutPostRedisplay();
133}
134
135static void
136reshape( int w, int h )
137{
138   winWidth = w;
139   winHeight = h;
140   /* No need to call glViewPort here since "draw" calls it! */
141}
142
143static void loadTexture( int width, int height )
144{
145   int		alphaSize = 1;
146   int		rgbSize = 3;
147   GLubyte	*texImage, *p;
148   int		elementsPerGroup, elementSize, groupSize, rowSize;
149   int		i, j;
150
151
152   elementsPerGroup = alphaSize + rgbSize;
153   elementSize = sizeof(GLubyte);
154   groupSize = elementsPerGroup * elementSize;
155   rowSize = width * groupSize;
156
157   if ( (texImage = (GLubyte *) malloc( height * rowSize ) ) == NULL ) {
158      fprintf( stderr, "texture malloc failed\n" );
159      return;
160   }
161
162   for ( i = 0 ; i < height ; i++ )
163   {
164      p = texImage + i * rowSize;
165
166      for ( j = 0 ; j < width ; j++ )
167      {
168	 if ( rgbSize > 0 )
169	 {
170	    /**
171	     ** +-----+-----+
172	     ** |     |     |
173	     ** |  R  |  G  |
174	     ** |     |     |
175	     ** +-----+-----+
176	     ** |     |     |
177	     ** |  Y  |  B  |
178	     ** |     |     |
179	     ** +-----+-----+
180	     **/
181	    if ( i > height / 2 ) {
182	       if ( j < width / 2 ) {
183		  p[0] = 0xff;
184		  p[1] = 0x00;
185		  p[2] = 0x00;
186	       } else {
187		  p[0] = 0x00;
188		  p[1] = 0xff;
189		  p[2] = 0x00;
190	       }
191	    } else {
192	       if ( j < width / 2 ) {
193		  p[0] = 0xff;
194		  p[1] = 0xff;
195		  p[2] = 0x00;
196	       } else {
197		  p[0] = 0x00;
198		  p[1] = 0x00;
199		  p[2] = 0xff;
200	       }
201	    }
202	    p += 3 * elementSize;
203	 }
204
205	 if ( alphaSize > 0 )
206	 {
207	    /**
208	     ** +-----------+
209	     ** |     W     |
210	     ** |  +-----+  |
211	     ** |  |     |  |
212	     ** |  |  B  |  |
213	     ** |  |     |  |
214	     ** |  +-----+  |
215	     ** |           |
216	     ** +-----------+
217	     **/
218	    int i2 = i - height / 2;
219	    int j2 = j - width / 2;
220	    int h8 = height / 8;
221	    int w8 = width / 8;
222	    if ( -h8 <= i2 && i2 <= h8 && -w8 <= j2 && j2 <= w8 ) {
223	       p[0] = 0x00;
224	    } else if ( -2 * h8 <= i2 && i2 <= 2 * h8 && -2 * w8 <= j2 && j2 <= 2 * w8 ) {
225	       p[0] = 0x55;
226	    } else if ( -3 * h8 <= i2 && i2 <= 3 * h8 && -3 * w8 <= j2 && j2 <= 3 * w8 ) {
227	       p[0] = 0xaa;
228	    } else {
229	       p[0] = 0xff;
230	    }
231	    p += elementSize;
232	 }
233      }
234   }
235
236   glTexImage2D( GL_TEXTURE_2D, 0,
237		 GL_RGBA, width, height, 0,
238		 GL_RGBA, GL_UNSIGNED_BYTE, texImage );
239
240   free( texImage );
241}
242
243
244static void drawSample( int x, int y, int w, int h,
245                        int texgenenabled, int coordnr )
246{
247   char buf[255];
248
249   glViewport( x, y, w, h );
250   glScissor( x, y, w, h );
251
252   glClearColor( 0.1, 0.1, 0.1, 1.0 );
253   glClear( GL_COLOR_BUFFER_BIT );
254
255   begin2D( w, h );
256   if (texgenenabled == 2) {
257      sprintf( buf, "TexCoord%df", coordnr);
258      drawString( buf, 10, h - 15, labelInfoColor );
259      sprintf( buf, "texgen enabled for %s coordinate(s)", coordnr == 2 ? "S" : "S/T");
260      drawString( buf, 10, 5, labelInfoColor );
261   }
262   else if (texgenenabled == 0) {
263      sprintf( buf, "TexCoord%df", coordnr);
264      drawString( buf, 10, h - 15, labelInfoColor );
265      drawString( "no texgen", 10, 5, labelInfoColor );
266   }
267   else if (texgenenabled == 1) {
268      drawString( "no TexCoord", 10, h - 15, labelInfoColor );
269      sprintf( buf, "texgen enabled for %s coordinate(s)",
270         coordnr == 2 ? "S/T" : (coordnr == 3 ? "S/T/R" : "S/T/R/Q"));
271      drawString( buf, 10, 5, labelInfoColor );
272   }
273
274   end2D();
275
276   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
277
278   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
279   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
280
281   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
282   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
283
284   loadTexture( textureWidth, textureHeight );
285
286   if ( drawTextured ) {
287      glEnable( GL_TEXTURE_2D );
288   }
289
290   glDisable( GL_TEXTURE_GEN_S );
291   glDisable( GL_TEXTURE_GEN_T );
292   glDisable( GL_TEXTURE_GEN_R );
293   glDisable( GL_TEXTURE_GEN_Q );
294
295   glMatrixMode( GL_TEXTURE );
296   glLoadIdentity();
297   glMatrixMode( GL_MODELVIEW );
298   glPushMatrix();
299
300   switch (coordnr) {
301   case 2:
302      switch (texgenenabled) {
303      case 0:
304         glBegin( GL_QUADS );
305         glTexCoord2f( 0.0, 0.0 );
306         glVertex2f( -0.8, -0.8 );
307
308         glTexCoord2f( 1.0, 0.0 );
309         glVertex2f( 0.8, -0.8 );
310
311         glTexCoord2f( 1.0, 1.0 );
312         glVertex2f( 0.8, 0.8 );
313
314         glTexCoord2f( 0.0, 1.0 );
315         glVertex2f( -0.8, 0.8 );
316         glEnd();
317         break;
318      case 1:
319         glTranslatef( -0.8, -0.8, 0.0 );
320         glScalef( 1.6, 1.6, 1.0 );
321         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
322         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
323         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
324         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
325         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS3);
326         glTexGenfv(GL_T, GL_OBJECT_PLANE, ObjPlaneT3);
327         glTexGenfv(GL_R, GL_OBJECT_PLANE, nullPlane);
328         glTexGenfv(GL_Q, GL_OBJECT_PLANE, nullPlane);
329
330         glEnable( GL_TEXTURE_GEN_S );
331         glEnable( GL_TEXTURE_GEN_T );
332
333         /* Issue a texcoord here to be sure Q isn't left over from a
334          * previous sample.
335          */
336         glTexCoord1f( 0.0 );
337         glBegin( GL_QUADS );
338         glVertex2f( 0.0, 0.0 );
339         glVertex2f( 1.0, 0.0 );
340         glVertex2f( 1.0, 1.0 );
341         glVertex2f( 0.0, 1.0 );
342         glEnd();
343         break;
344      case 2:
345         /* make sure that texgen T and non-texgen S coordinate are wrong */
346         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
347         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
348         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
349         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
350         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS1);
351         glTexGenfv(GL_T, GL_OBJECT_PLANE, nullPlane);
352         glTexGenfv(GL_R, GL_OBJECT_PLANE, nullPlane);
353         glTexGenfv(GL_Q, GL_OBJECT_PLANE, nullPlane);
354
355         glEnable( GL_TEXTURE_GEN_S );
356
357         glBegin( GL_QUADS );
358         /* use z coordinate to get correct texgen values... */
359         glTexCoord2f( 0.0, 0.0 );
360         glVertex3f( -0.8, -0.8, 0.8 );
361
362         glTexCoord2f( 0.0, 0.0 );
363         glVertex3f( 0.8, -0.8, 0.2 );
364
365         glTexCoord2f( 0.0, 1.0 );
366         glVertex3f( 0.8, 0.8, 0.2 );
367
368         glTexCoord2f( 0.0, 1.0 );
369         glVertex3f( -0.8, 0.8, 0.8 );
370         glEnd();
371         break;
372      }
373      break;
374   case 3:
375      glMatrixMode( GL_TEXTURE );
376      glLoadMatrixf( texmat_swap_rq );
377      glMatrixMode( GL_MODELVIEW );
378      glTranslatef( -0.8, -0.8, 0.0 );
379      glScalef( 1.6, 1.6, 1.0 );
380      switch (texgenenabled) {
381      case 0:
382         glBegin( GL_QUADS );
383         glTexCoord3f( 0.0, 0.0, 0.5 );
384         glVertex2f( 0.0, 0.0 );
385
386         glTexCoord3f( 0.5, 0.0, 0.5 );
387         glVertex2f( 1.0, 0.0 );
388
389         glTexCoord3f( 0.5, 0.5, 0.5 );
390         glVertex2f( 1.0, 1.0 );
391
392         glTexCoord3f( 0.0, 0.5, 0.5 );
393         glVertex2f( 0.0, 1.0 );
394         glEnd();
395         break;
396      case 1:
397         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
398         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
399         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
400         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
401         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS2);
402         glTexGenfv(GL_T, GL_OBJECT_PLANE, ObjPlaneT2);
403         glTexGenfv(GL_R, GL_OBJECT_PLANE, ObjPlaneR);
404         glTexGenfv(GL_Q, GL_OBJECT_PLANE, nullPlane);
405
406         glEnable( GL_TEXTURE_GEN_S );
407         glEnable( GL_TEXTURE_GEN_T );
408         glEnable( GL_TEXTURE_GEN_R );
409
410         glTexCoord1f( 0.0 ); /* to make sure Q is 1.0 */
411         glBegin( GL_QUADS );
412         glVertex3f( 0.0, 0.0, 0.5 );
413         glVertex3f( 1.0, 0.0, 0.5 );
414         glVertex3f( 1.0, 1.0, 0.5 );
415         glVertex3f( 0.0, 1.0, 0.5 );
416         glEnd();
417         break;
418      case 2:
419         /* make sure that texgen R/Q and non-texgen S/T coordinates are wrong */
420         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
421         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
422         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
423         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
424         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS2);
425         glTexGenfv(GL_T, GL_OBJECT_PLANE, ObjPlaneT2);
426         glTexGenfv(GL_R, GL_OBJECT_PLANE, nullPlane);
427         glTexGenfv(GL_Q, GL_OBJECT_PLANE, nullPlane);
428
429         glEnable( GL_TEXTURE_GEN_S );
430         glEnable( GL_TEXTURE_GEN_T );
431
432         glBegin( GL_QUADS );
433         glTexCoord3f( 0.0, 0.0, 0.5 );
434         glVertex2f( 0.0, 0.0);
435
436         glTexCoord3f( 0.0, 0.0, 0.5 );
437         glVertex2f( 1.0, 0.0);
438
439         glTexCoord3f( 0.0, 0.0, 0.5 );
440         glVertex2f( 1.0, 1.0);
441
442         glTexCoord3f( 0.0, 0.0, 0.5 );
443         glVertex2f( 0.0, 1.0);
444         glEnd();
445         break;
446      }
447      break;
448   case 4:
449      switch (texgenenabled) {
450      case 0:
451         glBegin( GL_QUADS );
452         /* don't need r coordinate but still setting it I'm mean */
453         glTexCoord4f( 0.0, 0.0, 0.0, 0.5 );
454         glVertex2f( -0.8, -0.8 );
455
456         glTexCoord4f( 0.5, 0.0, 0.2, 0.5 );
457         glVertex2f( 0.8, -0.8 );
458
459         glTexCoord4f( 0.5, 0.5, 0.5, 0.5 );
460         glVertex2f( 0.8, 0.8 );
461
462         glTexCoord4f( 0.0, 0.5, 0.5, 0.5 );
463         glVertex2f( -0.8, 0.8 );
464         glEnd();
465         break;
466      case 1:
467         glTranslatef( -0.8, -0.8, 0.0 );
468         glScalef( 1.6, 1.6, 1.0 );
469         /* make sure that texgen R/Q and non-texgen S/T coordinates are wrong */
470         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
471         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
472         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
473         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
474         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS2);
475         glTexGenfv(GL_T, GL_OBJECT_PLANE, ObjPlaneT2);
476         glTexGenfv(GL_R, GL_OBJECT_PLANE, ObjPlaneR);
477         glTexGenfv(GL_Q, GL_OBJECT_PLANE, ObjPlaneQ);
478
479         glEnable( GL_TEXTURE_GEN_S );
480         glEnable( GL_TEXTURE_GEN_T );
481         glEnable( GL_TEXTURE_GEN_R );
482         glEnable( GL_TEXTURE_GEN_Q );
483
484         glBegin( GL_QUADS );
485         glVertex2f( 0.0, 0.0 );
486         glVertex2f( 1.0, 0.0 );
487         glVertex2f( 1.0, 1.0 );
488         glVertex2f( 0.0, 1.0 );
489         glEnd();
490         break;
491      case 2:
492         glTranslatef( -0.8, -0.8, 0.0 );
493         glScalef( 1.6, 1.6, 1.0 );
494         /* make sure that texgen R/Q and non-texgen S/T coordinates are wrong */
495         glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
496         glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
497         glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
498         glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
499         glTexGenfv(GL_S, GL_OBJECT_PLANE, ObjPlaneS2);
500         glTexGenfv(GL_T, GL_OBJECT_PLANE, ObjPlaneT2);
501         glTexGenfv(GL_R, GL_OBJECT_PLANE, nullPlane);
502         glTexGenfv(GL_Q, GL_OBJECT_PLANE, nullPlane);
503
504         glEnable( GL_TEXTURE_GEN_S );
505         glEnable( GL_TEXTURE_GEN_T );
506
507         glBegin( GL_QUADS );
508         glTexCoord4f( 0.0, 0.0, 0.0, 0.5 );
509         glVertex2f( 0.0, 0.0 );
510
511         glTexCoord4f( 0.0, 0.0, 0.2, 0.5 );
512         glVertex2f( 1.0, 0.0 );
513
514         glTexCoord4f( 0.0, 0.0, 0.5, 0.5 );
515         glVertex2f( 1.0, 1.0 );
516
517         glTexCoord4f( 0.0, 0.0, 0.75, 0.5 );
518         glVertex2f( 0.0, 1.0 );
519         glEnd();
520         break;
521      }
522      break;
523   }
524
525   glPopMatrix();
526   glDisable( GL_TEXTURE_2D );
527
528}
529
530static void display( void )
531{
532   int		numX = 3, numY = 3;
533   float	xBase = (float) winWidth * 0.01;
534   float	xOffset = (winWidth - xBase) / numX;
535   float	xSize = max( xOffset - xBase, 1 );
536   float	yBase = (float) winHeight * 0.01;
537   float	yOffset = (winHeight - yBase) / numY;
538   float	ySize = max( yOffset - yBase, 1 );
539   float	x, y;
540   int		i, j;
541
542   glViewport( 0, 0, winWidth, winHeight );
543   glDisable( GL_SCISSOR_TEST );
544   glClearColor( 0.0, 0.0, 0.0, 0.0 );
545   glClear( GL_COLOR_BUFFER_BIT );
546   glEnable( GL_SCISSOR_TEST );
547
548   x = xBase;
549   y = (winHeight - 1) - yOffset;
550
551   for ( i = 0 ; i < numY ; i++ )
552   {
553
554      labelInfoColor = labelColor1;
555
556
557      for ( j = 0 ; j < numX ; j++ ) {
558	 drawSample( x, y, xSize, ySize, i, j+2 );
559	 x += xOffset;
560      }
561
562      x = xBase;
563      y -= yOffset;
564   }
565
566   if ( doubleBuffered ) {
567      glutSwapBuffers();
568   } else {
569      glFlush();
570   }
571
572   checkErrors();
573}
574
575static void usage( char *name )
576{
577   fprintf( stderr, "usage: %s [ options ]\n", name );
578   fprintf( stderr, "\n" );
579   fprintf( stderr, "options:\n" );
580   fprintf( stderr, "    -sb    single buffered\n" );
581   fprintf( stderr, "    -db    double buffered\n" );
582   fprintf( stderr, "    -info  print OpenGL driver info\n" );
583}
584
585static void instructions( void )
586{
587   fprintf( stderr, "texgenmix - mixed texgen/non-texgen texture coordinate test\n" );
588   fprintf( stderr, "all quads should look the same!\n" );
589   fprintf( stderr, "\n" );
590   fprintf( stderr, "  [t] - toggle texturing\n" );
591}
592
593int main( int argc, char *argv[] )
594{
595   GLboolean info = GL_FALSE;
596   int i;
597
598   glutInit( &argc, argv );
599
600   for ( i = 1 ; i < argc ; i++ ) {
601      if ( !strcmp( "-sb", argv[i] ) ) {
602	 doubleBuffered = GL_FALSE;
603      } else if ( !strcmp( "-db", argv[i] ) ) {
604	 doubleBuffered = GL_TRUE;
605      } else if ( !strcmp( "-info", argv[i] ) ) {
606	 info = GL_TRUE;
607      } else {
608	 usage( argv[0] );
609	 exit( 1 );
610      }
611   }
612
613   if ( doubleBuffered ) {
614      glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
615   } else {
616      glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
617   }
618
619   glutInitWindowSize( winWidth, winHeight );
620   glutInitWindowPosition( 0, 0 );
621   glutCreateWindow( "Mixed texgen/non-texgen texture coordinate test" );
622   glewInit();
623
624   initialize();
625   instructions();
626
627   if ( info ) {
628      printf( "\n" );
629      printf( "GL_RENDERER   = %s\n", (char *) glGetString( GL_RENDERER ) );
630      printf( "GL_VERSION    = %s\n", (char *) glGetString( GL_VERSION ) );
631      printf( "GL_VENDOR     = %s\n", (char *) glGetString( GL_VENDOR ) ) ;
632      printf( "GL_EXTENSIONS = %s\n", (char *) glGetString( GL_EXTENSIONS ) );
633   }
634
635   glutDisplayFunc( display );
636   glutReshapeFunc( reshape );
637   glutKeyboardFunc( keyboard );
638   glutSpecialFunc( special );
639   glutMainLoop();
640
641   return 0;
642}
643