Search code examples
c++openglopencvtexture2d

OpenGL texture doesn't show correctly - strange behaviour


I want to detect a marker with OpenCV, and then I want to overlay it with an image, with OpenGL. First part is ok (I achieve detection marker perfectly), but I have some problems with the second.

marker is:

enter image description here

and image is:

enter image description here

but the result is this:

enter image description here

code to generate the texture of image is:

GLuint *textures = new GLuint[2];
glGenTextures(2, textures);
Mat image = imread("Immagine.png");
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 4,image.cols, image.rows, 0, GL_RGB,GL_UNSIGNED_BYTE, image.data);

and to show the texture i use:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, WIDTH, HEIGHT, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f((GLfloat)(coord[1].x),(GLfloat)(coord[1].y));
glTexCoord2f(1.0f, 0.0f); glVertex2f((GLfloat)(coord[2].x),(GLfloat)(coord[2].y));
glTexCoord2f(1.0f, 1.0f); glVertex2f((GLfloat)(coord[3].x),(GLfloat)(coord[3].y));
glTexCoord2f(0.0f, 1.0f); glVertex2f((GLfloat)(coord[0].x),(GLfloat)(coord[0].y)); 
glEnd();

I don't know why textured image is so strange. Also, I use the same code to show (on opengl window) captured frames from webcam and I have no problem. I've noted also that if I use the same image without numbers at corners, it works correctly (even if it isn't in the same place/coordinates of marker).

Does anyone have any idea?


Solution

  • This is a padding/alignment issue.

    You're loading a format which has different padding requirements to GL (which by default expects rows of pixels to be padded to a multiple of 4 bytes).

    Possible fixes for this are:

    • Tell GL how your texture is packed, using (for example) glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    • Change the dimensions of your texture, such that the padding matches without changing anything
    • Change the loading of your texture, such that the padding is consistent with what GL expects