forked from KolibriOS/kolibrios
473 lines
9.9 KiB
HTML
473 lines
9.9 KiB
HTML
|
<HTML
|
||
|
><HEAD
|
||
|
><TITLE
|
||
|
>Video Examples</TITLE
|
||
|
><META
|
||
|
NAME="GENERATOR"
|
||
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
|
||
|
"><LINK
|
||
|
REL="HOME"
|
||
|
TITLE="SDL Library Documentation"
|
||
|
HREF="index.html"><LINK
|
||
|
REL="UP"
|
||
|
TITLE="Examples"
|
||
|
HREF="guideexamples.html"><LINK
|
||
|
REL="PREVIOUS"
|
||
|
TITLE="Examples"
|
||
|
HREF="guideexamples.html"><LINK
|
||
|
REL="NEXT"
|
||
|
TITLE="Event Examples"
|
||
|
HREF="guideeventexamples.html"></HEAD
|
||
|
><BODY
|
||
|
CLASS="SECT1"
|
||
|
BGCOLOR="#FFF8DC"
|
||
|
TEXT="#000000"
|
||
|
LINK="#0000ee"
|
||
|
VLINK="#551a8b"
|
||
|
ALINK="#ff0000"
|
||
|
><DIV
|
||
|
CLASS="NAVHEADER"
|
||
|
><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="guideexamples.html"
|
||
|
>Prev</A
|
||
|
></TD
|
||
|
><TD
|
||
|
WIDTH="80%"
|
||
|
ALIGN="center"
|
||
|
VALIGN="bottom"
|
||
|
>Chapter 4. Examples</TD
|
||
|
><TD
|
||
|
WIDTH="10%"
|
||
|
ALIGN="right"
|
||
|
VALIGN="bottom"
|
||
|
><A
|
||
|
HREF="guideeventexamples.html"
|
||
|
>Next</A
|
||
|
></TD
|
||
|
></TR
|
||
|
></TABLE
|
||
|
><HR
|
||
|
ALIGN="LEFT"
|
||
|
WIDTH="100%"></DIV
|
||
|
><DIV
|
||
|
CLASS="SECT1"
|
||
|
><H1
|
||
|
CLASS="SECT1"
|
||
|
><A
|
||
|
NAME="GUIDEVIDEOEXAMPLES"
|
||
|
>Video Examples</A
|
||
|
></H1
|
||
|
><P
|
||
|
></P
|
||
|
><DIV
|
||
|
CLASS="SECT2"
|
||
|
><H2
|
||
|
CLASS="SECT2"
|
||
|
><A
|
||
|
NAME="AEN375"
|
||
|
>Initializing the video display</A
|
||
|
></H2
|
||
|
><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 */
|
||
|
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
|
||
|
></P
|
||
|
></DIV
|
||
|
><DIV
|
||
|
CLASS="SECT2"
|
||
|
><H2
|
||
|
CLASS="SECT2"
|
||
|
><A
|
||
|
NAME="AEN379"
|
||
|
>Initializing the best video mode</A
|
||
|
></H2
|
||
|
><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
|
||
|
></P
|
||
|
></DIV
|
||
|
><DIV
|
||
|
CLASS="SECT2"
|
||
|
><H2
|
||
|
CLASS="SECT2"
|
||
|
><A
|
||
|
NAME="AEN383"
|
||
|
>Loading and displaying a BMP file</A
|
||
|
></H2
|
||
|
><P
|
||
|
><PRE
|
||
|
CLASS="PROGRAMLISTING"
|
||
|
> SDL_Surface *image;
|
||
|
SDL_Rect dest;
|
||
|
int ncolors, i;
|
||
|
SDL_Color *colors;
|
||
|
|
||
|
/* Load the BMP file into a surface */
|
||
|
image = SDL_LoadBMP("sample.bmp");
|
||
|
if ( image == NULL ) {
|
||
|
fprintf(stderr, "Couldn't load sample.bmp: %s\n",
|
||
|
SDL_GetError());
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/* Set the display colors -- SDL_SetColors() only does something on
|
||
|
palettized displays, but it doesn't hurt anything on HiColor or
|
||
|
TrueColor displays.
|
||
|
If the display colors have already been set, this step can be
|
||
|
skipped, and the library will automatically map the image to
|
||
|
the current display colors.
|
||
|
*/
|
||
|
if ( image->format->palette ) {
|
||
|
ncolors = image->format->palette->ncolors;
|
||
|
colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
|
||
|
memcpy(colors, image->format->palette->colors, ncolors);
|
||
|
}
|
||
|
else {
|
||
|
int r, g, b;
|
||
|
|
||
|
/* Allocate 256 color palette */
|
||
|
ncolors = 256;
|
||
|
colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
|
||
|
|
||
|
/* Set a 3,3,2 color cube */
|
||
|
for ( r=0; r<8; ++r ) {
|
||
|
for ( g=0; g<8; ++g ) {
|
||
|
for ( b=0; b<4; ++b ) {
|
||
|
i = ((r<<5)|(g<<2)|b);
|
||
|
colors[i].r = r<<5;
|
||
|
colors[i].g = g<<5;
|
||
|
colors[i].b = b<<6;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
/* Note: A better way of allocating the palette might be
|
||
|
to calculate the frequency of colors in the image
|
||
|
and create a palette based on that information.
|
||
|
*/
|
||
|
}
|
||
|
/* Set colormap, try for all the colors, but don't worry about it */
|
||
|
SDL_SetColors(screen, colors, 0, ncolors);
|
||
|
free(colors);
|
||
|
|
||
|
/* Blit onto the screen surface */
|
||
|
dest.x = 0;
|
||
|
dest.y = 0;
|
||
|
dest.w = image->w;
|
||
|
dest.h = image->h;
|
||
|
SDL_BlitSurface(image, NULL, screen, &dest);
|
||
|
|
||
|
SDL_UpdateRects(screen, 1, &dest);
|
||
|
|
||
|
/* Free the allocated BMP surface */
|
||
|
SDL_FreeSurface(image);
|
||
|
return;</PRE
|
||
|
></P
|
||
|
></DIV
|
||
|
><DIV
|
||
|
CLASS="SECT2"
|
||
|
><H2
|
||
|
CLASS="SECT2"
|
||
|
><A
|
||
|
NAME="AEN387"
|
||
|
>Drawing directly to the display</A
|
||
|
></H2
|
||
|
><P
|
||
|
><PRE
|
||
|
CLASS="PROGRAMLISTING"
|
||
|
> /* Code to set a yellow pixel at the center of the screen */
|
||
|
|
||
|
Sint32 X, Y;
|
||
|
Uint32 pixel;
|
||
|
Uint8 *bits, bpp;
|
||
|
|
||
|
/* 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.
|
||
|
*/
|
||
|
pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00);
|
||
|
|
||
|
/* Calculate the framebuffer offset of the center of the screen */
|
||
|
if ( SDL_MUSTLOCK(screen) ) {
|
||
|
if ( SDL_LockSurface(screen) < 0 )
|
||
|
return;
|
||
|
}
|
||
|
bpp = screen->format->BytesPerPixel;
|
||
|
X = screen->w/2;
|
||
|
Y = screen->h/2;
|
||
|
bits = ((Uint8 *)screen->pixels)+Y*screen->pitch+X*bpp;
|
||
|
|
||
|
/* Set the pixel */
|
||
|
switch(bpp) {
|
||
|
case 1:
|
||
|
*((Uint8 *)(bits)) = (Uint8)pixel;
|
||
|
break;
|
||
|
case 2:
|
||
|
*((Uint16 *)(bits)) = (Uint16)pixel;
|
||
|
break;
|
||
|
case 3: { /* Format/endian independent */
|
||
|
Uint8 r, g, b;
|
||
|
|
||
|
r = (pixel>>screen->format->Rshift)&0xFF;
|
||
|
g = (pixel>>screen->format->Gshift)&0xFF;
|
||
|
b = (pixel>>screen->format->Bshift)&0xFF;
|
||
|
*((bits)+screen->format->Rshift/8) = r;
|
||
|
*((bits)+screen->format->Gshift/8) = g;
|
||
|
*((bits)+screen->format->Bshift/8) = b;
|
||
|
}
|
||
|
break;
|
||
|
case 4:
|
||
|
*((Uint32 *)(bits)) = (Uint32)pixel;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Update the display */
|
||
|
if ( SDL_MUSTLOCK(screen) ) {
|
||
|
SDL_UnlockSurface(screen);
|
||
|
}
|
||
|
SDL_UpdateRect(screen, X, Y, 1, 1);
|
||
|
|
||
|
return;</PRE
|
||
|
></P
|
||
|
></DIV
|
||
|
><DIV
|
||
|
CLASS="SECT2"
|
||
|
><H2
|
||
|
CLASS="SECT2"
|
||
|
><A
|
||
|
NAME="AEN391"
|
||
|
>Fastest possible surface blit</A
|
||
|
></H2
|
||
|
><P
|
||
|
>There are three different ways you can draw an image to the screen:
|
||
|
<P
|
||
|
></P
|
||
|
><TABLE
|
||
|
BORDER="0"
|
||
|
><TBODY
|
||
|
><TR
|
||
|
><TD
|
||
|
>1.Create a surface and use <A
|
||
|
HREF="sdlblitsurface.html"
|
||
|
><TT
|
||
|
CLASS="FUNCTION"
|
||
|
>SDL_BlitSurface</TT
|
||
|
></A
|
||
|
> to blit it to the screen</TD
|
||
|
></TR
|
||
|
><TR
|
||
|
><TD
|
||
|
>2.Create the video surface in system memory and call <A
|
||
|
HREF="sdlupdaterect.html"
|
||
|
><TT
|
||
|
CLASS="FUNCTION"
|
||
|
>SDL_UpdateRect</TT
|
||
|
></A
|
||
|
></TD
|
||
|
></TR
|
||
|
><TR
|
||
|
><TD
|
||
|
>3.Create the video surface in video memory and call <A
|
||
|
HREF="sdllocksurface.html"
|
||
|
><TT
|
||
|
CLASS="FUNCTION"
|
||
|
>SDL_LockSurface</TT
|
||
|
></A
|
||
|
></TD
|
||
|
></TR
|
||
|
></TBODY
|
||
|
></TABLE
|
||
|
><P
|
||
|
></P
|
||
|
>
|
||
|
The best way to do this is to combine methods:
|
||
|
<PRE
|
||
|
CLASS="PROGRAMLISTING"
|
||
|
>#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include "SDL.h"
|
||
|
#include "SDL_timer.h"
|
||
|
|
||
|
void ComplainAndExit(void)
|
||
|
{
|
||
|
fprintf(stderr, "Problem: %s\n", SDL_GetError());
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
SDL_PixelFormat fmt;
|
||
|
SDL_Surface *screen, *locked;
|
||
|
SDL_Surface *imagebmp, *image;
|
||
|
SDL_Rect dstrect;
|
||
|
int i;
|
||
|
Uint8 *buffer;
|
||
|
|
||
|
/* Initialize SDL */
|
||
|
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
atexit(SDL_Quit);
|
||
|
|
||
|
/* Load a BMP image into a surface */
|
||
|
imagebmp = SDL_LoadBMP("image.bmp");
|
||
|
if ( imagebmp == NULL ) {
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
|
||
|
/* Set the video mode (640x480 at native depth) */
|
||
|
screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);
|
||
|
if ( screen == NULL ) {
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
|
||
|
/* Set the video colormap */
|
||
|
if ( imagebmp->format->palette != NULL ) {
|
||
|
SDL_SetColors(screen,
|
||
|
imagebmp->format->palette->colors, 0,
|
||
|
imagebmp->format->palette->ncolors);
|
||
|
}
|
||
|
|
||
|
/* Convert the image to the video format (maps colors) */
|
||
|
image = SDL_DisplayFormat(imagebmp);
|
||
|
SDL_FreeSurface(imagebmp);
|
||
|
if ( image == NULL ) {
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
|
||
|
/* Draw bands of color on the raw surface */
|
||
|
if ( SDL_MUSTLOCK(screen) ) {
|
||
|
if ( SDL_LockSurface(screen) < 0 )
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
buffer=(Uint8 *)screen->pixels;
|
||
|
for ( i=0; i<screen->h; ++i ) {
|
||
|
memset(buffer,(i*255)/screen->h,
|
||
|
screen->w*screen->format->BytesPerPixel);
|
||
|
buffer += screen->pitch;
|
||
|
}
|
||
|
if ( SDL_MUSTLOCK(screen) ) {
|
||
|
SDL_UnlockSurface(screen);
|
||
|
}
|
||
|
|
||
|
/* Blit the image to the center of the screen */
|
||
|
dstrect.x = (screen->w-image->w)/2;
|
||
|
dstrect.y = (screen->h-image->h)/2;
|
||
|
dstrect.w = image->w;
|
||
|
dstrect.h = image->h;
|
||
|
if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) {
|
||
|
SDL_FreeSurface(image);
|
||
|
ComplainAndExit();
|
||
|
}
|
||
|
SDL_FreeSurface(image);
|
||
|
|
||
|
/* Update the screen */
|
||
|
SDL_UpdateRects(screen, 1, &dstrect);
|
||
|
|
||
|
SDL_Delay(5000); /* Wait 5 seconds */
|
||
|
exit(0);
|
||
|
}</PRE
|
||
|
></P
|
||
|
></DIV
|
||
|
></DIV
|
||
|
><DIV
|
||
|
CLASS="NAVFOOTER"
|
||
|
><HR
|
||
|
ALIGN="LEFT"
|
||
|
WIDTH="100%"><TABLE
|
||
|
WIDTH="100%"
|
||
|
BORDER="0"
|
||
|
CELLPADDING="0"
|
||
|
CELLSPACING="0"
|
||
|
><TR
|
||
|
><TD
|
||
|
WIDTH="33%"
|
||
|
ALIGN="left"
|
||
|
VALIGN="top"
|
||
|
><A
|
||
|
HREF="guideexamples.html"
|
||
|
>Prev</A
|
||
|
></TD
|
||
|
><TD
|
||
|
WIDTH="34%"
|
||
|
ALIGN="center"
|
||
|
VALIGN="top"
|
||
|
><A
|
||
|
HREF="index.html"
|
||
|
>Home</A
|
||
|
></TD
|
||
|
><TD
|
||
|
WIDTH="33%"
|
||
|
ALIGN="right"
|
||
|
VALIGN="top"
|
||
|
><A
|
||
|
HREF="guideeventexamples.html"
|
||
|
>Next</A
|
||
|
></TD
|
||
|
></TR
|
||
|
><TR
|
||
|
><TD
|
||
|
WIDTH="33%"
|
||
|
ALIGN="left"
|
||
|
VALIGN="top"
|
||
|
>Examples</TD
|
||
|
><TD
|
||
|
WIDTH="34%"
|
||
|
ALIGN="center"
|
||
|
VALIGN="top"
|
||
|
><A
|
||
|
HREF="guideexamples.html"
|
||
|
>Up</A
|
||
|
></TD
|
||
|
><TD
|
||
|
WIDTH="33%"
|
||
|
ALIGN="right"
|
||
|
VALIGN="top"
|
||
|
>Event Examples</TD
|
||
|
></TR
|
||
|
></TABLE
|
||
|
></DIV
|
||
|
></BODY
|
||
|
></HTML
|
||
|
>
|