learnopengl——纹理

原文网址:https://learnopengl.com/Getting-started/Textures

纹理单元
你可能很想知道为什么sampler2D变量是一个全局变量,如果我们不适用glUniform对其赋值。使用glUniform1i,这样我们可以一次指定一个纹理对象,也可以一次指定多个纹理对象。这个纹理的位置就是通常所说的纹理单元。默认的纹理单元是0,这个是默认的激活的纹理单元,所以之前的章节我们没有对其指定位置。注意到不是所有的图形设备需要一个默认的纹理单元,所以之前的章节也许渲染不出对象。

纹理单元的主要目的是,它允许我们的shader使用多张纹理。通过指定纹理单元给采样器,我们可以一次绑定多个纹理,只要我们激活对应的纹理单元即可。像glBindTexture,我们可以使用glActiveTexture激活一个纹理单元,如下:

glActiveTexture(GL_TEXTURE0); // activate the texture unit first before binding texture
glBindTexture(GL_TEXTURE_2D, texture);

在激活纹理单元之后,紧接着使用glBindTexture,会绑定纹理到当前激活的纹理单元。纹理单元GL_TEXTURE0通常默认是激活的,所以之前的章节,我们不需要激活纹理单元,而直接调用了glBindTexture。

OpenGL应该至少有16个纹理单元供你使用。我们可以使用GL_TEXTURE0到GL_TEXTURE15激活对应的纹理单元。它们是按照顺序定义的,为了得到GL_TEXTURE8,可以使用GL_TEXTURE0+8形式。这个在循环迭代的时候获取指定的纹理单元很有用。

我们还需要编辑片段着色器来接收另外一个采样器,如下:

#version 330 core
...

uniform sampler2D texture1;
uniform sampler2D texture2;

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

最后的输出颜色,是结合了两张纹理。GLSL的内置函数mix,接收两个参数,然后在两者之间根据第三个参数进行线性插值。如果第三个参数是0,它返回第一个参数。如果第三个参数是1,则返回第二个参数。如果第三个参数是0.2,则返回80%的第一个参数,20%的第二个参数,这样就混合了两张贴图。

现在我们需要加载并创建另外一个纹理。你应该很熟悉这个过程了。确保创建另外一个纹理对象,加载和创建最终的纹理使用glTexImage2D。

unsigned char *data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}

注意到,我们加载了一张png后缀的图,它包含了透明通道。所以我们需要指定图片数据包含透明通道,使用GL_RGBA即可。否则OpenGL会不正确解析图片数据。

为了使用第二个纹理,我们需要修改对应的程序,绑定两个纹理。

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);

glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

我们还需要告诉OpenGL,哪个纹理单元属于哪个shader采样器,通过glUniform1i设定每个采样器。我们仅仅需要设定一次即可,所以我们可以在进入循环之前调用一次。

ourShader.use(); // don't forget to activate the shader before setting uniforms!  
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0); // set it manually
ourShader.setInt("texture2", 1); // or with shader class
  
while(...) 
{
    [...]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值