Tutorial SDL

Tutorial sobre a biblioteca SDL com exemplos práticos.

[ Hits: 48.091 ]

Por: Samuel Leonardo em 01/11/2013 | Blog: https://nerdki.blogspot.com.br/


Aplicação básica



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:
Linux: Tutorial SDL

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.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Aplicação básica
   3. Dando vida ao programa: o loop principal
   4. Eventos no SDL
   5. Controlando uma imagem com o teclado
Outros artigos deste autor

Desenhando fácil um pinguim no Inkscape

Desenhando um avatar do Tux no InkScape

Dicas para aprender programação

Programação de Jogos com SDL

Criatividade para TI parte 1

Leitura recomendada

Análise dos Métodos de Ordenação usados em Algoritmos Computacionais

Guia de Programação em C/GTK 2 - Construindo uma Calculadora Completa

Algoritmo... como fazer?

Linguagem C - Árvores Binárias

Otimização de algoritmos

  
Comentários
[1] Comentário enviado por nelson777 em 01/11/2013 - 15:40h

Finalmente um artigo de C que não é só mais um algoritmo básico de criança e sim algo útil. Parabéns.

[2] Comentário enviado por tsuriu em 03/11/2013 - 20:49h

Parabéns cara... Muito bom o artigo.

[3] Comentário enviado por danilo3610 em 04/11/2013 - 08:53h

Muito bom tutorial Samuel, segui passo a passo este tutorial no meu ubuntu 13.10 64bits,
instalei o SDL_DEV e usei o seu primeiro exemplo porem ao compilar (incluindo -ISDL)
apresentava erros com SDL_Init - "Undefined reference to SDL_Init...". Procurei na net
mas ninguem teve este mesmo problema, já aconteceu com alguem? Se alguem tiver alguma
solução agradeço. Lembrando instalei o SDL_DEV como mostra o tutorial.

att.

[4] Comentário enviado por SamL em 04/11/2013 - 11:32h

Esse problema geralmente acontece quando NÃO se usa -lSDL no final do comando. Veja se você compilou assim: gcc -o janela_01 janela_01.c -lSDL
com o link -lSDL no final.
Se não resolver talvez você tenha instalado a SDL 2.0, veja na pasta /usr/include/ se tem a pasta SDL2.
Se também não resolver, não sei mais o que fazer rsrsrs

[5] Comentário enviado por danilo3610 em 04/11/2013 - 14:00h

Talvez tenha confundido mas só uma duvida, a primeira letra é um l ou i maiúsculo? Desconfio que seja um L minúsculo e
tenha colocado um i maiúsculo no lugar. Quando chegar em casa irei testar.

[6] Comentário enviado por SamL em 04/11/2013 - 14:03h

É um L minúsculo. Avisa se funcionar quando testar.

[7] Comentário enviado por danilo3610 em 04/11/2013 - 19:24h

Era isso mesmo, troquei o I pelo l e funcionou, obrigado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts