简体   繁体   中英

OpenGL - texture mapping is incomplete

I have this weird problem with texturing of OBJ files in OpenGL. I have successfully parse and render the models correctly and i'm trying now to apply texture to it. Here's how I do it.

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// bind the vertices coord
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, cc * sizeof(GLfloat), vertices,   GL_STATIC_DRAW);


// bind the textures coord
GLuint tcbuffer;
glGenBuffers(1, &tcbuffer);
glBindBuffer(GL_ARRAY_BUFFER, tcbuffer);
glBufferData(GL_ARRAY_BUFFER, tcc * sizeof(GLfloat), textures GL_STATIC_DRAW);

// for the texture itself
GLuint tid;
glGenTextures(1, &tid);
glBindTexture(GL_TEXTURE_2D, tid);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nptr);

glEnableVertexAttribArray(m_vert);
glBindBuffer(GL_ARRAY_BUFFER, vbufferid);
glVertexAttribPointer(m_vert, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(m_texcoord);
glBindBuffer(GL_ARRAY_BUFFER, tcbufferid);
glVertexAttribPointer(m_texcoord, 2, GL_FLOAT, GL_FALSE, 0, 0);

glDrawArrays(GL_TRIANGLES, 0, vc);

And for the texture coordinates in my parser, I swap the y-coordinate(subtract y from 1) to get the proper orientation of the texture. This code works for different models but with this specific model, the texture is incomplete. You can here for the output I get with this model and here for the working ones. Hope you can help! :)

PS: the code is shorten for viewing purposes :)

Depending on how the modelling program generates textures and texture coordinates, it is possible that it will generate texture coordinates outside the standard [0.0, 1.0] range. Since you set the wrap modes as:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

all texture coordinates outside this range will get the color of the closest edge texel. It loos like your texture has black around the edge, so all those pixels will be sampled as black.

If this is the problem, you need to set the parameters as:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

It's also theoretically possible, even though less likely, that the modelling program would generate texture coordinates to work with mirrored repeat. If texture images show up in the currently black parts after switching to GL_REPEAT , but they look like the wrong parts of the texture, you could also try:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

There's a related problem that the OP had already figured out, but I'll mention it here just in case somebody else with a similar problem comes across this answer: In the OBJ files with textures I have seen, the second texture coordinates ( y , or t if you prefer that nomenclature) were in the opposite direction of the way OpenGL uses them (aka y-inverted). I'm not sure if this is standard in OBJ, or depends on what software generated the file. The typical symptom is that the texture is displayed on the geometry, but completely wrong parts of the texture are mapped. This can be fixed by mirroring the second coordinate, either while reading the file (replace y by 1.0 - y ), or by applying the corresponding mapping of the texture coordinates in the shader.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM