¿Cómo cargo texturas con SFML para OpenGL?

Respuestas:

16

Bienvenido a OpenGL, donde las cosas rápidas son gratis y las cosas fáciles se hacen difíciles.

Si pensabas que la muestra era larga y complicada, "solo por cargar una textura", entonces todavía no has visto nada. Espere hasta que tenga que cargar texturas DDS, procesar texturas HDR, admitir mapas de cubos, renderizar a una textura, etc.

La carga de una textura en OpenGL consta de dos componentes:

  • Obteniendo los datos de su formato de imagen. Puede cargar una textura desde un archivo o generarla procesalmente. No importa, siempre y cuando termines con una buena variedad de información de color.

  • Poner los datos en la tarjeta de video. Los datos deben pasar de la RAM del sistema a la RAM de video.

La primera parte debería ser fácil, porque SFML viene con un cargador de imágenes estándar.

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

A continuación, tendremos que generar un objeto de textura OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Hay varias opciones para unir una textura. Existen los tres tipos principales: 1D, 2D y 3D y tiene soporte para cubemaps (+ X, -X, + Y, -Y, + Z, -Z). Sin embargo, en el 99% de los casos, querrás una textura 2D.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Ahora llegamos a la parte interesante. Subamos nuestros datos a la tarjeta de video.

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

Finalmente, podemos establecer una serie de parámetros de textura. Estas preguntas responden como: ¿qué pasa si usamos una coordenada de textura que está fuera del rango (0.0, 1.0)? ¿Nos envolvemos ( GL_REPEAT) o no hacemos nada ( GL_CLAMP)? También se pueden usar para explicar a la tarjeta de video que queremos usar interpolación lineal en nuestras texturas.

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

Y ahora deberías poder unir tu textura usando glBindTexturey usarla para dibujar mallas texturizadas.

caballero666
fuente
mmm, intenté hacerlo y todo lo que obtengo es un cubo blanco: pastebin.com/nVQFAMRJ
Darestium
Intenta poner glEnable(GL_TEXTURE2D);en la función init.
knight666
Impresionante, funciona! ¡Gracias! Por cierto, ¿qué hace esa función? ¿Habilitar texturizado?
Darestium
Sí, activa el objeto de textura 2D, por lo que puede recibir datos de textura. Solo tiene que habilitarlo una vez en la inicialización, pero a menudo se olvida al copiar código en un nuevo proyecto. Yo incluido ;)
knight666
Muy buena explicación. ¡Podrías escribir tutoriales!
danijar
2

SFML 2.0+ hace que sea aún más fácil cargar una textura;

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
Conocer
fuente