4

我一直在为 iPhone 渲染定期更新的图像时遇到严重的性能问题。今天在 iPad 3 上试用后,我发现我只有 2fps。这太慢了。因此,我决定分析并发现几乎所有时间都用于将图像转换为 32 位 ARGB 图像(在 UIImage drawInRect 之后)。鉴于每个人都说 UIKit 使用 OpenGLES 渲染,我对性能如此糟糕感到非常震惊。

所以我将渲染代码转换为 GLES1(我懒得在 mo 处设置 GLES2 渲染器;))。性能已经飙升。我现在得到20 + fps。事实上,性能非常好,我开始怀疑我是否可以执行完整的视网膜渲染!

无论如何,我正在创建如下纹理:

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

不幸的是,这颠倒了组件顺序。我通过从以下位置反转位顺序来“修复”它:

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

到:

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

所以这证实了组件顺序在 CGImage 上是颠倒的。但是,此代码用于多种产品,因此我需要想出一种加载“组件反转”图像的方法。

因此,我找到了“GL_UNSIGNED_SHORT_1_5_5_5_REV”标志,但我无法让它工作。

我试过以下代码:

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

和:

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

但两者都返回给我 GL_INVALID_ENUM。那么我做错了什么?甚至可以加载组件反转图像吗?

提前致谢!

编辑:在此期间,我引入了另一个像素类,然后添加了以下代码:

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

所以我现在有了正确的渲染,但我试图避免这种颜色转换。在使用 GL 渲染时,我可能只是以该格式创建源图像,但令人讨厌的是我无法直接加载该格式:(

4

2 回答 2

3

GL_UNSIGNED_SHORT_1_5_5_5_REV 不起作用的原因是它不是纹理格式,尽管这在 iOS 上非常有用。1555 16b 格式是 GL_EXT_read_format_bgra 扩展的一部分(参见定义它的 #ifdef 块),它只为 glReadPixels 定义了这个枚举,不幸的是,不是 glTexImage2D:

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

这很烦人。iOS 将其 16b 缩略图存储在 A1B5G5R5 中,CGBitmapContext 也支持 A1B5G5R5 渲染,但 OpenGL ES 在 iOS 上仅支持 R5G5B5A1 (5551)。AFAIK,没有办法直接下载使用 16b 5551 的 ALAsset 缩略图。

于 2013-09-24T02:47:11.337 回答
1

UIKit 不使用 OpenGL ES 进行渲染,它只是将结果缓存在 OpenGL ES 纹理中以进行合成和转换。矢量的绘制仍然受 CPU 限制,因此在升级到 Retina 显示器时必须将光栅化的像素数量增加四倍会减慢速度。

我不太确定您要做什么,但听起来您想将 BGRA 数据上传到您的 OpenGL ES 纹理中。在这种情况下,您需要执行以下操作:

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

现在,我在这里做一个完整的每像素 32 字节的 RGBA 纹理,而不是你尝试的更紧凑的纹理,因为我希望纹理中的颜色保真度更高。我没有尝试过,但我相信您也可以使用更紧凑的颜色格式。

于 2012-11-03T23:12:32.473 回答