我目前正在使用Android和OpenGL ES 2.0上的NDK。我想知道是否以及如何以垃圾方式加载OpenGl纹理,以便在将其提供给OpenGl之前避免在app堆中使用整个未压缩的纹理。所以,我想做的事(simplfied)是从存储器读取512Kb到RAM,然后将这512kb传输到OpenGl,然后将下一个512kb加载到RAM中等等 - 因此纹理加载的内存占用应该总是大约512Kb。然而,我在OpenGL的所有示例中看到的是人们倾向于将整个未经注释的图像数据加载到RAM中(对于4096x4096x32bit纹理,将64MB加载!然后立即将整个数据复制到OpenGl。内存占用峰值仅为64MB用于加载纹理!!: - 我想知道更多,因为在Dalvik VM中运行的java编写的应用程序通常只有16Mb的可用堆内存 - 所以他们如何设法甚至将纹理加载到OpenGL?我在这里缺少一些基本的东西?
非常感谢和最诚挚的问候 塞缪尔
答案 0 :(得分:0)
是的,可以在帆船中加载纹理。
执行此操作的方法是首先使用完整大小调用glTexImage2D()
,然后使用空指针调用最后一个参数,否则将传递指向数据的指针。这指定了纹理的大小和格式,但没有用数据填充它。
之后,glTexSubImage2D()
可用于用数据块填充纹理。
例如,要使用1024x1024大小的块填充4096x4096 RGBA纹理:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4096, 4096, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data00);
glTexSubImage2D(GL_TEXTURE_2D, 0, 1024, 0, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data01);
glTexSubImage2D(GL_TEXTURE_2D, 0, 2048, 0, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data02);
glTexSubImage2D(GL_TEXTURE_2D, 0, 3072, 0, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data03);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 1024, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data10);
glTexSubImage2D(GL_TEXTURE_2D, 0, 1024, 1024, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data11);
glTexSubImage2D(GL_TEXTURE_2D, 0, 2048, 1024, 1024, 1024,
GL_RGBA, GL_UNSIGNED_BYTE, data12);
...
如果你确实需要这么大的纹理,你可能需要考虑使用压缩纹理。不幸的是,对特定压缩纹理格式的支持是依赖于ES 2.0的设备。但考虑到它可以减少内存使用量,并可能提高性能/功耗,它仍然值得研究。查看glCompressedTexImage2D()
作为起点。
当然,您还需要确保资产的分辨率不高于所需的分辨率。