Wie lade ich Texturen mit SFML für OpenGL?

Antworten:

16

Willkommen bei OpenGL, wo die schnellen Dinge kostenlos sind und die einfachen Dinge schwer gemacht werden.

Wenn Sie dachten, dass das Beispiel lang und kompliziert ist, "nur um eine Textur zu laden", dann haben Sie noch nichts gesehen. Warten Sie, bis Sie DDS-Texturen laden, HDR-Texturen verarbeiten, Cubemaps unterstützen, in eine Textur rendern usw. müssen.

Das Laden einer Textur in OpenGL besteht aus zwei Komponenten:

  • Abrufen der Daten aus Ihrem Bildformat. Sie können eine Textur aus einer Datei laden oder prozedural generieren. Es spielt keine Rolle, solange Sie eine schöne Reihe von Farbinformationen erhalten.

  • Daten auf die Videokarte legen. Die Daten müssen vom System-RAM zum Video-RAM wechseln.

Der erste Teil sollte einfach sein, da SFML mit einem Standard-Image-Loader geliefert wird.

sf::Image img_data;
if (!img_data.LoadFromFile("images/avatar.png"))
{
    LOG_ERROR("Could not load '%s'.", "images/avatar.png");
    return false;
}

Als nächstes müssen wir ein OpenGL-Texturobjekt generieren.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Es gibt eine Reihe von Möglichkeiten, eine Textur zu binden. Es gibt die drei Haupttypen: 1D, 2D und 3D, und Sie unterstützen Cubemaps (+ X, -X, + Y, -Y, + Z, -Z). In 99% der Fälle möchten Sie jedoch eine 2D-Textur.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Nun kommen wir zum interessanten Teil. Laden wir unsere Daten auf die Grafikkarte hoch.

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA,
    img_data.GetWidth(), img_data.GetHeight(),
    0,
    GL_RGBA, GL_UNSIGNED_BYTE, img_data.GetPixelsPtr()
);

Schließlich können wir eine Reihe von Texturparametern einstellen. Diese beantworten Fragen wie: Was ist, wenn wir eine Texturkoordinate verwenden, die außerhalb des Bereichs (0.0, 1.0) liegt? Wickeln wir uns um ( GL_REPEAT) oder tun wir nichts ( GL_CLAMP)? Sie können auch verwendet werden, um der Videokarte zu erklären, dass wir für unsere Texturen eine lineare Interpolation verwenden möchten.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

Und jetzt sollten Sie in der Lage sein, Ihre Textur zu binden glBindTextureund damit strukturierte Netze zu zeichnen.

Ritter666
quelle
mmm, ich versuchte , so zu tun und alles , was ich bekommen ist ein weißer Würfel: pastebin.com/nVQFAMRJ
Darestium
Versuchen Sie, glEnable(GL_TEXTURE2D);die Init-Funktion einzufügen.
Knight666
Super, funktioniert! Vielen Dank! Übrigens, was macht diese Funktion? Texturierung aktivieren?
Darestium
Ja, das 2D-Texturobjekt wird aktiviert, sodass Texturdaten empfangen werden können. Sie müssen es bei der Initialisierung nur einmal aktivieren, es wird jedoch häufig vergessen, wenn Sie Code in ein neues Projekt kopieren. Mich eingenommen. ;)
Knight666
Sehr schöne Erklärung. Sie könnten Tutorials schreiben!
Danijar
2

SFML 2.0+ macht das Laden einer Textur noch einfacher.

sf::Texture texLid;
std::string image2="images/top.jpg";
if (!texLid.loadFromFile(image2))
{
    std::cout << "Could not load" << image2;
    char c;
    std::cin>>c;
    return false;
}


glEnable(GL_TEXTURE_2D);//tell OpenGL to use textures when drawing

sf::Texture::bind(&texLid);//select this texture for OpenGL rendering
Ken
quelle