My UV-mapping gets wrong colors?

I have described my problem here https://stackoverflow.com/questions/50658037/uv-mapping-opengl-wrong-colors

I am loading the data into VBO buffers in the code like this:

void createMeshVAO(Context &ctx, const Mesh &mesh, MeshVAO *meshVAO)
{
    // Generates and populates a VBO for the vertices
    glGenBuffers(1, &(meshVAO->vertexVBO));
    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->vertexVBO);
    auto verticesNBytes = mesh.vertices.size() * sizeof(mesh.vertices[0]);
    glBufferData(GL_ARRAY_BUFFER, verticesNBytes, mesh.vertices.data(), GL_STATIC_DRAW);

    // Generates and populates a VBO for the vertex normals
    glGenBuffers(1, &(meshVAO->normalVBO));
    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->normalVBO);
    auto normalsNBytes = mesh.normals.size() * sizeof(mesh.normals[0]);
    glBufferData(GL_ARRAY_BUFFER, normalsNBytes, mesh.normals.data(), GL_STATIC_DRAW);

    // Generates and populates a VBO for the element indices
    glGenBuffers(1, &(meshVAO->indexVBO));
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshVAO->indexVBO);
    auto indicesNBytes = mesh.indices.size() * sizeof(mesh.indices[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesNBytes, mesh.indices.data(), GL_STATIC_DRAW);

    // Generates and populates a VBO for the UV indices
    glGenBuffers(1, &(meshVAO->textcoordsVBO));
    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->textcoordsVBO);
    auto uvsNBytes = mesh.texcoords.size() * sizeof(mesh.texcoords[0]);
    glBufferData(GL_ARRAY_BUFFER, uvsNBytes, mesh.texcoords.data(), GL_STATIC_DRAW);

    // Creates a vertex array object (VAO) for drawing the mesh
    glGenVertexArrays(1, &(meshVAO->vao));
    glBindVertexArray(meshVAO->vao);
    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->vertexVBO);
    glEnableVertexAttribArray(POSITION);
    glVertexAttribPointer(POSITION, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->textcoordsVBO);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glBindBuffer(GL_ARRAY_BUFFER, meshVAO->normalVBO);
    glEnableVertexAttribArray(NORMAL);
    glVertexAttribPointer(NORMAL, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshVAO->indexVBO);
    glBindVertexArray(ctx.defaultVAO); // unbinds the VAO

    // Additional information required by draw calls
    meshVAO->numVertices = mesh.vertices.size();
    meshVAO->numIndices = mesh.indices.size();
    meshVAO->numtextcoords = mesh.texcoords.size();
}

Then the GLSL catches the vertice-array and texturecoordinates array which I use to render the model.


//fragment shader
in vec2 UV;
uniform sampler2D u_testtext;
frag_color = texture( u_testtext, UV );

If anyone has any ideas, I’m really interested to hear about it.

How are you reading the OBJ file? Are you de-duplicating all of the positions and texture coordinates (so you have 3 distinct vertices per triangle), or are you using e.g. a std::map to track shared vertices? Are you taking account of the fact that OBJ uses 1-based indices while OpenGL uses 0-based indices?

I use this function to load the data https://gist.github.com/mlgrandom/5c3148eecd014b900a614ac24ab497f7
and I just assume that it “works”. Obviously the 3D model as shown in the pictures earlier is correct. And the normals being loaded from the OBJ file seems to be correct. The only part where difficulty has occured is when I map a texture <-> colors. I know the basics of the OBJ file contents and that “f a/b/c” marks how a certain vertice, a, is connected to a normal, b, and texturecoordinate, c.

It seems like OBJ loader-function is taking into acoount the 0-based/1-based indices thingy from looking at the comments in the code.

Also for potential debugging, here is my GLSL, shortened down.

// Vertex shader
#version 150
#extension GL_ARB_explicit_attrib_location : require

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_normal;
layout(location = 2) in vec2 vertexUV;

out vec2 UV;
out vec3 v_normal;
uniform mat4 u_mvp;
void main()
{
    v_normal = a_normal;	
    gl_Position = u_mvp * a_position;
    UV = vertexUV;
}
 //fragment shader
in vec3 v_normal;
in vec2 UV;
uniform sampler2D u_testtext;

void main()
{
    frag_color = texture(u_testtext, UV );
}

I solved the problem!!

After watching this youtube tutorial https://youtu.be/RnXDUFq7T6A?t=1772

I noticed that he put 1 - texturecoordinate.y since this tends to be “flipped” in images. Thus my GLSL is now
“UV = vec2(vertexUV.x, 1.0 - vertexUV.y);”