2012-11-09 25 views
0

目前,我的应用程序加载纹理(〜200MB)减少RAM使用对于纹理

我加载纹理到一个字符缓冲区,将它传递给OpenGL的,然后杀死后使用大量的内存缓冲区。

看起来这个内存是由OpenGL使用的,OpenGL在内部进行自己的纹理管理。

我可以采取什么措施来减少这种情况?

是否有可能阻止OpenGL在内部管理纹理?

回答

2

一个典型的解决方案是跟踪您在相机某个位置或时间范围内需要的纹理,并且只在需要时加载这些纹理(反对在加载应用程序时加载每个纹理)。你必须有一个“管理器”来控制glBindTexture指定的相应纹理编号的加载 - 卸载和边界的绑定(例如,将字符串,纹理名称和整数相关联的容器)。

其他选项是降低您使用的纹理的整体质量/尺寸。

2

这似乎是这种内存使用的OpenGL,

在内部做了自己的纹理管理。

不,不是纹理管理。它只需要将数据保存在某个地方。在现代系统上,GPU由多个同时运行的进程共享。并不是所有的数据都可以适应快速的GPU内存。所以OpenGL实现必须能够交换数据。 GPU快速内存不是存储,它只是另一个缓存级别。就像系统内存缓存系统存储一样。

此外,GPU可能会崩溃,现代驱动程序会在原位重置它们,而用户不会注意。为此,他们还需要完整的数据副本。

是否有可能阻止OpenGL在内部管理纹理?

不,因为这样做或者是单调乏味,或者是破坏事情。但是你可以做的只是加载绘制给定场景时真正需要的纹理。

如果你仔细看看我关于OpenGL的着述,你会注意到多年来我告诉人们不要编写像“initGL”函数这样的愚蠢的东西。把所有东西都放入你的绘图代码无论如何,你会经历一个绘图调度阶段(你必须对半透明的物体进行远近排列,截锥体筛选等)。这使您有机会检查您需要的纹理,并加载它们。你甚至可以走得很远,只加载较低分辨率的mipmap级别,这样当一个场景最初显示的时候它的细节很少,并且可以在背景中加载更高分辨率的mipmap;这当然需要适当设置最小和最大的mip级别以设置为纹理或采样器参数。

+0

什么是在文件加载时实现这种纹理流而不引起帧率问题的好方法?我目前只是在开始运行我的应用程序时加载所有纹理。 此外,我似乎还记得,直接x不会缓存纹理 – aCuria

+1

@aCuria:像素缓冲区对象允许映射与glTexImage2D(数据= 0)或glTexStorage分配的纹理存储到进程地址空间。在帧准备阶段,丢失的纹理将被分配和映射,然后纹理加载作业将排入次要线程的任务列表中。在加载高细节纹理时,主显示线程可以仅渲染部分加载的纹理(在此期间某些对象可能看起来很暗淡)。例如CryEngine就采用了这种技术,在加载地图之后增量纹理加载是明显的。 – datenwolf