test/testgl.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 06 Nov 2001 00:15:24 +0000
changeset 233 5b42a7f5fab3
parent 221 50620ec9c86a
child 234 1af4be6a73cd
permissions -rw-r--r--
SDL_OPENGLBLIT is deprecated, show the "right way" of doing things
     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 #include "SDL_opengl.h"
    10 
    11 #define SHADED_CUBE
    12 
    13 static SDL_bool USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
    14 
    15 void HotKey_ToggleFullScreen(void)
    16 {
    17 	SDL_Surface *screen;
    18 
    19 	screen = SDL_GetVideoSurface();
    20 	if ( SDL_WM_ToggleFullScreen(screen) ) {
    21 		printf("Toggled fullscreen mode - now %s\n",
    22 		    (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed");
    23 	} else {
    24 		printf("Unable to toggle fullscreen mode\n");
    25 	}
    26 }
    27 
    28 void HotKey_ToggleGrab(void)
    29 {
    30 	SDL_GrabMode mode;
    31 
    32 	printf("Ctrl-G: toggling input grab!\n");
    33 	mode = SDL_WM_GrabInput(SDL_GRAB_QUERY);
    34 	if ( mode == SDL_GRAB_ON ) {
    35 		printf("Grab was on\n");
    36 	} else {
    37 		printf("Grab was off\n");
    38 	}
    39 	mode = SDL_WM_GrabInput(!mode);
    40 	if ( mode == SDL_GRAB_ON ) {
    41 		printf("Grab is now on\n");
    42 	} else {
    43 		printf("Grab is now off\n");
    44 	}
    45 }
    46 
    47 void HotKey_Iconify(void)
    48 {
    49 	printf("Ctrl-Z: iconifying window!\n");
    50 	SDL_WM_IconifyWindow();
    51 }
    52 
    53 int HandleEvent(SDL_Event *event)
    54 {
    55 	int done;
    56 
    57 	done = 0;
    58 	switch( event->type ) {
    59 	    case SDL_ACTIVEEVENT:
    60 		/* See what happened */
    61 		printf( "app %s ", event->active.gain ? "gained" : "lost" );
    62 		if ( event->active.state & SDL_APPACTIVE ) {
    63 			printf( "active " );
    64 		} else if ( event->active.state & SDL_APPMOUSEFOCUS ) {
    65 			printf( "mouse " );
    66 		} else if ( event->active.state & SDL_APPINPUTFOCUS ) {
    67 			printf( "input " );
    68 		}
    69 		printf( "focus\n" );
    70 		break;
    71 		
    72 
    73 	    case SDL_KEYDOWN:
    74 		if ( event->key.keysym.sym == SDLK_ESCAPE ) {
    75 			done = 1;
    76 		}
    77 		if ( (event->key.keysym.sym == SDLK_g) &&
    78 		     (event->key.keysym.mod & KMOD_CTRL) ) {
    79 			HotKey_ToggleGrab();
    80 		}
    81 		if ( (event->key.keysym.sym == SDLK_z) &&
    82 		     (event->key.keysym.mod & KMOD_CTRL) ) {
    83 			HotKey_Iconify();
    84 		}
    85 		if ( (event->key.keysym.sym == SDLK_RETURN) &&
    86 		     (event->key.keysym.mod & KMOD_ALT) ) {
    87 			HotKey_ToggleFullScreen();
    88 		}
    89 		printf("key '%s' pressed\n", 
    90 			SDL_GetKeyName(event->key.keysym.sym));
    91 		break;
    92 	    case SDL_QUIT:
    93 		done = 1;
    94 		break;
    95 	}
    96 	return(done);
    97 }
    98 
    99 void SDL_GL_Enter2DMode()
   100 {
   101 	SDL_Surface *screen = SDL_GetVideoSurface();
   102 
   103 	/* Note, there may be other things you need to change,
   104 	   depending on how you have your OpenGL state set up.
   105 	*/
   106 	glPushAttrib(GL_ENABLE_BIT);
   107 	glDisable(GL_DEPTH_TEST);
   108 	glDisable(GL_CULL_FACE);
   109 	glEnable(GL_TEXTURE_2D);
   110 
   111 	glViewport(0, 0, screen->w, screen->h);
   112 
   113 	glMatrixMode(GL_PROJECTION);
   114 	glPushMatrix();
   115 	glLoadIdentity();
   116 
   117 	glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
   118 
   119 	glMatrixMode(GL_MODELVIEW);
   120 	glPushMatrix();
   121 	glLoadIdentity();
   122 
   123 	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
   124 }
   125 
   126 void SDL_GL_Leave2DMode()
   127 {
   128 	glMatrixMode(GL_MODELVIEW);
   129 	glPopMatrix();
   130 
   131 	glMatrixMode(GL_PROJECTION);
   132 	glPopMatrix();
   133 
   134 	glPopAttrib();
   135 }
   136 
   137 void DrawSDLLogo(void)
   138 {
   139 	static SDL_Surface *image = NULL;
   140 	static GLuint texture;
   141 	static int x = 0;
   142 	static int y = 0;
   143 	static int w, h;
   144 	static int delta_x = 1;
   145 	static int delta_y = 1;
   146 	static Uint32 last_moved = 0;
   147 
   148 	SDL_Rect dst;
   149 	SDL_Surface *screen;
   150 
   151 	if ( image == NULL ) {
   152 		SDL_Surface *temp;
   153 
   154 		temp = SDL_LoadBMP("icon.bmp");
   155 		if ( temp == NULL ) {
   156 			return;
   157 		}
   158 		image = SDL_CreateRGBSurface(
   159 				SDL_SWSURFACE,
   160 				temp->w, temp->h,
   161 				32,
   162 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
   163 				0x000000FF, 
   164 				0x0000FF00, 
   165 				0x00FF0000, 
   166 				0xFF000000
   167 #else
   168 				0xFF000000,
   169 				0x00FF0000, 
   170 				0x0000FF00, 
   171 				0x000000FF
   172 #endif
   173  			       );
   174 		if ( image != NULL ) {
   175 			SDL_BlitSurface(temp, NULL, image, NULL);
   176 		}
   177 		SDL_FreeSurface(temp);
   178 		if ( image == NULL ) {
   179 			return;
   180 		}
   181 		w = image->w;
   182 		h = image->h;
   183 
   184 		/* Create an OpenGL texture for the image */
   185 		if ( ! USE_DEPRECATED_OPENGLBLIT ) {
   186 			glGenTextures(1, &texture);
   187 			glBindTexture(GL_TEXTURE_2D, texture);
   188 			glTexParameteri(GL_TEXTURE_2D,
   189 			                GL_TEXTURE_MAG_FILTER,
   190 			                GL_NEAREST);
   191 			glTexParameteri(GL_TEXTURE_2D,
   192 			                GL_TEXTURE_MIN_FILTER,
   193 			                GL_NEAREST);
   194 			glTexImage2D(GL_TEXTURE_2D,
   195 			             0,
   196 			             GL_RGBA,
   197 			             w, h,
   198 			             0,
   199 			             GL_RGBA,
   200 			             GL_UNSIGNED_BYTE,
   201 			             image->pixels);
   202 			SDL_FreeSurface(image); /* No longer needed */
   203 		}
   204 	}
   205 
   206 	screen = SDL_GetVideoSurface();
   207 
   208 	/* Show the image on the screen */
   209 	dst.x = x;
   210 	dst.y = y;
   211 	dst.w = w;
   212 	dst.h = h;
   213 
   214 	/* Move it around
   215            Note that we do not clear the old position.  This is because we
   216            perform a glClear() which clears the framebuffer and then only
   217            update the new area.
   218            Note that you can also achieve interesting effects by modifying
   219            the screen surface alpha channel.  It's set to 255 by default..
   220          */
   221 	if ( (SDL_GetTicks() - last_moved) > 100 ) {
   222 		x += delta_x;
   223 		if ( x < 0 ) {
   224 			x = 0;
   225 			delta_x = -delta_x;
   226 		} else
   227 		if ( (x+w) > screen->w ) {
   228 			x = screen->w-w;
   229 			delta_x = -delta_x;
   230 		}
   231 		y += delta_y;
   232 		if ( y < 0 ) {
   233 			y = 0;
   234 			delta_y = -delta_y;
   235 		} else
   236 		if ( (y+h) > screen->h ) {
   237 			y = screen->h-h;
   238 			delta_y = -delta_y;
   239 		}
   240 		if ( USE_DEPRECATED_OPENGLBLIT ) {
   241 			SDL_BlitSurface(image, NULL, screen, &dst);
   242 		} else {
   243 			SDL_GL_Enter2DMode();
   244 			glBindTexture(GL_TEXTURE_2D, texture);
   245 			glBegin(GL_TRIANGLE_STRIP);
   246 			glTexCoord2f(0.0, 0.0); glVertex2i(x,   y  );
   247 			glTexCoord2f(1.0, 0.0); glVertex2i(x+w, y  );
   248 			glTexCoord2f(0.0, 1.0); glVertex2i(x,   y+h);
   249 			glTexCoord2f(1.0, 1.0); glVertex2i(x+w, y+h);
   250 			glEnd();
   251 			SDL_GL_Leave2DMode();
   252 		}
   253 	}
   254 	if ( USE_DEPRECATED_OPENGLBLIT ) {
   255 		SDL_UpdateRects(screen, 1, &dst);
   256 	}
   257 }
   258 
   259 int RunGLTest( int argc, char* argv[],
   260                int logo, int slowly, int bpp, float gamma )
   261 {
   262 	int i;
   263 	int rgb_size[3];
   264 	int w = 640;
   265 	int h = 480;
   266 	int done = 0;
   267 	int frames;
   268 	Uint32 start_time, this_time;
   269         float color[8][3]= {{ 1.0,  1.0,  0.0}, 
   270 			    { 1.0,  0.0,  0.0},
   271 			    { 0.0,  0.0,  0.0},
   272 			    { 0.0,  1.0,  0.0},
   273 			    { 0.0,  1.0,  1.0},
   274 			    { 1.0,  1.0,  1.0},
   275 			    { 1.0,  0.0,  1.0},
   276 			    { 0.0,  0.0,  1.0}};
   277 	float cube[8][3]= {{ 0.5,  0.5, -0.5}, 
   278 			   { 0.5, -0.5, -0.5},
   279 			   {-0.5, -0.5, -0.5},
   280 			   {-0.5,  0.5, -0.5},
   281 			   {-0.5,  0.5,  0.5},
   282 			   { 0.5,  0.5,  0.5},
   283 			   { 0.5, -0.5,  0.5},
   284 			   {-0.5, -0.5,  0.5}};
   285 	Uint32 video_flags;
   286 	int value;
   287 
   288 	if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
   289 		fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
   290 		exit( 1 );
   291 	}
   292 
   293 	/* See if we should detect the display depth */
   294 	if ( bpp == 0 ) {
   295 		if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
   296 			bpp = 8;
   297 		} else {
   298 			bpp = 16;  /* More doesn't seem to work */
   299 		}
   300 	}
   301 
   302 	/* Set the flags we want to use for setting the video mode */
   303 	if ( logo && USE_DEPRECATED_OPENGLBLIT ) {
   304 		video_flags = SDL_OPENGLBLIT;
   305 	} else {
   306 		video_flags = SDL_OPENGL;
   307 	}
   308 	for ( i=1; argv[i]; ++i ) {
   309 		if ( strcmp(argv[1], "-fullscreen") == 0 ) {
   310 			video_flags |= SDL_FULLSCREEN;
   311 		}
   312 	}
   313 
   314 	/* Initialize the display */
   315 	switch (bpp) {
   316 	    case 8:
   317 		rgb_size[0] = 2;
   318 		rgb_size[1] = 3;
   319 		rgb_size[2] = 3;
   320 		break;
   321 	    case 15:
   322 	    case 16:
   323 		rgb_size[0] = 5;
   324 		rgb_size[1] = 5;
   325 		rgb_size[2] = 5;
   326 		break;
   327             default:
   328 		rgb_size[0] = 8;
   329 		rgb_size[1] = 8;
   330 		rgb_size[2] = 8;
   331 		break;
   332 	}
   333 	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
   334 	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
   335 	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
   336 	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
   337 	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
   338 	if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
   339 		fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
   340 		SDL_Quit();
   341 		exit(1);
   342 	}
   343 
   344 	printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
   345 	printf("\n");
   346 	printf( "Vendor     : %s\n", glGetString( GL_VENDOR ) );
   347 	printf( "Renderer   : %s\n", glGetString( GL_RENDERER ) );
   348 	printf( "Version    : %s\n", glGetString( GL_VERSION ) );
   349 	printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
   350 	printf("\n");
   351 
   352 	SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
   353 	printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
   354 	SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
   355 	printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
   356 	SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
   357 	printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
   358 	SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
   359 	printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
   360 	SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
   361 	printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
   362 
   363 	/* Set the window manager title bar */
   364 	SDL_WM_SetCaption( "SDL GL test", "testgl" );
   365 
   366 	/* Set the gamma for the window */
   367 	if ( gamma != 0.0 ) {
   368 		SDL_SetGamma(gamma, gamma, gamma);
   369 	}
   370 
   371 	glViewport( 0, 0, w, h );
   372 	glMatrixMode( GL_PROJECTION );
   373 	glLoadIdentity( );
   374 
   375 	glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
   376 
   377 	glMatrixMode( GL_MODELVIEW );
   378 	glLoadIdentity( );
   379 
   380 	glEnable(GL_DEPTH_TEST);
   381 
   382 	glDepthFunc(GL_LESS);
   383 
   384 	glShadeModel(GL_SMOOTH);
   385 
   386 	/* Loop until done. */
   387 	start_time = SDL_GetTicks();
   388 	frames = 0;
   389 	while( !done ) {
   390 		GLenum gl_error;
   391 		char* sdl_error;
   392 		SDL_Event event;
   393 
   394 		/* Do our drawing, too. */
   395 		glClearColor( 0.0, 0.0, 0.0, 1.0 );
   396 		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   397 
   398 		glBegin( GL_QUADS );
   399 
   400 #ifdef SHADED_CUBE
   401 			glColor3fv(color[0]);
   402 			glVertex3fv(cube[0]);
   403 			glColor3fv(color[1]);
   404 			glVertex3fv(cube[1]);
   405 			glColor3fv(color[2]);
   406 			glVertex3fv(cube[2]);
   407 			glColor3fv(color[3]);
   408 			glVertex3fv(cube[3]);
   409 			
   410 			glColor3fv(color[3]);
   411 			glVertex3fv(cube[3]);
   412 			glColor3fv(color[4]);
   413 			glVertex3fv(cube[4]);
   414 			glColor3fv(color[7]);
   415 			glVertex3fv(cube[7]);
   416 			glColor3fv(color[2]);
   417 			glVertex3fv(cube[2]);
   418 			
   419 			glColor3fv(color[0]);
   420 			glVertex3fv(cube[0]);
   421 			glColor3fv(color[5]);
   422 			glVertex3fv(cube[5]);
   423 			glColor3fv(color[6]);
   424 			glVertex3fv(cube[6]);
   425 			glColor3fv(color[1]);
   426 			glVertex3fv(cube[1]);
   427 			
   428 			glColor3fv(color[5]);
   429 			glVertex3fv(cube[5]);
   430 			glColor3fv(color[4]);
   431 			glVertex3fv(cube[4]);
   432 			glColor3fv(color[7]);
   433 			glVertex3fv(cube[7]);
   434 			glColor3fv(color[6]);
   435 			glVertex3fv(cube[6]);
   436 
   437 			glColor3fv(color[5]);
   438 			glVertex3fv(cube[5]);
   439 			glColor3fv(color[0]);
   440 			glVertex3fv(cube[0]);
   441 			glColor3fv(color[3]);
   442 			glVertex3fv(cube[3]);
   443 			glColor3fv(color[4]);
   444 			glVertex3fv(cube[4]);
   445 
   446 			glColor3fv(color[6]);
   447 			glVertex3fv(cube[6]);
   448 			glColor3fv(color[1]);
   449 			glVertex3fv(cube[1]);
   450 			glColor3fv(color[2]);
   451 			glVertex3fv(cube[2]);
   452 			glColor3fv(color[7]);
   453 			glVertex3fv(cube[7]);
   454 #else // flat cube
   455 			glColor3f(1.0, 0.0, 0.0);
   456 			glVertex3fv(cube[0]);
   457 			glVertex3fv(cube[1]);
   458 			glVertex3fv(cube[2]);
   459 			glVertex3fv(cube[3]);
   460 			
   461 			glColor3f(0.0, 1.0, 0.0);
   462 			glVertex3fv(cube[3]);
   463 			glVertex3fv(cube[4]);
   464 			glVertex3fv(cube[7]);
   465 			glVertex3fv(cube[2]);
   466 			
   467 			glColor3f(0.0, 0.0, 1.0);
   468 			glVertex3fv(cube[0]);
   469 			glVertex3fv(cube[5]);
   470 			glVertex3fv(cube[6]);
   471 			glVertex3fv(cube[1]);
   472 			
   473 			glColor3f(0.0, 1.0, 1.0);
   474 			glVertex3fv(cube[5]);
   475 			glVertex3fv(cube[4]);
   476 			glVertex3fv(cube[7]);
   477 			glVertex3fv(cube[6]);
   478 
   479 			glColor3f(1.0, 1.0, 0.0);
   480 			glVertex3fv(cube[5]);
   481 			glVertex3fv(cube[0]);
   482 			glVertex3fv(cube[3]);
   483 			glVertex3fv(cube[4]);
   484 
   485 			glColor3f(1.0, 0.0, 1.0);
   486 			glVertex3fv(cube[6]);
   487 			glVertex3fv(cube[1]);
   488 			glVertex3fv(cube[2]);
   489 			glVertex3fv(cube[7]);
   490 #endif /* SHADED_CUBE */
   491 
   492 		glEnd( );
   493 		
   494 		glMatrixMode(GL_MODELVIEW);
   495 		glRotatef(5.0, 1.0, 1.0, 1.0);
   496 
   497 		/* Draw 2D logo onto the 3D display */
   498 		if ( logo ) {
   499 			DrawSDLLogo();
   500 		}
   501 
   502 		SDL_GL_SwapBuffers( );
   503 
   504 		/* Check for error conditions. */
   505 		gl_error = glGetError( );
   506 
   507 		if( gl_error != GL_NO_ERROR ) {
   508 			fprintf( stderr, "testgl: OpenGL error: %d\n", gl_error );
   509 		}
   510 
   511 		sdl_error = SDL_GetError( );
   512 
   513 		if( sdl_error[0] != '\0' ) {
   514 			fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
   515 			SDL_ClearError();
   516 		}
   517 
   518 		/* Allow the user to see what's happening */
   519 		if ( slowly ) {
   520 			SDL_Delay( 20 );
   521 		}
   522 
   523 		/* Check if there's a pending event. */
   524 		while( SDL_PollEvent( &event ) ) {
   525 			done = HandleEvent(&event);
   526 		}
   527 		++frames;
   528 	}
   529 
   530 	/* Print out the frames per second */
   531 	this_time = SDL_GetTicks();
   532 	if ( this_time != start_time ) {
   533 		printf("%2.2f FPS\n",
   534 			((float)frames/(this_time-start_time))*1000.0);
   535 	}
   536 
   537 	/* Destroy our GL context, etc. */
   538 	SDL_Quit( );
   539 	return(0);
   540 }
   541 
   542 int main(int argc, char *argv[])
   543 {
   544 	int i, logo;
   545 	int numtests;
   546 	int bpp = 0;
   547 	int slowly;
   548 	float gamma = 0.0;
   549 
   550 	logo = 0;
   551 	slowly = 0;
   552 	numtests = 1;
   553 	for ( i=1; argv[i]; ++i ) {
   554 		if ( strcmp(argv[i], "-twice") == 0 ) {
   555 			++numtests;
   556 		}
   557 		if ( strcmp(argv[i], "-logo") == 0 ) {
   558 			logo = 1;
   559 			USE_DEPRECATED_OPENGLBLIT = SDL_FALSE;
   560 		}
   561 		if ( strcmp(argv[i], "-logoblit") == 0 ) {
   562 			logo = 1;
   563 			USE_DEPRECATED_OPENGLBLIT = SDL_TRUE;
   564 		}
   565 		if ( strcmp(argv[i], "-slow") == 0 ) {
   566 			slowly = 1;
   567 		}
   568 		if ( strcmp(argv[i], "-bpp") == 0 ) {
   569  		       bpp = atoi(argv[++i]);
   570 		}
   571 		if ( strcmp(argv[i], "-gamma") == 0 ) {
   572  		       gamma = (float)atof(argv[++i]);
   573 		}
   574 		if ( strncmp(argv[i], "-h", 2) == 0 ) {
   575  		       printf(
   576 "Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n]\n",
   577  			      argv[0]);
   578 			exit(0);
   579 		}
   580 	}
   581 	for ( i=0; i<numtests; ++i ) {
   582  	       RunGLTest(argc, argv, logo, slowly, bpp, gamma);
   583 	}
   584 	return 0;
   585 }
   586 
   587 #else /* HAVE_OPENGL */
   588 
   589 int main(int argc, char *argv[])
   590 {
   591 	printf("No OpenGL support on this system\n");
   592 	return 1;
   593 }
   594 
   595 #endif /* HAVE_OPENGL */