Android Opengl ES 2绘制大纹理慢

时间:2013-02-21 05:25:52

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

我是非常 OpenGL的新手。

我正在尝试绘制纹理四边形(2个三角形)。纹理的大小是900x900px。我对一个四边形没有任何问题,但是当我试图绘制5-10个四边形时,我看到明显减速。

也许我做错了什么......

代码:

public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    ... matrix calculation ...
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}

顶点着色器:

uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
attribute vec2 a_TexCoordinate;
varying vec2 v_TexCoordinate;
void main() {
  gl_Position = uMVPMatrix*vPosition;
  v_TexCoordinate = a_TexCoordinate;
}

片段着色器:

    precision mediump float;
    uniform sampler2D u_PreviewTexture;
    varying vec2 v_TexCoordinate;

    void main() {
      vec4 color = texture2D(u_PreviewTexture, v_TexCoordinate);
      gl_FragColor = color;
    }

测试平台是Galaxy S3。 在分析器中,我看到大约60ms需要eglSwapBuffers调用。

如何快速绘制具有大纹理的四边形?

3 个答案:

答案 0 :(得分:4)

这可能是由于纹理的大小以及您正在使用的设备的OpenGL驱动程序实现。

大多数现代GPU在NPOT(无2的幂)纹理方面做得相当不错,但每次需要绘制到最接近2的幂(在你的情况下为1024X1024)时,这会导致纹理重新缩放。

尝试使用以下两种解决方案:

1-将纹理转换为1024x1024,并使用几何中的坐标仅绘制所需的坐标(900x900)

2-尝试生成mipmap,如果你有很多缩放,这在很多情况下都是性能救星。

答案 1 :(得分:1)

你的S3可能有大约600M texels / sec fillrate(见GLBenchmark)。 如果你正在渲染全屏四边形 - 十个双纹理四边形每帧提供20M纹素。假设GLBenchmark做了它所说的(测量纹理吞吐量),20M纹素是填充率的1/30,给出33ms 最佳,hw可以处理一帧。帧缓冲混合我肯定会积极竞争填充物 - 混合的1000万像素非常多,所以我猜测瓶颈也可能存在。

你可以尝试确定什么是慢速部分 - 减少纹理大小,比如512x512,看看它如何影响性能。减少渲染四边形的屏幕尺寸(相当于纹理 - 例如使其成为屏幕的一半/四分之一)。

答案 2 :(得分:0)

根据我的经验,纹理性能问题通常源于MIPMAP过滤的设置方式。如果未以最佳方式设置以下参数(显示最小设置),可能会丢失大量性能:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

如果可能,请尝试禁用深度测试。 @ marekb对纹理压缩的建议也提供了很多性能优势。