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