14 #include "SDL_opengl.h"
16 /* Undefine this if you want a flat cube instead of a rainbow cube */
19 /* Define this to be the name of the logo image to use with -logo */
20 #define LOGO_FILE "icon.bmp"
22 /* The SDL_OPENGLBLIT interface is deprecated.
23 The code is still available for benchmark purposes though.
26 static SDL_bool USE_DEPRECATED_OPENGLBLIT
= SDL_FALSE
;
28 static SDL_Surface
*global_image
= NULL
;
29 static GLuint global_texture
= 0;
30 static GLuint cursor_texture
= 0;
32 /**********************************************************************/
34 void HotKey_ToggleFullScreen(void)
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");
43 printf("Unable to toggle fullscreen mode\n");
47 void HotKey_ToggleGrab(void)
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");
56 printf("Grab was off\n");
58 mode
= SDL_WM_GrabInput(!mode
);
59 if ( mode
== SDL_GRAB_ON
) {
60 printf("Grab is now on\n");
62 printf("Grab is now off\n");
66 void HotKey_Iconify(void)
68 printf("Ctrl-Z: iconifying window!\n");
69 SDL_WM_IconifyWindow();
72 int HandleEvent(SDL_Event
*event
)
77 switch( event
->type
) {
79 /* See what happened */
80 printf( "app %s ", event
->active
.gain
? "gained" : "lost" );
81 if ( event
->active
.state
& SDL_APPACTIVE
) {
83 } else if ( event
->active
.state
& SDL_APPMOUSEFOCUS
) {
85 } else if ( event
->active
.state
& SDL_APPINPUTFOCUS
) {
93 if ( event
->key
.keysym
.sym
== SDLK_ESCAPE
) {
96 if ( (event
->key
.keysym
.sym
== SDLK_g
) &&
97 (event
->key
.keysym
.mod
& KMOD_CTRL
) ) {
100 if ( (event
->key
.keysym
.sym
== SDLK_z
) &&
101 (event
->key
.keysym
.mod
& KMOD_CTRL
) ) {
104 if ( (event
->key
.keysym
.sym
== SDLK_RETURN
) &&
105 (event
->key
.keysym
.mod
& KMOD_ALT
) ) {
106 HotKey_ToggleFullScreen();
108 printf("key '%s' pressed\n",
109 SDL_GetKeyName(event
->key
.keysym
.sym
));
118 void SDL_GL_Enter2DMode()
120 SDL_Surface
*screen
= SDL_GetVideoSurface();
122 /* Note, there may be other things you need to change,
123 depending on how you have your OpenGL state set up.
125 glPushAttrib(GL_ENABLE_BIT
);
126 glDisable(GL_DEPTH_TEST
);
127 glDisable(GL_CULL_FACE
);
128 glEnable(GL_TEXTURE_2D
);
130 /* This allows alpha blending of 2D textures with the scene */
132 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
134 glViewport(0, 0, screen
->w
, screen
->h
);
136 glMatrixMode(GL_PROJECTION
);
140 glOrtho(0.0, (GLdouble
)screen
->w
, (GLdouble
)screen
->h
, 0.0, 0.0, 1.0);
142 glMatrixMode(GL_MODELVIEW
);
146 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_DECAL
);
149 void SDL_GL_Leave2DMode()
151 glMatrixMode(GL_MODELVIEW
);
154 glMatrixMode(GL_PROJECTION
);
160 /* Quick utility function for texture creation */
161 static int power_of_two(int input
)
165 while ( value
< input
) {
171 GLuint
SDL_GL_LoadTexture(SDL_Surface
*surface
, GLfloat
*texcoord
)
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 */
188 image
= SDL_CreateRGBSurface(
192 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
204 if ( image
== NULL
) {
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);
215 /* Copy the surface into the GL texture image */
220 SDL_BlitSurface(surface
, &area
, image
, &area
);
222 /* Restore the alpha blending attributes */
223 if ( (saved_flags
& SDL_SRCALPHA
) == SDL_SRCALPHA
) {
224 SDL_SetAlpha(surface
, saved_flags
, saved_alpha
);
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
,
240 SDL_FreeSurface(image
); /* No longer needed */
245 void DrawLogoCursor(void)
247 static GLfloat texMinX
, texMinY
;
248 static GLfloat texMaxX
, texMaxY
;
252 if ( ! cursor_texture
) {
256 /* Load the image (could use SDL_image library here) */
257 image
= SDL_LoadBMP(LOGO_FILE
);
258 if ( image
== NULL
) {
264 /* Convert the image into an OpenGL texture */
265 cursor_texture
= SDL_GL_LoadTexture(image
, texcoord
);
267 /* Make texture coordinates easy to understand */
268 texMinX
= texcoord
[0];
269 texMinY
= texcoord
[1];
270 texMaxX
= texcoord
[2];
271 texMaxY
= texcoord
[3];
273 /* We don't need the original image anymore */
274 SDL_FreeSurface(image
);
276 /* Make sure that the texture conversion is okay */
277 if ( ! cursor_texture
) {
282 /* Move the image around */
283 SDL_GetMouseState(&x
, &y
);
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
);
296 SDL_GL_Leave2DMode();
299 void DrawLogoTexture(void)
301 static GLfloat texMinX
, texMinY
;
302 static GLfloat texMaxX
, texMaxY
;
306 static int delta_x
= 1;
307 static int delta_y
= 1;
309 SDL_Surface
*screen
= SDL_GetVideoSurface();
311 if ( ! global_texture
) {
315 /* Load the image (could use SDL_image library here) */
316 image
= SDL_LoadBMP(LOGO_FILE
);
317 if ( image
== NULL
) {
323 /* Convert the image into an OpenGL texture */
324 global_texture
= SDL_GL_LoadTexture(image
, texcoord
);
326 /* Make texture coordinates easy to understand */
327 texMinX
= texcoord
[0];
328 texMinY
= texcoord
[1];
329 texMaxX
= texcoord
[2];
330 texMaxY
= texcoord
[3];
332 /* We don't need the original image anymore */
333 SDL_FreeSurface(image
);
335 /* Make sure that the texture conversion is okay */
336 if ( ! global_texture
) {
341 /* Move the image around */
347 if ( (x
+w
) > screen
->w
) {
356 if ( (y
+h
) > screen
->h
) {
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
);
370 SDL_GL_Leave2DMode();
373 /* This code is deprecated, but available for speed comparisons */
374 void DrawLogoBlit(void)
379 static int delta_x
= 1;
380 static int delta_y
= 1;
383 SDL_Surface
*screen
= SDL_GetVideoSurface();
385 if ( global_image
== NULL
) {
388 /* Load the image (could use SDL_image library here) */
389 temp
= SDL_LoadBMP(LOGO_FILE
);
390 if ( temp
== NULL
) {
396 /* Convert the image into the screen format */
397 global_image
= SDL_CreateRGBSurface(
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
);
408 SDL_FreeSurface(temp
);
410 /* Make sure that the texture conversion is okay */
411 if ( ! global_image
) {
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
420 Note that you can also achieve interesting effects by modifying
421 the screen surface alpha channel. It's set to 255 by default..
428 if ( (x
+w
) > screen
->w
) {
437 if ( (y
+h
) > screen
->h
) {
445 SDL_BlitSurface(global_image
, NULL
, screen
, &dst
);
447 /* Show the image on the screen */
448 SDL_UpdateRects(screen
, 1, &dst
);
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
)
460 Uint32 start_time
, this_time
;
461 float color
[8][3]= {{ 1.0, 1.0, 0.0},
469 float cube
[8][3]= {{ 0.5, 0.5, -0.5},
480 if( SDL_Init( SDL_INIT_VIDEO
) < 0 ) {
481 fprintf(stderr
,"Couldn't initialize SDL: %s\n",SDL_GetError());
485 /* See if we should detect the display depth */
487 if ( SDL_GetVideoInfo()->vfmt
->BitsPerPixel
<= 8 ) {
490 bpp
= 16; /* More doesn't seem to work */
494 /* Set the flags we want to use for setting the video mode */
495 if ( logo
&& USE_DEPRECATED_OPENGLBLIT
) {
496 video_flags
= SDL_OPENGLBLIT
;
498 video_flags
= SDL_OPENGL
;
500 for ( i
=1; argv
[i
]; ++i
) {
501 if ( strcmp(argv
[i
], "-fullscreen") == 0 ) {
502 video_flags
|= SDL_FULLSCREEN
;
507 video_flags
|= SDL_NOFRAME
;
510 /* Initialize the display */
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 );
535 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS
, 1 );
536 SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES
, fsaa
);
539 SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL
, 1 );
542 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL
, 1 );
544 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL
, 0 );
546 if ( SDL_SetVideoMode( w
, h
, bpp
, video_flags
) == NULL
) {
547 fprintf(stderr
, "Couldn't set GL mode: %s\n", SDL_GetError());
552 printf("Screen BPP: %d\n", SDL_GetVideoSurface()->format
->BitsPerPixel
);
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
) );
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
);
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
);
577 SDL_GL_GetAttribute( SDL_GL_ACCELERATED_VISUAL
, &value
);
578 printf( "SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value
);
581 SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL
, &value
);
582 printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value
);
585 /* Set the window manager title bar */
586 SDL_WM_SetCaption( "SDL GL test", "testgl" );
588 /* Set the gamma for the window */
589 if ( gamma
!= 0.0 ) {
590 SDL_SetGamma(gamma
, gamma
, gamma
);
593 glViewport( 0, 0, w
, h
);
594 glMatrixMode( GL_PROJECTION
);
597 glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
599 glMatrixMode( GL_MODELVIEW
);
602 glEnable(GL_DEPTH_TEST
);
604 glDepthFunc(GL_LESS
);
606 glShadeModel(GL_SMOOTH
);
608 /* Loop until done. */
609 start_time
= SDL_GetTicks();
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
);
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]);
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]);
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]);
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]);
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]);
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]);
683 glColor3f(0.0, 1.0, 0.0);
684 glVertex3fv(cube
[3]);
685 glVertex3fv(cube
[4]);
686 glVertex3fv(cube
[7]);
687 glVertex3fv(cube
[2]);
689 glColor3f(0.0, 0.0, 1.0);
690 glVertex3fv(cube
[0]);
691 glVertex3fv(cube
[5]);
692 glVertex3fv(cube
[6]);
693 glVertex3fv(cube
[1]);
695 glColor3f(0.0, 1.0, 1.0);
696 glVertex3fv(cube
[5]);
697 glVertex3fv(cube
[4]);
698 glVertex3fv(cube
[7]);
699 glVertex3fv(cube
[6]);
701 glColor3f(1.0, 1.0, 0.0);
702 glVertex3fv(cube
[5]);
703 glVertex3fv(cube
[0]);
704 glVertex3fv(cube
[3]);
705 glVertex3fv(cube
[4]);
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 */
716 glMatrixMode(GL_MODELVIEW
);
717 glRotatef(5.0, 1.0, 1.0, 1.0);
719 /* Draw 2D logo onto the 3D display */
721 if ( USE_DEPRECATED_OPENGLBLIT
) {
731 SDL_GL_SwapBuffers( );
733 /* Check for error conditions. */
734 gl_error
= glGetError( );
736 if( gl_error
!= GL_NO_ERROR
) {
737 fprintf( stderr
, "testgl: OpenGL error: %d\n", gl_error
);
740 sdl_error
= SDL_GetError( );
742 if( sdl_error
[0] != '\0' ) {
743 fprintf(stderr
, "testgl: SDL error '%s'\n", sdl_error
);
747 /* Allow the user to see what's happening */
752 /* Check if there's a pending event. */
753 while( SDL_PollEvent( &event
) ) {
754 done
= HandleEvent(&event
);
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);
766 if ( global_image
) {
767 SDL_FreeSurface(global_image
);
770 if ( global_texture
) {
771 glDeleteTextures( 1, &global_texture
);
774 if ( cursor_texture
) {
775 glDeleteTextures( 1, &cursor_texture
);
779 /* Destroy our GL context, etc. */
784 int main(int argc
, char *argv
[])
786 int i
, logo
, logocursor
= 0;
799 for ( i
=1; argv
[i
]; ++i
) {
800 if ( strcmp(argv
[i
], "-twice") == 0 ) {
803 if ( strcmp(argv
[i
], "-logo") == 0 ) {
805 USE_DEPRECATED_OPENGLBLIT
= SDL_FALSE
;
807 if ( strcmp(argv
[i
], "-logoblit") == 0 ) {
809 USE_DEPRECATED_OPENGLBLIT
= SDL_TRUE
;
811 if ( strcmp(argv
[i
], "-logocursor") == 0 ) {
814 if ( strcmp(argv
[i
], "-slow") == 0 ) {
817 if ( strcmp(argv
[i
], "-bpp") == 0 ) {
818 bpp
= atoi(argv
[++i
]);
820 if ( strcmp(argv
[i
], "-gamma") == 0 ) {
821 gamma
= (float)atof(argv
[++i
]);
823 if ( strcmp(argv
[i
], "-noframe") == 0 ) {
826 if ( strcmp(argv
[i
], "-fsaa") == 0 ) {
829 if ( strcmp(argv
[i
], "-accel") == 0 ) {
832 if ( strcmp(argv
[i
], "-sync") == 0 ) {
835 if ( strncmp(argv
[i
], "-h", 2) == 0 ) {
837 "Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-accel] [-sync] [-fullscreen]\n",
842 for ( i
=0; i
<numtests
; ++i
) {
843 RunGLTest(argc
, argv
, logo
, logocursor
, slowly
, bpp
, gamma
, noframe
, fsaa
, sync
, accel
);
848 #else /* HAVE_OPENGL */
850 int main(int argc
, char *argv
[])
852 printf("No OpenGL support on this system\n");
856 #endif /* HAVE_OPENGL */