每幀更新VBO數據的最佳方法是什麼?目前,我在每幀調用glBufferData之後使用glBufferSubData,並且我無法達到超過25fps而沒有奇怪的口吃。Android OpenGL ES每幀更新VBO數據
我的主要目標是在50fps的兩幅圖像之間翻轉。
下面是一些代碼:
public void onDrawFrame(GL10 glUnused) {
endTime = System.currentTimeMillis();
dt = endTime - startTime;
if (dt < 20)
try {
Thread.sleep(20 - dt);
} catch (InterruptedException e) {
e.printStackTrace();
}
startTime = System.currentTimeMillis();
...some matrix operations
render();
}
void render() {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, floatbuffer.capacity() * BYTES_PER_FLOAT,
null, GLES20.GL_STREAM_DRAW);
...a bunch of if statements
if(side==1) {
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, floatbuffer.capacity() * BYTES_PER_FLOAT,floatbuffer);
side = 0;
} else {
GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, floatbuffer2.capacity() * BYTES_PER_FLOAT, floatbuffer2);
side = 1;
}
GLES20.glVertexAttribPointer(positionAttribute, POSITION_DATA_SIZE_IN_ELEMENTS, GLES20.GL_FLOAT, false, STRIDE, 0);
GLES20.glEnableVertexAttribArray(positionAttribute);
GLES20.glVertexAttribPointer(colorAttribute, COLOR_DATA_SIZE_IN_ELEMENTS, GLES20.GL_FLOAT, false, STRIDE, (POSITION_DATA_SIZE_IN_ELEMENTS) * BYTES_PER_FLOAT);
GLES20.glEnableVertexAttribArray(colorAttribute);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indexCount, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
}
我也嘗試設置多個VBO的每一個都有自己的數據不會改變,在我想要顯示的VBO調用glBindBuffer,我還注意到了口吃。
我對OpenGL有點新鮮,所以我不清楚最佳的處理方式。據我所知,將數據從CPU傳輸到GPU可能存在瓶頸。有沒有更有效的方法來解決這個問題?
鑑於在沒有任何數據傳輸的情況下使用靜態VBO仍然會結結巴巴,爲什麼您認爲這是您的問題? – solidpixel
你是完全正確的。我查看了代碼的其他部分,如果我刪除了onDrawFrame中的Thread.sleep()調用,則該應用程序呈現時不會出現口吃(除非偶爾會出現滑落)。你有關於如何正確獲得恆定幀速率的想法嗎?如果Thread.sleep()在如此低的ms計數時不準確,那麼還有什麼其他方法?是否可以使用RENDERMODE_WHEN_DIRTY並在正確的時間設置另一個調用requestRender()的線程? – Karam
添加並回答一些想法嘗試。 – solidpixel