Para entender lo que hace glTexStorage
, debe comprender lo que hacen las funciones glTexImage*
.
glTexImage2D
hace tres cosas:
- Se asigna almacenamiento OpenGL para una capa específica mipmap, con un tamaño específico. Por ejemplo, puede asignar una imagen 2D de 64x64 como nivel de mipmap 2.
- Establece el formato interno para el nivel de mipmap.
- Carga datos de píxeles a la textura. El último paso es opcional; si pasa NULL como valor de puntero (y ningún objeto de búfer está vinculado a
GL_PIXEL_UNPACK_BUFFER
), no se produce ninguna transferencia de píxeles.
La creación manual de una textura mipmapped requiere una secuencia de llamadas glTexImage
, una para cada nivel de mipmap. Cada uno de los tamaños de los niveles de mipmap debe tener el tamaño adecuado en función del tamaño del nivel anterior.
Ahora, si mira la sección 3.9.14 de la especificación GL 4.2, verá dos páginas de reglas que un objeto de textura debe seguir para ser "completo". No se puede acceder a un objeto de textura incompleto.
Entre esas reglas se encuentran cosas como "los mipmaps deben tener el tamaño apropiado". Tomemos el ejemplo que di más arriba: una imagen 2D de 64x64, que es el nivel 2 de mipmap. Sería código OpenGL perfectamente válido para asignar un nivel 1 de mipmap que usaba una textura de 256x256. O un 16x16. O un 10x345. Todos ellos serían perfectamente funcionales en lo que respecta al código fuente. Obviamente, producirían tonterías como textura, ya que la textura sería incompleta.
Consideremos nuevamente el mapa mip 64x64 2. Lo creo como mi primera imagen. Ahora, yo podría crear un 128x128 mipmap 1. Pero podría también crear una 128x12 mipmap 1. Ambos son completamente consistentes con el nivel de 64x64 mipmap 2 (tamaños mipmap siempre redondeando hacia abajo).Si bien ambos son consistentes, también son diferentes tamaños. Si un controlador tiene que asignar la cadena completa de mipmap de una vez (lo cual es totalmente posible), ¿qué tamaño asigna? No sabe. No puede saber hasta que asignas explícitamente el resto.
Aquí hay otro problema. Digamos que tengo una textura con una cadena completa de mipmap. Está completamente texturado, de acuerdo con las reglas. Y luego llamo al glTexImage2D
de nuevo. ¿Ahora que? Podría cambiar accidentalmente el formato interno. Cada nivel de mipmap tiene un formato interno separado; si no todos están de acuerdo, entonces la textura está incompleta. Podría cambiar accidentalmente el tamaño de la textura, volviendo a hacer la textura incompleta.
glTexStorage
previene todos estos posibles errores. Crea todos los mipmaps que desee por adelantado, dado el tamaño del nivel base. Asigna todos los mipmaps con el mismo formato de imagen, por lo que no se puede arruinar. Hace que la textura sea inmutable, por lo que no puede venir y tratar de romper la textura con una mala llamada glTexImage2D
. Y previene otros errores que ni siquiera me molesté en cubrir.
La pregunta no es "¿qué hace glTexStorage?" La pregunta es "¿por qué vamos tan largo sin".
glTexStorage
no tiene relación con glGenerateMipmap
; son funcionalidad ortogonal. glTexStorage
hace exactamente lo que dice: asigna textura espacio de almacenamiento. No llena ese espacio con nada. Por lo tanto, crea una textura con un tamaño dado lleno de datos no inicializados. Al igual que glRenderbufferStorage
, asigna un buffer de representación con un tamaño dado lleno de datos no inicializados. Si usa glTexStorage
, debe cargar datos con glTexSubImage
(ya que glTexImage
está prohibido en una textura inmutable).
glTexStorage
crea espacio para mipmaps. glGenerateMipmap
crea los datos mipmap en sí (las versiones más pequeñas de la capa base). También puede crear espacio para mipmaps si ese espacio no existe. Se usan para dos cosas diferentes.
"solo disponible en 4.2" Está disponible en la extensión ARB_texture_storage, que está ampliamente disponible (o lo estará pronto). NVIDIA lo admite en todo lo que se remonta a la GeForce 6600, y AMD lo admite en todo el hardware de clase HD. Dejando de lado los errores, debes usarlos siempre que sea posible. –
Dado que la lista de comentarios sobre la respuesta es tan larga, la pondré aquí. Afortunadamente, en el hardware de Apple, la extensión correspondiente 'EXT_texture_storage' es compatible con" todos los procesadores SGX Series 5 ", y también señalaré que' glTexStorage' está en el núcleo GL ES 3.0. –