Getting graphic files to work with textures

I have been struggling with getting textures to work via loading various .BMP, .JPG, etc. files. The images were being displayed with a “phase” problem. What I mean is that if there was a vertical line in the image, it would be displayed diagonally. Also the colors were messed up. It was as if the RGB codes got out of phase (i.e. there was an extra code per line that was throwing each successive line off). Actually only some files had the problem, others displayed correctly. After massive debugging struggles what appears to be happening is that if the .BMP or .JPG file has a width length or a height length that doesn’t end on a multiple of 4 bytes, the display is off (e.g. a width of 3 pixels has the problem as that is 9 bytes, where as a width of 4 pixels (12 bytes) doesn’t have the problem. It seems weird that OpenGL would have a bug like this so I am sending this to question my understanding. Please enlighten.

I am running under Windows 10 and am using OpenGL version 3.1 (I am using this version as it is the last that supports glGenList() and enables wglUseFontOutlines() to work, making it trivial to have 3D fonts)

The relevant code setting up the texture is:

        glBindTexture(GL_TEXTURE_2D, colorTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8, textureWidth, textureHeight, 0, (channels == 3) ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, td_ptr);
        glGenerateMipmap(GL_TEXTURE_2D);

        glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
        glBufferData(GL_ARRAY_BUFFER, numVertices * 2 * sizeof(texture[0]), texture, GL_STATIC_DRAW);
        glVertexAttribPointer(texCoordAttribute, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(texCoordAttribute);

The shader uses baseColor = texture(colorTexture, interpolated.textCoord); in what I think is very straight forward

Also I am not sure what the difference between GL_SRGB8 and GL_RGB8 is?

You need to call

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

before the glTexImage* call. The default value is 4, meaning the start of each row of pixels will be aligned to a 4-byte boundary.

See this page for an explanation of what sRGB is.

sRGB textures have the intensity values converted to a linear scale before being returned to the shader, and ideally before interpolation (filtering). This produces more accurate results, but you then have to convert the values back to sRGB before writing them to the framebuffer; either by using an sRGB framebuffer or via explicit conversions in the fragment shader. Using an sRGB framebuffer is preferable (particularly if you use alpha blending), but this feature has a history of implementation bugs, particularly for the default framebuffer.