diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/html/guidevideo.html	Thu Apr 26 16:45:43 2001 +0000
@@ -0,0 +1,705 @@
+<HTML
+><HEAD
+><TITLE
+>Graphics and Video</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"><LINK
+REL="HOME"
+TITLE="SDL Library Documentation"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="SDL Guide"
+HREF="guide.html"><LINK
+REL="PREVIOUS"
+TITLE="Initializing SDL"
+HREF="guidebasicsinit.html"><LINK
+REL="NEXT"
+TITLE="Input handling"
+HREF="guideinput.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFF8DC"
+TEXT="#000000"
+LINK="#0000ee"
+VLINK="#551a8b"
+ALINK="#ff0000"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>SDL Library Documentation</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="guidebasicsinit.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="guideinput.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="GUIDEVIDEO"
+>Chapter 2. Graphics and Video</A
+></H1
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="GUIDEVIDEOOPENGL"
+>Using OpenGL With SDL</A
+></H1
+><P
+>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
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN65"
+>Initialisation</A
+></H2
+><P
+>Initialising SDL to use OpenGL is not very different to initialising SDL normally. There are three differences; you must pass <TT
+CLASS="LITERAL"
+>SDL_OPENGL</TT
+> to <A
+HREF="sdlsetvideomode.html"
+><TT
+CLASS="FUNCTION"
+>SDL_SetVideoMode</TT
+></A
+>, you must specify several GL attributes (depth buffer size, framebuffer sizes) using <A
+HREF="sdlglsetattribute.html"
+><TT
+CLASS="FUNCTION"
+>SDL_GL_SetAttribute</TT
+></A
+> and finally, if you wish to use double buffering you must specify it as a GL attribute, <I
+CLASS="EMPHASIS"
+>not</I
+> by passing the <TT
+CLASS="LITERAL"
+>SDL_DOUBLEBUF</TT
+> flag to <TT
+CLASS="FUNCTION"
+>SDL_SetVideoMode</TT
+>.
+<PRE
+CLASS="PROGRAMLISTING"
+>    /* Information about the current video settings. */
+    const SDL_VideoInfo* info = NULL;
+    /* Dimensions of our window. */
+    int width = 0;
+    int height = 0;
+    /* Color depth in bits of our window. */
+    int bpp = 0;
+    /* Flags we will pass into SDL_SetVideoMode. */
+    int flags = 0;
+
+    /* First, initialize SDL's video subsystem. */
+    if( SDL_Init( SDL_INIT_VIDEO ) &#60; 0 ) {
+        /* Failed, exit. */
+        fprintf( stderr, "Video initialization failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /* Let's get some video information. */
+    info = SDL_GetVideoInfo( );
+
+    if( !info ) {
+        /* This should probably never happen. */
+        fprintf( stderr, "Video query failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * Set our width/height to 640/480 (you would
+     * of course let the user decide this in a normal
+     * app). We get the bpp we will request from
+     * the display. On X11, VidMode can't change
+     * resolution, so this is probably being overly
+     * safe. Under Win32, ChangeDisplaySettings
+     * can change the bpp.
+     */
+    width = 640;
+    height = 480;
+    bpp = info-&#62;vfmt-&#62;BitsPerPixel;
+
+    /*
+     * Now, we want to setup our requested
+     * window attributes for our OpenGL window.
+     * We want *at least* 5 bits of red, green
+     * and blue. We also want at least a 16-bit
+     * depth buffer.
+     *
+     * The last thing we do is request a double
+     * buffered window. '1' turns on double
+     * buffering, '0' turns it off.
+     *
+     * Note that we do not use SDL_DOUBLEBUF in
+     * the flags to SDL_SetVideoMode. That does
+     * not affect the GL attribute state, only
+     * the standard 2D blitting setup.
+     */
+    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+    /*
+     * We want to request that SDL provide us
+     * with an OpenGL window, in a fullscreen
+     * video mode.
+     *
+     * EXERCISE:
+     * Make starting windowed an option, and
+     * handle the resize events properly with
+     * glViewport.
+     */
+    flags = SDL_OPENGL | SDL_FULLSCREEN;
+
+    /*
+     * Set the video mode
+     */
+    if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+        /* 
+         * This could happen for a variety of reasons,
+         * including DISPLAY not being set, the specified
+         * resolution not being available, etc.
+         */
+        fprintf( stderr, "Video mode set failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN77"
+>Drawing</A
+></H2
+><P
+>Apart from initialisation, using OpenGL within SDL is the same as using. However if you have request a double buffered display (using <A
+HREF="sdlglsetattribute.html"
+><TT
+CLASS="FUNCTION"
+>SDL_GL_SetAttribute</TT
+></A
+>) and one (which can be checked by using <A
+HREF="sdlglgetattribute.html"
+><TT
+CLASS="FUNCTION"
+>SDL_GL_GetAttribute</TT
+></A
+>), then you must use <A
+HREF="sdlglswapbuffers.html"
+><TT
+CLASS="FUNCTION"
+>SDL_GL_SwapBuffers()</TT
+></A
+> to swap the buffers and update the display.</P
+><P
+>A full example code listing is now presented below.</P
+><DIV
+CLASS="EXAMPLE"
+><A
+NAME="AEN87"
+></A
+><P
+><B
+>Example 2-1. gl.c - SDL OpenGL Example</B
+></P
+><PRE
+CLASS="PROGRAMLISTING"
+>/*
+ * SDL OpenGL Tutorial.
+ * (c) Michael Vance, 2000
+ * briareos@lokigames.com
+ *
+ * Distributed under terms of the LGPL. 
+ */
+
+#include &#60;SDL/SDL.h&#62;
+#include &#60;GL/gl.h&#62;
+#include &#60;GL/glu.h&#62;
+
+#include &#60;stdio.h&#62;
+#include &#60;stdlib.h&#62;
+
+static GLboolean should_rotate = GL_TRUE;
+
+static void quit_tutorial( int code )
+{
+    /*
+     * Quit SDL so we can release the fullscreen
+     * mode and restore the previous video settings,
+     * etc.
+     */
+    SDL_Quit( );
+
+    /* Exit program. */
+    exit( code );
+}
+
+static void handle_key_down( SDL_keysym* keysym )
+{
+
+    /* 
+     * We're only interested if 'Esc' has
+     * been presssed.
+     *
+     * EXERCISE: 
+     * Handle the arrow keys and have that change the
+     * viewing position/angle.
+     */
+    switch( keysym-&#62;sym ) {
+    case SDLK_ESCAPE:
+        quit_tutorial( 0 );
+        break;
+    case SDLK_SPACE:
+        should_rotate = !should_rotate;
+        break;
+    default:
+        break;
+    }
+
+}
+
+static void process_events( void )
+{
+    /* Our SDL event placeholder. */
+    SDL_Event event;
+
+    /* Grab all the events off the queue. */
+    while( SDL_PollEvent( &#38;event ) ) {
+
+        switch( event.type ) {
+        case SDL_KEYDOWN:
+            /* Handle key presses. */
+            handle_key_down( &#38;event.key.keysym );
+            break;
+        case SDL_QUIT:
+            /* Handle quit requests (like Ctrl-c). */
+            quit_tutorial( 0 );
+            break;
+        }
+
+    }
+
+}
+
+static void draw_screen( void )
+{
+    /* Our angle of rotation. */
+    static float angle = 0.0f;
+
+    /*
+     * EXERCISE:
+     * Replace this awful mess with vertex
+     * arrays and a call to glDrawElements.
+     *
+     * EXERCISE:
+     * After completing the above, change
+     * it to use compiled vertex arrays.
+     *
+     * EXERCISE:
+     * Verify my windings are correct here ;).
+     */
+    static GLfloat v0[] = { -1.0f, -1.0f,  1.0f };
+    static GLfloat v1[] = {  1.0f, -1.0f,  1.0f };
+    static GLfloat v2[] = {  1.0f,  1.0f,  1.0f };
+    static GLfloat v3[] = { -1.0f,  1.0f,  1.0f };
+    static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
+    static GLfloat v5[] = {  1.0f, -1.0f, -1.0f };
+    static GLfloat v6[] = {  1.0f,  1.0f, -1.0f };
+    static GLfloat v7[] = { -1.0f,  1.0f, -1.0f };
+    static GLubyte red[]    = { 255,   0,   0, 255 };
+    static GLubyte green[]  = {   0, 255,   0, 255 };
+    static GLubyte blue[]   = {   0,   0, 255, 255 };
+    static GLubyte white[]  = { 255, 255, 255, 255 };
+    static GLubyte yellow[] = {   0, 255, 255, 255 };
+    static GLubyte black[]  = {   0,   0,   0, 255 };
+    static GLubyte orange[] = { 255, 255,   0, 255 };
+    static GLubyte purple[] = { 255,   0, 255,   0 };
+
+    /* Clear the color and depth buffers. */
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+    /* We don't want to modify the projection matrix. */
+    glMatrixMode( GL_MODELVIEW );
+    glLoadIdentity( );
+
+    /* Move down the z-axis. */
+    glTranslatef( 0.0, 0.0, -5.0 );
+
+    /* Rotate. */
+    glRotatef( angle, 0.0, 1.0, 0.0 );
+
+    if( should_rotate ) {
+
+        if( ++angle &#62; 360.0f ) {
+            angle = 0.0f;
+        }
+
+    }
+
+    /* Send our triangle data to the pipeline. */
+    glBegin( GL_TRIANGLES );
+
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+
+    glEnd( );
+
+    /*
+     * EXERCISE:
+     * Draw text telling the user that 'Spc'
+     * pauses the rotation and 'Esc' quits.
+     * Do it using vetors and textured quads.
+     */
+
+    /*
+     * Swap the buffers. This this tells the driver to
+     * render the next frame from the contents of the
+     * back-buffer, and to set all rendering operations
+     * to occur on what was the front-buffer.
+     *
+     * Double buffering prevents nasty visual tearing
+     * from the application drawing on areas of the
+     * screen that are being updated at the same time.
+     */
+    SDL_GL_SwapBuffers( );
+}
+
+static void setup_opengl( int width, int height )
+{
+    float ratio = (float) width / (float) height;
+
+    /* Our shading model--Gouraud (smooth). */
+    glShadeModel( GL_SMOOTH );
+
+    /* Culling. */
+    glCullFace( GL_BACK );
+    glFrontFace( GL_CCW );
+    glEnable( GL_CULL_FACE );
+
+    /* Set the clear color. */
+    glClearColor( 0, 0, 0, 0 );
+
+    /* Setup our viewport. */
+    glViewport( 0, 0, width, height );
+
+    /*
+     * Change to the projection matrix and set
+     * our viewing volume.
+     */
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity( );
+    /*
+     * EXERCISE:
+     * Replace this with a call to glFrustum.
+     */
+    gluPerspective( 60.0, ratio, 1.0, 1024.0 );
+}
+
+int main( int argc, char* argv[] )
+{
+    /* Information about the current video settings. */
+    const SDL_VideoInfo* info = NULL;
+    /* Dimensions of our window. */
+    int width = 0;
+    int height = 0;
+    /* Color depth in bits of our window. */
+    int bpp = 0;
+    /* Flags we will pass into SDL_SetVideoMode. */
+    int flags = 0;
+
+    /* First, initialize SDL's video subsystem. */
+    if( SDL_Init( SDL_INIT_VIDEO ) &#60; 0 ) {
+        /* Failed, exit. */
+        fprintf( stderr, "Video initialization failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /* Let's get some video information. */
+    info = SDL_GetVideoInfo( );
+
+    if( !info ) {
+        /* This should probably never happen. */
+        fprintf( stderr, "Video query failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * Set our width/height to 640/480 (you would
+     * of course let the user decide this in a normal
+     * app). We get the bpp we will request from
+     * the display. On X11, VidMode can't change
+     * resolution, so this is probably being overly
+     * safe. Under Win32, ChangeDisplaySettings
+     * can change the bpp.
+     */
+    width = 640;
+    height = 480;
+    bpp = info-&#62;vfmt-&#62;BitsPerPixel;
+
+    /*
+     * Now, we want to setup our requested
+     * window attributes for our OpenGL window.
+     * We want *at least* 5 bits of red, green
+     * and blue. We also want at least a 16-bit
+     * depth buffer.
+     *
+     * The last thing we do is request a double
+     * buffered window. '1' turns on double
+     * buffering, '0' turns it off.
+     *
+     * Note that we do not use SDL_DOUBLEBUF in
+     * the flags to SDL_SetVideoMode. That does
+     * not affect the GL attribute state, only
+     * the standard 2D blitting setup.
+     */
+    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+    /*
+     * We want to request that SDL provide us
+     * with an OpenGL window, in a fullscreen
+     * video mode.
+     *
+     * EXERCISE:
+     * Make starting windowed an option, and
+     * handle the resize events properly with
+     * glViewport.
+     */
+    flags = SDL_OPENGL | SDL_FULLSCREEN;
+
+    /*
+     * Set the video mode
+     */
+    if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+        /* 
+         * This could happen for a variety of reasons,
+         * including DISPLAY not being set, the specified
+         * resolution not being available, etc.
+         */
+        fprintf( stderr, "Video mode set failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * At this point, we should have a properly setup
+     * double-buffered window for use with OpenGL.
+     */
+    setup_opengl( width, height );
+
+    /*
+     * Now we want to begin our normal app process--
+     * an event loop with a lot of redrawing.
+     */
+    while( 1 ) {
+        /* Process incoming events. */
+        process_events( );
+        /* Draw the screen. */
+        draw_screen( );
+    }
+
+    /*
+     * EXERCISE:
+     * Record timings using SDL_GetTicks() and
+     * and print out frames per second at program
+     * end.
+     */
+
+    /* Never reached. */
+    return 0;
+}</PRE
+></DIV
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="guidebasicsinit.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="guideinput.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Initializing SDL</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="guide.html"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Input handling</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file