【问题标题】:glGetTexImage reads too much data with texture format GL_ALPHAglGetTexImage 读取的纹理格式为 GL_ALPHA 的数据过多
【发布时间】: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


【解决方案1】:

由 OpenGL 像素操作(如 glGetTexImage)写入或读取的每一行默认对齐到 4 字节边界,这可能会添加一些填充。

要修改对齐方式,请使用 glPixelStoreiGL_[UN]PACK_ALIGNMENT 设置。 GL_PACK_ALIGNMENT 影响从 OpenGL 内存读取的操作(glReadPixelsglGetTexImage 等),而GL_UNPACK_ALIGNMENT 影响写入 OpenGL 内存的操作(glTexImage 等)

对齐方式可以是1(紧密排列,没有填充)、24(默认)或8中的任何一个。

因此,在您的情况下,请先运行 glPixelStorei(GL_PACK_ALIGNMENT, 1);,然后再运行 glGetImage2D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 2018-03-31
    • 2014-04-22
    相关资源
    最近更新 更多