一段代码:
// Some codes intializing 'transWidth' and 'transHeight' are ommitted
static vector<GLfloat> pixels;
printf("Alloc: %dx%dx4=%d floats\n", transWidth, transHeight, transWidth * transHeight * 4);
pixels.resize(transWidth * transHeight*4);
// Some codes modifying 'pixels'
// omitted
_CheckErrorGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, transWidth, transHeight, 0, GL_RGBA, GL_FLOAT, pixels.data());
_CheckErrorGL
宏_CheckErrorGL
用于在必要时输出错误代码和描述:
#define _CheckErrorGL {\
GLenum code;\
if ((code = glGetError()) != GL_NO_ERROR)\
{\
printf("Error %d: %s\n", int(code), gluErrorString(code));\
assert(false);\
}\
}
此代码将执行多次。这是输出:
Ready for OpenGL 2.0
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 6561x1x4=26244 floats
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 732x737x4=2157936 floats
Alloc: 3168x3224x4=40854528 floats
Error 1285: 内存不足
Alloc: 6561x1x4=26244 floats
(&#39;内存不足&#39;表示&#39;内存不足&#39;。在发布模式下,assert
只是(无效)0。)
浮点数为172102344,假设浮点数为4Bytes,则为656.5MiB。我的显卡是NVIDIA GeForce GTX 660 Ti,内存为4042MB。发生了什么事?
更新
我尝试了Andon和Surgey的建议。
以下是我的纹理参数:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
仍然是相同的输出。但是当我在
中将RGBA32F
更改为RGBA16F
或RGBA
时
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, transWidth, transHeight, 0, GL_RGBA, GL_FLOAT, pixels.data());
然后所有分配都成功。我在另一台配备NVIDIA GeForce GTX Titan(4095MB视频内存)的机器上试用了代码,但所有结果都是一样的。
注意:我使用dxdiag.exe来显示总视频内存。
答案 0 :(得分:1)
看起来你已经达到了GPU特定的纹理大小限制。
尝试将内部格式GL_RGBA32F
更改为GL_RGBA16F
,然后更改为GL_RGBA
,看看是否能够创建这些纹理。
答案 1 :(得分:1)
我的显卡是NVIDIA GeForce GTX 660 Ti,内存为4042MB。
4042 MiB号码包括GART(图形地址重映射表 - 系统共享内存) - 您的视频卡的实际专用内存有所不同。此外,在现代系统中,视频内存(无论是GART还是专用)在进程之间共享......您无需保证在各个应用程序中可以访问4042 MiB的存储空间。
由于您使用的是NV GPU,因此您可能会发现GL_NVX_gpu_memory_info
扩展名很有用。
最后,您的纹理的实际存储要求并非您认为的那样。
创建GL纹理对象时,默认情况下有1000个纹理LOD,此代码生成不完整的纹理,因为您只为1000个LOD中的一个分配数据。您应该将GL_TEXTURE_MAX_LEVEL
设置为 0 ,因为您只为单个LOD分配存储空间。
或者,您可以使用glTexStorage2D (...)
来正确创建1 LOD的纹理,但这在OpenGL 2.0中不可用。