mirror of
https://github.com/yawut/SDL.git
synced 2026-09-08 17:16:19 -05:00
Added new docs for SDL 1.2.1
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
>Graphics and Video</TITLE
|
||||
><META
|
||||
NAME="GENERATOR"
|
||||
CONTENT="Modular DocBook HTML Stylesheet Version 1.61
|
||||
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
|
||||
"><LINK
|
||||
REL="HOME"
|
||||
TITLE="SDL Library Documentation"
|
||||
@@ -16,8 +16,8 @@ REL="PREVIOUS"
|
||||
TITLE="Initializing SDL"
|
||||
HREF="guidebasicsinit.html"><LINK
|
||||
REL="NEXT"
|
||||
TITLE="Input handling"
|
||||
HREF="guideinput.html"></HEAD
|
||||
TITLE="Using OpenGL With SDL"
|
||||
HREF="guidevideoopengl.html"></HEAD
|
||||
><BODY
|
||||
CLASS="CHAPTER"
|
||||
BGCOLOR="#FFF8DC"
|
||||
@@ -57,7 +57,7 @@ WIDTH="10%"
|
||||
ALIGN="right"
|
||||
VALIGN="bottom"
|
||||
><A
|
||||
HREF="guideinput.html"
|
||||
HREF="guidevideoopengl.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
@@ -73,573 +73,323 @@ NAME="GUIDEVIDEO"
|
||||
>Chapter 2. Graphics and Video</A
|
||||
></H1
|
||||
><DIV
|
||||
CLASS="TOC"
|
||||
><DL
|
||||
><DT
|
||||
><B
|
||||
>Table of Contents</B
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="guidevideo.html#GUIDEVIDEOINTRO"
|
||||
>Introduction to SDL Video</A
|
||||
></DT
|
||||
><DT
|
||||
><A
|
||||
HREF="guidevideoopengl.html"
|
||||
>Using OpenGL With SDL</A
|
||||
></DT
|
||||
></DL
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT1"
|
||||
><H1
|
||||
CLASS="SECT1"
|
||||
><A
|
||||
NAME="GUIDEVIDEOOPENGL"
|
||||
>Using OpenGL With SDL</A
|
||||
NAME="GUIDEVIDEOINTRO"
|
||||
>Introduction to SDL Video</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
|
||||
>Video is probably the most common thing that SDL is used for, and
|
||||
so it has the most complete subsystem. Here are a few
|
||||
examples to demonstrate the basics.</P
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="AEN65"
|
||||
>Initialisation</A
|
||||
NAME="AEN68"
|
||||
>Initializing the Video Display</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
|
||||
>This is what almost all SDL programs have to do in one way or
|
||||
another.</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN71"
|
||||
></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 ) < 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->vfmt->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
|
||||
><B
|
||||
>Example 2-1. Initializing the Video Display</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
> SDL_Surface *screen;
|
||||
|
||||
/* Initialize the SDL library */
|
||||
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
|
||||
fprintf(stderr,
|
||||
"Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Clean up on exit */
|
||||
atexit(SDL_Quit);
|
||||
|
||||
/*
|
||||
* Initialize the display in a 640x480 8-bit palettized mode,
|
||||
* requesting a software surface
|
||||
*/
|
||||
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
|
||||
if ( screen == NULL ) {
|
||||
fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
|
||||
SDL_GetError());
|
||||
exit(1);
|
||||
}</PRE
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="AEN77"
|
||||
>Drawing</A
|
||||
NAME="AEN74"
|
||||
>Initializing the Best Video Mode</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
|
||||
>If you have a preference for a certain pixel depth but will accept any
|
||||
other, use SDL_SetVideoMode with SDL_ANYFORMAT as below. You can also
|
||||
use SDL_VideoModeOK() to find the native video mode that is closest to
|
||||
the mode you request.</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN87"
|
||||
NAME="AEN77"
|
||||
></A
|
||||
><P
|
||||
><B
|
||||
>Example 2-1. gl.c - SDL OpenGL Example</B
|
||||
>Example 2-2. Initializing the Best Video Mode</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
> /* Have a preference for 8-bit, but accept any depth */
|
||||
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
|
||||
if ( screen == NULL ) {
|
||||
fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
|
||||
SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
printf("Set 640x480 at %d bits-per-pixel mode\n",
|
||||
screen->format->BitsPerPixel);</PRE
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="AEN80"
|
||||
>Loading and Displaying a BMP File</A
|
||||
></H2
|
||||
><P
|
||||
>The following function loads and displays a BMP file given as
|
||||
argument, once SDL is initialised and a video mode has been set.</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN83"
|
||||
></A
|
||||
><P
|
||||
><B
|
||||
>Example 2-3. Loading and Displaying a BMP File</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>void display_bmp(char *file_name)
|
||||
{
|
||||
SDL_Surface *image;
|
||||
|
||||
/* Load the BMP file into a surface */
|
||||
image = SDL_LoadBMP(file_name);
|
||||
if (image == NULL) {
|
||||
fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Palettized screen modes will have a default palette (a standard
|
||||
* 8*8*4 colour cube), but if the image is palettized as well we can
|
||||
* use that palette for a nicer colour matching
|
||||
*/
|
||||
if (image->format->palette && screen->format->palette) {
|
||||
SDL_SetColors(screen, image->format->palette->colors, 0,
|
||||
image->format->palette->ncolors);
|
||||
}
|
||||
|
||||
/* Blit onto the screen surface */
|
||||
if(SDL_BlitSurface(image, NULL, screen, NULL) < 0)
|
||||
fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
|
||||
|
||||
SDL_UpdateRect(screen, 0, 0, image->w, image->h);
|
||||
|
||||
/* Free the allocated BMP surface */
|
||||
SDL_FreeSurface(image);
|
||||
}</PRE
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="SECT2"
|
||||
><H2
|
||||
CLASS="SECT2"
|
||||
><A
|
||||
NAME="AEN86"
|
||||
>Drawing Directly to the Display</A
|
||||
></H2
|
||||
><P
|
||||
>The following two functions can be used to get and set single
|
||||
pixels of a surface. They are carefully written to work with any depth
|
||||
currently supported by SDL. Remember to lock the surface before
|
||||
calling them, and to unlock it before calling any other SDL
|
||||
functions.</P
|
||||
><P
|
||||
>To convert between pixel values and their red, green, blue
|
||||
components, use SDL_GetRGB() and SDL_MapRGB().</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN90"
|
||||
></A
|
||||
><P
|
||||
><B
|
||||
>Example 2-4. getpixel()</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>/*
|
||||
* SDL OpenGL Tutorial.
|
||||
* (c) Michael Vance, 2000
|
||||
* briareos@lokigames.com
|
||||
*
|
||||
* Distributed under terms of the LGPL.
|
||||
* Return the pixel value at (x, y)
|
||||
* NOTE: The surface must be locked before calling this!
|
||||
*/
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static GLboolean should_rotate = GL_TRUE;
|
||||
|
||||
static void quit_tutorial( int code )
|
||||
Uint32 getpixel(SDL_Surface *surface, int x, int y)
|
||||
{
|
||||
/*
|
||||
* Quit SDL so we can release the fullscreen
|
||||
* mode and restore the previous video settings,
|
||||
* etc.
|
||||
*/
|
||||
SDL_Quit( );
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
/* Here p is the address to the pixel we want to retrieve */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||
|
||||
/* Exit program. */
|
||||
exit( code );
|
||||
}
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
return *p;
|
||||
|
||||
static void handle_key_down( SDL_keysym* keysym )
|
||||
{
|
||||
case 2:
|
||||
return *(Uint16 *)p;
|
||||
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
return p[0] << 16 | p[1] << 8 | p[2];
|
||||
else
|
||||
return p[0] | p[1] << 8 | p[2] << 16;
|
||||
|
||||
case 4:
|
||||
return *(Uint32 *)p;
|
||||
|
||||
/*
|
||||
* We're only interested if 'Esc' has
|
||||
* been presssed.
|
||||
*
|
||||
* EXERCISE:
|
||||
* Handle the arrow keys and have that change the
|
||||
* viewing position/angle.
|
||||
*/
|
||||
switch( keysym->sym ) {
|
||||
case SDLK_ESCAPE:
|
||||
quit_tutorial( 0 );
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
should_rotate = !should_rotate;
|
||||
break;
|
||||
default:
|
||||
return 0; /* shouldn't happen, but avoids warnings */
|
||||
}
|
||||
}</PRE
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN93"
|
||||
></A
|
||||
><P
|
||||
><B
|
||||
>Example 2-5. putpixel()</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
>/*
|
||||
* Set the pixel at (x, y) to the given value
|
||||
* NOTE: The surface must be locked before calling this!
|
||||
*/
|
||||
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||
{
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
/* Here p is the address to the pixel we want to set */
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
*p = pixel;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(Uint16 *)p = pixel;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||
p[0] = (pixel >> 16) & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = pixel & 0xff;
|
||||
} else {
|
||||
p[0] = pixel & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = (pixel >> 16) & 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(Uint32 *)p = pixel;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void process_events( void )
|
||||
{
|
||||
/* Our SDL event placeholder. */
|
||||
SDL_Event event;
|
||||
|
||||
/* Grab all the events off the queue. */
|
||||
while( SDL_PollEvent( &event ) ) {
|
||||
|
||||
switch( event.type ) {
|
||||
case SDL_KEYDOWN:
|
||||
/* Handle key presses. */
|
||||
handle_key_down( &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 > 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 ) < 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->vfmt->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
|
||||
><P
|
||||
>The following code uses the putpixel() function above to set a
|
||||
yellow pixel in the middle of the screen.</P
|
||||
><DIV
|
||||
CLASS="EXAMPLE"
|
||||
><A
|
||||
NAME="AEN97"
|
||||
></A
|
||||
><P
|
||||
><B
|
||||
>Example 2-6. Using putpixel()</B
|
||||
></P
|
||||
><PRE
|
||||
CLASS="PROGRAMLISTING"
|
||||
> /* Code to set a yellow pixel at the center of the screen */
|
||||
|
||||
int x, y;
|
||||
Uint32 yellow;
|
||||
|
||||
/* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)
|
||||
Note: If the display is palettized, you must set the palette first.
|
||||
*/
|
||||
yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
|
||||
|
||||
x = screen->w / 2;
|
||||
y = screen->h / 2;
|
||||
|
||||
/* Lock the screen for direct access to the pixels */
|
||||
if ( SDL_MUSTLOCK(screen) ) {
|
||||
if ( SDL_LockSurface(screen) < 0 ) {
|
||||
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
putpixel(screen, x, y, yellow);
|
||||
|
||||
if ( SDL_MUSTLOCK(screen) ) {
|
||||
SDL_UnlockSurface(screen);
|
||||
}
|
||||
/* Update just the part of the display that we've changed */
|
||||
SDL_UpdateRect(screen, x, y, 1, 1);
|
||||
|
||||
return; </PRE
|
||||
></DIV
|
||||
></DIV
|
||||
></DIV
|
||||
></DIV
|
||||
@@ -674,7 +424,7 @@ WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
><A
|
||||
HREF="guideinput.html"
|
||||
HREF="guidevideoopengl.html"
|
||||
>Next</A
|
||||
></TD
|
||||
></TR
|
||||
@@ -696,7 +446,7 @@ HREF="guide.html"
|
||||
WIDTH="33%"
|
||||
ALIGN="right"
|
||||
VALIGN="top"
|
||||
>Input handling</TD
|
||||
>Using OpenGL With SDL</TD
|
||||
></TR
|
||||
></TABLE
|
||||
></DIV
|
||||
|
||||
Reference in New Issue
Block a user