OpenGL - 纹理映射不完整

OpenGL - texture mapping is incomplete

我在 OpenGL 中对 OBJ 文件进行纹理处理时遇到了这个奇怪的问题。我已经成功地正确解析和渲染了模型,现在我正在尝试对其应用纹理。这是我的做法。

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);

对于我的解析器中的纹理坐标,我交换了 y 坐标(从 1 中减去 y)以获得纹理的正确方向。此代码适用于不同的模型,但对于此特定模型,纹理不完整。你可以 here for the output I get with this model and here 工作的。希望你能帮忙! :)

P.S:代码已缩短以供查看:)

根据建模程序生成纹理和纹理坐标的方式,它可能会生成标准 [0.0, 1.0] 范围之外的纹理坐标。由于您将环绕模式设置为:

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_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

理论上也有可能,尽管不太可能,建模程序会生成纹理坐标以与镜像重复一起使用。如果切换到GL_REPEAT后,纹理图像显示在当前黑色部分,但它们看起来像错误的纹理部分,您也可以尝试:

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

OP 已经解决了一个相关问题,但我会在这里提及它,以防其他有类似问题的人遇到这个答案:在我见过的带有纹理的 OBJ 文件中,第二个纹理坐标(y,或者 t,如果你喜欢那个命名法)与 OpenGL 使用它们的方式相反(也称为 y 反转)。我不确定这是否是 OBJ 中的标准,或者取决于生成文件的软件。典型的症状是纹理显示在几何体上,但映射了完全错误的纹理部分。这可以通过在读取文件时镜像第二个坐标(将 y 替换为 1.0 - y)或通过在着色器中应用相应的纹理坐标映射来解决。