[英]Android OpenGL 2.0 Low FPS
我正在OpenGL 2.0中制作应用程序,但我遇到了每秒约20帧的极低FPS问题。 我为每个绘制的新对象制作了:
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,texture);
int mPositionHandle =
GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer);
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image,
"a_texCoord" );
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, uvBuffer);
int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image,
"uMVPMatrix");
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image,
"s_texture" );
GLES20.glUniform1i ( mSamplerLoc, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
GLES20.glFlush();
GLES20.glFinish();
现在,我只有四个精灵和大约20帧的fps,但是我要添加大约10-15个精灵。
有很多事情可能会帮助您提高表现。 从几个简单的项目开始:
正如@dari所指出的,摆脱那些glFlush()
和glFinish()
调用。 您应该很少需要它们。 过多的glFlush()
调用几乎总是对性能有害,而glFinish()
确实非常糟糕。 简而言之,像OpenGL这样的图形API的主要原理之一就是它们使GPU从CPU异步工作。 glFinish()
强制CPU和GPU之间完全同步,而不是让它们并行工作,这是非常不希望的。
编译着色器后,应该对所有那些glGetAttribLocation()
和glGetUniformLocation()
一次调用,并通常在类的成员变量中存储这些位置。 然后,只需使用这些变量的值即可,而不是每次绘制时都进行多余的调用。 例如,链接着色器一次后,您将执行以下语句,其中mPositionLoc
和mMatrixLoc
是成员变量:
mPositionLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition"); mMatrixLoc = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");
然后在绘制时,可以使用以下变量来设置属性和制服:
GLES20.glEnableVertexAttribArray(mPositionLoc); GLES20.glVertexAttribPointer(mPositionLoc, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); ... GLES20.glUniformMatrix4fv(mMatricLoc, 1, false, m, 0);
仅这两个因素可能已经使您迈出了一大步。 除此之外,您还应该研究使用顶点缓冲对象(VBO)。 它们允许您将顶点和索引数据存储在缓冲区中,而不是每次都将它们传递给glVertexAttribPointer()
和glDrawElements()
。 如果顶点数据不经常更改,这将特别有益。 您应该能够找到很多使用它们的教程和示例代码。 他们将使用诸如glGenBuffers()
, glBindBuffer()
等API调用。
如果这还不足以满足您的性能目标,请进一步考虑,您可以考虑将所有子画面的顶点数据存储在单个缓冲区中,而不是每个缓冲区都有单独的缓冲区。 这样,您将不需要glBindBuffer()
就能调用glVertexAttribPointer()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.