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 
>>