将纹理添加到由顶点构成的平面

Chr*_*ris 5 c++ opengl textures

我使用以下代码在OpenGL上创建了一个平面:

glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.8, 0.8, 0.5, 1.0);
glVertex3f(startlen, height, startwid);    
glVertex3f(startlen, height, startwid + width);
glVertex3f(startlen + length, height, startwid);
glVertex3f(startlen + length, height, startwid + width);
glEnd();
Run Code Online (Sandbox Code Playgroud)

现在我想在这个平面上应用纹理.

我在这里阅读了这个教程,但我已经停止了"在OpenGL中使用纹理"部分,因为我没有UV坐标.

我知道我们必须导入纹理文件,在我的例子中是一个位图文件.
加载器返回一个Glint,它是textureID,是全局的吗?在示例中,如果我需要加载该纹理,我只需要使用给定的ID调用绑定纹理函数?

无论如何,我怎样才能将纹理应用到平面上?


编辑#1: 现在发布的示例蚊子的纹理有效.
我发现的是我将纹理加载到类的构造函数中,我不应该因为该对象是公共的而且是在OpenGL初始化之前构造的.
所以纹理现在加载四个例子:)

现在的问题是我试图在我的飞机上使用它,它看起来很扭曲.对此的解决方案可能是将纹理加载多次,但保持原始大小(虽然我不知道如何做到这一点).

另外,我在当前的一个平面旁边创建了另一个带有奶油色的平面但是在纹理化之后它看起来像这样: 在此输入图像描述

所以现在有两个问题:

  • 纹理必须保持原始分辨率,但显示覆盖整个平面的次数
  • 它旁边的飞机失去了它的颜色(为什么会发生这种情况?如何解决它? - 我也可以使用这个平面的纹理)

编辑#2:

由于蚊子,第2个问题现在已经解决了!但是平铺仍然不起作用.这就是它现在的样子: 在此输入图像描述

这是我用过的纹理:
在此输入图像描述
它的尺寸是256x256(我用图像编辑器裁剪它)


编辑#3:
这些是glTexCoord2f坐标及其匹配的顶点(对于内边距):

glTexCoord2f(0.0f, 0.0f);   glVertex3f(startlen, height, startwid);
glTexCoord2f(0.0f, 1.0f);   glVertex3f(startlen, height, startwid - width/2);
glTexCoord2f(1.0f, 0.0f);   glVertex3f(startlen + length, height, startwid);
glTexCoord2f(1.0f, 1.0f);   glVertex3f(startlen + length, height, startwid - width/2);
Run Code Online (Sandbox Code Playgroud)

Pio*_*cki 10

如果你有一个返回textureID的加载器,它可能已经负责加载图像数据,设置属性并将其存储为真正的纹理以供进一步使用.所以我将继续将纹理绑定到纹理目标.

如果你有这个id,你基本上必须glBindTexture()在绘制三角形条之前调用函数:

glBindTexture(GL_TEXTURE_2D, id); // where id is GLuint returned by your loader
Run Code Online (Sandbox Code Playgroud)

现在,对于您绘制的每个顶点,您还应该为这些顶点指定纹理坐标.为此,您使用glTexCoord2f()功能.对于简单的四边形,它可能看起来像这样:

glBegin(GL_QUADS);
    // Bottom left
    glTexCoord2f(0.0f, 1.0f);                   
    glVertex2i(0.0f, 10.0f);

    // Top left
    glTexCoord2f(0.0f, 0.0f);
    glVertex2i(0.0f, 0.0f);

    // Top right
    glTexCoord2f(1.0f, 0.0f);
    glVertex2i(10.0f, 0.0f);

    // Bottom right
    glTexCoord2f(1.0f, 1.0f);
    glVertex2i(10.0f, 10.0f);
glEnd();
Run Code Online (Sandbox Code Playgroud)

如您所见,每个顶点都附有纹理"点".它会告诉OpenGL如何显示纹理.

现在,您可以通过指定顶点的正确坐标来选择希望如何将纹理分布在平面上.

您必须记住的是纹理坐标以0.0开头并以1.0结尾.将此值增加到大于1.0将导致行为取决于纹理的设置(例如平铺).

在你的教程中,你有非常好的图片呈现纹理坐标从0.0到1.0范围以及为特定顶点设置的纹理坐标:

在此输入图像描述

PS.为了显示纹理,您必须首先通过调用以下方式启用此功能:

glEnable(GL_TEXTURE_2D);
Run Code Online (Sandbox Code Playgroud)

每次用纹理绘制对象时都不必调用它.在绘图之前可能只调用一次.


编辑

  1. 根据你的下一个问题:你想要的是实现平铺效果,这可以在创建纹理时轻松完成.在您的装载机中,在此行之后:

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    你应该设置下一个纹理参数,如下所示:

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    
    Run Code Online (Sandbox Code Playgroud)

    在这种情况下GL_REPEAT,只要坐标高于1.0,就会重复使用纹理.例如,如果指定纹理坐标为2.0,则与放置1.0相同,依此类推.

  2. 你的第二个问题存在,因为你仍然有你的纹理绑定并且你启用了纹理(记住你使用过 glEnable(GL_TEXTURE_2D);),所以你现在绘制的所有内容都会被纹理所覆盖.

    但是,如果你现在想要绘制一些没有纹理的东西,你基本上必须在绘制第二个平面之前禁用纹理,并在绘制之后再次启用它:

    glDisable(GL_TEXTURE_2D);
       // Draw your second plane here
    glEnable(GL_TEXTURE_2D);
    
    Run Code Online (Sandbox Code Playgroud)

EDIT2

好吧,我觉得你误解了我一点.在这种情况下,平铺无法工作,因为您指定纹理坐标最大为1.0,这是纹理的结束.我准备了一张图片,可以告诉你我的意思:

在此输入图像描述

在那些中间有红色的图片中,我标记了纹理坐标和黑色 - 顶点坐标.

所以基本上如果你像现在这样设置你的纹理坐标(最大值为1.0),你可以让你的纹理在你的平面上伸展.现在想象一下这个平面非常大 - 如果纹理分辨率低,它只会造成丑陋的拉伸效果.

为了实现平铺效果,你必须设置高于1.0的值,就像在我的例子中 - 2.0导致纹理重复两次.

由于没有神奇的方法可以让你的纹理在飞机上看起来"漂亮",你必须使用一些数学来实现它.现在我留给你.