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