Co to jest renderer SDL?

104

Zaczynam od SDL2 i mam pewne problemy ze zrozumieniem, czym jest SDL_Renderer.

Co to jest? Co to robi? Jaka jest różnica między SDL_Renderer, SDL_Window, SDL_Surface i SDL_Texture i jak są one powiązane?

Miałem z tym problemy, próbując zrozumieć ten kod wprowadzający:

#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;
}

Korzystałem z samouczka Twinklebear (sugerowanego na SDL Wiki) i przeglądałem także dokumentację SDL Wiki i kilka książek. Ale wszyscy zakładają, że znam te definicje.

prcastro
źródło

Odpowiedzi:

197

SDL_Window

SDL_Window jest strukturą, która przechowuje wszystkie informacje o samym oknie: rozmiar, położenie, pełny ekran, obramowanie itp.


SDL_Renderer

SDL_Rendererjest strukturą, która obsługuje całe renderowanie. Jest on powiązany z elementem, SDL_Windowwięc może renderować tylko w nim SDL_Window. Śledzi również ustawienia związane z renderowaniem. Istnieje kilka ważnych funkcji powiązanych zSDL_Renderer

  • SDL_SetRenderDrawColor(renderer, r, g, b, a);
    Ustawia kolor, na jaki wyczyścisz ekran (patrz poniżej)

  • SDL_RenderClear(renderer);
    Spowoduje to wyczyszczenie celu renderowania z kolorem rysowania ustawionym powyżej

  • SDL_RenderCopy(
    Jest to prawdopodobnie funkcja, której będziesz używać najczęściej, służy do renderowania a SDL_Texturei ma następujące parametry:

    • SDL_Renderer* renderer,
      Mechanizm renderujący, którego chcesz użyć do renderowania.
    • SDL_Texture* texture,
      Tekstura, którą chcesz renderować.
    • const SDL_Rect* srcrect, Część tekstury, którą chcesz renderować, NULL, jeśli chcesz renderować całą teksturę
    • const SDL_Rect* dstrect)
      Miejsce, w którym chcesz renderować teksturę w oknie. Jeśli szerokość i wysokość SDL_Rectjest mniejsza lub większa niż wymiary samej tekstury, tekstura zostanie rozciągnięta zgodnie z tymSDL_Rect
  • SDL_RenderPresent(renderer);
    Inne funkcje SDL_Render * rysują do ukrytego celu. Ta funkcja weźmie to wszystko i narysuje to w oknie powiązanym z rendererem.

SDL_Textures i SDL_Surface

SDL_RendererTynków SDL_Texture, która przechowuje informacje piksela jednego elementu. To nowa wersja, SDL_Surfacektóra jest prawie taka sama. Różnica polega głównie na tym, że SDL_Surfacezawiera tylko structinformacje o pikselach, podczas gdy SDL_Texturejest to wydajna, specyficzna dla sterownika reprezentacja danych pikseli.

Możesz przekonwertować SDL_Surface * na SDL_Texture za pomocą

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

Następnie należy zwolnić SDL_Surface za pomocą

SDL_FreeSurface( SDL_Surface* surface )

Inną ważną różnicą jest to, że SDL_Surfacewykorzystuje renderowanie programowe (przez procesor), a SDL_Texturerenderowanie sprzętowe (przez GPU).


SDL_Rect

Najprostsza struktura w SDL. Zawiera tylko cztery spodenki. x, yktóry utrzymuje pozycję i w, hktóry utrzymuje szerokość i wysokość.

Należy zauważyć, że 0, 0jest to lewy górny róg w SDL. Zatem wyższa y-wartość oznacza niższą, a prawy dolny róg będzie miał współrzędnex + w, y + h


Możesz przeczytać więcej o SDL2 na moim blogu.

olevegard
źródło
1
Więc kiedy wywołujesz SDL_RenderPresent, bierzesz ten renderer ze wszystkimi jego ustawieniami i teksturami, które zostały do ​​niego załadowane i sprawisz, że renderuje te informacje w oknie, z którym jest powiązany?
prcastro
3
@olevegard, świetna odpowiedź. Aby wyjaśnić różnicę między SDL_Texture i SDL_Surface, chciałbym podkreślić, że SDL_Texture renderuje za pomocą GPU, a SDL_Surface wykorzystuje rederowanie programowe, które jest mniej wydajne, ale pozwala na dowolne manipulowanie informacjami o pikselach. Również świetny blog, na pewno go przeczytam :)
Fabio Picchi
Stwierdzenie „To usuwa cel renderowania z kolorem rysowania ustawionym powyżej” , moim zdaniem, jest poprawne, ale nie jestem w stanie zrozumieć wyrażenia „wyczyści” w instrukcji. Doc zawsze używa tego zwrotu. Czy mógłbyś wyjaśnić, co dokładnie oznacza tutaj „czysty” ? Czy to oznacza „malowanie” (w pewnym sensie) z bieżącym kolorem rysowania modułu renderującego?
Nawaz
Czy jest jakiś powód, aby używać SDL_Surfaceover SDL_Renderer?
Stevoisiak
Górna odpowiedź ma pewną niedokładność, SDL_Renderer może być również powiązany z powierzchnią, nie tylko z oknem, sprawdź link: wiki.libsdl.org/SDL_CreateSoftwareRenderer
dmitro
9

Pomyśl o SDL_Windowfizycznych pikselach SDL_Rendereri miejscu do przechowywania ustawień / kontekstu.

Więc tworzysz zbiór zasobów i wieszasz je na rendererze; a kiedy będzie gotowy, każesz rendererowi zebrać wszystko razem i wysłać wyniki do okna.

Woolstar
źródło