Android版的OpenGL 2.0,低帧率 [英] Android OpenGL 2.0 Low FPS

查看:688
本文介绍了Android版的OpenGL 2.0,低帧率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在OpenGL 2.0应用程序制作和我有关于非常低的FPS问题〜每秒20帧。

I'm making app in OpenGL 2.0 and i have problem with very low FPS about ~20 frames per second. I made for every spite new object which draw with:

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

现在,我只有四个关于20frames精灵和FPS,但我将添加约10-15 sprites.It将是马车。

Now, i have only four sprites and fps about 20frames,but i'm going to add about 10-15 sprites.It will be buggy.

推荐答案

有一个数字的东西,可能会帮助你的表现。用几个简单的项目启动:

There's a number of things that will probably help your performance. Starting with a couple of simple items:


  1. 由于@dari也指出,摆脱那些 glFlush() glfinish在()呼叫。你应该很少需要他们。过度 glFlush()电话几乎都是有害的性能和 glfinish在()是真的,真的很糟糕。总之,图形API,比如OpenGL的主要原则之一是,他们让GPU异步工作从CPU。 glfinish在()强制,而不是让他们在并行,这是极不可取的工作,CPU和GPU之间的完全同步。

  1. As @dari also pointed out, get rid of those glFlush() and glFinish() calls. You should very rarely need them. Excessive glFlush() calls are almost always harmful to performance, and glFinish() is really, really bad. In short, one of the main principles of graphics APIs like OpenGL is that they let the GPU work asynchronously from the CPU. glFinish() forces a full synchronization between CPU and GPU, instead of letting them work in parallel, which is highly undesirable.

您应该让所有的 glGetAttribLocation() glGetUniformLocation()编译着色器后,一旦调用,或贮存起来的位置,通常在你的类的成员变量。然后,只需使用这些变量而不是使每一个你画的时间冗余呼叫的值。例如,有一次你连接着色器之后,执行这些语句,其中 mPositionLoc mMatrixLoc 的成员变量:

You should make all those glGetAttribLocation() and glGetUniformLocation() calls once after compiling the shader, and store away the locations, typically in member variables of your class. Then just use the values of those variables instead of making redundant calls every time you draw. For example, one time after you link the shader, you execute these statements, where mPositionLoc and mMatrixLoc are member variables:

mPositionLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");
mMatrixLoc = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");

然后当你画,你可以使用这些变量来设置你的属性和制服:

Then when you draw, you use these variables for setting up your attributes and uniforms:

GLES20.glEnableVertexAttribArray(mPositionLoc);
GLES20.glVertexAttribPointer(mPositionLoc, 3,
                             GLES20.GL_FLOAT, false,
                             0, vertexBuffer);
...
GLES20.glUniformMatrix4fv(mMatricLoc, 1, false, m, 0);


光是这两可能已经把你向前迈进了一大步。除此之外,你应该考虑使用顶点缓冲对象(驻维也纳各组织)。它们允许你存储在缓冲区的顶点和索引数据,而不是将它们传递给 glVertexAttribPointer() glDrawElements()各一次。如果顶点数据不经常更改,这是特别有利的。你应该能够找到大量的教程和样本code对如何使用它们。他们将使用像 glGenBuffers API调用() glBindBuffer()

These two alone might already take you a big step forward. Beyond this, you should look into using Vertex Buffer Objects (VBOs). They allow you to store your vertex and index data in buffers, instead of passing them to glVertexAttribPointer() and glDrawElements() each time. This is particularly beneficial if the vertex data does not change frequently. You should be able to find plenty of tutorial and sample code for how to use them. They will use API calls like glGenBuffers(), glBindBuffer(), etc.

把它更进一步,如果这还不够满足​​你的绩效目标,你可以考虑存储在一个单一缓冲区所有精灵的顶点数据,而不必为每一个单独的缓冲区。这样一来,你就不会需要尽可能多的 glBindBuffer() glVertexAttribPointer()来电。

Taking it even further if this is not enough to meet your performance targets, you could consider storing the vertex data for all your sprites in a single buffer, instead of having a separate buffer for each. This way, you will not need as many glBindBuffer() can glVertexAttribPointer() calls.

这篇关于Android版的OpenGL 2.0,低帧率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆