首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多次调用glGetTexImage时缓冲区溢出错误

多次调用glGetTexImage时缓冲区溢出错误
EN

Stack Overflow用户
提问于 2013-12-06 23:13:48
回答 2查看 918关注 0票数 0

我正在创建一个类来使用OpenGL管理映像。为了加载图像,我使用土壤加载PNG。因为我需要检查碰撞,所以我想得到透明像素。所以我试着用: glGetTexImage获取数据

构造函数加载图像:

代码语言:javascript
复制
Image::Image(string imagePath, unsigned int flags){
    this->imagePath=imagePath;
    this->pxData=NULL;
    texture=SOIL_load_OGL_texture
    (
     imagePath.c_str(),
     SOIL_LOAD_AUTO,
     SOIL_CREATE_NEW_ID,
     flags
    );

    //Use that to subdivide in sprites the texture
    glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_WIDTH, &textureWidth);
    glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_HEIGHT, &textureHeight);
    glBindTexture(GL_TEXTURE_2D, this->texture);
    //cout << "Real Dimensions - " << textureWidth << "-" << textureHeight;

    loadPixels(); //multiple instances of image generates error here
}

LoadPixels在我的结构中加载像素数据。

代码语言:javascript
复制
typedef struct PixelData{
    unsigned char r;
    unsigned char g;
    unsigned char b;
    unsigned char a;
} PixelData;
PixelData* pxData;

然后在loadPixels中存储数据:

代码语言:javascript
复制
void Image::loadPixels(){
    pxData = new PixelData[textureHeight*textureWidth];
    glGetTexImage(GL_TEXTURE_2D, 1, GL_RGBA, GL_UNSIGNED_BYTE , pxData);
}

问题是,如果我创建一个图像:

代码语言:javascript
复制
Image img("/Developer/img.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);

效果很好。

如果我创造了很多图像:

代码语言:javascript
复制
    Image img("/Developer/img.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img2("/Developer/img2.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img3("/Developer/img3.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img4("/Developer/img4.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img5("/Developer/img5.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img6("/Developer/img6.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img7("/Developer/img7.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img8("/Developer/img8.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img9("/Developer/img9.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);
    Image img10("/Developer/img10.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);

然后我的程序崩溃:

错误是:

代码语言:javascript
复制
OpenGL Game Engine(35463,0x7fff7b121310) malloc: *** error for object 0x104017808: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug

如果我评论glGetTexImage(GL_TEXTURE_2D,1,GL_RGBA,GL_UNSIGNED_BYTE,pxData);它工作得很好,所以我想问题不在于分配。

我只需要得到像素数据来存储它,我想用这些像素创建一些数据,所以我需要得到我的纹理像素。

注意:

如果取消注释imagePath.c_str(),程序会在loadPixels ()处停止,如果我注释它,它会加载所有纹理

多亏了奥黛丽我得到了更多的信息。

代码语言:javascript
复制
glGetTexLevelParameteriv(GL_TEXTURE_2D, this->texture, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, this->texture, GL_TEXTURE_HEIGHT, &textureHeight);

Real Dimensions - 128-128
Real Dimensions - 64-64
Real Dimensions - 32-32
Real Dimensions - 16-16

这是相同的图像,但大小不断变小。

我检查了id,它每次都会创建一个新的id,那么为什么大小会被弄乱呢?

还有别的方法可以得到数据吗,我在这里遗漏了什么?另一个问题是,该方法获得绑定纹理,是否有一种使用纹理id获取纹理数据的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-06 23:37:29

代码语言:javascript
复制
glGetTexLevelParameteriv(GL_TEXTURE_2D, texture, GL_TEXTURE_HEIGHT, &textureHeight);

第二个参数不接受纹理ID,它是mipmap级别。您需要首先绑定纹理(),然后在放置纹理的地方使用0调用这个函数。

具体来说,您的纹理ID几乎可以肯定地被实例化为'0‘、'1’、'2‘等等.每次使用连续值调用glGetTexLevelParameteriv时,都要求在当前绑定纹理上设置一个较小的mipmap级别。您的第一个调用没有失败,这一事实使我怀疑SOIL_load_OGL_texture在返回之前实际上并没有解除它的绑定。

请记住,几乎没有任何OpenGL函数以纹理、缓冲区或着色器ID作为参数,而是对当前绑定的对象进行操作。在实际ID中通常使用的唯一函数是创建、销毁或绑定对象的函数,如glGenTexturesglDeleteTexturesglBindTexture

票数 1
EN

Stack Overflow用户

发布于 2013-12-06 23:31:16

根据注释中的讨论,看起来getGlTexImage正在溢出pxData缓冲区。如果您发布了给您提供textureWidthtextureHeight的函数的输出,我们可能会知道哪里出了问题。(例如,您确定getter函数的返回类型与变量textureWidth等之间的兼容性吗?)

编辑:我将检查您的<Gl.h>以查看函数glGetTexLevelParametersiv的签名。我在网上看了一下,这个版本的Microsoft与OpenGL.org上的版本有不同的签名,而且都不同意您使用的签名。

尝试重新排序并重写如下:

代码语言:javascript
复制
glBindTexture(GL_TEXTURE_2D, this->texture);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &textureHeight);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20435274

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档