我在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获取此模型的输出,here获取工作输出。希望你能帮忙! :)
P.S:代码缩短以便查看:)
答案 0 :(得分:2)
根据建模程序生成纹理和纹理坐标的方式,它可能会生成标准[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-inverted)。我不确定这是OBJ中的标准,还是取决于生成文件的软件。典型的症状是纹理显示在几何体上,但纹理的完全错误部分被映射。这可以通过镜像第二个坐标来修复,或者在读取文件时(用y
替换1.0 - y
),或者在着色器中应用纹理坐标的相应映射。