gpt4 book ai didi

android - OpenGL ES 2.0 : Performance drop using bindbuffer frequently

转载 作者:行者123 更新时间:2023-11-29 19:11:37 28 4
gpt4 key购买 nike

我的 opengl 2.0 游戏出现性能问题。在我对游戏进行更改之前,帧率一直很好。它是某种具有 64 种形状(砖 block )的爆发游戏。我现在想要的是,当球撞到一 block 砖时,它不会立即被移除——它会改变状态,包括改变纹理或更准确地说——图集的紫外线坐标。我有一个 textureatlas,我所做的只是为循环中的每个纹理调用 GLES20.bindBuffer(),而不是调用循环外部。早些时候我对所有形状都有相同的 uv 坐标,但现在我根据砖 block 状态更改它,这就是为什么我需要在循环内使用绑定(bind)

 private void drawShape() {


GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboDataListLevelSprites.get(iName).getBuff_id_vertices());
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, 0);


//used this snipped before when using the same image (uv-coords) for all bricks
/*GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboDataListLevelSprites.get(iName).getBuff_id_uvs());
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
*/

for (Iterator<BrickProperties> it = arrayListBricks.iterator(); it.hasNext(); ) {



BrickProperties bp = it.next();
//now bindbuffer inside loop just too switch uv-coords of the atlas when its time to use another image
int buffIndexVal = bp.get_status_diff();
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, BrickProperties.get_buff_id_uvs()[buffIndexVal]);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, 0);


Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, bp.getTranslateData()[0], bp.getTranslateData()[1], bp.getTranslateData()[2]);

if (bp.get_status() == 0) {
it.remove();
}

render();
}
}


private void render() {

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}

我知道性能下降的原因是对 GPU 的所有绑定(bind)缓冲区调用,但我怎么可能解决这个问题?

最佳答案

为每个对象绑定(bind)一个缓冲区是一回事,但使用 2 个缓冲区来绘制单个对象又是另一回事。在 render 方法的开头,您还有多余的调用来解除绑定(bind)缓冲区,只需将其删除即可。

在大多数情况下(可能是所有情况),您需要交错的顶点数据以提高性能。所以使用

{
position,
textureCoordinates
}

在一个缓冲区中。

我看到在你的情况下你有同一个对象的两个状态,其中第二个状态将改变顶点坐标而不是位置坐标。如果缓冲区相对较大(我假设不是),则在两者之间共享位置数据可能是有意义的。无论如何,对于这样的分享,我建议你宁愿使用你的缓冲区结构作为

{
position,
textureCoordinates,
secondaryTextureCoordinates
}

然后使用单独的缓冲区,甚至将次要纹理坐标放入同一缓冲区的另一部分。

因此,如果顶点缓冲区相对较小,那么我建议您使用“atlas”程序。对于您的情况,这意味着创建两倍大小的缓冲区并放置所有坐标(位置重复)并放置此顶点数据,以便一个接一个地存在。

我假设您可以轻松地为您当前的绘图做到这一点,并有效地将每次绘制调用的绑定(bind)缓冲区数量减少到 0(您只需要在某些初始化时绑定(bind)它)。现在您将进入第二部分,您将为每个绘制的元素设置属性指针,以便您可以控制使用哪个纹理坐标。这将再次出现冗余调用,在您的情况下可以避免这些调用:

因为缓冲区中的数据结构是一致的,所以真的没有理由多次设置指针。只需在绑定(bind)缓冲区时将它们设置一次,然后在绘制调用中使用偏移量来控制实际使用缓冲区的哪一部分 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, offset, 6)

如果正确完成,您的绘制方法应该类似于:

for (Iterator<BrickProperties> it = arrayListBricks.iterator(); it.hasNext(); ) {
BrickProperties bp = it.next();

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, bp.getTranslateData()[0], bp.getTranslateData()[1], bp.getTranslateData()[2]);

if (bp.get_status() == 0) {
it.remove();
}

Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, bp.vertexOffset, 6);
}

这将删除所有绑定(bind)并仅保留矩阵操作和绘制调用。如果管道中还有其他绘图,则需要在循环之前绑定(bind)缓冲区,否则您可以将其作为初始化的一部分。在这两种情况下,调用都应显着减少。

要在这里添加注释,通常的做法是让另一个对象跟踪 openGL 状态以避免冗余调用。与其调用 GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferID..,不如调用类似 contextObject.bindVertexBuffer(bufferID) 的方法来检查 bufferID 与之前的调用相同。如果是,则不会进行任何实际绑定(bind)。如果您创建并使用这样的系统,那么在调用缓冲区绑定(bind)和其余对象设置的位置上几乎没有区别,因为冗余调用不会有任何效果。仅此过程仍然不能使您的情况最佳,因此您仍然需要两者。

关于android - OpenGL ES 2.0 : Performance drop using bindbuffer frequently,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45096164/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com