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