You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
463 lines
9.0 KiB
463 lines
9.0 KiB
<HTML |
|
><HEAD |
|
><TITLE |
|
>Graphics and Video</TITLE |
|
><META |
|
NAME="GENERATOR" |
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ |
|
"><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="Using OpenGL With SDL" |
|
HREF="guidevideoopengl.html"></HEAD |
|
><BODY |
|
CLASS="CHAPTER" |
|
BGCOLOR="#FFF8DC" |
|
TEXT="#000000" |
|
LINK="#0000ee" |
|
VLINK="#551a8b" |
|
ALINK="#ff0000" |
|
><DIV |
|
CLASS="NAVHEADER" |
|
><TABLE |
|
SUMMARY="Header navigation 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" |
|
ACCESSKEY="P" |
|
>Prev</A |
|
></TD |
|
><TD |
|
WIDTH="80%" |
|
ALIGN="center" |
|
VALIGN="bottom" |
|
></TD |
|
><TD |
|
WIDTH="10%" |
|
ALIGN="right" |
|
VALIGN="bottom" |
|
><A |
|
HREF="guidevideoopengl.html" |
|
ACCESSKEY="N" |
|
>Next</A |
|
></TD |
|
></TR |
|
></TABLE |
|
><HR |
|
ALIGN="LEFT" |
|
WIDTH="100%"></DIV |
|
><DIV |
|
CLASS="CHAPTER" |
|
><H1 |
|
><A |
|
NAME="GUIDEVIDEO" |
|
></A |
|
>Chapter 2. Graphics and Video</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="GUIDEVIDEOINTRO" |
|
></A |
|
>Introduction to SDL Video</H1 |
|
><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="AEN68" |
|
></A |
|
>Initializing the Video Display</H2 |
|
><P |
|
>This is what almost all SDL programs have to do in one way or |
|
another.</P |
|
><DIV |
|
CLASS="EXAMPLE" |
|
><A |
|
NAME="AEN71" |
|
></A |
|
><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="AEN74" |
|
></A |
|
>Initializing the Best Video Mode</H2 |
|
><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="AEN77" |
|
></A |
|
><P |
|
><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" |
|
></A |
|
>Loading and Displaying a BMP File</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" |
|
></A |
|
>Drawing Directly to the Display</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" |
|
>/* |
|
* Return the pixel value at (x, y) |
|
* NOTE: The surface must be locked before calling this! |
|
*/ |
|
Uint32 getpixel(SDL_Surface *surface, int x, int y) |
|
{ |
|
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; |
|
|
|
switch(bpp) { |
|
case 1: |
|
return *p; |
|
|
|
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; |
|
|
|
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; |
|
} |
|
}</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 |
|
><DIV |
|
CLASS="NAVFOOTER" |
|
><HR |
|
ALIGN="LEFT" |
|
WIDTH="100%"><TABLE |
|
SUMMARY="Footer navigation table" |
|
WIDTH="100%" |
|
BORDER="0" |
|
CELLPADDING="0" |
|
CELLSPACING="0" |
|
><TR |
|
><TD |
|
WIDTH="33%" |
|
ALIGN="left" |
|
VALIGN="top" |
|
><A |
|
HREF="guidebasicsinit.html" |
|
ACCESSKEY="P" |
|
>Prev</A |
|
></TD |
|
><TD |
|
WIDTH="34%" |
|
ALIGN="center" |
|
VALIGN="top" |
|
><A |
|
HREF="index.html" |
|
ACCESSKEY="H" |
|
>Home</A |
|
></TD |
|
><TD |
|
WIDTH="33%" |
|
ALIGN="right" |
|
VALIGN="top" |
|
><A |
|
HREF="guidevideoopengl.html" |
|
ACCESSKEY="N" |
|
>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" |
|
ACCESSKEY="U" |
|
>Up</A |
|
></TD |
|
><TD |
|
WIDTH="33%" |
|
ALIGN="right" |
|
VALIGN="top" |
|
>Using OpenGL With SDL</TD |
|
></TR |
|
></TABLE |
|
></DIV |
|
></BODY |
|
></HTML |
|
> |