Tutoriais SDL 2: Lição 5 - Texturas

Olá a todos e bem-vindos à quinta lição sobre SDL 2, na qual analisaremos as texturas, simplificando o trabalho do computador. Você pode encontrar todas as lições em inglês aqui .

Na segunda versão SDL, há uma oportunidade muito boa para criar texturas e renderizá-las. A renderização de hardware é muito mais rápida do que desenhar superfícies em uma janela.

As texturas têm seu próprio tipo de dados - SDL_Texture . Ao trabalhar com texturas, precisamos de uma renderização para renderização. Agora vamos anunciar tudo isso.

#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; 

Aqui anunciamos a janela, render e esta flor.
Também conectamos bibliotecas e definimos tamanhos de janela.

A função Init também precisará ser alterada.

  bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } 

Primeiro, crie a variável ok , para não finalizar a função imediatamente, mas para encontrar todos os erros durante a inicialização. Em seguida, inicialize o SDL e crie uma janela de maneira conhecida.

É hora de declarar uma renderização.

  ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); 

A renderização é declarada pela função SDL_CreateRenderer . São necessários três valores: uma janela para a qual essa renderização será usada, um índice de driver (ou -1, se quisermos encontrar o primeiro adequado) e sinalizadores. Eu usei os sinalizadores SDL_RENDERER_ACCELERATED e SDL_RENDERER_PRESENTVSYNC . Aqui está uma lista de todas as bandeiras:

Bandeiras
SDL_RENDERER_SOFTWARE - substituto para;
SDL_RENDERER_ACCELERATED - uso de aceleração de hardware;
SDL_RENDERER_PRESENTVSYNC - sincronização vertical;
SDL_RENDERER_TARGETTEXTURE - suporte para renderização em textura.

Em seguida, usamos a função SDL_SetRenderDrawColor , que define a cor para desenhar primitivas.

Depois disso, inicialize o IMG e retorne ok .

  int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } 

Agora escrevemos a função Load .

 bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } 

Aqui também criamos a variável ok , para as mesmas necessidades. Eles criaram uma superfície temporária e carregaram imagens de flores nela.

Em seguida, precisamos fazer uma textura a partir da superfície.

  flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } 

A função SDL_CreateTextureFromSurface nos ajudará a criar a textura. Assume valores de renderização e superfície. Retorna uma instância da classe SDL_Texture .

Para não obstruir a memória, precisamos limpar a superfície temporária. Depois disso, retorne ok e a função estará pronta.

A função Quit executou mais algumas ações.

 void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } 

Aqui removemos a janela, renderizamos, texturizamos e deixamos SDL e IMG . Também defino todos os objetos excluídos como NULL para uma limpeza de memória ainda melhor.

Começamos a escrever a função principal .

 int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } 

Escrevemos a inicialização e o carregamento, não paramos por aqui.

O próximo passo é criar 2 variáveis.

  bool run = true; SDL_Event e; 

Este programa terá um ciclo principal para atualizar a memória, então vamos começar a escrevê-lo.

 while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } 

Processou o evento de pressionar a cruz e é isso.

Está na hora de desenhar. Ao usar texturas e renderizações, diferentes funções são usadas para renderizar aquelas que conhecemos. Para limpar a tela de texturas desenhadas, a função SDL_RenderClear é usada . Pinta a tela com a cor que especificamos com a função SDL_SetRenderDrawColor . A função SDL_RenderCopy é usada para renderizar a textura e SDL_RenderPresent é usada para atualizar a tela. Vamos escrever agora.

  SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } 

Analisaremos apenas a função SDL_RenderCopy . Leva 4 significados. O primeiro é uma renderização, o segundo é uma textura, o terceiro é um retângulo cuja área queremos recortar para renderização, o quarto é um retângulo cujas coordenadas são usadas para renderização e a largura e a altura são para redimensionar a textura.

Em seguida, chame a função Quit e retorne 0 .

  quit(); return 0; } 

Nisto terminarei a lição, se algo não estiver claro - escreva e digo adeus, adeus por enquanto!

A propósito, aqui está o código completo:

 #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <iostream> using namespace std; int SCREEN_WIDTH = 640; int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Renderer *ren = NULL; SDL_Texture *flower = NULL; bool init() { bool ok = true; if (SDL_Init(SDL_INIT_VIDEO) != 0) { cout << "Can't init: " << SDL_GetError() << endl; ok = false; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { cout << "Can't create window: " << SDL_GetError() << endl; ok = false; } ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (ren == NULL) { cout << "Can't create renderer: " << SDL_GetError() << endl; ok = false; } SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF); int flags = IMG_INIT_PNG; if (!(IMG_Init(flags) & flags)) { cout << "Can't init image: " << IMG_GetError() << endl; ok = false; } return ok; } bool load() { bool ok = true; SDL_Surface * temp_surf = NULL; temp_surf = IMG_Load("flower.png"); if (temp_surf == NULL) { cout << "Can't load image: " << IMG_GetError() << endl; ok = false; } flower = SDL_CreateTextureFromSurface(ren, temp_surf); if (flower == NULL) { cout << "Can't create texture from surface: " << SDL_GetError() << endl; ok = false; } SDL_FreeSurface(temp_surf); return ok; } void quit() { SDL_DestroyWindow(win); win = NULL; SDL_DestroyRenderer(ren); ren = NULL; SDL_DestroyTexture(flower); flower = NULL; SDL_Quit(); IMG_Quit(); } int main (int argc, char ** argv) { if (!init()) { quit(); return 1; } if (!load()) { quit(); return 1; } bool run = true; SDL_Event e; while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } } SDL_RenderClear(ren); SDL_RenderCopy(ren, flower, NULL, NULL); SDL_RenderPresent(ren); } quit(); return 0; } 

Lição anterior | Próxima lição

Source: https://habr.com/ru/post/pt456798/


All Articles