Olá pessoal! Esta é a quarta lição do SDL 2. Decidi combinar as duas lições em uma, pois no original elas são pequenas. Mas eles podem ser encontrados
aqui e
aqui . Bem, vamos começar a lição.
Primeiro, decidiremos o que faremos. Hoje, aprenderemos como fazer upload de imagens de outra extensão (não BMP), a saber: PNG. Refaça a imagem em um formato diferente para acelerar o trabalho e redimensionar a imagem. Vamos trabalhar com esta imagem:
Instalação
Então, primeiro aprendemos a baixar PNG. No conjunto de recursos padrão do SDL 2, não há upload de uma imagem no formato não BMP. Para baixar um formato diferente, você precisa instalar a extensão.
Aqui estão as instruções:
WindowsVocê acessa esta
página e baixa os arquivos ZIP ou TAR.GZ na seção
Bibliotecas de Desenvolvimento . Descompacte e jogue-os na pasta com o compilador.
LinuxSe o seu sistema usa Debian, você precisa inserir estes comandos:
apt-cache search libsdl2-image apt-get install libsdl2-image-dev
Se o Yellowdog Updater, Modified for usado, você deverá digitar estes comandos:
yum search SDL2_image-devel yum SDL2_image-devel
Mac OSFaça o download do arquivo DMG e leia o Leia-me.
Escrevendo um código
Depois de definir
SDL_image, começamos a escrever o código. Primeiro, como sempre, conectaremos as bibliotecas, definiremos o tamanho das janelas e criaremos 3 variáveis globais.
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL;
Observe que eu conectei o
SDL_image.h separadamente, pois é uma biblioteca separada.
Em seguida, escrevemos 3 funções, conhecidas por nós, nas quais vamos adicionar e alterar algo, como de costume.
Init () bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; }
Aqui nós adicionamos a inicialização do módulo SDL_image. Para inicializá-lo, primeiro crie uma variável
int , temos
sinalizadores e salve todos os sinalizadores que você deseja usar para a inicialização.
Lista de todos os sinalizadoresSDL_INIT_PNG - inicializa o downloader de imagem PNG;
SDL_INIT_JPG - inicializa o downloader de imagem JPG;
SDL_INIT_TIF - inicializa o downloader de imagem TIF;
Em seguida, escrevemos esta condição:
if ( !( IMG_Init( flags ) & flags ) )
A função
IMG_Init () retorna os sinalizadores que pôde inicializar. Se ela devolveu as bandeiras, mas a que queríamos estava faltando, retornamos um erro. Muito simples Além disso, observe que eu uso
IMG_GetError em vez de
SDL_GetError , pois estamos procurando um erro na função do módulo
SDL_image , não no
SDL .
Também quero observar que decidi usar o tipo
bool para
retornar a - esta é uma maneira mais racional.
Vamos continuar escrevendo nosso programa, escrevendo a função
Load () , na qual carregamos uma imagem PNG e a convertemos.
Carregar bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; }
Aqui, carregamos a imagem com a nova função
IMG_Load .
Sua função é a mesma que a de
SDL_LoadBMP e o resultado é o mesmo - ele retorna uma instância da classe
SDL_Surface . Para encontrar erros durante o carregamento, também usamos
IMG_GetError .
É hora de converter. Primeiro, um pouco de teoria. Poucas pessoas sabem, mas ao baixar uma imagem, ela é baixada no formato 24 bits, e a maioria das telas modernas está no formato 32 bits. E toda vez que exibíamos a imagem na tela, ela era refeita pela primeira vez no formato 32 bits. Para programas simples, isso não importa, mas ao criar algum tipo de projeto grande, ele afetará bastante o desempenho; portanto, tomaremos e no estágio de carregamento das imagens as refazeremos no formato de exibição. A função
SDL_ConvertSurface ajudará. São necessários três valores: a superfície que queremos formatar, o formato em que queremos formatar e os sinalizadores. queremos formatar a imagem da
flor , passe o primeiro parâmetro. O segundo parâmetro é o formato da superfície da janela, não usaremos sinalizadores. Essa função retorna uma cópia da superfície, que atribuímos imediatamente à
flor . Para procurar erros, usamos a função
SDL_GetError () ,
porque já estamos trabalhando com superfícies, e elas são do
SDL , e não do
SDL_image .
Em seguida, escrevemos a função Quit, adicionamos apenas uma função a ela.
Sair void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); }
Adicionamos
IMG_Quit para inicializar o módulo SDL_image.
Principal
Agora, a coisa mais simples permanece - a função
principal .
int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; }
Para começar, inicialize e crie tudo o que você precisa e faça o upload dos arquivos necessários. Nós não vamos parar por aqui.
SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0;
Depois disso, crie um objeto da classe
SDL_Rect . Vamos precisar para esticar a imagem. Se você notar, a imagem da flor é 4 vezes menor que a janela (2 vezes mais fina e 2 vezes menor), e precisamos esticá-la para a janela. Portanto, na largura do retângulo,
bg_flower escreva o valor da largura da janela e em altura - a altura da janela. defina as coordenadas como 0, para que a imagem seja exibida no canto superior esquerdo.
Para exibir imagens redimensionadas, há uma função especial. É assim:
SDL_BlitScaled(flower, NULL, scr, &bg_flower);
Leva 4 significados. A primeira é a imagem que queremos exibir, a segunda é o retângulo que queremos cortar desta imagem (se quisermos tirar a imagem inteira, escrevemos NULL), a terceira é a superfície na qual queremos exibir a imagem e a quarta é o mesmo retângulo, dimensões e as coordenadas que usamos para esticar ou comprimir e exibir a imagem.
Em seguida, basta atualizar a superfície da tela, definir o atraso, sair e retornar 0.
SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
É aqui que o nosso programa termina. Para compilar esse milagre, você precisa adicionar -lSDL2_image, como outra opção de compilação.
E nisso terminaremos por hoje. Aqui está o código que temos:
#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *flower = NULL; bool init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init video: " << SDL_GetError() << std::endl; return false; } int flags = IMG_INIT_PNG; if ( !( IMG_Init( flags ) & flags ) ) { std::cout << "Can't init image: " << IMG_GetError() << std::endl; return false; } win = SDL_CreateWindow(" PNG", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; return false; } scr = SDL_GetWindowSurface(win); return true; } bool load() { flower = IMG_Load("flower.png"); if (flower == NULL) { std::cout << "Can't load: " << IMG_GetError() << std::endl; return false; } flower = SDL_ConvertSurface(flower, scr->format, NULL); if (flower == NULL) { std::cout << "Can't convert: " << SDL_GetError() << std::endl; return false; } return true; } void quit() { SDL_FreeSurface(flower); SDL_FreeSurface(scr); SDL_DestroyWindow(win); SDL_Quit(); IMG_Quit(); } int main (int argc, char ** args) { if (!init()) { system("pause"); quit(); return 1; } if (!load()) { system("pause"); quit(); return 1; } SDL_Rect bg_flower; bg_flower.w = SCREEN_WIDTH; bg_flower.h = SCREEN_HEIGHT; bg_flower.x = 0; bg_flower.y = 0; SDL_BlitScaled(flower, NULL, scr, &bg_flower); SDL_UpdateWindowSurface(win); SDL_Delay(2000); quit(); return 0; };
Tchau pessoal!
<< Lição anterior || Próxima lição
>>