Was ist ein SDL-Renderer?

102

Ich beginne mit SDL2 und habe Probleme zu verstehen, was ein SDL_Renderer ist.

Was ist es? Was tut es? Was ist der Unterschied zwischen SDL_Renderer, SDL_Window, SDL_Surface und SDL_Texture und wie hängen sie zusammen?

Ich hatte Probleme damit, als ich versuchte, diesen Einführungscode zu verstehen:

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

Ich habe das Twinklebear-Tutorial (vorgeschlagen im SDL-Wiki) verwendet und mir auch die SDL-Wiki-Dokumentation und einige Bücher angesehen. Aber alle gehen davon aus, dass ich diese Definitionen kenne.

prcastro
quelle

Antworten:

194

SDL_Window

SDL_Window ist die Struktur, die alle Informationen über das Fenster selbst enthält: Größe, Position, Vollbild, Rahmen usw.


SDL_Renderer

SDL_Rendererist eine Struktur, die das gesamte Rendern übernimmt. Es ist an a gebunden, SDL_Windowso dass es nur innerhalb dessen rendern kann SDL_Window. Außerdem werden die Einstellungen für das Rendern verfolgt. Es gibt mehrere wichtige Funktionen, die mit dem verbunden sindSDL_Renderer

  • SDL_SetRenderDrawColor(renderer, r, g, b, a);
    Hiermit wird die Farbe eingestellt, auf die Sie den Bildschirm löschen (siehe unten).

  • SDL_RenderClear(renderer);
    Dadurch wird das Rendering-Ziel mit der oben festgelegten Zeichenfarbe gelöscht

  • SDL_RenderCopy(
    Dies ist wahrscheinlich die Funktion, die Sie am häufigsten verwenden. Sie wird zum Rendern von a verwendet SDL_Textureund hat die folgenden Parameter:

    • SDL_Renderer* renderer,
      Der Renderer, den Sie zum Rendern verwenden möchten.
    • SDL_Texture* texture,
      Die Textur, die Sie rendern möchten.
    • const SDL_Rect* srcrect, Der Teil der Textur, den Sie rendern möchten, NULL, wenn Sie die gesamte Textur rendern möchten
    • const SDL_Rect* dstrect)
      Wo Sie die Textur im Fenster rendern möchten. Wenn die Breite und Höhe SDL_Rectkleiner oder größer als die Abmessungen der Textur selbst ist, wird die Textur entsprechend gedehntSDL_Rect
  • SDL_RenderPresent(renderer);
    Die anderen SDL_Render * -Funktionen zeichnen auf ein verstecktes Ziel. Diese Funktion nimmt all das und zeichnet es in das Fenster, das mit dem Renderer verbunden ist.

SDL_Textures und SDL_Surface

Das SDL_RendererRendern SDL_Texture, das die Pixelinformationen eines Elements speichert. Es ist die neue Version, von SDL_Surfaceder es ähnlich ist. Der Unterschied besteht hauptsächlich darin, dass SDL_Surfacees sich nur um eine structenthaltende Pixelinformation handelt, während SDL_Texturees sich um eine effiziente, fahrerspezifische Darstellung von Pixeldaten handelt.

Sie können eine SDL_Surface * mit in SDL_Texture konvertieren

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

Danach sollte die SDL_Surface mit freigegeben werden

SDL_FreeSurface( SDL_Surface* surface )

Ein weiterer wichtiger Unterschied besteht darin, dass SDL_SurfaceSoftware-Rendering (über die CPU) und SDL_TextureHardware-Rendering (über die GPU) verwendet werden.


SDL_Rect

Die einfachste Struktur in SDL. Es enthält nur vier Shorts. x, ywelches die Position hält und w, hwelches Breite und Höhe hält.

Es ist wichtig zu beachten, dass dies 0, 0die obere linke Ecke in SDL ist. Ein höherer yWert bedeutet also niedriger, und die untere rechte Ecke hat die Koordinatex + w, y + h


Sie können mehr über SDL2 in meinem Blog lesen .

Olevegard
quelle
1
Wenn Sie also SDL_RenderPresent aufrufen, nehmen Sie diesen Renderer mit all seinen Einstellungen und Texturen, die hochgeladen wurden, und lassen Sie diese Informationen in dem Fenster rendern, an das er gebunden ist?
Prcastro
3
@olevegard, tolle Antwort. Um den Unterschied zwischen SDL_Texture und SDL_Surface zu verdeutlichen, möchte ich betonen, dass SDL_Texture mithilfe der GPU gerendert wird und SDL_Surface Software-Redering verwendet, das weniger effizient ist, aber die Pixelinformationen frei manipulieren lässt. Auch tolles Blog, ich werde es sicher lesen :)
Fabio Picchi
Die Aussage "Dadurch wird das Rendering-Ziel mit der oben festgelegten Zeichenfarbe gelöscht" ist meines Erachtens korrekt, aber ich kann den Ausdruck "Löscht" in der Anweisung nicht verstehen. Das Dokument verwendet immer diesen Ausdruck. Könnten Sie bitte erklären, was genau "klar" hier bedeutet? Bedeutet es "malen" (Art) mit der aktuellen Zeichenfarbe des Renderers?
Nawaz
Gibt es einen Grund zu verwenden , SDL_Surfaceüber SDL_Renderer?
Stevoisiak
Die Top-Antwort hat einige Ungenauigkeiten, SDL_Renderer kann auch an die Oberfläche gebunden werden, nicht nur an das Fenster. Bitte überprüfen Sie den Link: wiki.libsdl.org/SDL_CreateSoftwareRenderer
dmitro
9

Stellen Sie sich SDL_Windowphysische Pixel SDL_Rendererund einen Ort zum Speichern von Einstellungen / Kontexten vor.

Sie erstellen also eine Reihe von Ressourcen und hängen sie an den Renderer. Wenn es fertig ist, weisen Sie den Renderer an, alles zusammenzusetzen und die Ergebnisse an das Fenster zu senden.

Woolstar
quelle