在iOS上的CVOpenGLESTextureCache vs glTexSubImage2D

我的OpenGL应用程序使用OpenGL来全屏渲染纹理,并定期更新其中的一部分。 到目前为止,我一直在使用glTexImage2D推我的初始纹理,然后我用glTexSubImage2D更新脏区域。 要做到这一点,我使用单缓冲。 这很好。

我已经看到,可能有另一种方法来使用CVOpenGLESTextureCache实现相同的事情。 保存在纹理caching中的纹理引用一个CVPixelBuffer。 我想知道是否可以改变这些caching的纹理。 我试图为每个更新重新创build一个CVOpenGLESTexture,但这大大降低了我的帧速率(不要惊讶,因为我没有指定脏区域)。 也许我完全误解了这个纹理caching的用例。

有人可以提供一些指导?

更新:这是我正在使用的代码。 第一次更新工作正常。 后续更新不(没有发生)。 每次更新之间我修改原始位图。

if (firstUpdate) { CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, ctx, NULL, &texCache); CVPixelBufferRef pixelBuffer; CVPixelBufferCreateWithBytes(NULL, width_, height_, kCVPixelFormatType_32BGRA, bitmap, width_*4, NULL, 0, NULL, &pixelBuffer); CVPixelBufferLockBaseAddress(pixelBuffer, 0); CVOpenGLESTextureRef texture = NULL; CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, texCache, pixelBuffer, NULL, GL_TEXTURE_2D, GL_RGBA, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, 0, &texture); texture_[0] = CVOpenGLESTextureGetName(texture); CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); } CVOpenGLESTextureCacheFlush(texCache, 0); if (firstUpdate) { glBindTexture(GL_TEXTURE_2D, texture_[0]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); if (firstUpdate) { static const float textureVertices[] = { -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0 }; static const float textureCoords[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0 }; glVertexPointer(2, GL_FLOAT, 0, &textureVertices[0]); glTexCoordPointer(2, GL_FLOAT, 0, textureCoords); } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); firstUpdate = false; 

我已经用这些纹理API进行了相当多的黑客攻击,并且最终能够生成一个使用纹理cachingAPI通过内存写入纹理的工作示例。 这些API可以在iOS设备上工作,但不能在模拟器上工作,所以需要特殊的解决方法(基本上只是在模拟器中显式调用glTexSubImage2D())。 代码需要加倍缓冲在另一个线程中完成的纹理加载,以避免在渲染过程中进行更新。 完整的源代码和时间结果在opengl_write_texture_cache 。 链接的Xcode项目从PNG中解码,因此旧版iPhone硬件的性能稍差。 但是代码可以自由地做任何你想要的,所以它不应该很难适应其他像素源。 要仅写入一个脏区域,只能在后台线程中写入内存缓冲区的那一部分。