OpenGL - 纹理映射不完整

时间:2015-08-05 02:45:17

标签: c++ opengl opengl-es texture-mapping wavefront

我在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:代码缩短以便查看:)

1 个答案:

答案 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文件中,第二个纹理坐标(yt如果您更喜欢这种命名法)与OpenGL使用它们的方向相反(也就是y-inverted)。我不确定这是OBJ中的标准,还是取决于生成文件的软件。典型的症状是纹理显示在几何体上,但纹理的完全错误部分被映射。这可以通过镜像第二个坐标来修复,或者在读取文件时(用y替换1.0 - y),或者在着色器中应用纹理坐标的相应映射。