Texturas en OpenGL

Este tutorial agrega un elemento con el que se podría dar por terminado la especificación clásica de OpenGL, se trata de texturas, un tema que acompaña aun desde sus origines 2d a los gráficos por computadora. Para el caso de este tutorial se mostraran las diferentes propiedades y funcionalidades asociadas al manejo de texturas en OpenGL.

Existen cuatro tipos básicos de texturas en OpenGL GL_TEXTURE_1D, GL_TEXTURE _2D , GL_TEXTURE _3D y GL_TEXTURE_CUBE_MAP. Al igual que con iluminación, culling y otras propiedades, el texturizado puede ser activado y desactivado via glEnable() y glDisable(), utilizando cualquiera de los cuatro tipos de textura. Para los propósitos de este tutorial se tratará con las texturas bidimensionales, debido a que en principio es la más utilizada.

Se puede decir que para mostrar una textura en OpenGL hay que hacer cuatro cosas básicas:

  1. Cargar la textura desde algún lugar de almacenamiento, lo que implica leerla desde algún tipo de formato (png, bmp, jpg, gif, etc) y ponerla en memoria.
  2. Configurar las características de presentación de la textura, es decir, como OpenGL debe interpretarla y mostrarla.
  3. Generar un objeto-textura y con esto es necesario obtener un identificador para ésta.
  4. Asociar la textura a una o varias primitivas, especificando para cada caso la forma en que debe ser mapeada.

Debido a la gran variedad de formatos existentes y a la cantidad de posibilidades que tiene cada uno (compresión, profundidad de color, transparencia, paleta, etc), es dispendioso realizar un cargador funcional para videojuegos. Por suerte muchas personas ya han realizado el trabajo duro =) , por lo que basta a acudir a uno de los tantos proyectos Open Source para obtener cargadores de calidad libres de costos por licenciamiento.

Una vez la textura ha pasado del disco a memoria es necesario suministrar estos datos al API mediante la función:

void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data);

Los parámetros de la función son:

  • target: indica el tipo de textura a utilizar.
  • level: Indica el nivel de mipmap que se está cargando, el parámetro 0 corresponde a no utilizar mipmaps.
  • internalformat: Formato interno de la información suministrada en data.
  • width: El ancho en pixeles de la textura.
  • height: La altura en pixeles de la textura.
  • border: Cantidad de pixeles a agregar horizontal y verticalmente en los bordes de la imagen.
  • format: Formato de información que representan los datos.
  • type: Tipo de representados, indica el tamaño de cada componente de color, transparencia y/o luminancia.
  • data: Es el contenido de la imagen.

Dentro de los tipos posibles a utilizar como target se encuentran:

  • GL_TEXTURE_2D
  • GL_TEXTURE_PROXY_2D
  • GL_TEXTURE_PROXY_CUBE_MAP

O alguna de las seis caras del cube map

  • GL_TEXTURE_CUBE_MAP_POSITIVE_X
  • GL_TEXTURE_CUBE_MAP_POSITIVE_Y
  • GL_TEXTURE_CUBE_MAP_POSITIVE_Z
  • GL_TEXTURE_CUBE_MAP_NEGATIVE_X
  • GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
  • GL_TEXTURE_CUBE_MAP_NEGATIVE_Z

Adicionalmente a estos el soporte para manejar texturas con compresión es proveído mediante el mecanismo de extensiones, para interpretar formatos particulares. Mediante la función glCompressedTexImage2D() se puede crear la textura gl, que posee los mismos parámetros de la función sin compresión, excepto por el format que no se encuentra y que data debe apuntar a un bloque de memoria que representa la imagen con la compresión correspondiente a internalformat.

Esta tabla muestra los valores más comunes de internalformat utilizados, denominados formatos internos base:

Formato Interno Valores Tomados Valores
GL_ALPHA A Transparencia
GL_DEPTH_COMPONENT Depth Profundidad
GL_LUMINANCE R Luminosidad
GL_LUMINANCE_ALPHA R,A Luminosidad y trasparencia
GL_INTENSITY R Intensidad
GL_RGB R,G,B Red, Green, Blue (rojo, verde y azul)
GL_RGBA R,G,B,A Red, Green, Blue, Alpha (rojo, verde, azul y transparencia)

Existe una extensa tabla que muestra todos los posibles valores de bits para cada una de las combinaciones entre los diferentes formatos base, por ejemplo GL_RGB8 que indica que las componentes tendrán R-8 bits G-8 bits y B-8 bits. Esta tabla puede ser consultada en la glSpec 2.1 p. 154 -155. También se encuentra en estas los formatos genéricos de texturas con compresión internos.

Mipmaps: Un problema en los principios de la computación gráfica en tiempo real, especialmente en los videojuegos era la “pixelación” de las texturas a medida que un observador se acercaba a una primitiva texturizada. En principio esto se puede solucionar utilizando texturas de alta resolución, pero estas a su vez crean el inconveniente de requerir mayor tiempo de procesamiento y espacio en memoria utilizar este tipo de texturas.

La solución (parcial) entonces es utilizar mipmaps, que básicamente son versiones escaladas de una misma textura que se mantienen en memoria, con el fin de cambiar a texturas más pequeñas (baja resolución) cuando la vista del usuario está lejos del objeto texturizado y a mas altas resoluciones cuando este se encuentra cerca, evitando así la pixelación y los usos altos de procesamiento, pero consumiendo mas memoria, aproximadamente un tercio más que con la imagen de más alta resolución únicamente.

Mipmaps OpenGL

La imagen muestra una serie de mipmaps desde la textura con mas resolución hasta la textura con menor resolución. Los mipmaps deben ser alimentados manualmente cambiando el parámetro level en glTexImage2d(), aunque glu también posee una utilidad para crearlos automáticamente mediante gluBuildMipmaps().

1 2 3

Compartir esta entrada

DiggReddit