comparison docs/html/guidevideo.html @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 55f1f1b3e27d
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
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 ) &#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 /*
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-&#62;vfmt-&#62;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 &#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 {
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-&#62;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( &#38;event ) ) {
313
314 switch( event.type ) {
315 case SDL_KEYDOWN:
316 /* Handle key presses. */
317 handle_key_down( &#38;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 &#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
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 >