OpenGL纹理在四边形上未对齐

Posted

技术标签:

【中文标题】OpenGL纹理在四边形上未对齐【英文标题】:OpenGL texture misaligned on quad 【发布时间】:2010-06-06 20:48:09 【问题描述】:

这个问题我已经有一段时间了,我还没有找到任何可行的解决方案。这是问题和细节:

我正在将一个 256x256 未压缩的 TGA 加载到一个简单的 OpenGL 程序中,该程序在屏幕上绘制一个四边形,但是当它显示时,它向左移动了大约两个像素,裁剪的部分出现在右侧。困扰我很久了,有人建议用夹紧之类的,但不知怎的,我觉得我的问题可能很简单,但我就是不知道是什么!

为了清楚起见,这是一个屏幕截图,比较了 TGA(左)和它在程序中的运行方式(右)。另请注意,右上角有一个很小的黑色像素,我希望这与相同的问题有关。

alt text http://img64.imageshack.us/img64/2686/helpmed.png

这是加载器的代码,我确信我的问题在于我加载纹理的方式。

提前感谢任何可以解决我问题的人。

bool TGA::LoadUncompressedTGA(char *filename,ifstream &texturestream)

 cout << "G position status:" << texturestream.tellg() << endl;
 texturestream.read((char*)header, sizeof(header));     //read 6 bytes into the file to get the tga header
 width  = (GLuint)header[1] * 256 + (GLuint)header[0];    //read and calculate width and save
 height = (GLuint)header[3] * 256 + (GLuint)header[2];    //read and calculate height and save
 bpp    = (GLuint)header[4];           //read bpp and save

 cout << bpp << endl;

 if((width <= 0) || (height <= 0) || ((bpp != 24) && (bpp !=32))) //check to make sure the height, width, and bpp are valid
 
  return false;
 
 if(bpp == 24)         
 
  type = GL_RGB;
 
 else
 
  type = GL_RGBA;
 
 imagesize = ((bpp/8) * width * height);          //determine size in bytes of the image
 cout << imagesize << endl;
 imagedata = new GLubyte[imagesize];           //allocate memory for our imagedata variable

 texturestream.read((char*)imagedata,imagesize);        //read according the the size of the image and save into imagedata 

 for(GLuint cswap = 0; cswap < (GLuint)imagesize; cswap += (bpp/8))         //loop through and reverse the tga's BGR format to RGB
 
  imagedata[cswap] ^= imagedata[cswap+2] ^=                    //1st Byte XOR 3rd Byte XOR 1st Byte XOR 3rd Byte
     imagedata[cswap] ^= imagedata[cswap+2];
 

 texturestream.close();              //close ifstream because we're done with it
 cout << "image loaded" << endl;

 glGenTextures(1, &texID);             // Generate OpenGL texture IDs
 glBindTexture(GL_TEXTURE_2D, texID);          

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 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_NEAREST);
 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

 glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, imagedata);



    delete imagedata;
 return true;


//Public loading function for TGA images.  Opens TGA file and determines 
//its type, if any, then loads it and calls the appropriate function.
//Returns: TRUE on success, FALSE on failure

bool TGA::loadTGA(char *filename)

 cout << width << endl;
 ifstream texturestream;
 texturestream.open(filename,ios::binary);
 texturestream.read((char*)header,sizeof(header));     //read 6 bytes into the file, its the header.                //if it matches the uncompressed header's first 6 bytes, load it as uncompressed
 LoadUncompressedTGA(filename,texturestream); 
 return true;

【问题讨论】:

请添加header的声明。 【参考方案1】:

看起来您确实使用了两次标头(一次在 TGA::loadTGA 中,然后再次在 LoadUncompressedTGA 中)。

但如果是这样的话,那么我认为 widthheightbpp 都将是完全错误的,而且看起来也不会像现在这样正确。

【讨论】:

是的。据我所知,标头实际上是 18 个字节长。我认为我的评论实际上是不正确的,但正如你所说,如果我把标题搞砸了,图像就不会像现在这样。绝对是一个值得调查的地方,所以感谢您的提醒。 看来您的预感是正确的。我检查了它的读取距离,我注意到它读取了 24 个字节而不是它应该读取的 18 个字节。在加载 Alpha 通道 TGA 时,这也给我带来了问题。更改了它,现在一切正常。非常感谢。我知道这很简单。【参考方案2】:

为了清楚起见,这是一个屏幕截图,比较了 TGA(左)和它在程序中的运行方式(右)。另请注意,右上角有一个很小的黑色像素,我希望这与相同的问题有关。

看起来加载程序被破坏了 - 显然“吃掉”了两个像素(假设扫描线从下行到上行)。这不是 OPENGL 问题,而是您的加载例程中的一个错误某处

我不熟悉 *.tga 格式,但您可能希望将您的加载例程与来自 SDL_image 库的实现进行比较。据我所知 SDL_image 正确加载图像。由于您的例程没有这样做,因此这是您例程中的错误。将您的例程与工作代码进行比较以找出错误。

如果您决定将 SDL_image 代码复制到您的项目中,请谨慎使用许可。

【讨论】:

是的,我更愿意自己编写加载例程,正如我之前所说,我知道问题可能出在我的加载例程上,我似乎无法弄清楚它的哪一部分正在导致转变。不过,感谢您的指点。

以上是关于OpenGL纹理在四边形上未对齐的主要内容,如果未能解决你的问题,请参考以下文章

使用 OpenGL / LWJGL 绘制纹理四边形使用旧纹理

如何在opengl中平滑多个四边形的纹理

OpenGL核心配置文件不会纹理四边形

OpenGL调整纹理/四边形

透明四边形上的OpenGL DECAL纹理?

Opengl:地球纹理