OpenGL将图像平铺到纹理中并耗尽内存

Posted

技术标签:

【中文标题】OpenGL将图像平铺到纹理中并耗尽内存【英文标题】:OpenGL Tiling an Image into Textures and Run Out of Memory 【发布时间】:2013-03-21 18:21:19 【问题描述】:

我正在尝试实现用户可以缩放和平移的世界地图。我遇到了我的程序内存不足的问题。

这是我的情况:

0) 我正在用 C# 和 OpenGL 编写程序

1) 我从网上下载了一张 JPG 图片,它是世界的详细图片,大小为 19 兆。每个像素长 24 位。

2) 当我的程序初始化时,我在运行时将此图像分割成图块。我使用 glGenTexture、glBindTexture 和 glTexImage2d 将每个图块输入 OpenGL。

3) 在我的绘图程序中,我一张一张地绘制瓷砖并尝试绘制所有瓷砖,无论它们是否在屏幕上(这是另一个问题,我知道)。

对于小图像,一切正常。但是,对于大图像,当我将 JPG 解码为位图以便将其切碎时,我的程序的内存占用量会激增至超过 1 GB。我知道 JPG 是压缩的,而 .NET JpegBitmapDecoder 对象正在解压缩一个巨大的图像,这可能是让我遇到麻烦的原因。

我的问题是,在这种情况下究竟能做什么?由于 C# 解码代码是炸毁内存的第一责任方,是否有另一种创建图块并将它们提供给 OpenGL 的替代方法,而我应该追求(减去位图)?

【问题讨论】:

不要使用 JPEG,而是使用您的视频卡已用于压缩纹理的相同压缩格式。 【参考方案1】:

显然你应该购买更多的内存!

您可以在 GPU 上以压缩格式存储纹理。请参阅this page(也是 SC3T/DXT 部分。)您可能还需要根据需要在视频内存中交换纹理。如果不需要,请不要保留未压缩的数据。

【讨论】:

【参考方案2】:

我会考虑将 jpg 解码为位图文件,并使用位图上的流来异步加载视图中的相关图块数据(或尽可能多的内存可以处理) - 类似于例如android 版 Google 地图。

我也看到了这个,但无法确认"OOM from a Bitmap is very suspect. This class will throw the memory exception for just about anything that goes wrong, including bad parameters etc."

【讨论】:

流做到了。最初我将整个图像从流中复制到一个字节数组中,然后使用字节数组而不是流。我只是为了使用流而对其进行了更改,这产生了很大的不同。

以上是关于OpenGL将图像平铺到纹理中并耗尽内存的主要内容,如果未能解决你的问题,请参考以下文章

纹理不填充图形 - OpenGL

如何在 OpenGL 中将多个纹理分配到单个网格中?

✠OpenGL-5-纹理贴图

从帧缓冲区对象读取时,OpenGL 纹理坐标是相反的

如何在OpenGL中将像素作为纹理绘制到多边形?

OpenGL纹理内存布局和查找速度