我的OpenGL應用程序使用OpenGL以全屏方式渲染紋理並定期更新其中的一部分。到目前爲止,我一直在使用glTexImage2D來推送我的初始紋理,然後使用glTexSubImage2D更新髒區域。爲此,我使用單緩衝。這很好。iOS上的CVOpenGLESTextureCache vs 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;
是的,你真的不想爲每次更新重新創建緩存的紋理或像素緩衝區,而是創建一次並將其用於更新。在創建這個像素緩衝區和紋理時有一些開銷。一旦你有了紋理,你應該能夠通過寫入像素緩衝區的字節來更新它,因爲它們應該直接映射到紋理的內部字節。 –
這就是我的想法,但無法得到這個工作......我設法通過將我的位圖包裹在像素緩衝區中來將我的初始紋理推到屏幕上。然後我保留紋理緩存,紋理本身和像素緩衝區。接下來我要做的是更新我的底層位圖並重繪我的OpenGL四邊形。然而,什麼都沒有發生...... – user1727274
我已經測試了我能想到的每一個變體,並且在Sim,iPhone4和iPad2上發現了與您相同的結果。使用CVPixelBufferCreate()或CVPixelBufferCreateWithBytes()來創建cv緩衝區似乎並不重要。調用CVPixelBufferCreateWithBytes將上傳1幀(用戶緩衝區的初始狀態),但寫入映射的數據存儲器不起作用。實際上,我發現如果你在每一幀都刪除並重新創建紋理,那麼CVOpenGLESTextureCacheCreateTextureFromImage()API只需花費所有時間在glTexImage2D_Exec上進行。 – MoDJ