Manh Nguyen
Manh Nguyen

Reputation: 413

Why is my texture loaded into opengl not mapped correctly?

I am trying to load a simple model in openGL. Currently, I have a problem with the textures. The texture definitely does show up, but it is messed up and it also does not cover all the model (part of the model is black). I have tried several things to determine what is the source of the problem. I passed in a uniform red texture and it renders correctly. I used the texture coord as R and G value in the fragment shader and I get a red-green model so I assume the texture coordinate is also fine.

The texture is messed up, and part of it is black. This is just a simple minecraft character

the model's texture, which is a png

Here's how I am creating texture:

imageData = stbi_load(path.c_str(), &width, &height, &colorFormat, 0);
glGenTextures(1, &texID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

My fragment shader:

void main(){
    vec4 l = normalize(lightSourcePosition - positionEyeCoord);
    vec4 normalFrag = normalize(normalEyeCoord);
    if (hasTexture == 1){
        vec4 textureKD = vec4(texture(textureSampler, texCoord).rgba);
        vec4 diffuse = vec4(lightIntensity, 0.0) * textureKD * max(0.0, dot(l, normalFrag));
        vec4 ambient = vec4(ambientIntensity, 0.0) * textureKD;
        gl_FragColor = ambient + diffuse;
    }
    else {
        vec4 diffuse = vec4(lightIntensity * KD, 0.0) * max(0.0, dot(l, normalFrag));
        vec4 ambient = vec4(ambientIntensity * KA, 0.0);
        gl_FragColor = ambient + diffuse;
    }   
}

Upvotes: 1

Views: 857

Answers (1)

Nico Schertler
Nico Schertler

Reputation: 32637

Most likely, your character has been modeled using DirectX conventions for texturing. In DirectX, the texture coordinate origin is the top left of the image, whereas it is the bottom left corner in OpenGL.

There are a couple of things you can do (choose one):

  • When you load the model, replace all texture coordinates (u, v) by (u, 1 - v).
  • When you load the texture, flip the image vertically
  • In your shader, use vec2(texCoord.x, 1 - texCoord.y) for your texture coordinates.

I advise against using the third option for anything other than quick testing.

Upvotes: 1

Related Questions