| 1 | <HTML |
| 2 | ><HEAD |
| 3 | ><TITLE |
| 4 | >Graphics and Video</TITLE |
| 5 | ><META |
| 6 | NAME="GENERATOR" |
| 7 | CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+ |
| 8 | "><LINK |
| 9 | REL="HOME" |
| 10 | TITLE="SDL Library Documentation" |
| 11 | HREF="index.html"><LINK |
| 12 | REL="UP" |
| 13 | TITLE="SDL Guide" |
| 14 | HREF="guide.html"><LINK |
| 15 | REL="PREVIOUS" |
| 16 | TITLE="Initializing SDL" |
| 17 | HREF="guidebasicsinit.html"><LINK |
| 18 | REL="NEXT" |
| 19 | TITLE="Using OpenGL With SDL" |
| 20 | HREF="guidevideoopengl.html"></HEAD |
| 21 | ><BODY |
| 22 | CLASS="CHAPTER" |
| 23 | BGCOLOR="#FFF8DC" |
| 24 | TEXT="#000000" |
| 25 | LINK="#0000ee" |
| 26 | VLINK="#551a8b" |
| 27 | ALINK="#ff0000" |
| 28 | ><DIV |
| 29 | CLASS="NAVHEADER" |
| 30 | ><TABLE |
| 31 | SUMMARY="Header navigation table" |
| 32 | WIDTH="100%" |
| 33 | BORDER="0" |
| 34 | CELLPADDING="0" |
| 35 | CELLSPACING="0" |
| 36 | ><TR |
| 37 | ><TH |
| 38 | COLSPAN="3" |
| 39 | ALIGN="center" |
| 40 | >SDL Library Documentation</TH |
| 41 | ></TR |
| 42 | ><TR |
| 43 | ><TD |
| 44 | WIDTH="10%" |
| 45 | ALIGN="left" |
| 46 | VALIGN="bottom" |
| 47 | ><A |
| 48 | HREF="guidebasicsinit.html" |
| 49 | ACCESSKEY="P" |
| 50 | >Prev</A |
| 51 | ></TD |
| 52 | ><TD |
| 53 | WIDTH="80%" |
| 54 | ALIGN="center" |
| 55 | VALIGN="bottom" |
| 56 | ></TD |
| 57 | ><TD |
| 58 | WIDTH="10%" |
| 59 | ALIGN="right" |
| 60 | VALIGN="bottom" |
| 61 | ><A |
| 62 | HREF="guidevideoopengl.html" |
| 63 | ACCESSKEY="N" |
| 64 | >Next</A |
| 65 | ></TD |
| 66 | ></TR |
| 67 | ></TABLE |
| 68 | ><HR |
| 69 | ALIGN="LEFT" |
| 70 | WIDTH="100%"></DIV |
| 71 | ><DIV |
| 72 | CLASS="CHAPTER" |
| 73 | ><H1 |
| 74 | ><A |
| 75 | NAME="GUIDEVIDEO" |
| 76 | ></A |
| 77 | >Chapter 2. Graphics and Video</H1 |
| 78 | ><DIV |
| 79 | CLASS="TOC" |
| 80 | ><DL |
| 81 | ><DT |
| 82 | ><B |
| 83 | >Table of Contents</B |
| 84 | ></DT |
| 85 | ><DT |
| 86 | ><A |
| 87 | HREF="guidevideo.html#GUIDEVIDEOINTRO" |
| 88 | >Introduction to SDL Video</A |
| 89 | ></DT |
| 90 | ><DT |
| 91 | ><A |
| 92 | HREF="guidevideoopengl.html" |
| 93 | >Using OpenGL With SDL</A |
| 94 | ></DT |
| 95 | ></DL |
| 96 | ></DIV |
| 97 | ><DIV |
| 98 | CLASS="SECT1" |
| 99 | ><H1 |
| 100 | CLASS="SECT1" |
| 101 | ><A |
| 102 | NAME="GUIDEVIDEOINTRO" |
| 103 | ></A |
| 104 | >Introduction to SDL Video</H1 |
| 105 | ><P |
| 106 | >Video is probably the most common thing that SDL is used for, and |
| 107 | so it has the most complete subsystem. Here are a few |
| 108 | examples to demonstrate the basics.</P |
| 109 | ><DIV |
| 110 | CLASS="SECT2" |
| 111 | ><H2 |
| 112 | CLASS="SECT2" |
| 113 | ><A |
| 114 | NAME="AEN68" |
| 115 | ></A |
| 116 | >Initializing the Video Display</H2 |
| 117 | ><P |
| 118 | >This is what almost all SDL programs have to do in one way or |
| 119 | another.</P |
| 120 | ><DIV |
| 121 | CLASS="EXAMPLE" |
| 122 | ><A |
| 123 | NAME="AEN71" |
| 124 | ></A |
| 125 | ><P |
| 126 | ><B |
| 127 | >Example 2-1. Initializing the Video Display</B |
| 128 | ></P |
| 129 | ><PRE |
| 130 | CLASS="PROGRAMLISTING" |
| 131 | > SDL_Surface *screen; |
| 132 | |
| 133 | /* Initialize the SDL library */ |
| 134 | if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { |
| 135 | fprintf(stderr, |
| 136 | "Couldn't initialize SDL: %s\n", SDL_GetError()); |
| 137 | exit(1); |
| 138 | } |
| 139 | |
| 140 | /* Clean up on exit */ |
| 141 | atexit(SDL_Quit); |
| 142 | |
| 143 | /* |
| 144 | * Initialize the display in a 640x480 8-bit palettized mode, |
| 145 | * requesting a software surface |
| 146 | */ |
| 147 | screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); |
| 148 | if ( screen == NULL ) { |
| 149 | fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", |
| 150 | SDL_GetError()); |
| 151 | exit(1); |
| 152 | }</PRE |
| 153 | ></DIV |
| 154 | ></DIV |
| 155 | ><DIV |
| 156 | CLASS="SECT2" |
| 157 | ><H2 |
| 158 | CLASS="SECT2" |
| 159 | ><A |
| 160 | NAME="AEN74" |
| 161 | ></A |
| 162 | >Initializing the Best Video Mode</H2 |
| 163 | ><P |
| 164 | >If you have a preference for a certain pixel depth but will accept any |
| 165 | other, use SDL_SetVideoMode with SDL_ANYFORMAT as below. You can also |
| 166 | use SDL_VideoModeOK() to find the native video mode that is closest to |
| 167 | the mode you request.</P |
| 168 | ><DIV |
| 169 | CLASS="EXAMPLE" |
| 170 | ><A |
| 171 | NAME="AEN77" |
| 172 | ></A |
| 173 | ><P |
| 174 | ><B |
| 175 | >Example 2-2. Initializing the Best Video Mode</B |
| 176 | ></P |
| 177 | ><PRE |
| 178 | CLASS="PROGRAMLISTING" |
| 179 | > /* Have a preference for 8-bit, but accept any depth */ |
| 180 | screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT); |
| 181 | if ( screen == NULL ) { |
| 182 | fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", |
| 183 | SDL_GetError()); |
| 184 | exit(1); |
| 185 | } |
| 186 | printf("Set 640x480 at %d bits-per-pixel mode\n", |
| 187 | screen->format->BitsPerPixel);</PRE |
| 188 | ></DIV |
| 189 | ></DIV |
| 190 | ><DIV |
| 191 | CLASS="SECT2" |
| 192 | ><H2 |
| 193 | CLASS="SECT2" |
| 194 | ><A |
| 195 | NAME="AEN80" |
| 196 | ></A |
| 197 | >Loading and Displaying a BMP File</H2 |
| 198 | ><P |
| 199 | >The following function loads and displays a BMP file given as |
| 200 | argument, once SDL is initialised and a video mode has been set.</P |
| 201 | ><DIV |
| 202 | CLASS="EXAMPLE" |
| 203 | ><A |
| 204 | NAME="AEN83" |
| 205 | ></A |
| 206 | ><P |
| 207 | ><B |
| 208 | >Example 2-3. Loading and Displaying a BMP File</B |
| 209 | ></P |
| 210 | ><PRE |
| 211 | CLASS="PROGRAMLISTING" |
| 212 | >void display_bmp(char *file_name) |
| 213 | { |
| 214 | SDL_Surface *image; |
| 215 | |
| 216 | /* Load the BMP file into a surface */ |
| 217 | image = SDL_LoadBMP(file_name); |
| 218 | if (image == NULL) { |
| 219 | fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError()); |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | /* |
| 224 | * Palettized screen modes will have a default palette (a standard |
| 225 | * 8*8*4 colour cube), but if the image is palettized as well we can |
| 226 | * use that palette for a nicer colour matching |
| 227 | */ |
| 228 | if (image->format->palette && screen->format->palette) { |
| 229 | SDL_SetColors(screen, image->format->palette->colors, 0, |
| 230 | image->format->palette->ncolors); |
| 231 | } |
| 232 | |
| 233 | /* Blit onto the screen surface */ |
| 234 | if(SDL_BlitSurface(image, NULL, screen, NULL) < 0) |
| 235 | fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError()); |
| 236 | |
| 237 | SDL_UpdateRect(screen, 0, 0, image->w, image->h); |
| 238 | |
| 239 | /* Free the allocated BMP surface */ |
| 240 | SDL_FreeSurface(image); |
| 241 | }</PRE |
| 242 | ></DIV |
| 243 | ></DIV |
| 244 | ><DIV |
| 245 | CLASS="SECT2" |
| 246 | ><H2 |
| 247 | CLASS="SECT2" |
| 248 | ><A |
| 249 | NAME="AEN86" |
| 250 | ></A |
| 251 | >Drawing Directly to the Display</H2 |
| 252 | ><P |
| 253 | >The following two functions can be used to get and set single |
| 254 | pixels of a surface. They are carefully written to work with any depth |
| 255 | currently supported by SDL. Remember to lock the surface before |
| 256 | calling them, and to unlock it before calling any other SDL |
| 257 | functions.</P |
| 258 | ><P |
| 259 | >To convert between pixel values and their red, green, blue |
| 260 | components, use SDL_GetRGB() and SDL_MapRGB().</P |
| 261 | ><DIV |
| 262 | CLASS="EXAMPLE" |
| 263 | ><A |
| 264 | NAME="AEN90" |
| 265 | ></A |
| 266 | ><P |
| 267 | ><B |
| 268 | >Example 2-4. getpixel()</B |
| 269 | ></P |
| 270 | ><PRE |
| 271 | CLASS="PROGRAMLISTING" |
| 272 | >/* |
| 273 | * Return the pixel value at (x, y) |
| 274 | * NOTE: The surface must be locked before calling this! |
| 275 | */ |
| 276 | Uint32 getpixel(SDL_Surface *surface, int x, int y) |
| 277 | { |
| 278 | int bpp = surface->format->BytesPerPixel; |
| 279 | /* Here p is the address to the pixel we want to retrieve */ |
| 280 | Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; |
| 281 | |
| 282 | switch(bpp) { |
| 283 | case 1: |
| 284 | return *p; |
| 285 | |
| 286 | case 2: |
| 287 | return *(Uint16 *)p; |
| 288 | |
| 289 | case 3: |
| 290 | if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
| 291 | return p[0] << 16 | p[1] << 8 | p[2]; |
| 292 | else |
| 293 | return p[0] | p[1] << 8 | p[2] << 16; |
| 294 | |
| 295 | case 4: |
| 296 | return *(Uint32 *)p; |
| 297 | |
| 298 | default: |
| 299 | return 0; /* shouldn't happen, but avoids warnings */ |
| 300 | } |
| 301 | }</PRE |
| 302 | ></DIV |
| 303 | ><DIV |
| 304 | CLASS="EXAMPLE" |
| 305 | ><A |
| 306 | NAME="AEN93" |
| 307 | ></A |
| 308 | ><P |
| 309 | ><B |
| 310 | >Example 2-5. putpixel()</B |
| 311 | ></P |
| 312 | ><PRE |
| 313 | CLASS="PROGRAMLISTING" |
| 314 | >/* |
| 315 | * Set the pixel at (x, y) to the given value |
| 316 | * NOTE: The surface must be locked before calling this! |
| 317 | */ |
| 318 | void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) |
| 319 | { |
| 320 | int bpp = surface->format->BytesPerPixel; |
| 321 | /* Here p is the address to the pixel we want to set */ |
| 322 | Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; |
| 323 | |
| 324 | switch(bpp) { |
| 325 | case 1: |
| 326 | *p = pixel; |
| 327 | break; |
| 328 | |
| 329 | case 2: |
| 330 | *(Uint16 *)p = pixel; |
| 331 | break; |
| 332 | |
| 333 | case 3: |
| 334 | if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { |
| 335 | p[0] = (pixel >> 16) & 0xff; |
| 336 | p[1] = (pixel >> 8) & 0xff; |
| 337 | p[2] = pixel & 0xff; |
| 338 | } else { |
| 339 | p[0] = pixel & 0xff; |
| 340 | p[1] = (pixel >> 8) & 0xff; |
| 341 | p[2] = (pixel >> 16) & 0xff; |
| 342 | } |
| 343 | break; |
| 344 | |
| 345 | case 4: |
| 346 | *(Uint32 *)p = pixel; |
| 347 | break; |
| 348 | } |
| 349 | }</PRE |
| 350 | ></DIV |
| 351 | ><P |
| 352 | >The following code uses the putpixel() function above to set a |
| 353 | yellow pixel in the middle of the screen.</P |
| 354 | ><DIV |
| 355 | CLASS="EXAMPLE" |
| 356 | ><A |
| 357 | NAME="AEN97" |
| 358 | ></A |
| 359 | ><P |
| 360 | ><B |
| 361 | >Example 2-6. Using putpixel()</B |
| 362 | ></P |
| 363 | ><PRE |
| 364 | CLASS="PROGRAMLISTING" |
| 365 | > /* Code to set a yellow pixel at the center of the screen */ |
| 366 | |
| 367 | int x, y; |
| 368 | Uint32 yellow; |
| 369 | |
| 370 | /* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00) |
| 371 | Note: If the display is palettized, you must set the palette first. |
| 372 | */ |
| 373 | yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00); |
| 374 | |
| 375 | x = screen->w / 2; |
| 376 | y = screen->h / 2; |
| 377 | |
| 378 | /* Lock the screen for direct access to the pixels */ |
| 379 | if ( SDL_MUSTLOCK(screen) ) { |
| 380 | if ( SDL_LockSurface(screen) < 0 ) { |
| 381 | fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError()); |
| 382 | return; |
| 383 | } |
| 384 | } |
| 385 | |
| 386 | putpixel(screen, x, y, yellow); |
| 387 | |
| 388 | if ( SDL_MUSTLOCK(screen) ) { |
| 389 | SDL_UnlockSurface(screen); |
| 390 | } |
| 391 | /* Update just the part of the display that we've changed */ |
| 392 | SDL_UpdateRect(screen, x, y, 1, 1); |
| 393 | |
| 394 | return; </PRE |
| 395 | ></DIV |
| 396 | ></DIV |
| 397 | ></DIV |
| 398 | ></DIV |
| 399 | ><DIV |
| 400 | CLASS="NAVFOOTER" |
| 401 | ><HR |
| 402 | ALIGN="LEFT" |
| 403 | WIDTH="100%"><TABLE |
| 404 | SUMMARY="Footer navigation table" |
| 405 | WIDTH="100%" |
| 406 | BORDER="0" |
| 407 | CELLPADDING="0" |
| 408 | CELLSPACING="0" |
| 409 | ><TR |
| 410 | ><TD |
| 411 | WIDTH="33%" |
| 412 | ALIGN="left" |
| 413 | VALIGN="top" |
| 414 | ><A |
| 415 | HREF="guidebasicsinit.html" |
| 416 | ACCESSKEY="P" |
| 417 | >Prev</A |
| 418 | ></TD |
| 419 | ><TD |
| 420 | WIDTH="34%" |
| 421 | ALIGN="center" |
| 422 | VALIGN="top" |
| 423 | ><A |
| 424 | HREF="index.html" |
| 425 | ACCESSKEY="H" |
| 426 | >Home</A |
| 427 | ></TD |
| 428 | ><TD |
| 429 | WIDTH="33%" |
| 430 | ALIGN="right" |
| 431 | VALIGN="top" |
| 432 | ><A |
| 433 | HREF="guidevideoopengl.html" |
| 434 | ACCESSKEY="N" |
| 435 | >Next</A |
| 436 | ></TD |
| 437 | ></TR |
| 438 | ><TR |
| 439 | ><TD |
| 440 | WIDTH="33%" |
| 441 | ALIGN="left" |
| 442 | VALIGN="top" |
| 443 | >Initializing SDL</TD |
| 444 | ><TD |
| 445 | WIDTH="34%" |
| 446 | ALIGN="center" |
| 447 | VALIGN="top" |
| 448 | ><A |
| 449 | HREF="guide.html" |
| 450 | ACCESSKEY="U" |
| 451 | >Up</A |
| 452 | ></TD |
| 453 | ><TD |
| 454 | WIDTH="33%" |
| 455 | ALIGN="right" |
| 456 | VALIGN="top" |
| 457 | >Using OpenGL With SDL</TD |
| 458 | ></TR |
| 459 | ></TABLE |
| 460 | ></DIV |
| 461 | ></BODY |
| 462 | ></HTML |
| 463 | > |