Android OpenGL 2.0低FPS

时间:2014-07-18 13:12:10

标签: android opengl-es opengl-es-2.0

我在OpenGL 2.0中制作应用程序,我的FPS非常低,每秒约20帧。我为每一个用来绘制的新对象做了:

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();

现在,我只有四个精灵和fps约20帧,但我要添加大约10-15个精灵。它将是错误的。

1 个答案:

答案 0 :(得分:2)

有很多事情可能对你的表现有所帮助。从几个简单的项目开始:

  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);
    
  3. 这两个人可能已经向你迈出了一大步。除此之外,您应该研究使用顶点缓冲对象(VBO)。它们允许您将顶点和索引数据存储在缓冲区中,而不是每次都将它们传递给glVertexAttribPointer()glDrawElements()。如果顶点数据不经常改变,这尤其有益。您应该能够找到大量有关如何使用它们的教程和示例代码。他们将使用glGenBuffers()glBindBuffer()等API调用。

    如果这还不足以满足您的性能目标,那么您可以考虑将所有精灵的顶点数据存储在单个缓冲区中,而不是为每个精灵存储单独的缓冲区。这样,您就不需要glBindBuffer()glVertexAttribPointer()次{{1}}次呼叫。