comparison docs/html/guidevideo.html @ 55:55f1f1b3e27d

Added new docs for SDL 1.2.1
author Sam Lantinga <slouken@lokigames.com>
date Sun, 10 Jun 2001 19:31:57 +0000
parents 74212992fb08
children 355632dca928
comparison
equal deleted inserted replaced
54:028447a8a758 55:55f1f1b3e27d
2 ><HEAD 2 ><HEAD
3 ><TITLE 3 ><TITLE
4 >Graphics and Video</TITLE 4 >Graphics and Video</TITLE
5 ><META 5 ><META
6 NAME="GENERATOR" 6 NAME="GENERATOR"
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.61 7 CONTENT="Modular DocBook HTML Stylesheet Version 1.64
8 "><LINK 8 "><LINK
9 REL="HOME" 9 REL="HOME"
10 TITLE="SDL Library Documentation" 10 TITLE="SDL Library Documentation"
11 HREF="index.html"><LINK 11 HREF="index.html"><LINK
12 REL="UP" 12 REL="UP"
14 HREF="guide.html"><LINK 14 HREF="guide.html"><LINK
15 REL="PREVIOUS" 15 REL="PREVIOUS"
16 TITLE="Initializing SDL" 16 TITLE="Initializing SDL"
17 HREF="guidebasicsinit.html"><LINK 17 HREF="guidebasicsinit.html"><LINK
18 REL="NEXT" 18 REL="NEXT"
19 TITLE="Input handling" 19 TITLE="Using OpenGL With SDL"
20 HREF="guideinput.html"></HEAD 20 HREF="guidevideoopengl.html"></HEAD
21 ><BODY 21 ><BODY
22 CLASS="CHAPTER" 22 CLASS="CHAPTER"
23 BGCOLOR="#FFF8DC" 23 BGCOLOR="#FFF8DC"
24 TEXT="#000000" 24 TEXT="#000000"
25 LINK="#0000ee" 25 LINK="#0000ee"
55 ><TD 55 ><TD
56 WIDTH="10%" 56 WIDTH="10%"
57 ALIGN="right" 57 ALIGN="right"
58 VALIGN="bottom" 58 VALIGN="bottom"
59 ><A 59 ><A
60 HREF="guideinput.html" 60 HREF="guidevideoopengl.html"
61 >Next</A 61 >Next</A
62 ></TD 62 ></TD
63 ></TR 63 ></TR
64 ></TABLE 64 ></TABLE
65 ><HR 65 ><HR
71 ><A 71 ><A
72 NAME="GUIDEVIDEO" 72 NAME="GUIDEVIDEO"
73 >Chapter 2. Graphics and Video</A 73 >Chapter 2. Graphics and Video</A
74 ></H1 74 ></H1
75 ><DIV 75 ><DIV
76 CLASS="TOC"
77 ><DL
78 ><DT
79 ><B
80 >Table of Contents</B
81 ></DT
82 ><DT
83 ><A
84 HREF="guidevideo.html#GUIDEVIDEOINTRO"
85 >Introduction to SDL Video</A
86 ></DT
87 ><DT
88 ><A
89 HREF="guidevideoopengl.html"
90 >Using OpenGL With SDL</A
91 ></DT
92 ></DL
93 ></DIV
94 ><DIV
76 CLASS="SECT1" 95 CLASS="SECT1"
77 ><H1 96 ><H1
78 CLASS="SECT1" 97 CLASS="SECT1"
79 ><A 98 ><A
80 NAME="GUIDEVIDEOOPENGL" 99 NAME="GUIDEVIDEOINTRO"
81 >Using OpenGL With SDL</A 100 >Introduction to SDL Video</A
82 ></H1 101 ></H1
83 ><P 102 ><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 103 >Video is probably the most common thing that SDL is used for, and
104 so it has the most complete subsystem. Here are a few
105 examples to demonstrate the basics.</P
85 ><DIV 106 ><DIV
86 CLASS="SECT2" 107 CLASS="SECT2"
87 ><H2 108 ><H2
88 CLASS="SECT2" 109 CLASS="SECT2"
89 ><A 110 ><A
90 NAME="AEN65" 111 NAME="AEN68"
91 >Initialisation</A 112 >Initializing the Video Display</A
92 ></H2 113 ></H2
93 ><P 114 ><P
94 >Initialising SDL to use OpenGL is not very different to initialising SDL normally. There are three differences; you must pass <TT 115 >This is what almost all SDL programs have to do in one way or
95 CLASS="LITERAL" 116 another.</P
96 >SDL_OPENGL</TT 117 ><DIV
97 > to <A 118 CLASS="EXAMPLE"
98 HREF="sdlsetvideomode.html" 119 ><A
99 ><TT 120 NAME="AEN71"
100 CLASS="FUNCTION" 121 ></A
101 >SDL_SetVideoMode</TT 122 ><P
102 ></A 123 ><B
103 >, you must specify several GL attributes (depth buffer size, framebuffer sizes) using <A 124 >Example 2-1. Initializing the Video Display</B
104 HREF="sdlglsetattribute.html" 125 ></P
105 ><TT 126 ><PRE
106 CLASS="FUNCTION" 127 CLASS="PROGRAMLISTING"
107 >SDL_GL_SetAttribute</TT 128 > SDL_Surface *screen;
108 ></A 129
109 > and finally, if you wish to use double buffering you must specify it as a GL attribute, <I 130 /* Initialize the SDL library */
110 CLASS="EMPHASIS" 131 if( SDL_Init(SDL_INIT_VIDEO) &#60; 0 ) {
111 >not</I 132 fprintf(stderr,
112 > by passing the <TT 133 "Couldn't initialize SDL: %s\n", SDL_GetError());
113 CLASS="LITERAL" 134 exit(1);
114 >SDL_DOUBLEBUF</TT 135 }
115 > flag to <TT 136
116 CLASS="FUNCTION" 137 /* Clean up on exit */
117 >SDL_SetVideoMode</TT 138 atexit(SDL_Quit);
118 >. 139
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 ) &#60; 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 /* 140 /*
150 * Set our width/height to 640/480 (you would 141 * Initialize the display in a 640x480 8-bit palettized mode,
151 * of course let the user decide this in a normal 142 * requesting a software surface
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 */ 143 */
158 width = 640; 144 screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
159 height = 480; 145 if ( screen == NULL ) {
160 bpp = info-&#62;vfmt-&#62;BitsPerPixel; 146 fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
147 SDL_GetError());
148 exit(1);
149 }</PRE
150 ></DIV
151 ></DIV
152 ><DIV
153 CLASS="SECT2"
154 ><H2
155 CLASS="SECT2"
156 ><A
157 NAME="AEN74"
158 >Initializing the Best Video Mode</A
159 ></H2
160 ><P
161 >If you have a preference for a certain pixel depth but will accept any
162 other, use SDL_SetVideoMode with SDL_ANYFORMAT as below. You can also
163 use SDL_VideoModeOK() to find the native video mode that is closest to
164 the mode you request.</P
165 ><DIV
166 CLASS="EXAMPLE"
167 ><A
168 NAME="AEN77"
169 ></A
170 ><P
171 ><B
172 >Example 2-2. Initializing the Best Video Mode</B
173 ></P
174 ><PRE
175 CLASS="PROGRAMLISTING"
176 > /* Have a preference for 8-bit, but accept any depth */
177 screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
178 if ( screen == NULL ) {
179 fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
180 SDL_GetError());
181 exit(1);
182 }
183 printf("Set 640x480 at %d bits-per-pixel mode\n",
184 screen-&#62;format-&#62;BitsPerPixel);</PRE
185 ></DIV
186 ></DIV
187 ><DIV
188 CLASS="SECT2"
189 ><H2
190 CLASS="SECT2"
191 ><A
192 NAME="AEN80"
193 >Loading and Displaying a BMP File</A
194 ></H2
195 ><P
196 >The following function loads and displays a BMP file given as
197 argument, once SDL is initialised and a video mode has been set.</P
198 ><DIV
199 CLASS="EXAMPLE"
200 ><A
201 NAME="AEN83"
202 ></A
203 ><P
204 ><B
205 >Example 2-3. Loading and Displaying a BMP File</B
206 ></P
207 ><PRE
208 CLASS="PROGRAMLISTING"
209 >void display_bmp(char *file_name)
210 {
211 SDL_Surface *image;
212
213 /* Load the BMP file into a surface */
214 image = SDL_LoadBMP(file_name);
215 if (image == NULL) {
216 fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
217 return;
218 }
161 219
162 /* 220 /*
163 * Now, we want to setup our requested 221 * Palettized screen modes will have a default palette (a standard
164 * window attributes for our OpenGL window. 222 * 8*8*4 colour cube), but if the image is palettized as well we can
165 * We want *at least* 5 bits of red, green 223 * use that palette for a nicer colour matching
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 */ 224 */
178 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); 225 if (image-&#62;format-&#62;palette &#38;&#38; screen-&#62;format-&#62;palette) {
179 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); 226 SDL_SetColors(screen, image-&#62;format-&#62;palette-&#62;colors, 0,
180 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); 227 image-&#62;format-&#62;palette-&#62;ncolors);
181 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); 228 }
182 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); 229
183 230 /* Blit onto the screen surface */
184 /* 231 if(SDL_BlitSurface(image, NULL, screen, NULL) &#60; 0)
185 * We want to request that SDL provide us 232 fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
186 * with an OpenGL window, in a fullscreen 233
187 * video mode. 234 SDL_UpdateRect(screen, 0, 0, image-&#62;w, image-&#62;h);
188 * 235
189 * EXERCISE: 236 /* Free the allocated BMP surface */
190 * Make starting windowed an option, and 237 SDL_FreeSurface(image);
191 * handle the resize events properly with 238 }</PRE
192 * glViewport. 239 ></DIV
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 240 ></DIV
211 ><DIV 241 ><DIV
212 CLASS="SECT2" 242 CLASS="SECT2"
213 ><H2 243 ><H2
214 CLASS="SECT2" 244 CLASS="SECT2"
215 ><A 245 ><A
216 NAME="AEN77" 246 NAME="AEN86"
217 >Drawing</A 247 >Drawing Directly to the Display</A
218 ></H2 248 ></H2
219 ><P 249 ><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 250 >The following two functions can be used to get and set single
221 HREF="sdlglsetattribute.html" 251 pixels of a surface. They are carefully written to work with any depth
222 ><TT 252 currently supported by SDL. Remember to lock the surface before
223 CLASS="FUNCTION" 253 calling them, and to unlock it before calling any other SDL
224 >SDL_GL_SetAttribute</TT 254 functions.</P
225 ></A 255 ><P
226 >) and one (which can be checked by using <A 256 >To convert between pixel values and their red, green, blue
227 HREF="sdlglgetattribute.html" 257 components, use SDL_GetRGB() and SDL_MapRGB().</P
228 ><TT 258 ><DIV
229 CLASS="FUNCTION" 259 CLASS="EXAMPLE"
230 >SDL_GL_GetAttribute</TT 260 ><A
231 ></A 261 NAME="AEN90"
232 >), then you must use <A 262 ></A
233 HREF="sdlglswapbuffers.html" 263 ><P
234 ><TT 264 ><B
235 CLASS="FUNCTION" 265 >Example 2-4. getpixel()</B
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 266 ></P
250 ><PRE 267 ><PRE
251 CLASS="PROGRAMLISTING" 268 CLASS="PROGRAMLISTING"
252 >/* 269 >/*
253 * SDL OpenGL Tutorial. 270 * Return the pixel value at (x, y)
254 * (c) Michael Vance, 2000 271 * NOTE: The surface must be locked before calling this!
255 * briareos@lokigames.com
256 *
257 * Distributed under terms of the LGPL.
258 */ 272 */
259 273 Uint32 getpixel(SDL_Surface *surface, int x, int y)
260 #include &#60;SDL/SDL.h&#62;
261 #include &#60;GL/gl.h&#62;
262 #include &#60;GL/glu.h&#62;
263
264 #include &#60;stdio.h&#62;
265 #include &#60;stdlib.h&#62;
266
267 static GLboolean should_rotate = GL_TRUE;
268
269 static void quit_tutorial( int code )
270 { 274 {
271 /* 275 int bpp = surface-&#62;format-&#62;BytesPerPixel;
272 * Quit SDL so we can release the fullscreen 276 /* Here p is the address to the pixel we want to retrieve */
273 * mode and restore the previous video settings, 277 Uint8 *p = (Uint8 *)surface-&#62;pixels + y * surface-&#62;pitch + x * bpp;
274 * etc. 278
275 */ 279 switch(bpp) {
276 SDL_Quit( ); 280 case 1:
277 281 return *p;
278 /* Exit program. */ 282
279 exit( code ); 283 case 2:
280 } 284 return *(Uint16 *)p;
281 285
282 static void handle_key_down( SDL_keysym* keysym ) 286 case 3:
287 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
288 return p[0] &#60;&#60; 16 | p[1] &#60;&#60; 8 | p[2];
289 else
290 return p[0] | p[1] &#60;&#60; 8 | p[2] &#60;&#60; 16;
291
292 case 4:
293 return *(Uint32 *)p;
294
295 default:
296 return 0; /* shouldn't happen, but avoids warnings */
297 }
298 }</PRE
299 ></DIV
300 ><DIV
301 CLASS="EXAMPLE"
302 ><A
303 NAME="AEN93"
304 ></A
305 ><P
306 ><B
307 >Example 2-5. putpixel()</B
308 ></P
309 ><PRE
310 CLASS="PROGRAMLISTING"
311 >/*
312 * Set the pixel at (x, y) to the given value
313 * NOTE: The surface must be locked before calling this!
314 */
315 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
283 { 316 {
284 317 int bpp = surface-&#62;format-&#62;BytesPerPixel;
285 /* 318 /* Here p is the address to the pixel we want to set */
286 * We're only interested if 'Esc' has 319 Uint8 *p = (Uint8 *)surface-&#62;pixels + y * surface-&#62;pitch + x * bpp;
287 * been presssed. 320
288 * 321 switch(bpp) {
289 * EXERCISE: 322 case 1:
290 * Handle the arrow keys and have that change the 323 *p = pixel;
291 * viewing position/angle.
292 */
293 switch( keysym-&#62;sym ) {
294 case SDLK_ESCAPE:
295 quit_tutorial( 0 );
296 break; 324 break;
297 case SDLK_SPACE: 325
298 should_rotate = !should_rotate; 326 case 2:
327 *(Uint16 *)p = pixel;
299 break; 328 break;
300 default: 329
330 case 3:
331 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
332 p[0] = (pixel &#62;&#62; 16) &#38; 0xff;
333 p[1] = (pixel &#62;&#62; 8) &#38; 0xff;
334 p[2] = pixel &#38; 0xff;
335 } else {
336 p[0] = pixel &#38; 0xff;
337 p[1] = (pixel &#62;&#62; 8) &#38; 0xff;
338 p[2] = (pixel &#62;&#62; 16) &#38; 0xff;
339 }
301 break; 340 break;
302 } 341
303 342 case 4:
304 } 343 *(Uint32 *)p = pixel;
305 344 break;
306 static void process_events( void ) 345 }
307 { 346 }</PRE
308 /* Our SDL event placeholder. */ 347 ></DIV
309 SDL_Event event; 348 ><P
310 349 >The following code uses the putpixel() function above to set a
311 /* Grab all the events off the queue. */ 350 yellow pixel in the middle of the screen.</P
312 while( SDL_PollEvent( &#38;event ) ) { 351 ><DIV
313 352 CLASS="EXAMPLE"
314 switch( event.type ) { 353 ><A
315 case SDL_KEYDOWN: 354 NAME="AEN97"
316 /* Handle key presses. */ 355 ></A
317 handle_key_down( &#38;event.key.keysym ); 356 ><P
318 break; 357 ><B
319 case SDL_QUIT: 358 >Example 2-6. Using putpixel()</B
320 /* Handle quit requests (like Ctrl-c). */ 359 ></P
321 quit_tutorial( 0 ); 360 ><PRE
322 break; 361 CLASS="PROGRAMLISTING"
362 >&#13; /* Code to set a yellow pixel at the center of the screen */
363
364 int x, y;
365 Uint32 yellow;
366
367 /* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)
368 Note: If the display is palettized, you must set the palette first.
369 */
370 yellow = SDL_MapRGB(screen-&#62;format, 0xff, 0xff, 0x00);
371
372 x = screen-&#62;w / 2;
373 y = screen-&#62;h / 2;
374
375 /* Lock the screen for direct access to the pixels */
376 if ( SDL_MUSTLOCK(screen) ) {
377 if ( SDL_LockSurface(screen) &#60; 0 ) {
378 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
379 return;
323 } 380 }
324 381 }
325 } 382
326 383 putpixel(screen, x, y, yellow);
327 } 384
328 385 if ( SDL_MUSTLOCK(screen) ) {
329 static void draw_screen( void ) 386 SDL_UnlockSurface(screen);
330 { 387 }
331 /* Our angle of rotation. */ 388 /* Update just the part of the display that we've changed */
332 static float angle = 0.0f; 389 SDL_UpdateRect(screen, x, y, 1, 1);
333 390
334 /* 391 return;&#13;</PRE
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 &#62; 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 ) &#60; 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-&#62;vfmt-&#62;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 392 ></DIV
643 ></DIV 393 ></DIV
644 ></DIV 394 ></DIV
645 ></DIV 395 ></DIV
646 ><DIV 396 ><DIV
672 ><TD 422 ><TD
673 WIDTH="33%" 423 WIDTH="33%"
674 ALIGN="right" 424 ALIGN="right"
675 VALIGN="top" 425 VALIGN="top"
676 ><A 426 ><A
677 HREF="guideinput.html" 427 HREF="guidevideoopengl.html"
678 >Next</A 428 >Next</A
679 ></TD 429 ></TD
680 ></TR 430 ></TR
681 ><TR 431 ><TR
682 ><TD 432 ><TD
694 ></TD 444 ></TD
695 ><TD 445 ><TD
696 WIDTH="33%" 446 WIDTH="33%"
697 ALIGN="right" 447 ALIGN="right"
698 VALIGN="top" 448 VALIGN="top"
699 >Input handling</TD 449 >Using OpenGL With SDL</TD
700 ></TR 450 ></TR
701 ></TABLE 451 ></TABLE
702 ></DIV 452 ></DIV
703 ></BODY 453 ></BODY
704 ></HTML 454 ></HTML