Skip to content


“Hello World!” na SDL

Depois de configurarmos a SDL, está na hora de começar a parte divertida: usá-la!

Para isto, vamos começar com o clássico Hello World!. Ao final do tutorial teremos algo parecido com isto:

Hello World!

Este código foi feito pelo Lazy Foo. Modificado e traduzido por mim.
Então, vamos começar. Abra seu editor preferido.

1
2
3
#include "SDL/SDL.h"
#include <string>
using std::string;

Aqui só incluímos os headers que iremos utilizar. No caso, SDL e String.

4
5
6
7
//Constantes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

Nesta parte setamos as contantes de, respectivamente, o comprimento, altura, e bpp(bytes per pixel) da tela. Usarmos um BPP com 32 significa que além dos valores de vermelho, verde e azul(RGB), também temos o valor da claridade(alpha) de cada pixel.

8
9
10
//Superficies utilizadas
SDL_Surface *tux = NULL;
SDL_Surface *tela = NULL;

Aqui setamos dois ponteiros para os SDL_Surface que iremos utilizar. SDL_Surface é uma estrutura que representa uma área onde nós poderemos desenhar. Imagine-a como um pedaço de papel em branco, até agora.

12
13
14
15
16
17
18
19
//Feito por Lazy Foo
SDL_Surface *load_image( string filename )
{
	//Variável temporária para a imagem que será carregada
	SDL_Surface* loadedImage = NULL;
 
	//Imagem otimizada para o BPP da tela
	SDL_Surface* optimizedImage = NULL;

Esta é a nossa função para carregar uma imagem.
Ela recebe o caminho para a imagem e retorna um ponteiro para um SDL_Surface contendo uma versão otimizada da imagem.
A variável loadedImage é aonde nós iremos carregar temporariamente a imagem que está em filename. optimizedImage é a versão otimizada da imagem.

20
21
	//Carrega a imagem
	loadedImage = SDL_LoadBMP( filename.c_str() );

Aqui nós carregamos a imagem para loadedImage.
Nós não devemos utilizá-la agora pois ela tem 24 bits, e nossa tela tem 32 bits. Devemos evitar blitar(é como “colar” uma superfície em cima da outra) uma superfície em outra que tenha um BPP diferente, pois a SDL terá que convertê-la antes disso, o que irá tornar o jogo mais lento.

22
23
24
25
26
27
28
29
30
	//Se não houveram problemas carregando a imagem
	if( loadedImage != NULL )
	{
		//Cria uma imagem otimizada
		optimizedImage = SDL_DisplayFormat( loadedImage );
 
		//Libera a imagem antiga
		SDL_FreeSurface( loadedImage );
}

Primeiro checamos se ele carregou sem erros a imagem. Se sim, criamos uma versão otimizada da mesma. A função SDL_DisplayFormat() recebe como parâmetro um SDL_Surface* e retorna outro SDL_Surface* com o mesmo BPP da tela.
Depois de termos a imagem otimizada, não precisamos mais da loadedImage, então a liberamos através da SDL_FreeSurface().

31
32
33
	//Retorna a imagem otimizada
	return optimizedImage;
}

Retornamos a versão otimizada da imagem.

34
35
36
37
38
39
40
41
//Feito por Lazy Foo
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
	//Cria um SDL_Rect temporário para guardar as coordenadas para onde blitar a imagem
	SDL_Rect offset;
	//Salva as coordenadas no SDL_Rect
	offset.x = x;
	offset.y = y;

Esta é nossa função para blitar superfícies.
Ela recebe as coordenadas da onde você quer blitar a superfície, qual a superfície que você quer blitar, e em qual superfície você quer blitá-la.
Para isso, primeiro nós colocamos as coordenadas em um SDL_Rect, que é uma estrutura bem simples, com somente quatro elementos: as coordenadas x e y, o comprimento(w) e a altura(h). Fazemos isso pois o método que iremos utilizar, SDL_BlitSurface() só aceita as coordenadas dentro de um SDL_Rect.

42
43
44
	//Blita a superfície
	SDL_BlitSurface( source, NULL, destination, &offset );
}

Aqui nos blitamos a superfície com a função SDL_BlitSurface().
Ela recebe quatro parâmetros: a superfície que você quer blitar; a parte da superfície que você quer blitar(bom para sprites, mas, como queremos que ele envie a imagem inteira, usamos NULL); a superfície onde você quer blitar; o endereço do SDL_Rect com as coordenadas da onde blitar.

45
46
47
//Início do main
int main (int argc, char* args[])
{

Finalmente iniciamos a main. Quando usar a SDL você tem que ter cuidado para só usar a main assim como usamos ou

int main (int argc, char** args)

Qualquer outro jeito não irá funcionar.

48
49
50
51
52
	// Inicializamos a SDL e todos seus subsistemas
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
	return 1;
	}

Aqui inicializamos a SDL pela função SDL_Init(). Passamos SDL_INIT_EVERYTHING para ele iniciar todos os subsistemas, como audio, vídeo, timers, etc..
Caso ela não consiga inicializar, a função irá retornar -1, e nós sairemos do programa com o código de erro 1.

53
54
	//Inicializa a tela
	tela = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

A função SDL_SetVideoMode() cria nossa tela com o tamanho, altura, bpp especificados. O último parâmetro são as flags da tela. Como, por exemplo, se usaremos OpenGL, a memória da placa-de-vídeo, etc. Aqui nós criamos a tela na memória do sistema.

55
56
57
58
59
	//Se houve algum erro na inicialização da tela
	if (tela == NULL)
	{
	return 1;
	}

Caso a SDL não tenha conseguido inicializar a tela, paramos a execução com o código de erro 1.

60
61
	//Muda o nome da janela
	SDL_WM_SetCaption( "Hello World", NULL );

Mudamos o nome da janela para Hello World. O segundo parâmetro da função é para o nome do ícone, que não usaremos.

62
63
	//Pinta a tela de branco
	SDL_FillRect(tela, NULL, 0xFFFFFFFF);

Usamos a função SDL_FillRect() para pintar a tela de branco. Esta função recebe como parâmetros a superfície que você quer pintar, um SDL_Rect*, caso você queira pintar só uma parte da superfície, e a cor, em RGBA, para pintar.

64
65
	//Carrega a imagem
	tux = load_image("tux.bmp");

Carregamos a imagem do tux usando a função load_image() do Lazy Foo.

66
67
	//Aplicamos o Tux à tela
	apply_surface( 180, 140, tux, tela );

Aplicamos, ou blitamos, o tux a tela usando a função apply_surface() do Lazy Foo.
Lembre-se que na SDL, como na maioria dos lugares em computação, a coordenada y é diferente da matemática. Ela cresce de cima para baixo, ao invés de ser de baixo pra cima.

68
69
70
71
72
	//Atualiza a tela
	if (SDL_Flip(tela) == -1)
	{
	return 1;
	}

Até agora nós só estavamos escrevendo no buffer. As imagens só são mostradas quando chamamos o método SDL_Flip() com a superfície que queremos atualizar. Esta função retorna -1 em caso de erro. Nós testamos isso e, caso positivo, paramos a execução do programa com o código de erro 1.

73
74
	//Para a execução por 5 segundos
	SDL_Delay(5000);

Nós chamamos a função SDL_Delay() para que consigamos ver alguma coisa, caso contrário o programa iria abrir e fechar tão rápido que não veríamos nada. Ele recebe como parâmetro o tempo em milissegundos(um segundo tem 1000 milissegundos) que queremos pausar a execução.

75
76
77
78
79
80
81
82
83
	//Libera a superfície
	SDL_FreeSurface(tux);
 
	//Destrói a SDL
	SDL_Quit();
 
	//Termina a execução
	return 0;
}

Aqui nós limpamos o que usamos durante a execução do programa. Com a função SDL_FreeSurface() nós liberamos a memória das superfícies que usamos. Não precisamos liberar a tela, pois o SDL_Quit() cuida disso.

Baixe os fontes e a imagem deste tutorial aqui.

Posts relacionados:

  1. Exemplo da SDL_gfx
  2. Configurando a SDL - Windows
  3. Introdução ao tratamento de eventos na SDL
  4. Configurando a SDL - Linux
  5. Instalando extensões para a SDL - Linux

Publicado em Artigos, SDL.

0 comentários

Um pouco de HTML pode ser usado

(obrigatório)

(obrigatório, mas nunca divulgado)

ou, responda este post via trackback.