【发布时间】:2014-09-25 19:32:27
【问题描述】:
我正在尝试通过 glGetTexImage 检索仅 alpha 纹理的像素信息。
问题是,glGetTexImage-Call 读取的数据似乎比它应该读取的多,导致内存损坏和 delete[]-Call 崩溃。这是我的代码:
int format;
glGetTexLevelParameteriv(target,0,GL_TEXTURE_INTERNAL_FORMAT,&format);
int w;
int h;
glGetTexLevelParameteriv(target,0,GL_TEXTURE_WIDTH,&w);
glGetTexLevelParameteriv(target,0,GL_TEXTURE_HEIGHT,&h);
if(w == 0 || h == 0)
return false;
if(format != GL_ALPHA)
return false;
unsigned int size = w *h *sizeof(unsigned char);
unsigned char *pixels = new unsigned char[size];
glGetTexImage(target,level,format,GL_UNSIGNED_BYTE,&pixels[0]);
delete[] pixels;
glGetError 不会报告任何错误,并且没有 glGetTexImage-Call 它不会崩溃。
'target' 为 GL_TEXTURE_2D(纹理有效且在所示代码之前绑定),'w' 为 19,'h' 为 24,'level' 为 0。
如果我将数组大小增加到 (w *h *100) 它也不会崩溃。我知道 GL_UNSIGNED_BYTE 与我系统上的 unsigned char 大小相同,所以我不明白这里发生了什么。
额外数据来自哪里?如何确保我的数组足够大?
【问题讨论】:
-
由 OpenGL 像素操作(如
glGetTexImage)写入的每一行默认对齐到 4 字节边界,这可能会添加一些填充。查找GL_[UN]PACK_ALIGNMENT -
那么,我可以将 GL_UNPACK_ALIGNMENT 设置为 1,还是取决于创建纹理时设置的 GL_PACK_ALIGNMENT 是什么?我尝试在 glGetTexImage-Call 之前将 GL_UNPACK_ALIGNMENT 设置为 1,但这似乎没有帮助。
-
打包和解包只影响像素传输。也就是说,当您上传它时,GL 使用解包对齐来解释数据,它将以它选择的本机格式存储它,然后它真的不再重要了。同样,当您下载图像时,您可以让 GL 根据一些可能与其内部使用的规则不同的规则打包它返回的图像。但在这两种情况下,一个确实不会影响另一个。
-
为此,在下载纹理图像之前设置解包对齐不会有任何作用。您需要设置包装对齐方式。你基本上把这两件事搞混了。
-
谢谢,现在说得通了。改变包装对齐就可以了。
标签: c++ arrays opengl crash textures