Usando GL_UNSIGNED_SHORT_1_5_5_5_REV en iPhone

He estado sufriendo graves problemas de performance que brindan una image actualizada regularmente al iPhone. Después de probarlo en el iPad 3 hoy me enteré de que solo obtuve 2 fps. Esto fue WAAAY muy lento. Como tal, decidí hacer un perfil y descubrí que casi todo el time se había invertido convirtiendo la image en una image ARGB de 32 bits (después del UIImage drawInRect). Estoy muy sorprendido de lo horrible que es el performance de todo el mundo dice que UIKit se utiliza con OpenGLES.

Así que convertí el código de representación a GLES1 (no me molesta en configurar un renderizador GLES2 en el mo;)). El performance se ha disparado. Ahora obtengo 20 + fps. De hecho, el performance es tan bueno que estoy empezando a preguntarme si puedo realizar una renderización completa de la retina.

De todos modos estoy creando la textura de la siguiente manera:

glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, &colours.front() ); 

Desafortunadamente esto invierte el order de los componentes. Lo he "arreglado" invirtiendo el order de bits de:

 val = ((rgba.a >> 7) << 15) | ((rgba.b >> 3) << 10) | ((rgba.g >> 3) << 5) | ((rgba.r >> 3) << 0); 

a:

 val = ((rgba.r >> 3) << 11) | ((rgba.g >> 3) << 6) | ((rgba.b >> 3) << 1) | ((rgba.a >> 7) << 0); 

Entonces, esto confirma que el order de los componentes se invierte sobre CGImage. Sin embargo, este código se utiliza en varios productos, así que necesito encontrar una forma de cargar la image "componente invertido".

Como tal, encontré la bandera "GL_UNSIGNED_SHORT_1_5_5_5_REV", pero no puedo hacer que funcione.

He probado el siguiente código:

 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, &colours.front() ); 

y:

 glTexImage2D( GL_TEXTURE_2D, 0, GL_BGRA, width, height, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, &colours.front() ); 

pero ambos me devuelven GL_INVALID_ENUM. Entonces, ¿qué estoy haciendo mal? ¿Es posible cargar las imágenes invertidas de los componentes?

¡Gracias por adelantado!

editar : Mientras tanto, he introducido YET otra class de píxeles y luego agregué el siguiente código:

 inline uint32_t UpdateGLTexture( uint32_t texture, std::vector< R5G5B5A1 >& colours, unsigned int width, unsigned int height ) { std::vector< A1R5G5B5 > convertedColours( colours.size() ); ColourSpaceConversion::ConvertFormat( convertedColours, colours ); return UpdateGLTexture( texture, convertedColours, width, height ); } 

Así que ahora tengo una representación correcta, pero trato de evitar este tipo de conversiones de color. Es posible que solo cree la image de origen en ese formatting cuando se utiliza la representación de GL pero es molesto que no pueda cargar el formatting directamente 🙁

La razón GL_UNSIGNED_SHORT_1_5_5_5_REV no funciona es porque no es un formatting de textura, aunque sería muy útil en iOS. El formatting 1555 16b es parte de la extensión GL_EXT_read_format_bgra (vea el bloque #defdef donde está definido), que define esta enumeración solo para glReadPixels, no glTexImage2D por desgracia:

http://www.khronos.org/registry/gles/extensions/EXT/EXT_read_format_bgra.txt

Esto es molesto. iOS almacena sus miniaturas 16b en A1B5G5R5, y CGBitmapContext también admite la prestación A1B5G5R5, pero OpenGL ES solo admite R5G5B5A1 (5551) en iOS. AFAIK, no hay forma de download directamente las miniaturas de ALAsset que usan 16b 5551.

UIKit no representa usando OpenGL ES, simplemente almacena en caching el resultado en una textura OpenGL ES para la composition y las transformaciones. El dibujo de los vectores sigue estando vinculado a la CPU, por lo que cuadruplicar el número de píxeles que tiene que rasterizar cuando se sube a la pantalla de Retina networkingucirá la velocidad de las cosas.

No estoy muy seguro de qué estás tratando de hacer, pero parece que quieres upload datos de BGRA a tu textura de OpenGL ES. En ese caso, querrás hacer algo como lo siguiente:

 glGenTextures(1, &outputTexture); glBindTexture(GL_TEXTURE_2D, outputTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData); 

Ahora, estoy haciendo una textura completa RGBA de 32 bytes por píxel aquí, no la más compacta que intentas allí, porque quería ese poco de fidelidad de color en la textura. No lo he intentado, pero creo que también puedes usar lo anterior con un formatting de color más compacto.