2010-08-02 8 views
10

Estoy generando una imagen usando cuarzo 2d y quiero usarlo como una textura opengl. La parte difícil es que quiero utilizar el menor número de bits por píxel como sea posible, por lo que estoy creando cgContext la siguiente manera:Uso de una imagen creada con CGBitmapContextCreate como una textura opengl

int bitsPerComponent = 5; 
int bytesPerPixel = 2; 
int width = 1024; 
int height = 1024; 
void* imageData = malloc(width * height * bytesPerPixel); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGImageContext context = CGBitmapContextCreate(imageData, width, height, bitsPerComponent, width * bytesPerPixel, colorSpace, kCGImageAlphaNoneSkipFirst); 
//draw things into context, release memory, etc. 

Como se indica en la documentación here, este es el formato de píxeles RGB sólo está soportado por CGBitmapContextCreate que usa 16 bits por píxel. Así que ahora quiero subir esta propiedad imageData que se parece a "1 bit saltado - 5 bits de color rojo - verde 5 bits - 5 bits azul" en una textura de OpenGL. Por lo que debería hacer algo como esto:

glGenTextures(1, &texture); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, imageData); 

que no funciona debido a que en esta llamada he especificado el formato de píxel como "5 rojo - verde 5 - 5 azules - 1 alfa". Eso está mal, pero parece que no hay un formato que coincida con la salida de gráficos centrales.
hay algunas otras opciones como GL_UNSIGNED_SHORT_1_5_5_5_REV, pero los que no trabajará en el iPhone.

Necesito alguna forma de utilizar este imageData como una textura, pero realmente no quiero intercambiar bytes manualmente utilizando memset o similar, porque eso parece terriblemente ineficiente.

+0

Por qué la preocupación por 5 bits por píxel? ¿Por qué no simplemente tener su contexto es lo que funciona más fácilmente para OpenGL y si sus imágenes de origen son diferentes, permita que el cuarzo realice la conversión cuando lo atraiga a su contexto? Tengo todo tipo de texturas dinámicas en mi juego y nunca tuve estos problemas. – badweasel

+0

He creado esta pregunta en 2010, cuando todavía estábamos soportando 2g deivces. 2g y 3g tenían muy poca memoria, y la aplicación no era un juego, era un lector de libros electrónicos. Tuvimos que usar al menos 10MB de datos solo para nuestro motor de análisis/diseño/estilo de texto, y cada pequeño bit de bytes era vital. No estoy seguro de que alguien tenga que usar esto en 2012, pero tal vez todavía hay aplicaciones que se eliminan con la advertencia de memmory y quieren reducir la huella de memmory. – Alexey

+0

@Alexey: ¿Puede informarnos cuál es la resolución de los datos de imagen que está cargando para la textura? – 8Ours

Respuesta

2

Necesita intercambiar bits para obtener un formato más denso como RGBA551 o RGB565, ya que como observará, CGBitmapContext no admite estos formatos para dibujar (por simplicidad y eficiencia).

memset no va a dar el paso, pero hay rutinas de conversión "rápidas" en Accelerate.framework.

Consulte vImageConvert_ARGB8888toRGB565(…) y vImageConvert_ARGB8888toARGB1555(…), disponible en iOS 5 y posterior.

1

Para iOS 7.0, X.9 OS y después:

vImage_CGImageFormat fmt = { 
    .bitsPerComponent = 5, 
    .bitsPerPixel = 16, 
    .colorSpace = NULL, // faster with CGImageGetColorSpace(cgImage) if known to be RGB 
    .bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder16Little // ARGB1555 little endian 
}; 
vImage_Buffer buf; 
vImageBuffer_InitWithCGImage(&buf, &fmt, NULL, cgImage, kvImageNoFlags); 

...

free(buf.data); 

datos están en buf.data, junto con la altura de la imagen, el ancho y rowBytes información. No recuerdo cuáles son los requisitos de GL para si se permite el relleno de filas. Puede controlar eso al asignar previamente los campos buf.data y buf.rowBytes y pasar kvImageDoNotAllocate en los indicadores.

565_REV es kCGImageAlphaNone | kCGBitmapByteOrder16Little. 5551_REV es kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder16Little

Cuestiones relacionadas