Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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