Este post deveria ter vindo logo depois do primeiro sobre SDL (SDL - A Biblioteca dos Jogos 2D). Se você estava meio perdido esta leitura é recomendada.
A abordagem começa com os pixels e se estende até o blit completo ou parcial.
» Post Completo...
typedef struct SDL_Surface {
Uint32 flags;
SDL_PixelFormat *format;
int w, h;
Uint16 pitch;
void *pixels;
SDL_Rect clip_rect;
int refcount;
} SDL_Surface;
Todos estes valores são apenas para leitura, exceto pixels. Nem sempre pixels está disponível para escrita, neste caso você deve usar SDL_LockSurface() e SDL_UnlockSurface() para ter acesso direto aos dados.
Uma curiosidade é saber como os pixels estão dispostos exatamente em *pixels. Uma imagem 3x3 de 24bpp possui pitch=12 e pixels[36]. w*h*bpp = 3*3*3 = 27, mas não é dessa forma que as coisas funcionam.
Observe a imagem:

*** Screen ***
É através da SDL_Surface que tudo será apresentado ao usuário, e usualmente eu nomeio a superfície da tela como screen:

#include <SDL/SDL.h>
SDL_Surface *screen = NULL; //- Tela
int main(int argc, char *argv[]){
//- Inicializa a SDL -//
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER);
//- Inicializa a tela -//
screen = SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);
//- título da janela -//
SDL_WM_SetCaption("Aplicação SDL em 3 segundos !!!", NULL);
//- Atualiza a tela -//
SDL_Flip(screen);
//- Pausa de 3 segundos -//
SDL_Delay(3000);
//- Finaliza a SDL -//
SDL_Quit();
return 0;
}
» Incluí a biblioteca SDL. (Ela deve estar instalada)
» Criei um ponteiro para armazenar a superfície da tela (screen).
» Minha função main da maneira correta, exatamente como a SDL a espera.
» Inicializo a SDL
» Inicializo a tela. 640x480 e 32bpp é criada na memória.
» Define "Aplicação SDL em 3 segundos !!!" como título da janela.
» Mostra a superfície no vídeo. Se você estiver utilizando SDL_DOUBLEBUF esta função terá o papel crucial.
» Como ainda não estamos tratando eventos do teclado fiz uma pausa de 3 segundos para que a janela possa ser visualizada.
» Devemos inicializar e também finalizar a SDL.
» Retornar 0 indica que tudo ocorreu bem.
*** Imagens ***
Com SDL é fácil carregar (SDL_LoadBMP) e salvar (SDL_SaveBMP) imagens no formato BMP. Pena que o formato BMP não suporta mais que 24bpp, e isto nos limita a usar cor de transparência, já que não podemos carregar imagens com alpha. O formato PNG suporta alpha, mas não se pode carregar PNG com a função SDL_LoadBMP(), para isto devemos utilizar a lib SDL_Image (veremos mais à frente).
Trecho de código:
SDL_Surface *img = NULL;
...
int main(int argc, char *argv[]){
//- Inicializa a SDL -//
...
//- carrega imagem -//
img = SDL_LoadBMP("img/imagem.bmp");
//- pinta imagem na em outra screen -//
SDL_BlitSurface(img,0,screen,0);
//- salvando a tela -//
SDL_SaveBMP(screen,"img/screen.bmp");
//- Atualiza a tela -//
SDL_Flip(screen);
//- Pausa de 3 segundos -//
SDL_Delay(3000);
//- limpando memória -//
SDL_FreeSurface( img );
//- Finaliza a SDL -//
SDL_Quit();
return 0;
}
» Em main inicializamos a SDL.
» Carregamos "img/imagem.bmp" com a função SDL_LoadBMP e guardamos seu ponteiro em img. Usar / é o mesmo que usar \\ e funciona no Windows e Linux. Caso a imagem não seja carregada verifique se seu nome está correto ou se o programa está sendo executado do local correto. system("pwd") ou system("dir") podem esclarecer o que digo.
» SDL_BlitSurface é capaz de pintar uma superfície sobre outra. Desta maneira a imagem será pintada completamente nas coordenadas 0x0 da imagem de destino.
» Com SDL_SaveBMP é fácil gravar uma screenshot do seu jogo !
» SDL_Flip e SDL_Delay para visualizarmos a janela.
» SDL_FreeSurface é utilizada para limpar a memória da imagem carregada.
» Por fim SDL_Quit e return 0;
Se você quiser ganhar performance em seu jogo não trabalhe com diferentes formatos de superfície (não estou falando dos formatos de arquivo). Toda vez que blita uma superfície de 24bpp em outra de 32bpp há uma conversão em tempo de blitagem, e para ganhar performance temos que deixar todas as superfícies convertidas em um único formato, o formato do display (nossa tela).
SDL_Surface *aux, *img;
aux = SDL_LoadBMP("smiley.bmp");
SDL_SetColorKey(aux, SDL_SRCCOLORKEY, SDL_MapRGB(aux->format,0xff,0,0xff) );
img = SDL_DisplayFormatAlpha(aux);
SDL_FreeSurface(aux);
» O rosa 0xff00ff é setado como cor de transparência. (faça antes de converter pro display)
» SDL_DisplayFormatAlpha é chamado e converte a imagem para 32bpp e transforma a cor de transparência em uma camada de transparência.
» aux deve ser limpada, pois SDL_DisplayFormat cria uma nova superfície.
*** SDL_BlitSurface ***
Até agora só trabalhamos com SDL_BlitSurface em sua forma mais simples (imagem, NULL, imagem, NULL). Esta função tem diversas utilidades, tais como imprimir apenas parte de uma imagem em outra.

int SDL_BlitSurface(
SDL_Surface *src, //- Imagem de origem (imagem a pintar)
SDL_Rect *srcrect, //- Retângulo de corte. permite pintar
// parte dela.
SDL_Surface *dst, //- Imagem de destino (imagem modificada)
SDL_Rect *dstrect //- Coordenadas da imagem de origem.
);
A forma mais simples de uso é onde uma imagem é toda impressa em outra nas coordenadas de origem:
SDL_BlitSurface(img, NULL, screen, NULL);
Para imprimir uma imagem por completo em uma determinada posição de outra imagem:SDL_Rect xy = {x,y,0,0};
SDL_BlitSurface(img, NULL, screen, &xy);
SDL_Rect ret = {retx, rety, retw, reth};
SDL_Rect xy = {x,y,0,0};
SDL_BlitSurface(img, &ret, screen, &xy);
» Uma imagem não precisa estar realmente cortada para que se possa imprimir parte dela.
» A imagem de destino nunca irá mudar de tamanho para acomodar a imagem de origem.
» Só serão aproveitados o x e y do retângulo de destino, logo ele só servirá para posicionar onde a imagem será impressa.
» Você não poderá redimensionar ou rotacionar imagens com SDL_BlitSurface. Para isto use SDL_Gfx.
*** Link's ***
Download: » código fonte
» Surface Loading and Blitting
» Documentação da SDL (online)
5 comentários:
aew cara!!
mtoo bom o blog! ja ta add no favoritos!
continuee assim :D!!
t++ abrasss
Vlw !
O objetivo é não quebrar a corrente... não cheguei aqui sozinho e agradeço a todos !
Diogo,
Somos 2 desenvolvedores e estamos procurando mais gente que goste de criacao de jogos e tenha experiencia na area.
Estamos comecando a rascunhar um jogo no estilo tactics (FF Tactics, Ogre Tactics) pra Linux/Windows.
Caso voce esteja interessado, manda um email pra renato.azimuth@gmail.com e conversaremos.
Entender a forma com que a SDL representa suas superficies é fundamental, ajuda a achar possiveis bugs, e criar funções para manipular bit-a-bit. O que mais gostei no seu artigo foi o Mais informações isso ajuda muito quem está começando, pois as vezes ficamos confuzos se devemos ou não usar algo.
Parabéms!
fla primao>>
tou de olho por aqui>>
abrçao..
jonathas
Postar um comentário