安卓Openg GL ES 2绘制大贴图速度慢

9

我对OpenGL非常陌生。

我正在尝试绘制带纹理的四边形(2个三角形)。纹理的大小为900x900像素。一个四边形没问题,但当我尝试绘制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。 在分析器中,我看到eglSwapBuffers调用大约需要60毫秒。

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


一些更重要的信息:位图采用ARGB_8888格式,并启用GL_BLEND。 - mik_os
3个回答

4
这可能是由于您的纹理尺寸和您正在使用的设备的OpenGL驱动程序实现导致的。大多数现代GPU对NPOT(非2次幂)纹理做得很好,但这会导致每次需要绘制到最近的2的幂(在您的情况下为1024X1024)时重新缩放纹理。
请尝试使用以下两个解决方案: 1-将您的纹理转换为1024x1024,并在几何图形中使用坐标仅绘制所需部分(900x900)。 2-尝试生成mipmaps,如果您有很多缩放操作,则在许多情况下可以提高性能。

如果纹理是静态的,压缩也可以减少内存带宽。ETC1压缩可能在所有移动设备上都可用。它仅支持RGB格式,没有alpha通道。 - marekb
感谢您的回答。我尝试将纹理缩放到1024x1024,但没有任何区别。而且我无法使用ETC1,因为我在运行时获取位图。我尝试对GPU调用进行分析,看起来所有调用都少于2毫秒... - mik_os
另一个测试:10个四边形,每个四边形有两个1024x1024的纹理(使用mix()函数):eglSwapBuffers调用大约需要35-40毫秒,但在GPU分析器中,所有绘图过程都少于3毫秒。 - mik_os

1
你的S3大约有每秒600M个纹素的填充率(请参见GLBenchmark)。 如果你正在渲染全屏幕四边形-十个双材质四边形每帧提供20M个纹素。假设GLBenchmark所说的是真的(测量纹理吞吐量),则20M个纹素是填充率的1/30,即每帧最快33ms处理一帧。我敢肯定,帧缓冲混合也会积极争夺填充率-10M像素混合是相当多的,所以我可以猜想瓶颈可能也在那里。
你可以尝试确保哪部分速度较慢-将纹理大小减小到512x512,看看它如何影响性能。将呈现的四边形的屏幕大小缩小(与纹理一样显著-例如将其缩小至屏幕的一半/四分之一)。

1
根据我的经验,纹理性能问题通常源于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关于纹理压缩的建议也提供了很多性能优势。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接