繁体   English   中英

Android OpenGL 2.0低FPS

[英]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个精灵。

有很多事情可能会帮助您提高表现。 从几个简单的项目开始:

  1. 正如@dari所指出的,摆脱那些glFlush()glFinish()调用。 您应该很少需要它们。 过多的glFlush()调用几乎总是对性能有害,而glFinish()确实非常糟糕。 简而言之,像OpenGL这样的图形API的主要原理之一就是它们使GPU从CPU异步工作。 glFinish()强制CPU和GPU之间完全同步,而不是让它们并行工作,这是非常不希望的。

  2. 编译着色器后,应该对所有那些glGetAttribLocation()glGetUniformLocation()一次调用,并通常在类的成员变量中存储这些位置。 然后,只需使用这些变量的值即可,而不是每次绘制时都进行多余的调用。 例如,链接着色器一次后,您将执行以下语句,其中mPositionLocmMatrixLoc是成员变量:

     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM