代码之家  ›  专栏  ›  技术社区  ›  Alexey

使用CGBitmapContextCreate创建的图像作为opengl纹理

  •  10
  • Alexey  · 技术社区  · 14 年前

    我正在用 quartz2d 我想用它作为 opengl 棘手的是,我希望每个像素使用尽可能少的位,所以我正在创建 cgContext

    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.
    

    如文件所述 here RGB 像素格式 CGBitmapContextCreate 所以现在我想把这个看起来像“1位跳过-5位红色-5位绿色-5位蓝色”的图像数据上传到opengl纹理中。所以我应该这样做:

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

    这不起作用,因为在这个调用中,我将像素格式指定为 5 red - 5 green - 5 blue - 1 alpha . 这是错误的,但似乎没有与核心图形输出匹配的格式。
    还有其他一些选择,比如 GL_UNSIGNED_SHORT_1_5_5_5_REV ,但这些不会在 iphone .

    imageData 作为一个纹理,但是我真的不想使用memset之类的工具来手动交换字节,因为这看起来非常低效。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Andrew Pouliot    12 年前

    您确实需要交换位来将其转换为更密集的格式,如RGBA551或RGB565,因为正如您所注意到的,CGBitmapContext不支持这些格式来绘制(为了简单和高效)。

    memset 不会成功的,但是在 Accelerate.framework .

    vImageConvert_ARGB8888toRGB565(…) vImageConvert_ARGB8888toARGB1555(…) ,可在iOS 5及更高版本上使用。

        2
  •  1
  •   Ian Ollmann    11 年前

    对于iOS 7.0、OS X.9及更高版本:

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

    数据在buf.Data中,还有图像高度、宽度和行字节信息。我不记得德国劳埃德船级社对是否允许行填充有什么要求。您可以通过预先分配buf.data和buf.rowBytes字段并在标志中传递kvImageDoNotAllocate来控制这一点。

    565_REV是kCGImageAlphaNone | kCGBitmapByteOrder16Little。