0
+ − 1 <HTML
+ − 2 ><HEAD
+ − 3 ><TITLE
+ − 4 >Graphics and Video</TITLE
+ − 5 ><META
+ − 6 NAME="GENERATOR"
+ − 7 CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+ − 8 "><LINK
+ − 9 REL="HOME"
+ − 10 TITLE="SDL Library Documentation"
+ − 11 HREF="index.html"><LINK
+ − 12 REL="UP"
+ − 13 TITLE="SDL Guide"
+ − 14 HREF="guide.html"><LINK
+ − 15 REL="PREVIOUS"
+ − 16 TITLE="Initializing SDL"
+ − 17 HREF="guidebasicsinit.html"><LINK
+ − 18 REL="NEXT"
+ − 19 TITLE="Input handling"
+ − 20 HREF="guideinput.html"></HEAD
+ − 21 ><BODY
+ − 22 CLASS="CHAPTER"
+ − 23 BGCOLOR="#FFF8DC"
+ − 24 TEXT="#000000"
+ − 25 LINK="#0000ee"
+ − 26 VLINK="#551a8b"
+ − 27 ALINK="#ff0000"
+ − 28 ><DIV
+ − 29 CLASS="NAVHEADER"
+ − 30 ><TABLE
+ − 31 WIDTH="100%"
+ − 32 BORDER="0"
+ − 33 CELLPADDING="0"
+ − 34 CELLSPACING="0"
+ − 35 ><TR
+ − 36 ><TH
+ − 37 COLSPAN="3"
+ − 38 ALIGN="center"
+ − 39 >SDL Library Documentation</TH
+ − 40 ></TR
+ − 41 ><TR
+ − 42 ><TD
+ − 43 WIDTH="10%"
+ − 44 ALIGN="left"
+ − 45 VALIGN="bottom"
+ − 46 ><A
+ − 47 HREF="guidebasicsinit.html"
+ − 48 >Prev</A
+ − 49 ></TD
+ − 50 ><TD
+ − 51 WIDTH="80%"
+ − 52 ALIGN="center"
+ − 53 VALIGN="bottom"
+ − 54 ></TD
+ − 55 ><TD
+ − 56 WIDTH="10%"
+ − 57 ALIGN="right"
+ − 58 VALIGN="bottom"
+ − 59 ><A
+ − 60 HREF="guideinput.html"
+ − 61 >Next</A
+ − 62 ></TD
+ − 63 ></TR
+ − 64 ></TABLE
+ − 65 ><HR
+ − 66 ALIGN="LEFT"
+ − 67 WIDTH="100%"></DIV
+ − 68 ><DIV
+ − 69 CLASS="CHAPTER"
+ − 70 ><H1
+ − 71 ><A
+ − 72 NAME="GUIDEVIDEO"
+ − 73 >Chapter 2. Graphics and Video</A
+ − 74 ></H1
+ − 75 ><DIV
+ − 76 CLASS="SECT1"
+ − 77 ><H1
+ − 78 CLASS="SECT1"
+ − 79 ><A
+ − 80 NAME="GUIDEVIDEOOPENGL"
+ − 81 >Using OpenGL With SDL</A
+ − 82 ></H1
+ − 83 ><P
+ − 84 >SDL has the ability to create and use OpenGL contexts on several platforms(Linux/X11, Win32, BeOS, MacOS Classic/Toolbox, MacOS 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
+ − 85 ><DIV
+ − 86 CLASS="SECT2"
+ − 87 ><H2
+ − 88 CLASS="SECT2"
+ − 89 ><A
+ − 90 NAME="AEN65"
+ − 91 >Initialisation</A
+ − 92 ></H2
+ − 93 ><P
+ − 94 >Initialising SDL to use OpenGL is not very different to initialising SDL normally. There are three differences; you must pass <TT
+ − 95 CLASS="LITERAL"
+ − 96 >SDL_OPENGL</TT
+ − 97 > to <A
+ − 98 HREF="sdlsetvideomode.html"
+ − 99 ><TT
+ − 100 CLASS="FUNCTION"
+ − 101 >SDL_SetVideoMode</TT
+ − 102 ></A
+ − 103 >, you must specify several GL attributes (depth buffer size, framebuffer sizes) using <A
+ − 104 HREF="sdlglsetattribute.html"
+ − 105 ><TT
+ − 106 CLASS="FUNCTION"
+ − 107 >SDL_GL_SetAttribute</TT
+ − 108 ></A
+ − 109 > and finally, if you wish to use double buffering you must specify it as a GL attribute, <I
+ − 110 CLASS="EMPHASIS"
+ − 111 >not</I
+ − 112 > by passing the <TT
+ − 113 CLASS="LITERAL"
+ − 114 >SDL_DOUBLEBUF</TT
+ − 115 > flag to <TT
+ − 116 CLASS="FUNCTION"
+ − 117 >SDL_SetVideoMode</TT
+ − 118 >.
+ − 119 <PRE
+ − 120 CLASS="PROGRAMLISTING"
+ − 121 > /* Information about the current video settings. */
+ − 122 const SDL_VideoInfo* info = NULL;
+ − 123 /* Dimensions of our window. */
+ − 124 int width = 0;
+ − 125 int height = 0;
+ − 126 /* Color depth in bits of our window. */
+ − 127 int bpp = 0;
+ − 128 /* Flags we will pass into SDL_SetVideoMode. */
+ − 129 int flags = 0;
+ − 130
+ − 131 /* First, initialize SDL's video subsystem. */
+ − 132 if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
+ − 133 /* Failed, exit. */
+ − 134 fprintf( stderr, "Video initialization failed: %s\n",
+ − 135 SDL_GetError( ) );
+ − 136 quit_tutorial( 1 );
+ − 137 }
+ − 138
+ − 139 /* Let's get some video information. */
+ − 140 info = SDL_GetVideoInfo( );
+ − 141
+ − 142 if( !info ) {
+ − 143 /* This should probably never happen. */
+ − 144 fprintf( stderr, "Video query failed: %s\n",
+ − 145 SDL_GetError( ) );
+ − 146 quit_tutorial( 1 );
+ − 147 }
+ − 148
+ − 149 /*
+ − 150 * Set our width/height to 640/480 (you would
+ − 151 * of course let the user decide this in a normal
+ − 152 * app). We get the bpp we will request from
+ − 153 * the display. On X11, VidMode can't change
+ − 154 * resolution, so this is probably being overly
+ − 155 * safe. Under Win32, ChangeDisplaySettings
+ − 156 * can change the bpp.
+ − 157 */
+ − 158 width = 640;
+ − 159 height = 480;
+ − 160 bpp = info->vfmt->BitsPerPixel;
+ − 161
+ − 162 /*
+ − 163 * Now, we want to setup our requested
+ − 164 * window attributes for our OpenGL window.
+ − 165 * We want *at least* 5 bits of red, green
+ − 166 * and blue. We also want at least a 16-bit
+ − 167 * depth buffer.
+ − 168 *
+ − 169 * The last thing we do is request a double
+ − 170 * buffered window. '1' turns on double
+ − 171 * buffering, '0' turns it off.
+ − 172 *
+ − 173 * Note that we do not use SDL_DOUBLEBUF in
+ − 174 * the flags to SDL_SetVideoMode. That does
+ − 175 * not affect the GL attribute state, only
+ − 176 * the standard 2D blitting setup.
+ − 177 */
+ − 178 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+ − 179 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+ − 180 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+ − 181 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+ − 182 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ − 183
+ − 184 /*
+ − 185 * We want to request that SDL provide us
+ − 186 * with an OpenGL window, in a fullscreen
+ − 187 * video mode.
+ − 188 *
+ − 189 * EXERCISE:
+ − 190 * Make starting windowed an option, and
+ − 191 * handle the resize events properly with
+ − 192 * glViewport.
+ − 193 */
+ − 194 flags = SDL_OPENGL | SDL_FULLSCREEN;
+ − 195
+ − 196 /*
+ − 197 * Set the video mode
+ − 198 */
+ − 199 if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+ − 200 /*
+ − 201 * This could happen for a variety of reasons,
+ − 202 * including DISPLAY not being set, the specified
+ − 203 * resolution not being available, etc.
+ − 204 */
+ − 205 fprintf( stderr, "Video mode set failed: %s\n",
+ − 206 SDL_GetError( ) );
+ − 207 quit_tutorial( 1 );
+ − 208 }</PRE
+ − 209 ></P
+ − 210 ></DIV
+ − 211 ><DIV
+ − 212 CLASS="SECT2"
+ − 213 ><H2
+ − 214 CLASS="SECT2"
+ − 215 ><A
+ − 216 NAME="AEN77"
+ − 217 >Drawing</A
+ − 218 ></H2
+ − 219 ><P
+ − 220 >Apart from initialisation, using OpenGL within SDL is the same as using. However if you have request a double buffered display (using <A
+ − 221 HREF="sdlglsetattribute.html"
+ − 222 ><TT
+ − 223 CLASS="FUNCTION"
+ − 224 >SDL_GL_SetAttribute</TT
+ − 225 ></A
+ − 226 >) and one (which can be checked by using <A
+ − 227 HREF="sdlglgetattribute.html"
+ − 228 ><TT
+ − 229 CLASS="FUNCTION"
+ − 230 >SDL_GL_GetAttribute</TT
+ − 231 ></A
+ − 232 >), then you must use <A
+ − 233 HREF="sdlglswapbuffers.html"
+ − 234 ><TT
+ − 235 CLASS="FUNCTION"
+ − 236 >SDL_GL_SwapBuffers()</TT
+ − 237 ></A
+ − 238 > to swap the buffers and update the display.</P
+ − 239 ><P
+ − 240 >A full example code listing is now presented below.</P
+ − 241 ><DIV
+ − 242 CLASS="EXAMPLE"
+ − 243 ><A
+ − 244 NAME="AEN87"
+ − 245 ></A
+ − 246 ><P
+ − 247 ><B
+ − 248 >Example 2-1. gl.c - SDL OpenGL Example</B
+ − 249 ></P
+ − 250 ><PRE
+ − 251 CLASS="PROGRAMLISTING"
+ − 252 >/*
+ − 253 * SDL OpenGL Tutorial.
+ − 254 * (c) Michael Vance, 2000
+ − 255 * briareos@lokigames.com
+ − 256 *
+ − 257 * Distributed under terms of the LGPL.
+ − 258 */
+ − 259
+ − 260 #include <SDL/SDL.h>
+ − 261 #include <GL/gl.h>
+ − 262 #include <GL/glu.h>
+ − 263
+ − 264 #include <stdio.h>
+ − 265 #include <stdlib.h>
+ − 266
+ − 267 static GLboolean should_rotate = GL_TRUE;
+ − 268
+ − 269 static void quit_tutorial( int code )
+ − 270 {
+ − 271 /*
+ − 272 * Quit SDL so we can release the fullscreen
+ − 273 * mode and restore the previous video settings,
+ − 274 * etc.
+ − 275 */
+ − 276 SDL_Quit( );
+ − 277
+ − 278 /* Exit program. */
+ − 279 exit( code );
+ − 280 }
+ − 281
+ − 282 static void handle_key_down( SDL_keysym* keysym )
+ − 283 {
+ − 284
+ − 285 /*
+ − 286 * We're only interested if 'Esc' has
+ − 287 * been presssed.
+ − 288 *
+ − 289 * EXERCISE:
+ − 290 * Handle the arrow keys and have that change the
+ − 291 * viewing position/angle.
+ − 292 */
+ − 293 switch( keysym->sym ) {
+ − 294 case SDLK_ESCAPE:
+ − 295 quit_tutorial( 0 );
+ − 296 break;
+ − 297 case SDLK_SPACE:
+ − 298 should_rotate = !should_rotate;
+ − 299 break;
+ − 300 default:
+ − 301 break;
+ − 302 }
+ − 303
+ − 304 }
+ − 305
+ − 306 static void process_events( void )
+ − 307 {
+ − 308 /* Our SDL event placeholder. */
+ − 309 SDL_Event event;
+ − 310
+ − 311 /* Grab all the events off the queue. */
+ − 312 while( SDL_PollEvent( &event ) ) {
+ − 313
+ − 314 switch( event.type ) {
+ − 315 case SDL_KEYDOWN:
+ − 316 /* Handle key presses. */
+ − 317 handle_key_down( &event.key.keysym );
+ − 318 break;
+ − 319 case SDL_QUIT:
+ − 320 /* Handle quit requests (like Ctrl-c). */
+ − 321 quit_tutorial( 0 );
+ − 322 break;
+ − 323 }
+ − 324
+ − 325 }
+ − 326
+ − 327 }
+ − 328
+ − 329 static void draw_screen( void )
+ − 330 {
+ − 331 /* Our angle of rotation. */
+ − 332 static float angle = 0.0f;
+ − 333
+ − 334 /*
+ − 335 * EXERCISE:
+ − 336 * Replace this awful mess with vertex
+ − 337 * arrays and a call to glDrawElements.
+ − 338 *
+ − 339 * EXERCISE:
+ − 340 * After completing the above, change
+ − 341 * it to use compiled vertex arrays.
+ − 342 *
+ − 343 * EXERCISE:
+ − 344 * Verify my windings are correct here ;).
+ − 345 */
+ − 346 static GLfloat v0[] = { -1.0f, -1.0f, 1.0f };
+ − 347 static GLfloat v1[] = { 1.0f, -1.0f, 1.0f };
+ − 348 static GLfloat v2[] = { 1.0f, 1.0f, 1.0f };
+ − 349 static GLfloat v3[] = { -1.0f, 1.0f, 1.0f };
+ − 350 static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
+ − 351 static GLfloat v5[] = { 1.0f, -1.0f, -1.0f };
+ − 352 static GLfloat v6[] = { 1.0f, 1.0f, -1.0f };
+ − 353 static GLfloat v7[] = { -1.0f, 1.0f, -1.0f };
+ − 354 static GLubyte red[] = { 255, 0, 0, 255 };
+ − 355 static GLubyte green[] = { 0, 255, 0, 255 };
+ − 356 static GLubyte blue[] = { 0, 0, 255, 255 };
+ − 357 static GLubyte white[] = { 255, 255, 255, 255 };
+ − 358 static GLubyte yellow[] = { 0, 255, 255, 255 };
+ − 359 static GLubyte black[] = { 0, 0, 0, 255 };
+ − 360 static GLubyte orange[] = { 255, 255, 0, 255 };
+ − 361 static GLubyte purple[] = { 255, 0, 255, 0 };
+ − 362
+ − 363 /* Clear the color and depth buffers. */
+ − 364 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ − 365
+ − 366 /* We don't want to modify the projection matrix. */
+ − 367 glMatrixMode( GL_MODELVIEW );
+ − 368 glLoadIdentity( );
+ − 369
+ − 370 /* Move down the z-axis. */
+ − 371 glTranslatef( 0.0, 0.0, -5.0 );
+ − 372
+ − 373 /* Rotate. */
+ − 374 glRotatef( angle, 0.0, 1.0, 0.0 );
+ − 375
+ − 376 if( should_rotate ) {
+ − 377
+ − 378 if( ++angle > 360.0f ) {
+ − 379 angle = 0.0f;
+ − 380 }
+ − 381
+ − 382 }
+ − 383
+ − 384 /* Send our triangle data to the pipeline. */
+ − 385 glBegin( GL_TRIANGLES );
+ − 386
+ − 387 glColor4ubv( red );
+ − 388 glVertex3fv( v0 );
+ − 389 glColor4ubv( green );
+ − 390 glVertex3fv( v1 );
+ − 391 glColor4ubv( blue );
+ − 392 glVertex3fv( v2 );
+ − 393
+ − 394 glColor4ubv( red );
+ − 395 glVertex3fv( v0 );
+ − 396 glColor4ubv( blue );
+ − 397 glVertex3fv( v2 );
+ − 398 glColor4ubv( white );
+ − 399 glVertex3fv( v3 );
+ − 400
+ − 401 glColor4ubv( green );
+ − 402 glVertex3fv( v1 );
+ − 403 glColor4ubv( black );
+ − 404 glVertex3fv( v5 );
+ − 405 glColor4ubv( orange );
+ − 406 glVertex3fv( v6 );
+ − 407
+ − 408 glColor4ubv( green );
+ − 409 glVertex3fv( v1 );
+ − 410 glColor4ubv( orange );
+ − 411 glVertex3fv( v6 );
+ − 412 glColor4ubv( blue );
+ − 413 glVertex3fv( v2 );
+ − 414
+ − 415 glColor4ubv( black );
+ − 416 glVertex3fv( v5 );
+ − 417 glColor4ubv( yellow );
+ − 418 glVertex3fv( v4 );
+ − 419 glColor4ubv( purple );
+ − 420 glVertex3fv( v7 );
+ − 421
+ − 422 glColor4ubv( black );
+ − 423 glVertex3fv( v5 );
+ − 424 glColor4ubv( purple );
+ − 425 glVertex3fv( v7 );
+ − 426 glColor4ubv( orange );
+ − 427 glVertex3fv( v6 );
+ − 428
+ − 429 glColor4ubv( yellow );
+ − 430 glVertex3fv( v4 );
+ − 431 glColor4ubv( red );
+ − 432 glVertex3fv( v0 );
+ − 433 glColor4ubv( white );
+ − 434 glVertex3fv( v3 );
+ − 435
+ − 436 glColor4ubv( yellow );
+ − 437 glVertex3fv( v4 );
+ − 438 glColor4ubv( white );
+ − 439 glVertex3fv( v3 );
+ − 440 glColor4ubv( purple );
+ − 441 glVertex3fv( v7 );
+ − 442
+ − 443 glColor4ubv( white );
+ − 444 glVertex3fv( v3 );
+ − 445 glColor4ubv( blue );
+ − 446 glVertex3fv( v2 );
+ − 447 glColor4ubv( orange );
+ − 448 glVertex3fv( v6 );
+ − 449
+ − 450 glColor4ubv( white );
+ − 451 glVertex3fv( v3 );
+ − 452 glColor4ubv( orange );
+ − 453 glVertex3fv( v6 );
+ − 454 glColor4ubv( purple );
+ − 455 glVertex3fv( v7 );
+ − 456
+ − 457 glColor4ubv( green );
+ − 458 glVertex3fv( v1 );
+ − 459 glColor4ubv( red );
+ − 460 glVertex3fv( v0 );
+ − 461 glColor4ubv( yellow );
+ − 462 glVertex3fv( v4 );
+ − 463
+ − 464 glColor4ubv( green );
+ − 465 glVertex3fv( v1 );
+ − 466 glColor4ubv( yellow );
+ − 467 glVertex3fv( v4 );
+ − 468 glColor4ubv( black );
+ − 469 glVertex3fv( v5 );
+ − 470
+ − 471 glEnd( );
+ − 472
+ − 473 /*
+ − 474 * EXERCISE:
+ − 475 * Draw text telling the user that 'Spc'
+ − 476 * pauses the rotation and 'Esc' quits.
+ − 477 * Do it using vetors and textured quads.
+ − 478 */
+ − 479
+ − 480 /*
+ − 481 * Swap the buffers. This this tells the driver to
+ − 482 * render the next frame from the contents of the
+ − 483 * back-buffer, and to set all rendering operations
+ − 484 * to occur on what was the front-buffer.
+ − 485 *
+ − 486 * Double buffering prevents nasty visual tearing
+ − 487 * from the application drawing on areas of the
+ − 488 * screen that are being updated at the same time.
+ − 489 */
+ − 490 SDL_GL_SwapBuffers( );
+ − 491 }
+ − 492
+ − 493 static void setup_opengl( int width, int height )
+ − 494 {
+ − 495 float ratio = (float) width / (float) height;
+ − 496
+ − 497 /* Our shading model--Gouraud (smooth). */
+ − 498 glShadeModel( GL_SMOOTH );
+ − 499
+ − 500 /* Culling. */
+ − 501 glCullFace( GL_BACK );
+ − 502 glFrontFace( GL_CCW );
+ − 503 glEnable( GL_CULL_FACE );
+ − 504
+ − 505 /* Set the clear color. */
+ − 506 glClearColor( 0, 0, 0, 0 );
+ − 507
+ − 508 /* Setup our viewport. */
+ − 509 glViewport( 0, 0, width, height );
+ − 510
+ − 511 /*
+ − 512 * Change to the projection matrix and set
+ − 513 * our viewing volume.
+ − 514 */
+ − 515 glMatrixMode( GL_PROJECTION );
+ − 516 glLoadIdentity( );
+ − 517 /*
+ − 518 * EXERCISE:
+ − 519 * Replace this with a call to glFrustum.
+ − 520 */
+ − 521 gluPerspective( 60.0, ratio, 1.0, 1024.0 );
+ − 522 }
+ − 523
+ − 524 int main( int argc, char* argv[] )
+ − 525 {
+ − 526 /* Information about the current video settings. */
+ − 527 const SDL_VideoInfo* info = NULL;
+ − 528 /* Dimensions of our window. */
+ − 529 int width = 0;
+ − 530 int height = 0;
+ − 531 /* Color depth in bits of our window. */
+ − 532 int bpp = 0;
+ − 533 /* Flags we will pass into SDL_SetVideoMode. */
+ − 534 int flags = 0;
+ − 535
+ − 536 /* First, initialize SDL's video subsystem. */
+ − 537 if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
+ − 538 /* Failed, exit. */
+ − 539 fprintf( stderr, "Video initialization failed: %s\n",
+ − 540 SDL_GetError( ) );
+ − 541 quit_tutorial( 1 );
+ − 542 }
+ − 543
+ − 544 /* Let's get some video information. */
+ − 545 info = SDL_GetVideoInfo( );
+ − 546
+ − 547 if( !info ) {
+ − 548 /* This should probably never happen. */
+ − 549 fprintf( stderr, "Video query failed: %s\n",
+ − 550 SDL_GetError( ) );
+ − 551 quit_tutorial( 1 );
+ − 552 }
+ − 553
+ − 554 /*
+ − 555 * Set our width/height to 640/480 (you would
+ − 556 * of course let the user decide this in a normal
+ − 557 * app). We get the bpp we will request from
+ − 558 * the display. On X11, VidMode can't change
+ − 559 * resolution, so this is probably being overly
+ − 560 * safe. Under Win32, ChangeDisplaySettings
+ − 561 * can change the bpp.
+ − 562 */
+ − 563 width = 640;
+ − 564 height = 480;
+ − 565 bpp = info->vfmt->BitsPerPixel;
+ − 566
+ − 567 /*
+ − 568 * Now, we want to setup our requested
+ − 569 * window attributes for our OpenGL window.
+ − 570 * We want *at least* 5 bits of red, green
+ − 571 * and blue. We also want at least a 16-bit
+ − 572 * depth buffer.
+ − 573 *
+ − 574 * The last thing we do is request a double
+ − 575 * buffered window. '1' turns on double
+ − 576 * buffering, '0' turns it off.
+ − 577 *
+ − 578 * Note that we do not use SDL_DOUBLEBUF in
+ − 579 * the flags to SDL_SetVideoMode. That does
+ − 580 * not affect the GL attribute state, only
+ − 581 * the standard 2D blitting setup.
+ − 582 */
+ − 583 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+ − 584 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+ − 585 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+ − 586 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+ − 587 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ − 588
+ − 589 /*
+ − 590 * We want to request that SDL provide us
+ − 591 * with an OpenGL window, in a fullscreen
+ − 592 * video mode.
+ − 593 *
+ − 594 * EXERCISE:
+ − 595 * Make starting windowed an option, and
+ − 596 * handle the resize events properly with
+ − 597 * glViewport.
+ − 598 */
+ − 599 flags = SDL_OPENGL | SDL_FULLSCREEN;
+ − 600
+ − 601 /*
+ − 602 * Set the video mode
+ − 603 */
+ − 604 if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+ − 605 /*
+ − 606 * This could happen for a variety of reasons,
+ − 607 * including DISPLAY not being set, the specified
+ − 608 * resolution not being available, etc.
+ − 609 */
+ − 610 fprintf( stderr, "Video mode set failed: %s\n",
+ − 611 SDL_GetError( ) );
+ − 612 quit_tutorial( 1 );
+ − 613 }
+ − 614
+ − 615 /*
+ − 616 * At this point, we should have a properly setup
+ − 617 * double-buffered window for use with OpenGL.
+ − 618 */
+ − 619 setup_opengl( width, height );
+ − 620
+ − 621 /*
+ − 622 * Now we want to begin our normal app process--
+ − 623 * an event loop with a lot of redrawing.
+ − 624 */
+ − 625 while( 1 ) {
+ − 626 /* Process incoming events. */
+ − 627 process_events( );
+ − 628 /* Draw the screen. */
+ − 629 draw_screen( );
+ − 630 }
+ − 631
+ − 632 /*
+ − 633 * EXERCISE:
+ − 634 * Record timings using SDL_GetTicks() and
+ − 635 * and print out frames per second at program
+ − 636 * end.
+ − 637 */
+ − 638
+ − 639 /* Never reached. */
+ − 640 return 0;
+ − 641 }</PRE
+ − 642 ></DIV
+ − 643 ></DIV
+ − 644 ></DIV
+ − 645 ></DIV
+ − 646 ><DIV
+ − 647 CLASS="NAVFOOTER"
+ − 648 ><HR
+ − 649 ALIGN="LEFT"
+ − 650 WIDTH="100%"><TABLE
+ − 651 WIDTH="100%"
+ − 652 BORDER="0"
+ − 653 CELLPADDING="0"
+ − 654 CELLSPACING="0"
+ − 655 ><TR
+ − 656 ><TD
+ − 657 WIDTH="33%"
+ − 658 ALIGN="left"
+ − 659 VALIGN="top"
+ − 660 ><A
+ − 661 HREF="guidebasicsinit.html"
+ − 662 >Prev</A
+ − 663 ></TD
+ − 664 ><TD
+ − 665 WIDTH="34%"
+ − 666 ALIGN="center"
+ − 667 VALIGN="top"
+ − 668 ><A
+ − 669 HREF="index.html"
+ − 670 >Home</A
+ − 671 ></TD
+ − 672 ><TD
+ − 673 WIDTH="33%"
+ − 674 ALIGN="right"
+ − 675 VALIGN="top"
+ − 676 ><A
+ − 677 HREF="guideinput.html"
+ − 678 >Next</A
+ − 679 ></TD
+ − 680 ></TR
+ − 681 ><TR
+ − 682 ><TD
+ − 683 WIDTH="33%"
+ − 684 ALIGN="left"
+ − 685 VALIGN="top"
+ − 686 >Initializing SDL</TD
+ − 687 ><TD
+ − 688 WIDTH="34%"
+ − 689 ALIGN="center"
+ − 690 VALIGN="top"
+ − 691 ><A
+ − 692 HREF="guide.html"
+ − 693 >Up</A
+ − 694 ></TD
+ − 695 ><TD
+ − 696 WIDTH="33%"
+ − 697 ALIGN="right"
+ − 698 VALIGN="top"
+ − 699 >Input handling</TD
+ − 700 ></TR
+ − 701 ></TABLE
+ − 702 ></DIV
+ − 703 ></BODY
+ − 704 ></HTML
+ − 705 >