| <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 |
| > |