O que é um renderizador SDL?

103

Estou começando com SDL2 e tendo alguns problemas para tentar entender o que é um SDL_Renderer.

O que é isso? O que isso faz? Qual é a diferença entre SDL_Renderer, SDL_Window, SDL_Surface e SDL_Texture e como eles estão relacionados?

Tive problemas com isso ao tentar entender este código introdutório:

#include <iostream>
#include <SDL2/SDL.h>

int main()
{
    /* Starting SDL */
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Create a Window */
    SDL_Window *window = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Create a Render */
    SDL_Renderer *render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (render == nullptr) {
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Load bitmap image */
    SDL_Surface *bmp = SDL_LoadBMP("./Tutorial/res/Lesson1/hello.bmp");
    if (bmp == nullptr) {
        std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Upload surface to render, and then, free the surface */
    SDL_Texture *texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);
    if (texture == nullptr){
        std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Draw the render on window */
    SDL_RenderClear(render); // Fill render with color
    SDL_RenderCopy(render, texture, NULL, NULL); // Copy the texture into render
    SDL_RenderPresent(render); // Show render on window

    /* Wait 2 seconds */
    SDL_Delay(5000);

    /* Free all objects*/
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(render);
    SDL_DestroyWindow(window);

    /* Quit program */
    SDL_Quit();
    return 0;
}

Eu estava usando o tutorial Twinklebear (sugerido no SDL Wiki) e também procurei na documentação do SDL Wiki e alguns livros. Mas todos eles presumem que eu conheço essas definições.

prcastro
fonte

Respostas:

196

SDL_Window

SDL_Window é a estrutura que contém todas as informações sobre a própria janela: tamanho, posição, tela inteira, bordas etc.


SDL_Renderer

SDL_Rendereré uma estrutura que lida com toda a renderização. Ele está vinculado a um, SDL_Windowportanto, só pode ser renderizado dentro dele SDL_Window. Ele também controla as configurações relacionadas à renderização. Existem várias funções importantes ligadas aoSDL_Renderer

  • SDL_SetRenderDrawColor(renderer, r, g, b, a);
    Isso define a cor que você limpa a tela (veja abaixo)

  • SDL_RenderClear(renderer);
    Isso limpa o alvo de renderização com a cor de desenho definida acima

  • SDL_RenderCopy(
    Esta é provavelmente a função que você mais usará, ela é usada para renderizar um SDL_Texturee tem os seguintes parâmetros:

    • SDL_Renderer* renderer,
      O renderizador que você deseja usar para renderizar.
    • SDL_Texture* texture,
      A textura que você deseja renderizar.
    • const SDL_Rect* srcrect, A parte da textura que você deseja renderizar, NULL se você deseja renderizar a textura inteira
    • const SDL_Rect* dstrect)
      Onde você deseja renderizar a textura na janela. Se a largura e altura deste SDL_Rectfor menor ou maior do que as dimensões da própria textura, a textura será esticada de acordo com esteSDL_Rect
  • SDL_RenderPresent(renderer);
    As outras funções SDL_Render * atraem um alvo oculto. Esta função pegará tudo isso e o desenhará na janela vinculada ao renderizador.

SDL_Textures e SDL_Surface

Os SDL_Rendererrenderizadores SDL_Texture, que armazenam as informações de pixel de um elemento. É a nova versão SDL_Surfaceque é praticamente a mesma. A diferença é principalmente que SDL_Surfaceé apenas uma structinformação de pixel contendo, enquanto SDL_Textureé uma representação eficiente e específica do driver de dados de pixel.

Você pode converter um SDL_Surface * em SDL_Texture usando

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                          SDL_Surface*  surface)

Depois disso, o SDL_Surface deve ser liberado usando

SDL_FreeSurface( SDL_Surface* surface )

Outra diferença importante é que SDL_Surfaceusa renderização de software (via CPU) enquanto SDL_Textureusa renderização de hardware (via GPU).


SDL_Rect

A estrutura mais simples em SDL. Ele contém apenas quatro shorts. x, yque mantém a posição e w, hque mantém a largura e a altura.

É importante observar que 0, 0é o canto superior esquerdo do SDL. Portanto, um yvalor mais alto significa menor, e o canto inferior direito terá a coordenadax + w, y + h


Você pode ler mais sobre SDL2 em meu blog.

Olevegard
fonte
1
Então, o que você quando chama SDL_RenderPresent é pegar aquele renderizador com todas as suas configurações e texturas que foram carregadas nele e torná-lo renderizar essas informações na janela à qual está vinculado?
prcastro de
3
@olevegard, ótima resposta. Apenas para esclarecer a diferença entre SDL_Texture e SDL_Surface, gostaria de enfatizar que SDL_Texture renderiza usando a GPU e SDL_Surface usa redering de software, que é menos eficiente, mas permite que você manipule livremente as informações de pixel. Além disso, ótimo blog, com certeza irei lê-lo :)
Fabio Picchi
A declaração "Isso limpa o alvo de renderização com a cor de desenho definida acima" , acredito, está correta, mas não consigo entender a frase "limpa" na declaração. O doc sempre usa essa frase. Você poderia explicar o que exatamente "claro" significa aqui? Significa "pintar" (mais ou menos) com a cor de desenho atual do renderizador?
Nawaz
Existe alguma razão para usar SDL_Surfacemais SDL_Renderer?
Stevoisiak de
A resposta principal tem alguma imprecisão, SDL_Renderer pode ser vinculado à superfície também, não apenas à janela, verifique o link: wiki.libsdl.org/SDL_CreateSoftwareRenderer
dmitro
9

Pense SDL_Windowem pixels físicos SDL_Renderere um lugar para armazenar configurações / contexto.

Portanto, você cria vários recursos e os pendura no renderizador; e então, quando estiver pronto, você diz ao renderizador para juntar tudo e enviar os resultados para a janela.

Woolstar
fonte