【二十一,纹理-03纹理单元】

纹理单元

在我们刚开始学习纹理时,片段着色器中的uniform sampler2D texture是一个uniform,我们却没有在代码中给它赋值,这是为什么呢?一个纹理的位置通常称为纹理单元(Texture Unit),一个纹理的默认位置是0,它是默认的激活纹理单元,所以在前面使用纹理的例子中我们没有为它分配一个位置。

OpenGL至少保证有16个纹理单元供我们使用,也就是说我们可以激活从GL_TEXTURE0到GL_TEXTRUE15。它们都是按顺序定义的,所以我们也可以通过GL_TEXTURE0 + 8的方式获得GL_TEXTURE8,这在当我们需要循环一些纹理单元的时候会很有用。

使用纹理单元允许我们在片段着色器中使用多个纹理采样器:

#version 330 core

out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1; // 采样器1
uniform sampler2D texture2; // 采样器2

void main()
{
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

mix函数的功能是将两个纹理的颜色进行线性插值混合,假设第三个参数为val,第一、二个参数的值为color1,color2,则最终颜色为 color1(1-val) + clolor2val 。

多个纹理单元的使用

  • 分配位置
    使用glUniform1i为着色器采样器设置位置
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
glUniform1i(glGetUniformLocation(ourShader.ID, "texture2"), 1);
  • 激活与绑定纹理
    ** glActiveTexture**函数激活纹理单元位置,如果我们要激活绑定0号位置的纹理,可以进行如下操作:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
  • 代码
  1. 着色器
    顶点着色器依旧使用上节练习中的4_1_tex.vs,将本文开头的片段着色器保存到工程中:4_1_2tex.fs。
  2. 渲染类
    使用两个纹理进行渲染和使用一个纹理进行渲染的渲染类的代码很相似,这次需要定义两个渲染纹理对象:
    renderTexture *m_pTex1;
    renderTexture *m_pTex2;

生成纹理对象:

    m_pTex1 = new renderTexture("resources/textures/container.jpg", GL_RGB);
    m_pTex2 = new renderTexture("resources/textures/awesomeface.png", GL_RGBA);

第二个纹理对象使用的是PNG图片,有alpha通道,在生成纹理对象时需要使用GL_RGBA作为参数。
设置纹理位置:

    m_pShader->use();
    m_pShader->setInt("texture1", 0);
    m_pShader->setInt("texture2", 1);

渲染
在渲染的过程中,需要激活纹理位置后,绑定纹理对象:

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, m_pTex1->textureId);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, m_pTex2->textureId);

使用两张图片渲染

你可能感兴趣的:(【二十一,纹理-03纹理单元】)