I use PBO to upload an large image(3072 x 2048) to an 2D texture, it seems that the image has been damaged during loading(there is no problem if the image is not big enough). My computer is a windows 7 x64 and I have install the catalyst 11.8 driver, my video card is radeon HD 5770. The following code snippet can produce this problem:
...
QImage img("d:/big_image.png");
const unsigned int imageWidth = img.width();
const unsigned int imageHeight = img.height();
// create texture
GLuint tex = 0;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageWidth, imageHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
// create PBO
GLuint pbo = 0;
glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
// allocate storage for PBO
glBufferData(GL_PIXEL_UNPACK_BUFFER, imageWidth * 4 * imageHeight, 0, GL_DYNAMIC_DRAW);
// map PBO
void *pboBuffer = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, imageWidth * imageHeight * 4, GL_MAP_WRITE_BIT);
if (pboBuffer) {
unsigned char *pixel = (unsigned char *)pboBuffer;
for (int i = 0; i < imageHeight; i++) {
memcpy(pixel, img.scanLine(i), img.bytesPerLine());
pixel += img.bytesPerLine();
}
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
// copy PBO to texture
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, imageWidth, imageHeight, GL_BGRA, GL_UNSIGNED_BYTE, 0);
// download texture image
glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, img.bits());
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glDeleteBuffers(1, &pbo);
glDeleteTextures(1, &tex);
img.save("d:/output.bmp");
...
The idea of code is to load an big image (for example, 3072 x 2048, and this image should be a 32bit ARGB image), create a PBO and a texture to load this image to the texture(through the PBO), and then download this texture back to host memory and save it to a image file. The newly saved image file should have the same content of the original image file, but according to my test, when the image is big enough the output image is damaged. Is this my code's bug or a driver bug?
To run this code, you have to install Qt library, but if don't have Qt, you can use whatever toolkit you like to load and store image and replace the Qt code. Both a GL2 or GL3 context can produce this problem.
which card did you use? which driver?can you send us a vc project so we can easily debug on it? thanks.
Video Card: AMD radeon 5770
Driver: Catalyst 11.8
OS: windows 7 x64
I have a VC project to produce this problem, but where should I send it? The forum seems lack of file attachment function.
would you please send it to farosis'at'gmail.com?
I think I may have the same problem.
What I want to do :
- load a huge bitmap (~2800x~4300)
- create a viewport of same dimensions
- create a huge quad of same dimensions
- texture this quad with the bitmap (no interpolation)
- render the whole thing in a framebuffer object using orthogonal projection
Within these conditions, OpenGL should reproduce the original bitmap exactly.
My code gives me the exact same bitmap using NVidia driver (GeForce 310M) : zero differences, even md5sum of original texture and opengl rendering are identical (and it should be, according to opengl spec)
But using ATI driver (even the most recent one) and my Radeon HD4200 a part of the rendered image is a bit different, as if driver made some kind of floating-point error, or some kind of texture interpolation.
A zoom on the corrupted part : skin pixels are bad, and some blue and red ones appeared along the black border.
If I make a 'diff' (using imagemagick) between a texture and what opengl rendered, it looks like this (differences are in pink) :
Once again, things are perfectly identical (to the md5sum) when I run the same code with the same images on a pc equipped with NVidia's hardware.