OpenGL纹理

纹理采样器----纹理坐标

只有纹理坐标,纹理没有作用。

纹理坐标是在顶点着色器中设置,需要传入片段着色器,在片段着色器中需要定义纹理采样器。

然后调用texture函数利用采样器和纹理坐标对纹理进行采样。

我们使用GLSL内建的texture函数来采样纹理的颜色,它第一个参数是纹理采样器,第二个参数是对应的纹理坐标。texture函数会使用之前设置的纹理参数对相应的颜色值进行采样。这个片段着色器的输出就是纹理的(插值)纹理坐标上的(过滤后的)颜色。

绑定纹理采样器到纹理单元

不绑定

当纹理只有一个时,这个纹理单元默认是被激活的,可以不用给采样器指定纹理单元,默认使用的就是第一个纹理。

绑定

当有多个纹理时,如果我们需要选择使,就需要给采样器指定我们需要的纹理单元。

设置采样器和纹理单元的对应关系

片段着色器

#version 330 core
in vec2 textureCoor;
uniform sampler2D texture0;
uniform sampler2D texture1;
void main()
{
    gl_FragColor =texture(texture0,textureCoor);
}

纹理

    m_texture0=new QOpenGLTexture(QImage(":/image/tree.png"));//.mirrored());
    m_texture1=new QOpenGLTexture(QImage(":/image/laugh.png"));

采样器绑定到对应的纹理单元

    shaderProgram.setUniformValue("texture0",0);
    shaderProgram.setUniformValue("texture1",1);

将第一个纹理绑定到第一个纹理单元

m_texture0->bind(0);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

OpenGL纹理_第1张图片

将第二个纹理绑定到第一个纹理单元

m_texture1->bind(1);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

OpenGL纹理_第2张图片

第二个采样器在着色器中没有使用,如果将纹理绑定到第二个采样器,就不会发生采样:

m_texture1->bind(1);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

OpenGL纹理_第3张图片

 纹理单元

纹理单元不是纹理对象。


纹理单元是 OpenGL 中负责纹理管理的概念之一,它是一个由硬件实现的状态机,用于在不同的纹理对象和纹理参数之间切换。在渲染过程中,我们可以使用不同的纹理单元,从而使用不同的纹理对象和纹理参数。纹理单元类似于一个数组,其索引就是纹理单元的编号,编号从 0 开始,直到硬件所支持的最大纹理单元数。

一般情况下,在渲染过程中,我们需要先绑定纹理对象到纹理单元上,然后再渲染对应的图形。一个纹理单元可以绑定一个纹理对象,也可以切换到另一个纹理对象。

在 OpenGL 中,使用 `glActiveTexture()` 函数来选择当前的纹理单元。`glActiveTexture()` 函数的参数是纹理单元的编号,例如 `GL_TEXTURE0` 表示纹理单元 0,`GL_TEXTURE1` 表示纹理单元 1,以此类推。

示例代码如下:

```cpp
// 选择纹理单元 0
glActiveTexture(GL_TEXTURE0);

// 绑定纹理对象到纹理单元 0 上
glBindTexture(GL_TEXTURE_2D, textureID);

// 在着色器程序中传递纹理单元号
glUniform1i(glGetUniformLocation(programID, "texture"), 0);
```

在上述示例代码中,我们选择纹理单元 0,然后将纹理对象 `textureID` 绑定到该纹理单元上。然后,我们将纹理单元号 0 传递到着色器程序中的 `texture` uniform 变量中。这样,在渲染过程中,OpenGL 就会从纹理单元 0 中获取相应的纹理对象来渲染。

GL_TEXTURE_2D是什么

GL_TEXTURE_2D是OpenGL中用于指定2D纹理目标的一个常量。它是纹理管理中一部分重要的 API 函数的参数。

指定纹理单元的两种方式

OpenGL至少保证有16个纹理单元供你使用,也就是说你可以激活从GL_TEXTURE0到GL_TEXTRUE15。它们都是按顺序定义的,所以我们也可以通过GL_TEXTURE0 + 8的方式获得GL_TEXTURE8。

纹理对象--纹理采样器--纹理单元

纹理单元和纹理采样器是相关概念但并不完全相同。

纹理单元是管理纹理对象的硬件状态机,它是通过指定纹理单元编号来管理不同的纹理对象和纹理参数的。一个纹理单元可以绑定一个纹理对象,并且可以被多个纹理采样器所使用。

纹理采样器是在着色器程序中声明的 uniform 变量,用于在纹理采样过程中控制纹理的采样方式(例如使用线性过滤还是最邻近过滤等)和采样坐标的变换(例如旋转、缩放等)。纹理采样器用于指定在片段着色器中对应的纹理单元,以便于绑定特定的纹理对象。

因此,纹理单元和纹理采样器的作用不同,但它们常常被一起使用。在着色器程序中,我们通过纹理采样器来指定纹理的采样方式和变换方式,然后使用 `glUniform1i()` 函数将该纹理采样器绑定到相应的纹理单元上,从而实现在特定的纹理单元中呈现相应的纹理对象。

纹理采样器通过shader.setUniformValue("xxx",n)绑定到对应的纹理单元;

纹理对象通过bind(n)绑定到对应的纹理单元;

总之,纹理对象设置进入纹理单元;纹理采样器从纹理单元读取纹理对象进行采样。

你可能感兴趣的:(qt)