每帧更新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