将纹理快速加载到 OpenGL 2.0

Posted

技术标签:

【中文标题】将纹理快速加载到 OpenGL 2.0【英文标题】:Loading Textures fast into OpenGL 2.0 【发布时间】:2011-12-13 03:07:28 【问题描述】:

我正在为 android 构建一个简单的动态壁纸。我正在使用以下代码将所需的纹理上传到 OpenGL ES 2.0。我已将所有图像加载到大小为 2048x2048 的单个文件中。下面的代码大约需要 900 到 1200 毫秒来加载纹理。这是正常时间还是我做错了什么让它变慢?

每次在渲染器中调用 onSurfaceCreated 时,我也会尝试清除 Opengl 中的纹理列表。这是正确的做法,还是有一种方法可以简单地检查先前加载的纹理是否已经在内存中,如果是,则避免清除和重新加载?请让我知道你的cmets。谢谢。

在屏幕方向改变时也会调用 OnSurfaceCreated。所以纹理上传再次发生。这不是一个好主意。解决方法是什么?

public int addTexture(Bitmap texture) 

    int bitmapFormat = texture.getConfig() == Config.ARGB_8888 ? GLES20.GL_RGBA : GLES20.GL_RGB;

    int[] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    int textureId = textures[0];
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmapFormat, texture, 0);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR_MIPMAP_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
    GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    return textureId;

【问题讨论】:

【参考方案1】:

提高性能的几种方法。

    不要在每次调用onSurfaceChanged 时加载纹理。将您的textureId 初始化为-1(在您的渲染器的构造函数/surfaceCreated 中)并在onSurfaceChanged 的开头检查您是否有不同的Id。当您拨打glGenTextures 时,您会得到一个正数。 您需要 Mipmap 吗?这可能是您的方法的关键点。尝试不使用GLES20.glGenerateMipMap(GLES20.GL_TEXTURE_2D); 2048x2048 是巨大的。特别是对于纹理。你真的需要那么多细节吗?也许 1024x1024 就足够了。 避免使用 RGB_888,改用 RGB_565:您将获得几乎相同的视觉质量,但尺寸只有一半。

【讨论】:

I size 2048x2048 是因为我将应用程序中许多项目的纹理合并到一个文件中。我可以轻松地将纹理拆分为 4 个不同的 1024x1024 文件。但是我将不得不加载 4 个不同的文件。这种拆分方式会提高我的性能还是会导致上传时间增加,因为我现在要上传 4 张图片? 我会说如果你拆分文件,由于与其他函数调用相关的一些开销,上传时间会增加,但你可能不得不尝试。 谢谢。我也想知道加载2048x2048大小的贴图会不会有问题?我的意思是,在任何运行 2.2 的旧 android 手机中,图像大小会有任何限制吗? 从内存方面考虑:2048*2048*2 字节 (RGB_565) 需要 8 MB 内存。具有 4 个字节 (RGBA_8888) 的相同图像需要 16 MB。那是很多。您还可以在“纹理压缩支持”中查看纹理压缩 developer.android.com/guide/topics/graphics/opengl.html

以上是关于将纹理快速加载到 OpenGL 2.0的主要内容,如果未能解决你的问题,请参考以下文章

C++ OpenGL/SDL 2.0 无法加载纹理

OpenGL ES 2.0 - iOS - 使用 FBO 渲染到纹理

OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)

OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)

OpenGL ES 2.0 Framebuffer 渲染到纹理 iOS:没有显示

OpenGL:将图像加载到纹理数组中