2014-09-05 130 views
0

我目前在Android和OpenGL ES 2.0上玩NDK。我想知道是否以及如何可能加载OpenGl纹理垃圾,所以我可以避免在将应用程序堆中的整个未压缩纹理赋予OpenGl之前。所以,我想要做的事情(简单化)是从存储器读取512Kb到RAM中,然后将这些512kb转移到OpenGl,然后将下一个512kb加载到RAM中,等等 - 因此纹理加载的内存占用空间应该总是在512KB。然而,我在OpenGL的所有例子中看到,人们倾向于将整体未压缩的图像数据加载到RAM中(对于4096x4096x32位的纹理,为64MB)然后将整个数据立即复制到OpenGl,只有64MB的内存占用高峰用于加载纹理!!: - 我想知道甚至更多,因为用Dalvik VM运行的java中编写的应用程序通常只有16Mb的可用堆内存 - 所以他们如何设法将纹理加载到OpenGL的?我失去了一些东西基本在这里吗?OpenGl ES 2.0加载纹理junkwise

非常感谢和问候 塞缪尔

+0

自2009年以来,应用程序并未拥有16MB托管堆限制。尽管如此,64MB是移动设备上单个纹理的相当大量的数据,使用压缩纹理格式会更好。 – fadden 2014-09-05 15:34:19

回答

0

是,纹理可以在帆船装载。

wa行ay要做到这一点,首先调用glTexImage2D()全尺寸,最后一个参数的空指针,否则你会传递一个指向数据的指针。这指定纹理的大小和格式,但不填充数据。

之后,可以使用glTexSubImage2D()来填充具有数据块的纹理。

例如,填补了4096×4096 RGBA纹理1024×1024大小的块:

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()的起点。

当然,您还要确保您的资产不会高于需要的分辨率。