test/testgl.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 25 Oct 2001 05:37:32 +0000
changeset 214 0e5d6dd77bda
parent 0 74212992fb08
child 221 50620ec9c86a
permissions -rw-r--r--
Added platform independent OpenGL header - SDL_opengl.h
     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 #endif
    11 
    12 #define SHADED_CUBE
    13 
    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 DrawSDLLogo(void)
   100 {
   101 	static SDL_Surface *image = NULL;
   102 	static int x = 0;
   103 	static int y = 0;
   104 	static int delta_x = 1;
   105 	static int delta_y = 1;
   106 	static Uint32 last_moved = 0;
   107 
   108 	SDL_Rect dst;
   109 	SDL_Surface *screen;
   110 
   111 	if ( image == NULL ) {
   112 		SDL_Surface *temp;
   113 
   114 		temp = SDL_LoadBMP("icon.bmp");
   115 		if ( temp == NULL ) {
   116 			return;
   117 		}
   118 		image = SDL_CreateRGBSurface(
   119 				SDL_SWSURFACE,
   120 				temp->w, temp->h,
   121 				32,
   122 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   123 				0x000000FF, 
   124 				0x0000FF00, 
   125 				0x00FF0000, 
   126  			       0xFF000000
   127 #else
   128  			       0xFF000000,
   129  			       0x00FF0000, 
   130  			       0x0000FF00, 
   131  			       0x000000FF
   132 #endif
   133  			       );
   134 		if ( image != NULL ) {
   135 			SDL_BlitSurface(temp, NULL, image, NULL);
   136 		}
   137 		SDL_FreeSurface(temp);
   138 		if ( image == NULL ) {
   139 			return;
   140 		}
   141 	}
   142 
   143 	screen = SDL_GetVideoSurface();
   144 
   145 	/* Show the image on the screen */
   146 	dst.x = x;
   147 	dst.y = y;
   148 	dst.w = image->w;
   149 	dst.h = image->h;
   150 
   151 	/* Move it around
   152            Note that we do not clear the old position.  This is because we
   153            perform a glClear() which clears the framebuffer and then only
   154            update the new area.
   155            Note that you can also achieve interesting effects by modifying
   156            the screen surface alpha channel.  It's set to 255 by default..
   157          */
   158 	if ( (SDL_GetTicks() - last_moved) > 100 ) {
   159 		x += delta_x;
   160 		if ( x < 0 ) {
   161 			x = 0;
   162 			delta_x = -delta_x;
   163 		} else
   164 		if ( (x+image->w) > screen->w ) {
   165 			x = screen->w-image->w;
   166 			delta_x = -delta_x;
   167 		}
   168 		y += delta_y;
   169 		if ( y < 0 ) {
   170 			y = 0;
   171 			delta_y = -delta_y;
   172 		} else
   173 		if ( (y+image->h) > screen->h ) {
   174 			y = screen->h-image->h;
   175 			delta_y = -delta_y;
   176 		}
   177 		SDL_BlitSurface(image, NULL, screen, &dst);
   178 	}
   179 	SDL_UpdateRects(screen, 1, &dst);
   180 }
   181 
   182 int RunGLTest( int argc, char* argv[],
   183                int logo, int slowly, int bpp, float gamma )
   184 {
   185 	int i;
   186 	int rgb_size[3];
   187 	int w = 640;
   188 	int h = 480;
   189 	int done = 0;
   190 	int frames;
   191 	Uint32 start_time, this_time;
   192         float color[8][3]= {{ 1.0,  1.0,  0.0}, 
   193 			    { 1.0,  0.0,  0.0},
   194 			    { 0.0,  0.0,  0.0},
   195 			    { 0.0,  1.0,  0.0},
   196 			    { 0.0,  1.0,  1.0},
   197 			    { 1.0,  1.0,  1.0},
   198 			    { 1.0,  0.0,  1.0},
   199 			    { 0.0,  0.0,  1.0}};
   200 	float cube[8][3]= {{ 0.5,  0.5, -0.5}, 
   201 			   { 0.5, -0.5, -0.5},
   202 			   {-0.5, -0.5, -0.5},
   203 			   {-0.5,  0.5, -0.5},
   204 			   {-0.5,  0.5,  0.5},
   205 			   { 0.5,  0.5,  0.5},
   206 			   { 0.5, -0.5,  0.5},
   207 			   {-0.5, -0.5,  0.5}};
   208 	Uint32 video_flags;
   209 	int value;
   210 
   211 	if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
   212 		fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
   213 		exit( 1 );
   214 	}
   215 
   216 	/* See if we should detect the display depth */
   217 	if ( bpp == 0 ) {
   218 		if ( SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8 ) {
   219 			bpp = 8;
   220 		} else {
   221 			bpp = 16;  /* More doesn't seem to work */
   222 		}
   223 	}
   224 
   225 	/* Set the flags we want to use for setting the video mode */
   226 	if ( logo ) {
   227 		video_flags = SDL_OPENGLBLIT;
   228 	} else {
   229 		video_flags = SDL_OPENGL;
   230 	}
   231 	for ( i=1; argv[i]; ++i ) {
   232 		if ( strcmp(argv[1], "-fullscreen") == 0 ) {
   233 			video_flags |= SDL_FULLSCREEN;
   234 		}
   235 	}
   236 
   237 	/* Initialize the display */
   238 	switch (bpp) {
   239 	    case 8:
   240 		rgb_size[0] = 2;
   241 		rgb_size[1] = 3;
   242 		rgb_size[2] = 3;
   243 		break;
   244 	    case 15:
   245 	    case 16:
   246 		rgb_size[0] = 5;
   247 		rgb_size[1] = 5;
   248 		rgb_size[2] = 5;
   249 		break;
   250             default:
   251 		rgb_size[0] = 8;
   252 		rgb_size[1] = 8;
   253 		rgb_size[2] = 8;
   254 		break;
   255 	}
   256 	SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rgb_size[0] );
   257 	SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, rgb_size[1] );
   258 	SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, rgb_size[2] );
   259 	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
   260 	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
   261 	if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
   262 		fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
   263 		SDL_Quit();
   264 		exit(1);
   265 	}
   266 
   267 	printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format->BitsPerPixel);
   268 	printf("\n");
   269 	printf( "Vendor     : %s\n", glGetString( GL_VENDOR ) );
   270 	printf( "Renderer   : %s\n", glGetString( GL_RENDERER ) );
   271 	printf( "Version    : %s\n", glGetString( GL_VERSION ) );
   272 	printf( "Extensions : %s\n", glGetString( GL_EXTENSIONS ) );
   273 	printf("\n");
   274 
   275 	SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &value );
   276 	printf( "SDL_GL_RED_SIZE: requested %d, got %d\n", rgb_size[0],value);
   277 	SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &value );
   278 	printf( "SDL_GL_GREEN_SIZE: requested %d, got %d\n", rgb_size[1],value);
   279 	SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &value );
   280 	printf( "SDL_GL_BLUE_SIZE: requested %d, got %d\n", rgb_size[2],value);
   281 	SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &value );
   282 	printf( "SDL_GL_DEPTH_SIZE: requested %d, got %d\n", bpp, value );
   283 	SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &value );
   284 	printf( "SDL_GL_DOUBLEBUFFER: requested 1, got %d\n", value );
   285 
   286 	/* Set the window manager title bar */
   287 	SDL_WM_SetCaption( "SDL GL test", "testgl" );
   288 
   289 	/* Set the gamma for the window */
   290 	if ( gamma != 0.0 ) {
   291 		SDL_SetGamma(gamma, gamma, gamma);
   292 	}
   293 
   294 	glViewport( 0, 0, w, h );
   295 	glMatrixMode( GL_PROJECTION );
   296 	glLoadIdentity( );
   297 
   298 	glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
   299 
   300 	glMatrixMode( GL_MODELVIEW );
   301 	glLoadIdentity( );
   302 
   303 	glEnable(GL_DEPTH_TEST);
   304 
   305 	glDepthFunc(GL_LESS);
   306 
   307 	glShadeModel(GL_SMOOTH);
   308 
   309 	/* Loop until done. */
   310 	start_time = SDL_GetTicks();
   311 	frames = 0;
   312 	while( !done ) {
   313 		GLenum gl_error;
   314 		char* sdl_error;
   315 		SDL_Event event;
   316 
   317 		/* Do our drawing, too. */
   318 		glClearColor( 0.0, 0.0, 0.0, 1.0 );
   319 		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   320 
   321 		glBegin( GL_QUADS );
   322 
   323 #ifdef SHADED_CUBE
   324 			glColor3fv(color[0]);
   325 			glVertex3fv(cube[0]);
   326 			glColor3fv(color[1]);
   327 			glVertex3fv(cube[1]);
   328 			glColor3fv(color[2]);
   329 			glVertex3fv(cube[2]);
   330 			glColor3fv(color[3]);
   331 			glVertex3fv(cube[3]);
   332 			
   333 			glColor3fv(color[3]);
   334 			glVertex3fv(cube[3]);
   335 			glColor3fv(color[4]);
   336 			glVertex3fv(cube[4]);
   337 			glColor3fv(color[7]);
   338 			glVertex3fv(cube[7]);
   339 			glColor3fv(color[2]);
   340 			glVertex3fv(cube[2]);
   341 			
   342 			glColor3fv(color[0]);
   343 			glVertex3fv(cube[0]);
   344 			glColor3fv(color[5]);
   345 			glVertex3fv(cube[5]);
   346 			glColor3fv(color[6]);
   347 			glVertex3fv(cube[6]);
   348 			glColor3fv(color[1]);
   349 			glVertex3fv(cube[1]);
   350 			
   351 			glColor3fv(color[5]);
   352 			glVertex3fv(cube[5]);
   353 			glColor3fv(color[4]);
   354 			glVertex3fv(cube[4]);
   355 			glColor3fv(color[7]);
   356 			glVertex3fv(cube[7]);
   357 			glColor3fv(color[6]);
   358 			glVertex3fv(cube[6]);
   359 
   360 			glColor3fv(color[5]);
   361 			glVertex3fv(cube[5]);
   362 			glColor3fv(color[0]);
   363 			glVertex3fv(cube[0]);
   364 			glColor3fv(color[3]);
   365 			glVertex3fv(cube[3]);
   366 			glColor3fv(color[4]);
   367 			glVertex3fv(cube[4]);
   368 
   369 			glColor3fv(color[6]);
   370 			glVertex3fv(cube[6]);
   371 			glColor3fv(color[1]);
   372 			glVertex3fv(cube[1]);
   373 			glColor3fv(color[2]);
   374 			glVertex3fv(cube[2]);
   375 			glColor3fv(color[7]);
   376 			glVertex3fv(cube[7]);
   377 #else // flat cube
   378 			glColor3f(1.0, 0.0, 0.0);
   379 			glVertex3fv(cube[0]);
   380 			glVertex3fv(cube[1]);
   381 			glVertex3fv(cube[2]);
   382 			glVertex3fv(cube[3]);
   383 			
   384 			glColor3f(0.0, 1.0, 0.0);
   385 			glVertex3fv(cube[3]);
   386 			glVertex3fv(cube[4]);
   387 			glVertex3fv(cube[7]);
   388 			glVertex3fv(cube[2]);
   389 			
   390 			glColor3f(0.0, 0.0, 1.0);
   391 			glVertex3fv(cube[0]);
   392 			glVertex3fv(cube[5]);
   393 			glVertex3fv(cube[6]);
   394 			glVertex3fv(cube[1]);
   395 			
   396 			glColor3f(0.0, 1.0, 1.0);
   397 			glVertex3fv(cube[5]);
   398 			glVertex3fv(cube[4]);
   399 			glVertex3fv(cube[7]);
   400 			glVertex3fv(cube[6]);
   401 
   402 			glColor3f(1.0, 1.0, 0.0);
   403 			glVertex3fv(cube[5]);
   404 			glVertex3fv(cube[0]);
   405 			glVertex3fv(cube[3]);
   406 			glVertex3fv(cube[4]);
   407 
   408 			glColor3f(1.0, 0.0, 1.0);
   409 			glVertex3fv(cube[6]);
   410 			glVertex3fv(cube[1]);
   411 			glVertex3fv(cube[2]);
   412 			glVertex3fv(cube[7]);
   413 #endif /* SHADED_CUBE */
   414 
   415 		glEnd( );
   416 		
   417 		glMatrixMode(GL_MODELVIEW);
   418 		glRotatef(5.0, 1.0, 1.0, 1.0);
   419 
   420 		/* Draw 2D logo onto the 3D display */
   421 		if ( logo ) {
   422 			DrawSDLLogo();
   423 		}
   424 
   425 		SDL_GL_SwapBuffers( );
   426 
   427 		/* Check for error conditions. */
   428 		gl_error = glGetError( );
   429 
   430 		if( gl_error != GL_NO_ERROR ) {
   431 			fprintf( stderr, "testgl: OpenGL error: %d\n", gl_error );
   432 		}
   433 
   434 		sdl_error = SDL_GetError( );
   435 
   436 		if( sdl_error[0] != '\0' ) {
   437 			fprintf(stderr, "testgl: SDL error '%s'\n", sdl_error);
   438 			SDL_ClearError();
   439 		}
   440 
   441 		/* Allow the user to see what's happening */
   442 		if ( slowly ) {
   443 			SDL_Delay( 20 );
   444 		}
   445 
   446 		/* Check if there's a pending event. */
   447 		while( SDL_PollEvent( &event ) ) {
   448 			done = HandleEvent(&event);
   449 		}
   450 		++frames;
   451 	}
   452 
   453 	/* Print out the frames per second */
   454 	this_time = SDL_GetTicks();
   455 	if ( this_time != start_time ) {
   456 		printf("%2.2f FPS\n",
   457 			((float)frames/(this_time-start_time))*1000.0);
   458 	}
   459 
   460 	/* Destroy our GL context, etc. */
   461 	SDL_Quit( );
   462 	return(0);
   463 }
   464 
   465 int main(int argc, char *argv[])
   466 {
   467 	int i, logo;
   468 	int numtests;
   469 	int bpp = 0;
   470 	int slowly;
   471 	float gamma = 0.0;
   472 
   473 	logo = 0;
   474 	slowly = 0;
   475 	numtests = 1;
   476 	for ( i=1; argv[i]; ++i ) {
   477 		if ( strcmp(argv[i], "-twice") == 0 ) {
   478 			++numtests;
   479 		}
   480 		if ( strcmp(argv[i], "-logo") == 0 ) {
   481 			logo = 1;
   482 		}
   483 		if ( strcmp(argv[i], "-slow") == 0 ) {
   484 			slowly = 1;
   485 		}
   486 		if ( strcmp(argv[i], "-bpp") == 0 ) {
   487  		       bpp = atoi(argv[++i]);
   488 		}
   489 		if ( strcmp(argv[i], "-gamma") == 0 ) {
   490  		       gamma = (float)atof(argv[++i]);
   491 		}
   492 		if ( strncmp(argv[i], "-h", 2) == 0 ) {
   493  		       printf(
   494 "Usage: %s [-twice] [-logo] [-slow] [-bpp n] [-gamma n]\n",
   495  			      argv[0]);
   496 			exit(0);
   497 		}
   498 	}
   499 	for ( i=0; i<numtests; ++i ) {
   500  	       RunGLTest(argc, argv, logo, slowly, bpp, gamma);
   501 	}
   502 	return 0;
   503 }
   504 
   505 #else /* HAVE_OPENGL */
   506 
   507 int main(int argc, char *argv[])
   508 {
   509 	printf("No OpenGL support on this system\n");
   510 	return 1;
   511 }
   512 
   513 #endif /* HAVE_OPENGL */