CVOpenGLESTextureCache vs glTexSubImage2D no iOS
Meu aplicativo OpenGL usa o OpenGL para renderizar uma textura em tela cheia e atualiza parte dela em intervalos regulares. Até agora, eu tenho usado o glTexImage2D para empurrar minha textura inicial e então atualizo as regiões sujas com glTexSubImage2D. Para fazer isso, estou usando o buffer único. Isso funciona bem.
Eu vi que pode haver outra maneira de conseguir a mesma coisa usando CVOpenGLESTextureCache. As texturas contidas no cache de textura fazem referência a um CVPixelBuffer. Eu gostaria de saber se posso mudar essas texturas em cache. Eu tentei recriar um CVOpenGLESTexture para cada atualização, mas isso diminui minha taxa de quadros drasticamente (não é surpreendente, afinal, desde que eu não estou especificando a região suja em qualquer lugar). Talvez eu tenha entendido mal o caso de uso desse cache de textura.
Alguém pode fornecer alguma orientação?
UPDATE: aqui está o código que estou usando. A primeira atualização funciona bem. As atualizações subseqüentes não (nada acontece). Entre cada atualização modifico o bitmap bruto.
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;