test/testgl.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 27 Apr 2006 07:59:16 +0000
changeset 1736 3b2a92126f4d
parent 1439 4d3bb026cd16
child 1737 eacc5bc01d1c
permissions -rw-r--r--
Implemented bug #2, 117:

Date: Mon, 21 Mar 2005 12:06:14 +0100
From: Per Inge Mathisen
Subject: Re: [SDL] Outstanding patches?

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