我正在创建一个类来使用OpenGL管理映像。为了加载图像,我使用土壤加载PNG。因为我需要检查碰撞,所以我想得到透明像素。所以我试着用: glGetTexImage获取数据
构造函数加载图像:
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在我的结构中加载像素数据。
typedef struct PixelData{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
} PixelData;
PixelData* pxData;然后在loadPixels中存储数据:
void Image::loadPixels(){
pxData = new PixelData[textureHeight*textureWidth];
glGetTexImage(GL_TEXTURE_2D, 1, GL_RGBA, GL_UNSIGNED_BYTE , pxData);
}问题是,如果我创建一个图像:
Image img("/Developer/img.png", SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT);效果很好。
如果我创造了很多图像:
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);然后我的程序崩溃:
错误是:
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 ()处停止,如果我注释它,它会加载所有纹理
多亏了奥黛丽我得到了更多的信息。
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获取纹理数据的方法?
发布于 2013-12-06 23:37:29
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中通常使用的唯一函数是创建、销毁或绑定对象的函数,如glGenTextures、glDeleteTextures和glBindTexture
发布于 2013-12-06 23:31:16
根据注释中的讨论,看起来getGlTexImage正在溢出pxData缓冲区。如果您发布了给您提供textureWidth和textureHeight的函数的输出,我们可能会知道哪里出了问题。(例如,您确定getter函数的返回类型与变量textureWidth等之间的兼容性吗?)
编辑:我将检查您的<Gl.h>以查看函数glGetTexLevelParametersiv的签名。我在网上看了一下,这个版本的Microsoft与OpenGL.org上的版本有不同的签名,而且都不同意您使用的签名。
尝试重新排序并重写如下:
glBindTexture(GL_TEXTURE_2D, this->texture);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &textureHeight);https://stackoverflow.com/questions/20435274
复制相似问题