Neste tutorial vou mostrar, utilizando o código do tutorial anterior, como trabalhar com configurar a cor transparente, transparência (alphamod), mistura de cores (blendmod) das imagens.
Para o formato de imagem bitmap somente os de 32 bits de cor possuem um canal de transparência, para os de 24 bits é necessário configurar a cor que será a cor transparente da imagem e habilitá-la, enquanto que para as imagens de 8 e 16 bits, usando as funções padrão da biblioteca, não tem como configurar a cor transparente.
A vantagem em se usar a configuração de uma cor como sendo a transparente da imagem e não uma imagem de 32 bits está no tamanho do arquivo, veja na tabela abaixo o comparativo de tamanho para nossa imagem de referência.
128x128 pixels
|
Bits Por Pixel
|
KB
|
8
|
9
|
16
|
33
|
24
|
49
|
32
|
65
|
Cor transparente
Na biblioteca SDL existe a função SDL_SetColorKey() que é usada para configurar a cor transparente da imagem. O primeiro parâmetro passado para ela é o ponteiro para SDL_Surface que guarda a imagem, o segundo habilita (SDL_TRUE) ou desabilita (SDL_FALSE) a transparência e o terceiro parâmetro é um inteiro de 32 bits que referencia a cor que será a transparente.
#include <stdio.h> // Para a fprintf #include <SDL2/SDL.h> int main(int argc,char* argv[]){ if(SDL_Init(SDL_INIT_VIDEO) !=0){ fprintf(stderr, "\nImpossivel iniciar o video: %s\n", SDL_GetError()); return 1; } SDL_Window* janela; janela = SDL_CreateWindow("Primeira janela", 100, 100, 800, 600, 0 | SDL_WINDOW_SHOWN); if(janela == NULL){ printf("Não foi possivel criar a janela: %s", SDL_GetError()); return 1; } SDL_Renderer* render = SDL_CreateRenderer(janela, -1, SDL_RENDERER_ACCELERATED); if(render == NULL){ printf("Erro ao criar o reder: %s", SDL_GetError()); } SDL_Surface* imagem = SDL_LoadBMP("circulos24.bmp"); if(imagem == NULL){ printf("Não foi possivel carregar a imagem"); } SDL_SetColorKey(imagem, SDL_TRUE, 0xffffff); // Este é outro modo de usar o comando acima //SDL_SetColorKey(imagem, SDL_TRUE, SDL_MapRGB(imagem->format, 0xff, 0xff, 0xff)); SDL_Texture* textura = SDL_CreateTextureFromSurface(render, imagem); SDL_FreeSurface(imagem); SDL_RenderClear(render); SDL_Rect* src1_rect = new(SDL_Rect); src1_rect->x = 64; src1_rect->y = 0; src1_rect->w = 64; src1_rect->h = 64; SDL_Rect* dst1_rect = new(SDL_Rect); dst1_rect->x = 0; dst1_rect->y = 0; dst1_rect->w = 64; dst1_rect->h = 64; SDL_RenderCopy(render, textura, src1_rect, dst1_rect); SDL_RenderPresent(render); SDL_Delay(5000); SDL_DestroyTexture(textura); SDL_DestroyRenderer(render); SDL_DestroyWindow(janela); SDL_Quit(); return 0; }
Veja pelo trecho de código abaixo que a função foi colocada logo depois de se ter carregado a imagem para a memória. Como podemos ver a cor de fundo de nossa imagem é o branco por isso passamos o valor em hexadecimal 0xffffff para o último parâmetro da função.
Bom… para quem já está acostumado com html já deve conhecer o padrão usado aqui, o valor hexadecimal se refere aos valores RGB da cor (Red, Green, Blue), 0xffffff. Estes podem varia de 0 a 255 ou de 00 a FF em hexadecimal.
SDL_Surface* imagem = SDL_LoadBMP("circulos24.bmp"); if(imagem == NULL){ printf("Não foi possivel carregar a imagem"); } SDL_SetColorKey(imagem, SDL_TRUE, 0xffffff); // Este é outro modo de usar o comando acima // SDL_SetColorKey(imagem, SDL_TRUE, SDL_MapRGB(imagem->format, 0xff, 0xff, 0xff));
Uma opção que eu uso é abrir a imagem no programa Gimp, selecionar a ferramenta de seleção de cores e então clicar na cor que quero saber o valor segurando a tecla shift. Uma janela
igual a abaixo se abrira e é possível ver o valor em hexadecimal da cor selecionada.
O resultado do código acima está na imagem a seguir, não tem mais a borda branca em volta do círculo.
Como pode ser visto a cor branca, que estava ao redor da imagem, já não é mais exibida.
Transparência (Alpha Mod)
Outra opção que temos é configurar o nível de transparência da imagem que pode ir de totalmente opaco a totalmente transparente com a função SDL_SetTextureAlphaMod(). O primeiro parâmetro passado para ela é a textura e o segundo é um valor entre 0 (totalmente transparente) e 255 (totalmente opaco). Uma informação importante é que esta função só irá ter efeito se a imagem tiver um canal de transparecia (para bitmaps de 32 bits) ou tiver sido feita a configuração de cor transparente com a função SDL_SetColorKey() (para bitmaps de 24 bits).
#include <stdio.h> // Para a fprintf #include <SDL2/SDL.h> int main(int argc,char* argv[]){ if(SDL_Init(SDL_INIT_VIDEO) !=0){ fprintf(stderr, "\nImpossivel iniciar o video: %s\n", SDL_GetError()); return 1; } SDL_Window* janela; janela = SDL_CreateWindow("Primeira janela", 100, 100, 800, 600, 0 | SDL_WINDOW_SHOWN); if(janela == NULL){ printf("Não foi possivel criar a janela: %s", SDL_GetError()); return 1; } SDL_Renderer* render = SDL_CreateRenderer(janela, -1, SDL_RENDERER_ACCELERATED); if(render == NULL){ printf("Erro ao criar o reder: %s", SDL_GetError()); } SDL_Surface* imagem = SDL_LoadBMP("circulos24.bmp"); if(imagem == NULL){ printf("Não foi possivel carregar a imagem"); } // Configura a cor transparente SDL_SetColorKey(imagem, SDL_TRUE, SDL_MapRGB(imagem->format, 0xff, 0xff, 0xff)); SDL_Texture* textura = SDL_CreateTextureFromSurface(render, imagem); SDL_Texture* textura1 = SDL_CreateTextureFromSurface(render, imagem); SDL_FreeSurface(imagem); SDL_RenderClear(render); SDL_Rect* src_rect = new(SDL_Rect); src_rect->x = 0; src_rect->y = 64; src_rect->w = 64; src_rect->h = 64; SDL_Rect* dst_rect = new(SDL_Rect); dst_rect->x = 32; dst_rect->y = 0; dst_rect->w = 64; dst_rect->h = 64; SDL_Rect* src1_rect = new(SDL_Rect); src1_rect->x = 64; src1_rect->y = 0; src1_rect->w = 64; src1_rect->h = 64; SDL_Rect* dst1_rect = new(SDL_Rect); dst1_rect->x = 0; dst1_rect->y = 0; dst1_rect->w = 64; dst1_rect->h = 64; // Circulo verde SDL_RenderCopy(render, textura1, src_rect, dst_rect); // Circulo Vermelho SDL_SetTextureAlphaMod(textura, 100); SDL_RenderCopy(render, textura, src1_rect, dst1_rect); SDL_RenderPresent(render); SDL_Delay(5000); SDL_DestroyTexture(textura); SDL_DestroyTexture(textura1); SDL_DestroyRenderer(render); SDL_DestroyWindow(janela); SDL_Quit(); return 0; }
Uma outra modificação feita foi que agora são desenhadas dois círculos, por baixo é desenhado o círculo verde e por cima o vermelho onde é aplicado a transparência.
// Circulo verde SDL_RenderCopy(render, textura1, src_rect, dst_rect); SDL_SetTextureAlphaMod(textura, 100); // Circulo vermelho SDL_RenderCopy(render, textura, src1_rect, dst1_rect);
No nosso exemplo a linha de código que configura a transparência da imagem é colocado logo antes de desenhá-la. A saída é vista na imagem abaixo. Podemos ver que as cores se combinam por causa da transparência da imagem que foi desenhada por cima
Mistura de cores (BlendMod)
No exemplo anterior mostrei que as cores se combinam quando existe um elemento transparente sobre outro elemento. No exemplo que se segue vou mostrar os tipos de combinação de cores.
Para fazer o controle do modo de combinação de cores usa-se a função SDL_SetTextureBlendMode(), esta recebe como primeiro parâmetro um ponteiro para a textura e como segundo parâmetro o modo de mistura de cores que podem ser:
SDL_BLENDMODE_NONE : desabilita os efeitos, as mudanças feitas com SDL_SetColorKey e SDL_SetTextureAlphaMod serão desfeitas
SDL_BLENDMODE_BLEND : está é o padrão, o mesmo efeito dos exemplos anteriores é visto com esta opção, sendo este afetado apenas pela transparência da imagem.
SDL_BLENDMODE_ADD : Soma a cor de fundo e a cor da frente e o resultado é uma cor mais clara. A transparencia configurada com SDL_SetTextureAlphaMod afeta essa soma.
SDL_BLENDMODE_MOD : Modula a cor de fundo e a da frente o resultado é uma cor mais escura. A transparencia configurada com SDL_SetTextureAlphaMod é desabilitada.
Vamos ao código de exemplo:
#include// Para a fprintf #include int main(int argc,char* argv[]){ if(SDL_Init(SDL_INIT_VIDEO) !=0){ fprintf(stderr, "\nImpossivel iniciar o video: %s\n", SDL_GetError()); return 1; } SDL_Window* janela; janela = SDL_CreateWindow("Primeira janela", 100, 100, 800, 600, 0 | SDL_WINDOW_SHOWN); if(janela == NULL){ printf("Não foi possivel criar a janela: %s", SDL_GetError()); return 1; } SDL_Renderer* render = SDL_CreateRenderer(janela, -1, SDL_RENDERER_ACCELERATED); if(render == NULL){ printf("Erro ao criar o reder: %s", SDL_GetError()); } SDL_Surface* imagem = SDL_LoadBMP("circulos24.bmp"); if(imagem == NULL){ printf("Não foi possivel carregar a imagem"); } // Configura a cor transparente SDL_SetColorKey(imagem, SDL_TRUE, SDL_MapRGB(imagem->format, 0xff, 0xff, 0xff)); SDL_Texture* textura = SDL_CreateTextureFromSurface(render, imagem); SDL_Texture* textura1 = SDL_CreateTextureFromSurface(render, imagem); SDL_FreeSurface(imagem); SDL_SetRenderDrawColor(render, 255, 255, 255, 255); SDL_RenderClear(render); SDL_Rect* src_rect = new(SDL_Rect); src_rect->x = 0; src_rect->y = 64; src_rect->w = 64; src_rect->h = 64; SDL_Rect* dst_rect = new(SDL_Rect); dst_rect->x = 32; dst_rect->y = 0; dst_rect->w = 64; dst_rect->h = 64; SDL_Rect* src1_rect = new(SDL_Rect); src1_rect->x = 64; src1_rect->y = 0; src1_rect->w = 64; src1_rect->h = 64; SDL_Rect* dst1_rect = new(SDL_Rect); dst1_rect->x = 0; dst1_rect->y = 0; dst1_rect->w = 64; dst1_rect->h = 64; // Circulo verde SDL_RenderCopy(render, textura1, src_rect, dst_rect); SDL_SetTextureBlendMode(textura, SDL_BLENDMODE_BLEND); SDL_SetTextureAlphaMod(textura, 100); //Circulo vermelho SDL_RenderCopy(render, textura, src1_rect, dst1_rect); SDL_RenderPresent(render); SDL_Delay(5000); SDL_DestroyTexture(textura); SDL_DestroyTexture(textura1); SDL_DestroyRenderer(render); SDL_DestroyWindow(janela); SDL_Quit(); return 0; }
A primeira mudança em relação ao código do exemplo anterior fica no uso da função SDL_SetRenderDrawColor(), o primeiro parâmetro passado para ela é um ponteiro para o render, os quatro seguintes correspondem ao valor R, G, B, A (onde R é o vermelho, G é o verde, B é o azul e A é a transparencia que podem variar de 0 a 255). Esta função é usada para definir qual vai ser a cor usada para limpar a tela.
SDL_SetRenderDrawColor(render, 255, 255, 255, 255); SDL_RenderClear(render);
A segunda mudança é a linha que configura o modo de mistura de cores.
SDL_SetTextureBlendMode(textura, SDL_BLENDMODE_BLEND);
Onde
SDL_BLENDMODE_BLEND pode ser substituído por qualquer uma das quatro
opções descritas anteriormente.
Nas imagens abaixo mostro o
resultado do código acima e das outras opções.
SDL_BLENDMODE_NONE
|
SDL_BLENDMODE_BLEND
|
SDL_BLENDMODE_ADD
|
SDL_BLENDMODE_MOD
|
Ufa! Termino por qui mais um
tutorial. Até o próximo, duvidas ou sugestões é só deixar nos
comentários. Obrigado.
Referências
Nenhum comentário:
Postar um comentário