Exemplos de Vídeo
Iniciando o Display de Vídeo
SDL_Surface *screen;
/* Inicializa a biblioteca SDL */
if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Não pode iniciar SDL: %s\n", SDL_GetError());
exit(1);
}
/* Limpa e sai */
atexit(SDL_Quit);
/* Inicia o vídeo em um modo 640x480 usando uma paleta de 8-bits */
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
if ( screen == NULL ) {
fprintf(stderr, "Não foi possível estabelecer o modo 640x480x8: %s\n", SDL_GetError());
exit(1);
}
Iniciando o Melhor Modo de Vídeo
/* Tem preferência por 8-bits, mas aceita qualquer outra profundidade */
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
if ( screen == NULL ) {
fprintf(stderr, "Não foi possível estabelecer o modo 640x480x8: %s\n", SDL_GetError());
exit(1);
}
printf("Estabelecendo o modo 640x480 a %d bits-por-pixel \n", screen->format->BitsPerPixel);
Carregando e Mostrando um Arquivo BMP
SDL_Surface *image;
SDL_Rect dest;
int ncolors, i;
SDL_Color *colors;
/* Carrega um arquivo BMP em uma surface */
image = SDL_LoadBMP("sample.bmp");
if ( image == NULL ) {
fprintf(stderr, "Não pode carregar sample.bmp: %s\n", SDL_GetError());
return;
}
/* Estabelece as cores do vídeo SDL_SetColors() só funciona em
displays paletizados, mas ele não funciona em displays HiColor ou
TrueColor.
Se as cores do vídeo já tiverem sido estabelecidas, este passo pode ser
pulado, e a biblioteca irá mapear as imagens automaticamente para
as cores atuais do vídeo.
*/
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;
/* Aloca uma paleta de 256 cores */
ncolors = 256;
colors = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
/* Define um cubo colorido 3,3,2 */
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;
}
}
}
/* Nota: A melhor maneira de alocar uma paleta pode ser
calcular a freqüência de cores na imagem e criar uma
paleta baseada nessa informação.
*/
}
/* Define um mapa de cores, teste para todas as cores, mas não se preocupe com isso */
SDL_SetColors(screen, colors, 0, ncolors);
free(colors);
/* Blita na surface de vídeo */
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);
/* Libera o bitmap alocado */
SDL_FreeSurface(image);
return;
Desenhando Diretamente no Vídeo
/* Código para colocar um pixel amarelo no centro da tela */
Sint32 X, Y;
Uint32 pixel;
Uint8 *bits, bpp;
/* Mapeie a cor amarela para o vídeo (R=0xFF, G=0xFF, B=0x00)
Nota: Se o vídeo for paletizado, você deve estabelecer a paleta primeiro.
*/
pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00);
/* Calcula o framebuffer offset do centro do vídeo */
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;
/* Define o pixel */
switch(bpp) {
case 1:
*((Uint8 *)(bits)) = (Uint8)pixel;
break;
case 2:
*((Uint16 *)(bits)) = (Uint16)pixel;
break;
case 3: { /* Independente do formato */
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;
}
/* Atualiza a tela */
if ( SDL_MUSTLOCK(screen) ) {
SDL_UnlockSurface(screen);
}
SDL_UpdateRect(screen, X, Y, 1, 1);
return;
O Mais Rápido Blit de Surface Possível
Existem três maneiras diferentes em que você pode desenhar uma imagem no vídeo:
Criar uma surface e blitar ela no vídeo com SDL_BlitSurface
Criar a surface de vídeo na memória do sistema e chamar SDL_UpdateRect
Criar a surface de vídeo na memória de vídeo e chamar SDL_LockSurface
A melhor maneira de fazer isso é combinar os métodos:
#include <stdio.h>
#include <stdlib.h>
#include "SDL.h"
#include "SDL_timer.h"
void ComplainAndExit(void)
{
fprintf(stderr, "Problema: %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;
/* Inicializa a SDL */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
ComplainAndExit();
}
atexit(SDL_Quit);
/* Carrega uma imagem BMP em uma surface */
imagebmp = SDL_LoadBMP("image.bmp");
if ( imagebmp == NULL ) {
ComplainAndExit();
}
/* Estabelece o modo de vídeo (640x480 na profundidade(depth) nativa) */
screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);
if ( screen == NULL ) {
ComplainAndExit();
}
/* Definindo o mapa de cores do vídeo */
if ( imagebmp->format->palette != NULL ) {
SDL_SetColors(screen,
imagebmp->format->palette->colors, 0,
imagebmp->format->palette->ncolors);
}
/* Converte a imagem para o formato do vídeo (mapa de cores) */
image = SDL_DisplayFormat(imagebmp);
SDL_FreeSurface(imagebmp);
if ( image == NULL ) {
ComplainAndExit();
}
/* Desenha faixas coloridas na 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);
}
/* Blita a imagem no centro da tela */
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);
/* Atualiza o vídeo */
SDL_UpdateRects(screen, 1, &dstrect);
SDL_Delay(5000); /* Espera 5 segundos */
exit(0);
}