Comment charger des textures avec SFML pour OpenGL?

Réponses:

16

Bienvenue chez OpenGL, où les choses rapides sont gratuites et les choses faciles rendues difficiles.

Si vous pensiez que cet échantillon était long et compliqué, "juste pour charger une texture", alors vous n'avez encore rien vu. Attendez d'avoir à charger des textures DDS, à traiter des textures HDR, à prendre en charge les cubemaps, à effectuer un rendu sur une texture, etc.

Le chargement d'une texture dans OpenGL comprend deux composants:

  • Obtenir les données de votre format d'image. Vous pouvez charger une texture à partir d'un fichier ou la générer de manière procédurale. Peu importe, tant que vous vous retrouvez avec une belle gamme d'informations sur les couleurs.

  • Mettre les données sur la carte vidéo. Les données doivent passer de la RAM système à la RAM vidéo.

La première partie devrait être facile, car SFML est livré avec un chargeur d'image standard.

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

Ensuite, nous devrons générer un objet de texture OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Il existe un certain nombre de choix pour lier une texture. Il existe trois types principaux: 1D, 2D et 3D et vous avez la prise en charge des cubemaps (+ X, -X, + Y, -Y, + Z, -Z). Cependant, dans 99% des cas, vous souhaiterez une texture 2D.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Nous arrivons maintenant à la partie intéressante. Importons nos données sur la carte vidéo.

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

Enfin, nous pouvons définir un certain nombre de paramètres de texture. Ces réponses répondent à des questions comme: que se passe-t-il si nous utilisons une coordonnée de texture qui est en dehors de la plage (0,0, 1,0)? Enveloppons-nous ( GL_REPEAT) ou ne faisons-nous rien ( GL_CLAMP)? Ils peuvent également être utilisés pour expliquer à la carte vidéo que nous voulons utiliser l'interpolation linéaire sur nos textures.

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);

Et maintenant, vous devriez pouvoir lier votre texture à l'aide glBindTextureet l'utiliser pour dessiner des maillages texturés.

chevalier666
la source
mmm, j'ai essayé de le faire et tout ce que j'obtiens est un cube blanc: pastebin.com/nVQFAMRJ
Darestium
Essayez de mettre glEnable(GL_TEXTURE2D);la fonction init.
knight666
Génial, ça marche! Merci! BTW, que fait cette fonction? Activer la texturation?
Darestium
Oui, il active l'objet de texture 2D, afin qu'il puisse recevoir des données de texture. Vous ne devez l'activer qu'une seule fois lors de l'initialisation, mais il est souvent oublié lors de la copie de code dans un nouveau projet. Moi-même inclus. ;)
knight666
Très belle explication. Vous pourriez écrire des tutoriels!
danijar
2

SFML 2.0+ facilite encore plus le chargement d'une texture;

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
la source