Uma janela
Agora, vamos criar uma aplicação básica em SDL. Ela mostrará uma janela simples e como iniciar/fechar o SDL e, após alguns segundos, fechará.
Arquivo:
janela_01.c
#include <SDL/SDL.h> // Inclui a biblioteca SDL
int main()
{
SDL_Init(SDL_INIT_VIDEO); // Inicializa o SDL e o sistema de vídeo
SDL_Surface * screen; // A janela principal
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); // Cria a janela
SDL_Delay(5000); // Espera 5000 milissegundos OU 5 segundos
SDL_Quit(); // Fecha o SDL
return 0;
}
Para compilar:
gcc -o janela_01 janela_01.c -lSDL
Onde:
- #include <SDL/SDL.h> :: "include a biblioteca SDL. Em SDL.h", estão todos os headers que precisamos.
- SDL_Init(SDL_INIT_VIDEO); :: inicializa o SDL e o subsistema de vídeo. É possível inicializar mais subsistemas com essa função. Por enquanto, apenas o subsistema de vídeo é o bastante pra esse tutorial.
- SDL_Surface * screen; :: declara uma SDL_Surface para a janela principal.
- screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); :: cria uma janela com largura de 640 e altura 480 com 16 bits de profundidade. A flag SDL_SWSURFACE indica que a janela será criada na memória RAM, há outra flag que usa a memória de vídeo (SDL_HWSURFACE) para outras flags digite man SDL_SetVideoMode no terminal. Se ocorrer erro na criação da janela, será retornado NULL, caso contrário, será retornado um ponteiro para uma surface (janela principal).
- SDL_Delay(5000); :: SDL_Delay faz o programa parar por um tempo determinado. O tempo de espera é um número inteiro e positivo. Geralmente, 10 milissegundos é o bastante para um loop principal.
- SDL_Quit(); :: essa função deve ser chamada sempre que o programa for terminar. Ela encerra o SDL liberando as SDL_Surfaces alocadas e fechando todos os subsistemas antes inicializados.
Uma janela com imagem
Arquivo:
janela_02.c
#include <SDL/SDL.h>
#include <stdio.h>
int main()
{
SDL_Init(SDL_INIT_VIDEO); // Inicializa o SDL e o sistema de vídeo
SDL_Surface * screen; // A janela principal
SDL_Surface * image; // A imagem
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); // Cria a janela
image = SDL_LoadBMP("ball.bmp"); // Carrega a imagem no formato BMP
// Verifica se carregou a imagem corretamente
if (image == NULL)
{
printf("Não foi possivel abrir ball.bmp\n");
return 1;
}
SDL_FillRect(screen, NULL, 0x0); // Pinta de preto todo o screen
SDL_BlitSurface(image, NULL, screen, NULL); // Joga a imagem na tela
SDL_UpdateRect(screen, 0,0,0,0); // Atualiza o screen com a imagem blitada
SDL_Delay(5000); // Espera 5000 milissegundos OU 5 segundos
SDL_Quit(); // Fecha o SDL
return 0;
}
Para compilar:
gcc -o janela_02 janela_02.c -lSDL
No SDL, as imagens também são
SDL_Surface (e ponteiros). Para declarar uma imagem em SDL, basta usar o tipo
SDL_Surface:
SDL_Surface * nome_da_variável;
Por padrão, o SDL só carrega imagens no formato BMP, se quiser carregar em PNG, por exemplo, precisará usar outra biblioteca auxiliar (SDL_image). Por enquanto, vou usar apenas o padrão SDL.
De forma geral, para carregar uma imagem, use:
SDL_Surface * nome_da_variável = SDL_LoadBMP("caminho_para_o_arquivo.bmp");
SDL_LoadBMP retorna um ponteiro SDL_Surface, ou
NULL, se não conseguir carregar o arquivo. O parâmetro
"caminho_para_arquivo.bmp", é o caminho completo para o arquivo de imagem em formato BMP. Toda surface possui largura(w de width) e altura(h de height).
Para acessá-los, use:
nome_da_variável->w para largura e nome_da_variável->h para altura
SDL_FillRect(screen, NULL, 0x0); :: pinta de preto todo o screen.
SDL_BlitSurface(image, NULL, screen, NULL); :: essa função joga uma imagem (ou parte dela) em cima de outra
SDL_Surface. O primeiro parâmetro
image, é a surface de origem.
O segundo parâmetro
NULL é o clip, como ele é nulo, toda a imagem será usada como clip, com ele poderia usar um
SDL_Rect para pegar uma parte interna da imagem e jogar no screen.
O terceiro parâmetro
screen é a
SDL_Surface de destino, é onde será jogada a imagem.
O quarto parâmetro é o destino da imagem dentro da
SDL_Surface de destino (o screen). Com esse parâmetro, é possível alterar a posição de
image dentro do
screen. Como ele, é nulo significa que a
image será jogada no destino
x = 0 e
y = 0. Veremos mais a frente mais informação sobre ele.
SDL_UpdateRect(screen, 0,0,0,0); :: atualiza o screen inteiro. Sempre é preciso atualizar o
screen quando se "blita" uma imagem. Mas, não é necessário atualizar todo o screen, poderia atualizar somente uma parte dele, onde se blitou/colocou a imagem. Para mais informações sobre essa função use
man SDL_UpdateRect no terminal.
Blitando uma imagem em várias posições
No SDL, os eixo X e Y são orientados da seguinte maneira:
Sendo o canto superior esquerdo da tela, como o ponto (0, 0). A largura e altura da janela são o máximo de visão que se pode ter. Ou seja, se uma imagem estiver além dos limites da altura e largura da janela, não será vista.
Arquivo:
janela_03.c
#include <SDL/SDL.h>
int main()
{
SDL_Init(SDL_INIT_VIDEO); // Inicializa o SDL e o sistema de vídeo
SDL_Surface * screen; // A janela principal
SDL_Surface * image; // A imagem
SDL_Rect dest; // Destino da imagem
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE); // Cria a janela
image = SDL_LoadBMP("ball.bmp"); // Carrega a imagem no formato BMP
// Verifica se carregou a imagem corretamente
if (image == NULL)
{
printf("Não foi possivel abrir ball.bmp\n");
return 1;
}
// Move a imagem para o ponto X = 0 e Y = 0
dest.x = 0; // Ponto de destino no eixo X
dest.y = 0; // Ponto de destino no exito Y
SDL_FillRect(screen, NULL, 0x0); // Pinta de preto todo o screen
SDL_BlitSurface(image, NULL, screen, &dest); // Joga a imagem no screen em dest
SDL_UpdateRect(screen, 0,0,0,0); // Atualiza o screen com a imagem blitada
SDL_Delay(5000); // Espera 5000 milissegundos OU 5 segundos
// Move a imagem para o ponto X = 10 e Y = 15
dest.x = 10; // Ponto de destino no eixo X
dest.y = 15; // Ponto de destino no exito Y
SDL_FillRect(screen, NULL, 0x0); // Pinta de preto todo o screen
SDL_BlitSurface(image, NULL, screen, &dest); // Joga a imagem no screen em dest
SDL_UpdateRect(screen, 0,0,0,0); // Atualiza o screen com a imagem blitada
SDL_Delay(5000); // Espera 5000 milissegundos OU 5 segundos
// Move a imagem para o ponto X = 40 e Y = 25
dest.x = 40; // Ponto de destino no eixo X
dest.y = 25; // Ponto de destino no exito Y
SDL_FillRect(screen, NULL, 0x0); // Pinta de preto todo o screen
SDL_BlitSurface(image, NULL, screen, &dest); // Joga a imagem no screen em dest
SDL_UpdateRect(screen, 0,0,0,0); // Atualiza o screen com a imagem blitada
SDL_Delay(5000); // Espera 5000 milissegundos OU 5 segundos
SDL_Quit(); // Fecha o SDL
return 0;
}
Para compilar:
gcc -o janela_03 janela_03.c -lSDL
Observe que, antes da chamada de
SDL_BlitSurface, chamei
SDL_FillRect para pintar todo o screen de preto. O segundo parâmetro
NULL indica que vamos pintar todo o screen com uma cor.
A cor usada no screen é 0x0 em hexadecimal, mas se quiser outra cor, é só usar no lugar de
0x0 SDL_MapRGB(screen->format, "VERMELHO", "VERDE", "AZUL") "VERMELHO", "VERDE" e "AZUL" são números inteiros.
SDL_MapRGB criará uma cor com o valor de "VERMELHO", "VERDE" e "AZUL". Cada cor primária é um número inteiro de 0 até 255, indicando a quantidade de cada cor primária para criar uma cor combinada.
Por exemplo, para pintar todo o screen de amarelo, use (antes de
SDL_BlitSurface): SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 0).
SDL_Rect dest; :: essa variável será usada para colocar a
image em várias posições diferentes dentro do
screen.
Todo
SDL_Rect tem 4 membros:
x, y, w e
h. Os membros
x e
y são as coordenadas da tela, e o
w e
h são largura (w de
width) e altura (h de
height).
Toda vez que mudar a posição da imagem através de
dest, será preciso reblitar a imagem no screen.