我的OpenGL应用程序使用OpenGL以全屏模式渲染纹理,并定期更新部分纹理。到目前为止,我一直在使用glTexImage2D来推送我的初始纹理,然后用glTexSubImage2D更新脏区域。要做到这一点,我正在使用单缓冲。这很有效。
我已经看到使用CVOpenGLESTextureCache可能有另一种方法来实现相同的功能。纹理缓存中保存的纹理引用CVPixelBuffer。我想知道我是否可以改变这些缓存的纹理。我尝试为每次更新重新创建一个CVOpenGLESTexture,但这会大大降低我的帧速率(毕竟因为我没有在任何地方指定脏区域,所以并不奇怪)。也许我完全误解了这个纹理缓存的用例。
有人可以提供一些指导吗?
更新:这是我正在使用的代码。第一次更新工作正常。后续更新不会(没有任何反应)。在每次更新之间,我修改了原始位图。
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;
答案 0 :(得分:1)
我一直在使用这些纹理API进行相当多的黑客攻击,我终于能够使用纹理缓存API生成一个通过内存写入纹理的工作示例。这些API可以在iOS设备上运行,但不能在模拟器上运行,因此需要一个特殊的解决方法(基本上只是在模拟器中显式调用glTexSubImage2D())。代码需要双重缓冲在另一个线程中完成的纹理加载,以避免在渲染进行时进行更新。完整的源代码和时序结果为opengl_write_texture_cache。链接的Xcode项目从PNG解码,因此旧iPhone硬件上的性能有点差。但是代码可以自由地做任何你想做的事情,所以不应该很难适应其他像素源。要只写一个脏区域,只写入后台线程中内存缓冲区的那一部分。