4 >Using OpenGL With SDL</TITLE
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
10 TITLE="SDL Library Documentation"
11 HREF="index.html"><LINK
13 TITLE="Graphics and Video"
14 HREF="guidevideo.html"><LINK
16 TITLE="Graphics and Video"
17 HREF="guidevideo.html"><LINK
19 TITLE="Input handling"
20 HREF="guideinput.html"></HEAD
31 SUMMARY="Header navigation table"
40 >SDL Library Documentation</TH
48 HREF="guidevideo.html"
56 >Chapter 2. Graphics and Video</TD
62 HREF="guideinput.html"
76 NAME="GUIDEVIDEOOPENGL"
78 >Using OpenGL With SDL</H1
80 >SDL has the ability to create and use OpenGL contexts on several platforms(Linux/X11, Win32, BeOS, MacOS Classic/Toolbox, Mac OS X, FreeBSD/X11 and Solaris/X11). This allows you to use SDL's audio, event handling, threads and times in your OpenGL applications (a function often performed by GLUT).</P
90 >Initialising SDL to use OpenGL is not very different to initialising SDL normally. There are three differences; you must pass <TT
94 HREF="sdlsetvideomode.html"
99 >, you must specify several GL attributes (depth buffer size, framebuffer sizes) using <A
100 HREF="sdlglsetattribute.html"
103 >SDL_GL_SetAttribute</TT
105 > and finally, if you wish to use double buffering you must specify it as a GL attribute, <SPAN
116 >SDL_SetVideoMode</TT
125 >Example 2-7. Initializing SDL with OpenGL</B
128 CLASS="PROGRAMLISTING"
129 > /* Information about the current video settings. */
130 const SDL_VideoInfo* info = NULL;
131 /* Dimensions of our window. */
134 /* Color depth in bits of our window. */
136 /* Flags we will pass into SDL_SetVideoMode. */
139 /* First, initialize SDL's video subsystem. */
140 if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
142 fprintf( stderr, "Video initialization failed: %s\n",
147 /* Let's get some video information. */
148 info = SDL_GetVideoInfo( );
151 /* This should probably never happen. */
152 fprintf( stderr, "Video query failed: %s\n",
158 * Set our width/height to 640/480 (you would
159 * of course let the user decide this in a normal
160 * app). We get the bpp we will request from
161 * the display. On X11, VidMode can't change
162 * resolution, so this is probably being overly
163 * safe. Under Win32, ChangeDisplaySettings
164 * can change the bpp.
168 bpp = info->vfmt->BitsPerPixel;
171 * Now, we want to setup our requested
172 * window attributes for our OpenGL window.
173 * We want *at least* 5 bits of red, green
174 * and blue. We also want at least a 16-bit
177 * The last thing we do is request a double
178 * buffered window. '1' turns on double
179 * buffering, '0' turns it off.
181 * Note that we do not use SDL_DOUBLEBUF in
182 * the flags to SDL_SetVideoMode. That does
183 * not affect the GL attribute state, only
184 * the standard 2D blitting setup.
186 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
187 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
188 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
189 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
190 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
193 * We want to request that SDL provide us
194 * with an OpenGL window, in a fullscreen
198 * Make starting windowed an option, and
199 * handle the resize events properly with
202 flags = SDL_OPENGL | SDL_FULLSCREEN;
207 if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
209 * This could happen for a variety of reasons,
210 * including DISPLAY not being set, the specified
211 * resolution not being available, etc.
213 fprintf( stderr, "Video mode set failed: %s\n",
228 >Apart from initialisation, using OpenGL within SDL is the same as using OpenGL
229 with any other API, e.g. GLUT. You still use all the same function calls and
230 data types. However if you are using a double-buffered display, then you must
233 HREF="sdlglswapbuffers.html"
236 >SDL_GL_SwapBuffers()</TT
239 to swap the buffers and update the display. To request double-buffering
242 HREF="sdlglsetattribute.html"
245 >SDL_GL_SetAttribute</TT
250 >SDL_GL_DOUBLEBUFFER</TT
253 HREF="sdlglgetattribute.html"
256 >SDL_GL_GetAttribute</TT
259 to see if you actually got it.</P
261 >A full example code listing is now presented below.</P
269 >Example 2-8. SDL and OpenGL</B
272 CLASS="PROGRAMLISTING"
274 * SDL OpenGL Tutorial.
275 * (c) Michael Vance, 2000
276 * briareos@lokigames.com
278 * Distributed under terms of the LGPL.
281 #include <SDL/SDL.h>
282 #include <GL/gl.h>
283 #include <GL/glu.h>
285 #include <stdio.h>
286 #include <stdlib.h>
288 static GLboolean should_rotate = GL_TRUE;
290 static void quit_tutorial( int code )
293 * Quit SDL so we can release the fullscreen
294 * mode and restore the previous video settings,
303 static void handle_key_down( SDL_keysym* keysym )
307 * We're only interested if 'Esc' has
311 * Handle the arrow keys and have that change the
312 * viewing position/angle.
314 switch( keysym->sym ) {
319 should_rotate = !should_rotate;
327 static void process_events( void )
329 /* Our SDL event placeholder. */
332 /* Grab all the events off the queue. */
333 while( SDL_PollEvent( &event ) ) {
335 switch( event.type ) {
337 /* Handle key presses. */
338 handle_key_down( &event.key.keysym );
341 /* Handle quit requests (like Ctrl-c). */
350 static void draw_screen( void )
352 /* Our angle of rotation. */
353 static float angle = 0.0f;
357 * Replace this awful mess with vertex
358 * arrays and a call to glDrawElements.
361 * After completing the above, change
362 * it to use compiled vertex arrays.
365 * Verify my windings are correct here ;).
367 static GLfloat v0[] = { -1.0f, -1.0f, 1.0f };
368 static GLfloat v1[] = { 1.0f, -1.0f, 1.0f };
369 static GLfloat v2[] = { 1.0f, 1.0f, 1.0f };
370 static GLfloat v3[] = { -1.0f, 1.0f, 1.0f };
371 static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
372 static GLfloat v5[] = { 1.0f, -1.0f, -1.0f };
373 static GLfloat v6[] = { 1.0f, 1.0f, -1.0f };
374 static GLfloat v7[] = { -1.0f, 1.0f, -1.0f };
375 static GLubyte red[] = { 255, 0, 0, 255 };
376 static GLubyte green[] = { 0, 255, 0, 255 };
377 static GLubyte blue[] = { 0, 0, 255, 255 };
378 static GLubyte white[] = { 255, 255, 255, 255 };
379 static GLubyte yellow[] = { 0, 255, 255, 255 };
380 static GLubyte black[] = { 0, 0, 0, 255 };
381 static GLubyte orange[] = { 255, 255, 0, 255 };
382 static GLubyte purple[] = { 255, 0, 255, 0 };
384 /* Clear the color and depth buffers. */
385 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
387 /* We don't want to modify the projection matrix. */
388 glMatrixMode( GL_MODELVIEW );
391 /* Move down the z-axis. */
392 glTranslatef( 0.0, 0.0, -5.0 );
395 glRotatef( angle, 0.0, 1.0, 0.0 );
397 if( should_rotate ) {
399 if( ++angle > 360.0f ) {
405 /* Send our triangle data to the pipeline. */
406 glBegin( GL_TRIANGLES );
410 glColor4ubv( green );
419 glColor4ubv( white );
422 glColor4ubv( green );
424 glColor4ubv( black );
426 glColor4ubv( orange );
429 glColor4ubv( green );
431 glColor4ubv( orange );
436 glColor4ubv( black );
438 glColor4ubv( yellow );
440 glColor4ubv( purple );
443 glColor4ubv( black );
445 glColor4ubv( purple );
447 glColor4ubv( orange );
450 glColor4ubv( yellow );
454 glColor4ubv( white );
457 glColor4ubv( yellow );
459 glColor4ubv( white );
461 glColor4ubv( purple );
464 glColor4ubv( white );
468 glColor4ubv( orange );
471 glColor4ubv( white );
473 glColor4ubv( orange );
475 glColor4ubv( purple );
478 glColor4ubv( green );
482 glColor4ubv( yellow );
485 glColor4ubv( green );
487 glColor4ubv( yellow );
489 glColor4ubv( black );
496 * Draw text telling the user that 'Spc'
497 * pauses the rotation and 'Esc' quits.
498 * Do it using vetors and textured quads.
502 * Swap the buffers. This this tells the driver to
503 * render the next frame from the contents of the
504 * back-buffer, and to set all rendering operations
505 * to occur on what was the front-buffer.
507 * Double buffering prevents nasty visual tearing
508 * from the application drawing on areas of the
509 * screen that are being updated at the same time.
511 SDL_GL_SwapBuffers( );
514 static void setup_opengl( int width, int height )
516 float ratio = (float) width / (float) height;
518 /* Our shading model--Gouraud (smooth). */
519 glShadeModel( GL_SMOOTH );
522 glCullFace( GL_BACK );
523 glFrontFace( GL_CCW );
524 glEnable( GL_CULL_FACE );
526 /* Set the clear color. */
527 glClearColor( 0, 0, 0, 0 );
529 /* Setup our viewport. */
530 glViewport( 0, 0, width, height );
533 * Change to the projection matrix and set
534 * our viewing volume.
536 glMatrixMode( GL_PROJECTION );
540 * Replace this with a call to glFrustum.
542 gluPerspective( 60.0, ratio, 1.0, 1024.0 );
545 int main( int argc, char* argv[] )
547 /* Information about the current video settings. */
548 const SDL_VideoInfo* info = NULL;
549 /* Dimensions of our window. */
552 /* Color depth in bits of our window. */
554 /* Flags we will pass into SDL_SetVideoMode. */
557 /* First, initialize SDL's video subsystem. */
558 if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
560 fprintf( stderr, "Video initialization failed: %s\n",
565 /* Let's get some video information. */
566 info = SDL_GetVideoInfo( );
569 /* This should probably never happen. */
570 fprintf( stderr, "Video query failed: %s\n",
576 * Set our width/height to 640/480 (you would
577 * of course let the user decide this in a normal
578 * app). We get the bpp we will request from
579 * the display. On X11, VidMode can't change
580 * resolution, so this is probably being overly
581 * safe. Under Win32, ChangeDisplaySettings
582 * can change the bpp.
586 bpp = info->vfmt->BitsPerPixel;
589 * Now, we want to setup our requested
590 * window attributes for our OpenGL window.
591 * We want *at least* 5 bits of red, green
592 * and blue. We also want at least a 16-bit
595 * The last thing we do is request a double
596 * buffered window. '1' turns on double
597 * buffering, '0' turns it off.
599 * Note that we do not use SDL_DOUBLEBUF in
600 * the flags to SDL_SetVideoMode. That does
601 * not affect the GL attribute state, only
602 * the standard 2D blitting setup.
604 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
605 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
606 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
607 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
608 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
611 * We want to request that SDL provide us
612 * with an OpenGL window, in a fullscreen
616 * Make starting windowed an option, and
617 * handle the resize events properly with
620 flags = SDL_OPENGL | SDL_FULLSCREEN;
625 if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
627 * This could happen for a variety of reasons,
628 * including DISPLAY not being set, the specified
629 * resolution not being available, etc.
631 fprintf( stderr, "Video mode set failed: %s\n",
637 * At this point, we should have a properly setup
638 * double-buffered window for use with OpenGL.
640 setup_opengl( width, height );
643 * Now we want to begin our normal app process--
644 * an event loop with a lot of redrawing.
647 /* Process incoming events. */
649 /* Draw the screen. */
655 * Record timings using SDL_GetTicks() and
656 * and print out frames per second at program
671 SUMMARY="Footer navigation table"
682 HREF="guidevideo.html"
700 HREF="guideinput.html"
710 >Graphics and Video</TD
716 HREF="guidevideo.html"