); glvertex3fv( v1 ); glcolor4ubv( red ); glvertex3fv( v0 ); glcolor4ubv( yellow ); glvertex3fv( v4 ); glcolor4ubv( green ); glvertex3fv( v1 ); glcolor4ubv( yellow ); glvertex3fv( v4 ); glcolor4ubv( black ); glvertex3fv( v5 ); glend( ); /* * exercise: * draw text telling the user that 'spc' * pauses the rotation and 'esc' quits. * do it using vetors and textured quads. */ /* * swap the buffers. this this tells the driver to * render the next frame from the contents of the * back-buffer, and to set all rendering operations * to occur on what was the front-buffer. * * double buffering prevents nasty visual tearing * from the application drawing on areas of the * screen that are being updated at the same time. */ sdl_gl_swapbuffers( ); } static void setup_opengl( int width, int height ) { float ratio = (float) width / (float) height; /* our shading model--gouraud (smooth). */ glshademodel( gl_smooth ); /* culling. */ glcullface( gl_back ); glfrontface( gl_ccw ); glenable( gl_cull_face ); /* set the clear color. */ glclearcolor( 0, 0, 0, 0 ); /* setup our viewport. */ glviewport( 0, 0, width, height ); /* * change to the projection matrix and set * our viewing volume. */ glmatrixmode( gl_projection ); glloadidentity( ); /* * exercise: * replace this with a call to glfrustum. */ gluperspective( 60.0, ratio, 1.0, 1024.0 ); } int main( int argc, char* argv[] ) { /* information about the current video settings. */ const sdl_videoinfo* info = null; /* dimensions of our window. */ int width = 0; int height = 0; /* color depth in bits of our window. */ int bpp = 0; /* flags we will pass into sdl_setvideomode. */ int flags = 0; /* first, initialize sdl's video subsystem. */ if( sdl_init( sdl_init_video ) < 0 ) { /* failed, exit. */ fprintf( stderr, "video initialization failed: %s\n", sdl_geterror( ) ); quit_tutorial( 1 ); } /* let's get some video information. */ info = sdl_getvideoinfo( ); if( !info ) { /* this should probably never happen. */ fprintf( stderr, "video query failed: %s\n", sdl_geterror( ) ); quit_tutorial( 1 ); } /* * set our width/height to 640/480 (you would * of course let the user decide this in a normal * app). we get the bpp we will request from * the display. on x11, vidmode can't change * resolution, so this is probably being overly * safe. under win32, changedisplaysettings * can change the bpp. */ width = 640; height = 480; bpp = info->vfmt->bitsperpixel; /* * now, we want to setup our requested * window attributes for our opengl window. * we want *at least* 5 bits of red, green * and blue. we also want at least a 16-bit * depth buffer. * * the last thing we do is request a double * buffered window. '1' turns on double * buffering, '0' turns it off. * * note that we do not use sdl_doublebuf in * the flags to sdl_setvideomode. that does * not affect the gl attribute state, only * the standard 2d blitting setup. */ sdl_gl_setattribute( sdl_gl_red_size, 5 ); sdl_gl_setattribute( sdl_gl_green_size, 5 ); sdl_gl_setattribute( sdl_gl_blue_size, 5 ); sdl_gl_setattribute( sdl_gl_depth_size, 16 ); sdl_gl_setattribute( sdl_gl_doublebuffer, 1 ); /* * we want to request that sdl provide us * with an opengl window, in a fullscreen * video mode. * * exercise: * make starting windowed an option, and * handle the resize events properly with * glviewport. */ flags = sdl_opengl | sdl_fullscreen; /* * set the video mode */ if( sdl_setvideomode( width, height, bpp, flags ) == 0 ) { /* * this could happen for a variety of reasons, * including display not being set, the specified * resolution not being available, etc. */ fprintf( stderr, "video mode set failed: %s\n", sdl_geterror( ) ); quit_tutorial( 1 ); } /* * at this point, we should have a properly setup * double-buffered window for use with opengl. */ setup_opengl( width, height ); /* * now we want to begin our normal app process-- * an event loop with a lot of redrawing. */ while( 1 ) { /* process incoming events. */ process_events( ); /* draw the screen. */ draw_screen( ); } /* * exercise: * record timings