OpenGL 纹理无法正常工作

Posted

技术标签:

【中文标题】OpenGL 纹理无法正常工作【英文标题】:OpenGL texturing does not work as it should 【发布时间】:2013-12-12 09:21:50 【问题描述】:

我有 128 x 128 px 24 位 bmp 文件用于纹理。这是一个带有一条垂直线的绿色正方形。它可以使用 stbi_image 加载。在初始化中启用

glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);

和纹理参数是

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

我有一个由立方体和圆柱体(以及一些带有顶点的多边形)组成的对象。我将纹理绑定到这样的一个 glut

glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tex1_id);
glColor3f(0.0f, 1.0f, 0.0f);
glTranslatef(-0.5f, 0.2f, 0.05f);
glScalef(2.4f, 0.4f, 1.0f);
glutSolidCube(0.6f);
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();

或到顶点正方形:

glPushMatrix();
glTranslatef(-0.03f, 1.26f, -0.35f);
glRotatef(94, 1.0f, 0, 0);
glBindTexture(GL_TEXTURE_2D, tex1);
glBegin(GL_QUADS);  
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-0.3f, 0.4f, 0.0f);  
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-0.3f, 0.85f, 0.0f);  
glTexCoord2f(1.0f, 1.0f);
glVertex3f(0.3f, 0.85f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(0.3f, 0.4f, 0.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();

我知道 glutSolidCube 不会生成纹理坐标,但显然使用上部 glEnables 它工作得很好。所以纹理出现在物体上。此时一切看起来都很好。

当我使用 lookAt 更改视图或在某个路径中平移和旋转对象时,问题就开始了。然后它看起来就像纹理不随物体移动和旋转,而是保持静止。

第一:初步看法;第二:稍微旋转的视图(lookAt);第三:轻微翻译的对象

如果我用顶点绘制那个对象,也会发生同样的事情。我在 C++ 中使用 OpenGL 2.1 和 glut。

【问题讨论】:

我相信您自己已经发现了问题。如果没有纹理坐标,它怎么可能将顶点映射到纹理中的某个点? @Dave 我希望有一些神奇的方法可以使它成为可能。实心立方体很容易实现,所以我更关心实心圆柱体的实现。如果我实现 glutSolidCylinder 并在其中放入一些纹理坐标,它会起作用吗? 【参考方案1】:

你做错了。您必须定义纹理坐标。 通过自己给顶点和纹理坐标来绘制立方体。

//first face of cube
glTexCoord2f(0.0, 0.0);
glVertex3f(x, y, z);
glTexCoord2f(1.0, 0.0);
glVertex3f(x, y, z);
glTexCoord2f(1.0, 1.0);
glVertex3f(x, y, z);
glTexCoord2f(0.0, 1.0);
glVertex3f(x, y, z);

//and so on for all six face of cube.

您必须了解纹理坐标的工作原理。 现在,如果您想绘制圆柱体,请使用gluCylinder 函数查看here 了解详细信息。您可以使用gluQuadricTexture 函数将纹理映射到使用gluCylinder 渲染的圆柱体上,如下所示。我假设您已经加载了纹理。

//Create the quadric object to render cylinder 
GLUquadric *quad;
quad = gluNewQuadric();


glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gluQuadricTexture(quad,1);
gluCylinder(quad,2,2,3,20,20);

你可以找到类似的例子here。

【讨论】:

可能我的问题描述得不够好,所以我更新了我的问题。有顶点和添加纹理坐标的方式没有效果。 glutSolidCube 是实际问题。它不会生成纹理坐标,因此如果您平移或旋转立方体,纹理不会随立方体平移,而是映射到不同的位置。 我知道,我还修改了glutSolidCube的原始功能,并在那里添加了纹理坐标。没有效果。即使我用 4 个顶点和纹理坐标绘制简单的正方形,它也不起作用。 @drive235:您必须禁用自动纹理坐标生成才能使 texcoords 生效。

以上是关于OpenGL 纹理无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES 无法正常工作

在OpenGL中将纹理映射到VBO的问题

Mac OS X 上的 OpenGL 纹理损坏

opengl 纹理无法正确渲染

在openGL中。如何将纹理的一部分复制到另一个纹理

OpenGL代码适用于GLFW,但不适用于Qt OpenGL