SDL-1.2.14
[sdl_omap.git] / test / testgl.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <math.h>
5
6 #include "SDL.h"
7
8 #ifdef __MACOS__
9 #define HAVE_OPENGL
10 #endif
11
12 #ifdef HAVE_OPENGL
13
14 #include "SDL_opengl.h"
15
16 /* Undefine this if you want a flat cube instead of a rainbow cube */
17 #define SHADED_CUBE
18
19 /* Define this to be the name of the logo image to use with -logo */
20 #define LOGO_FILE       "icon.bmp"
21
22 /* The SDL_OPENGLBLIT interface is deprecated.
23    The code is still available for benchmark purposes though.
24 */
25
26 static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
27
28 static SDL_Surface *global_image = NULL;
29 static GLuint global_texture = 0;
30 static GLuint cursor_texture = 0;
31
32 /**********************************************************************/
33
34 void HotKey_ToggleFullScreen(void)
35 {
36         SDL_Surface *screen;
37
38         screen = SDL_GetVideoSurface();
39         if ( SDL_WM_ToggleFullScreen(screen) ) {
40                 printf("Toggled fullscreen mode - now %s\n",
41                     (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
42         } else {
43                 printf("Unable to toggle fullscreen mode\n");
44         }
45 }
46
47 void HotKey_ToggleGrab(void)
48 {
49         SDL_GrabMode mode;
50
51         printf("Ctrl-G: toggling input grab!\n");
52         mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
53         if ( mode == SDL_GRAB_ON ) {
54                 printf("Grab was on\n");
55         } else {
56                 printf("Grab was off\n");
57         }
58         mode = SDL_WM_GrabInput(!mode);
59         if ( mode == SDL_GRAB_ON ) {
60                 printf("Grab is now on\n");
61         } else {
62                 printf("Grab is now off\n");
63         }
64 }
65
66 void HotKey_Iconify(void)
67 {
68         printf("Ctrl-Z: iconifying window!\n");
69         SDL_WM_IconifyWindow();
70 }
71
72 int HandleEvent(SDL_Event *event)
73 {
74         int done;
75
76         done = 0;
77         switch( event->type ) {
78             case SDL_ACTIVEEVENT:
79                 /* See what happened */
80                 printf( "app %s ", event->active.gain ? "gained" : "lost" );
81                 if ( event->active.state & SDL_APPACTIVE ) {
82                         printf( "active " );
83                 } else if ( event->active.state & SDL_APPMOUSEFOCUS ) {
84                         printf( "mouse " );
85                 } else if ( event->active.state & SDL_APPINPUTFOCUS ) {
86                         printf( "input " );
87                 }
88                 printf( "focus\n" );
89                 break;
90                 
91
92             case SDL_KEYDOWN:
93                 if ( event->key.keysym.sym == SDLK_ESCAPE ) {
94                         done = 1;
95                 }
96                 if ( (event->key.keysym.sym == SDLK_g) &&
97                      (event->key.keysym.mod & KMOD_CTRL) ) {
98                         HotKey_ToggleGrab();
99                 }
100                 if ( (event->key.keysym.sym == SDLK_z) &&
101                      (event->key.keysym.mod & KMOD_CTRL) ) {
102                         HotKey_Iconify();
103                 }
104                 if ( (event->key.keysym.sym == SDLK_RETURN) &&
105                      (event->key.keysym.mod & KMOD_ALT) ) {
106                         HotKey_ToggleFullScreen();
107                 }
108                 printf("key '%s' pressed\n", 
109                         SDL_GetKeyName(event->key.keysym.sym));
110                 break;
111             case SDL_QUIT:
112                 done = 1;
113                 break;
114         }
115         return(done);
116 }
117
118 void SDL_GL_Enter2DMode()
119 {
120         SDL_Surface *screen = SDL_GetVideoSurface();
121
122         /* Note, there may be other things you need to change,
123            depending on how you have your OpenGL state set up.
124         */
125         glPushAttrib(GL_ENABLE_BIT);
126         glDisable(GL_DEPTH_TEST);
127         glDisable(GL_CULL_FACE);
128         glEnable(GL_TEXTURE_2D);
129
130         /* This allows alpha blending of 2D textures with the scene */
131         glEnable(GL_BLEND);
132         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
133
134         glViewport(0, 0, screen->w, screen->h);
135
136         glMatrixMode(GL_PROJECTION);
137         glPushMatrix();
138         glLoadIdentity();
139
140         glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
141
142         glMatrixMode(GL_MODELVIEW);
143         glPushMatrix();
144         glLoadIdentity();
145
146         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
147 }
148
149 void SDL_GL_Leave2DMode()
150 {
151         glMatrixMode(GL_MODELVIEW);
152         glPopMatrix();
153
154         glMatrixMode(GL_PROJECTION);
155         glPopMatrix();
156
157         glPopAttrib();
158 }
159
160 /* Quick utility function for texture creation */
161 static int power_of_two(int input)
162 {
163         int value = 1;
164
165         while ( value < input ) {
166                 value <<= 1;
167         }
168         return value;
169 }
170
171 GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
172 {
173         GLuint texture;
174         int w, h;
175         SDL_Surface *image;
176         SDL_Rect area;
177         Uint32 saved_flags;
178         Uint8  saved_alpha;
179
180         /* Use the surface width and height expanded to powers of 2 */
181         w = power_of_two(surface->w);
182         h = power_of_two(surface->h);
183         texcoord[0] = 0.0f;                     /* Min X */
184         texcoord[1] = 0.0f;                     /* Min Y */
185         texcoord[2] = (GLfloat)surface->w / w;  /* Max X */
186         texcoord[3] = (GLfloat)surface->h / h;  /* Max Y */
187
188         image = SDL_CreateRGBSurface(
189                         SDL_SWSURFACE,
190                         w, h,
191                         32,
192 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
193                         0x000000FF, 
194                         0x0000FF00, 
195                         0x00FF0000, 
196                         0xFF000000
197 #else
198                         0xFF000000,
199                         0x00FF0000, 
200                         0x0000FF00, 
201                         0x000000FF
202 #endif
203                        );
204         if ( image == NULL ) {
205                 return 0;
206         }
207
208         /* Save the alpha blending attributes */
209         saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
210         saved_alpha = surface->format->alpha;
211         if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
212                 SDL_SetAlpha(surface, 0, 0);
213         }
214
215         /* Copy the surface into the GL texture image */
216         area.x = 0;
217         area.y = 0;
218         area.w = surface->w;
219         area.h = surface->h;
220         SDL_BlitSurface(surface, &area, image, &area);
221
222         /* Restore the alpha blending attributes */
223         if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
224                 SDL_SetAlpha(surface, saved_flags, saved_alpha);
225         }
226
227         /* Create an OpenGL texture for the image */
228         glGenTextures(1, &texture);
229         glBindTexture(GL_TEXTURE_2D, texture);
230         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
231         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
232         glTexImage2D(GL_TEXTURE_2D,
233                      0,
234                      GL_RGBA,
235                      w, h,
236                      0,
237                      GL_RGBA,
238                      GL_UNSIGNED_BYTE,
239                      image->pixels);
240         SDL_FreeSurface(image); /* No longer needed */
241
242         return texture;
243 }
244
245 void DrawLogoCursor(void)
246 {
247         static GLfloat texMinX, texMinY;
248         static GLfloat texMaxX, texMaxY;
249         static int w, h;
250         int x, y;
251
252         if ( ! cursor_texture ) {
253                 SDL_Surface *image;
254                 GLfloat texcoord[4];
255
256                 /* Load the image (could use SDL_image library here) */
257                 image = SDL_LoadBMP(LOGO_FILE);
258                 if ( image == NULL ) {
259                         return;
260                 }
261                 w = image->w;
262                 h = image->h;
263
264                 /* Convert the image into an OpenGL texture */
265                 cursor_texture = SDL_GL_LoadTexture(image, texcoord);
266
267                 /* Make texture coordinates easy to understand */
268                 texMinX = texcoord[0];
269                 texMinY = texcoord[1];
270                 texMaxX = texcoord[2];
271                 texMaxY = texcoord[3];
272
273                 /* We don't need the original image anymore */
274                 SDL_FreeSurface(image);
275
276                 /* Make sure that the texture conversion is okay */
277                 if ( ! cursor_texture ) {
278                         return;
279                 }
280         }
281
282         /* Move the image around */
283         SDL_GetMouseState(&x, &y);
284         x -= w/2;
285         y -= h/2;
286
287         /* Show the image on the screen */
288         SDL_GL_Enter2DMode();
289         glBindTexture(GL_TEXTURE_2D, cursor_texture);
290         glBegin(GL_TRIANGLE_STRIP);
291         glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
292         glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
293         glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
294         glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
295         glEnd();
296         SDL_GL_Leave2DMode();
297 }
298
299 void DrawLogoTexture(void)
300 {
301         static GLfloat texMinX, texMinY;
302         static GLfloat texMaxX, texMaxY;
303         static int x = 0;
304         static int y = 0;
305         static int w, h;
306         static int delta_x = 1;
307         static int delta_y = 1;
308
309         SDL_Surface *screen = SDL_GetVideoSurface();
310
311         if ( ! global_texture ) {
312                 SDL_Surface *image;
313                 GLfloat texcoord[4];
314
315                 /* Load the image (could use SDL_image library here) */
316                 image = SDL_LoadBMP(LOGO_FILE);
317                 if ( image == NULL ) {
318                         return;
319                 }
320                 w = image->w;
321                 h = image->h;
322
323                 /* Convert the image into an OpenGL texture */
324                 global_texture = SDL_GL_LoadTexture(image, texcoord);
325
326                 /* Make texture coordinates easy to understand */
327                 texMinX = texcoord[0];
328                 texMinY = texcoord[1];
329                 texMaxX = texcoord[2];
330                 texMaxY = texcoord[3];
331
332                 /* We don't need the original image anymore */
333                 SDL_FreeSurface(image);
334
335                 /* Make sure that the texture conversion is okay */
336                 if ( ! global_texture ) {
337                         return;
338                 }
339         }
340
341         /* Move the image around */
342         x += delta_x;
343         if ( x < 0 ) {
344                 x = 0;
345                 delta_x = -delta_x;
346         } else
347         if ( (x+w) > screen->w ) {
348                 x = screen->w-w;
349                 delta_x = -delta_x;
350         }
351         y += delta_y;
352         if ( y < 0 ) {
353                 y = 0;
354                 delta_y = -delta_y;
355         } else
356         if ( (y+h) > screen->h ) {
357                 y = screen->h-h;
358                 delta_y = -delta_y;
359         }
360
361         /* Show the image on the screen */
362         SDL_GL_Enter2DMode();
363         glBindTexture(GL_TEXTURE_2D, global_texture);
364         glBegin(GL_TRIANGLE_STRIP);
365         glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
366         glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
367         glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
368         glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
369         glEnd();
370         SDL_GL_Leave2DMode();
371 }
372
373 /* This code is deprecated, but available for speed comparisons */
374 void DrawLogoBlit(void)
375 {
376         static int x = 0;
377         static int y = 0;
378         static int w, h;
379         static int delta_x = 1;
380         static int delta_y = 1;
381
382         SDL_Rect dst;
383         SDL_Surface *screen = SDL_GetVideoSurface();
384
385         if ( global_image == NULL ) {
386                 SDL_Surface *temp;
387
388                 /* Load the image (could use SDL_image library here) */
389                 temp = SDL_LoadBMP(LOGO_FILE);
390                 if ( temp == NULL ) {
391                         return;
392                 }
393                 w = temp->w;
394                 h = temp->h;
395
396                 /* Convert the image into the screen format */
397                 global_image = SDL_CreateRGBSurface(
398                                 SDL_SWSURFACE,
399                                 w, h,
400                                 screen->format->BitsPerPixel,
401                                 screen->format->Rmask,
402                                 screen->format->Gmask,
403                                 screen->format->Bmask,
404                                 screen->format->Amask);
405                 if ( global_image ) {
406                         SDL_BlitSurface(temp, NULL, global_image, NULL);
407                 }
408                 SDL_FreeSurface(temp);
409
410                 /* Make sure that the texture conversion is okay */
411                 if ( ! global_image ) {
412                         return;
413                 }
414         }
415
416         /* Move the image around
417            Note that we do not clear the old position.  This is because we
418            perform a glClear() which clears the framebuffer and then only
419            update the new area.
420            Note that you can also achieve interesting effects by modifying
421            the screen surface alpha channel.  It's set to 255 by default..
422          */
423         x += delta_x;
424         if ( x < 0 ) {
425                 x = 0;
426                 delta_x = -delta_x;
427         } else
428         if ( (x+w) > screen->w ) {
429                 x = screen->w-w;
430                 delta_x = -delta_x;
431         }
432         y += delta_y;
433         if ( y < 0 ) {
434                 y = 0;
435                 delta_y = -delta_y;
436         } else
437         if ( (y+h) > screen->h ) {
438                 y = screen->h-h;
439                 delta_y = -delta_y;
440         }
441         dst.x = x;
442         dst.y = y;
443         dst.w = w;
444         dst.h = h;
445         SDL_BlitSurface(global_image, NULL, screen, &dst);
446
447         /* Show the image on the screen */
448         SDL_UpdateRects(screen, 1, &dst);
449 }
450
451 int RunGLTest( int argc, char* argv[],
452                int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync, int accel )
453 {
454         int i;
455         int rgb_size[3];
456         int w = 640;
457         int h = 480;
458         int done = 0;
459         int frames;
460         Uint32 start_time, this_time;
461         float color[8][3]= {{ 1.0,  1.0,  0.0}, 
462                             { 1.0,  0.0,  0.0},
463                             { 0.0,  0.0,  0.0},
464                             { 0.0,  1.0,  0.0},
465                             { 0.0,  1.0,  1.0},
466                             { 1.0,  1.0,  1.0},
467                             { 1.0,  0.0,  1.0},
468                             { 0.0,  0.0,  1.0}};
469         float cube[8][3]= {{ 0.5,  0.5, -0.5}, 
470                            { 0.5, -0.5, -0.5},
471                            {-0.5, -0.5, -0.5},
472                            {-0.5,  0.5, -0.5},
473                            {-0.5,  0.5,  0.5},
474                            { 0.5,  0.5,  0.5},
475                            { 0.5, -0.5,  0.5},
476                            {-0.5, -0.5,  0.5}};
477         Uint32 video_flags;
478         int value;
479
480         if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
481                 fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
482                 exit( 1 );
483         }
484
485         /* See if we should detect the display depth */
486         if ( bpp == 0 ) {
487                 if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
488                         bpp = 8;
489                 } else {
490                         bpp = 16;  /* More doesn't seem to work */
491                 }
492         }
493
494         /* Set the flags we want to use for setting the video mode */
495         if ( logo && USE_DEPRECATED_OPENGLBLIT ) {
496                 video_flags = SDL_OPENGLBLIT;
497         } else {
498                 video_flags = SDL_OPENGL;
499         }
500         for ( i=1; argv[i]; ++i ) {
501                 if ( strcmp(argv[i], "-fullscreen") == 0 ) {
502                         video_flags |= SDL_FULLSCREEN;
503                 }
504         }
505
506         if (noframe) {
507            video_flags |= SDL_NOFRAME;
508         }
509
510         /* Initialize the display */
511         switch (bpp) {
512             case 8:
513                 rgb_size[0] = 3;
514                 rgb_size[1] = 3;
515                 rgb_size[2] = 2;
516                 break;
517             case 15:
518             case 16:
519                 rgb_size[0] = 5;
520                 rgb_size[1] = 5;
521                 rgb_size[2] = 5;
522                 break;
523             default:
524                 rgb_size[0] = 8;
525                 rgb_size[1] = 8;
526                 rgb_size[2] = 8;
527                 break;
528         }
529         SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
530         SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
531         SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
532         SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
533         SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
534         if ( fsaa ) {
535                 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
536                 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa );
537         }
538         if ( accel ) {
539                 SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
540         }
541         if ( sync ) {
542                 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
543         } else {
544                 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
545         }
546         if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
547                 fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
548                 SDL_Quit();
549                 exit(1);
550         }
551
552         printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
553         printf("\n");
554         printf( "Vendor     : %s\n", glGetString( GL_VENDOR ) );
555         printf( "Renderer   : %s\n", glGetString( GL_RENDERER ) );
556         printf( "Version    : %s\n", glGetString( GL_VERSION ) );
557         printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
558         printf("\n");
559
560         SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
561         printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
562         SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
563         printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
564         SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
565         printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
566         SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
567         printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
568         SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
569         printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
570         if ( fsaa ) {
571                 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &value );
572                 printf("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value );
573                 SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value );
574                 printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value );
575         }
576         if ( accel ) {
577                 SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL, &value );
578                 printf( "SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value );
579         }
580         if ( sync ) {
581                 SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL, &value );
582                 printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value );
583         }
584
585         /* Set the window manager title bar */
586         SDL_WM_SetCaption( "SDL GL test", "testgl" );
587
588         /* Set the gamma for the window */
589         if ( gamma != 0.0 ) {
590                 SDL_SetGamma(gamma, gamma, gamma);
591         }
592
593         glViewport( 0, 0, w, h );
594         glMatrixMode( GL_PROJECTION );
595         glLoadIdentity( );
596
597         glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
598
599         glMatrixMode( GL_MODELVIEW );
600         glLoadIdentity( );
601
602         glEnable(GL_DEPTH_TEST);
603
604         glDepthFunc(GL_LESS);
605
606         glShadeModel(GL_SMOOTH);
607
608         /* Loop until done. */
609         start_time = SDL_GetTicks();
610         frames = 0;
611         while( !done ) {
612                 GLenum gl_error;
613                 char* sdl_error;
614                 SDL_Event event;
615
616                 /* Do our drawing, too. */
617                 glClearColor( 0.0, 0.0, 0.0, 1.0 );
618                 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
619
620                 glBegin( GL_QUADS );
621
622 #ifdef SHADED_CUBE
623                         glColor3fv(color[0]);
624                         glVertex3fv(cube[0]);
625                         glColor3fv(color[1]);
626                         glVertex3fv(cube[1]);
627                         glColor3fv(color[2]);
628                         glVertex3fv(cube[2]);
629                         glColor3fv(color[3]);
630                         glVertex3fv(cube[3]);
631                         
632                         glColor3fv(color[3]);
633                         glVertex3fv(cube[3]);
634                         glColor3fv(color[4]);
635                         glVertex3fv(cube[4]);
636                         glColor3fv(color[7]);
637                         glVertex3fv(cube[7]);
638                         glColor3fv(color[2]);
639                         glVertex3fv(cube[2]);
640                         
641                         glColor3fv(color[0]);
642                         glVertex3fv(cube[0]);
643                         glColor3fv(color[5]);
644                         glVertex3fv(cube[5]);
645                         glColor3fv(color[6]);
646                         glVertex3fv(cube[6]);
647                         glColor3fv(color[1]);
648                         glVertex3fv(cube[1]);
649                         
650                         glColor3fv(color[5]);
651                         glVertex3fv(cube[5]);
652                         glColor3fv(color[4]);
653                         glVertex3fv(cube[4]);
654                         glColor3fv(color[7]);
655                         glVertex3fv(cube[7]);
656                         glColor3fv(color[6]);
657                         glVertex3fv(cube[6]);
658
659                         glColor3fv(color[5]);
660                         glVertex3fv(cube[5]);
661                         glColor3fv(color[0]);
662                         glVertex3fv(cube[0]);
663                         glColor3fv(color[3]);
664                         glVertex3fv(cube[3]);
665                         glColor3fv(color[4]);
666                         glVertex3fv(cube[4]);
667
668                         glColor3fv(color[6]);
669                         glVertex3fv(cube[6]);
670                         glColor3fv(color[1]);
671                         glVertex3fv(cube[1]);
672                         glColor3fv(color[2]);
673                         glVertex3fv(cube[2]);
674                         glColor3fv(color[7]);
675                         glVertex3fv(cube[7]);
676 #else /* flat cube */
677                         glColor3f(1.0, 0.0, 0.0);
678                         glVertex3fv(cube[0]);
679                         glVertex3fv(cube[1]);
680                         glVertex3fv(cube[2]);
681                         glVertex3fv(cube[3]);
682                         
683                         glColor3f(0.0, 1.0, 0.0);
684                         glVertex3fv(cube[3]);
685                         glVertex3fv(cube[4]);
686                         glVertex3fv(cube[7]);
687                         glVertex3fv(cube[2]);
688                         
689                         glColor3f(0.0, 0.0, 1.0);
690                         glVertex3fv(cube[0]);
691                         glVertex3fv(cube[5]);
692                         glVertex3fv(cube[6]);
693                         glVertex3fv(cube[1]);
694                         
695                         glColor3f(0.0, 1.0, 1.0);
696                         glVertex3fv(cube[5]);
697                         glVertex3fv(cube[4]);
698                         glVertex3fv(cube[7]);
699                         glVertex3fv(cube[6]);
700
701                         glColor3f(1.0, 1.0, 0.0);
702                         glVertex3fv(cube[5]);
703                         glVertex3fv(cube[0]);
704                         glVertex3fv(cube[3]);
705                         glVertex3fv(cube[4]);
706
707                         glColor3f(1.0, 0.0, 1.0);
708                         glVertex3fv(cube[6]);
709                         glVertex3fv(cube[1]);
710                         glVertex3fv(cube[2]);
711                         glVertex3fv(cube[7]);
712 #endif /* SHADED_CUBE */
713
714                 glEnd( );
715                 
716                 glMatrixMode(GL_MODELVIEW);
717                 glRotatef(5.0, 1.0, 1.0, 1.0);
718
719                 /* Draw 2D logo onto the 3D display */
720                 if ( logo ) {
721                         if ( USE_DEPRECATED_OPENGLBLIT ) {
722                                 DrawLogoBlit();
723                         } else {
724                                 DrawLogoTexture();
725                         }
726                 }
727                 if ( logocursor ) {
728                         DrawLogoCursor();
729                 }
730
731                 SDL_GL_SwapBuffers( );
732
733                 /* Check for error conditions. */
734                 gl_error = glGetError( );
735
736                 if( gl_error != GL_NO_ERROR ) {
737                         fprintf( stderr, "testgl: OpenGL error: %d\n", gl_error );
738                 }
739
740                 sdl_error = SDL_GetError( );
741
742                 if( sdl_error[0] != '\0' ) {
743                         fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
744                         SDL_ClearError();
745                 }
746
747                 /* Allow the user to see what's happening */
748                 if ( slowly ) {
749                         SDL_Delay( 20 );
750                 }
751
752                 /* Check if there's a pending event. */
753                 while( SDL_PollEvent( &event ) ) {
754                         done = HandleEvent(&event);
755                 }
756                 ++frames;
757         }
758
759         /* Print out the frames per second */
760         this_time = SDL_GetTicks();
761         if ( this_time != start_time ) {
762                 printf("%2.2f FPS\n",
763                         ((float)frames/(this_time-start_time))*1000.0);
764         }
765
766         if ( global_image ) {
767                 SDL_FreeSurface(global_image);
768                 global_image = NULL;
769         }
770         if ( global_texture ) {
771                 glDeleteTextures( 1, &global_texture );
772                 global_texture = 0;
773         }
774         if ( cursor_texture ) {
775                 glDeleteTextures( 1, &cursor_texture );
776                 cursor_texture = 0;
777         }
778
779         /* Destroy our GL context, etc. */
780         SDL_Quit( );
781         return(0);
782 }
783
784 int main(int argc, char *argv[])
785 {
786         int i, logo, logocursor = 0;
787         int numtests;
788         int bpp = 0;
789         int slowly;
790         float gamma = 0.0;
791         int noframe = 0;
792         int fsaa = 0;
793         int accel = 0;
794         int sync = 0;
795
796         logo = 0;
797         slowly = 0;
798         numtests = 1;
799         for ( i=1; argv[i]; ++i ) {
800                 if ( strcmp(argv[i], "-twice") == 0 ) {
801                         ++numtests;
802                 }
803                 if ( strcmp(argv[i], "-logo") == 0 ) {
804                         logo = 1;
805                         USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
806                 }
807                 if ( strcmp(argv[i], "-logoblit") == 0 ) {
808                         logo = 1;
809                         USE_DEPRECATED_OPENGLBLIT = SDL_TRUE;
810                 }
811                 if ( strcmp(argv[i], "-logocursor") == 0 ) {
812                         logocursor = 1;
813                 }
814                 if ( strcmp(argv[i], "-slow") == 0 ) {
815                         slowly = 1;
816                 }
817                 if ( strcmp(argv[i], "-bpp") == 0 ) {
818                        bpp = atoi(argv[++i]);
819                 }
820                 if ( strcmp(argv[i], "-gamma") == 0 ) {
821                        gamma = (float)atof(argv[++i]);
822                 }
823                 if ( strcmp(argv[i], "-noframe") == 0 ) {
824                        noframe = 1;
825                 }
826                 if ( strcmp(argv[i], "-fsaa") == 0 ) {
827                        ++fsaa;
828                 }
829                 if ( strcmp(argv[i], "-accel") == 0 ) {
830                        ++accel;
831                 }
832                 if ( strcmp(argv[i], "-sync") == 0 ) {
833                        ++sync;
834                 }
835                 if ( strncmp(argv[i], "-h", 2) == 0 ) {
836                        printf(
837 "Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel] [-sync] [-fullscreen]\n",
838                               argv[0]);
839                         exit(0);
840                 }
841         }
842         for ( i=0; i<numtests; ++i ) {
843                 RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa, sync, accel);
844         }
845         return 0;
846 }
847
848 #else /* HAVE_OPENGL */
849
850 int main(int argc, char *argv[])
851 {
852         printf("No OpenGL support on this system\n");
853         return 1;
854 }
855
856 #endif /* HAVE_OPENGL */