3 Texture
文本统计:约 435 个字 • 22 行代码
给物体进行纹理贴图的过程分为生成纹理与应用纹理
生成纹理的过程与前面的基本相似
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// 为当前绑定的纹理对象设置环绕、过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 加载并生成纹理
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
关于纹理的环绕方式与过滤方式直接看文章即可
然后应用纹理,需要纹理的顶点坐标以及相应的纹理对象。
相应的纹理坐标在顶点着色器中被导入
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
纹理对象在片段着色器中被导入
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}
那么纹理对象是怎么被导入到片段着色器的呢,这里用纹理单元的例子。当我们需要导入多个纹理的时候,就需要用到纹理单元,分别是 GL_TEXTURE0
到 GL_TEXTURE15
,每当我需要导入纹理对象的时候,先将相应的纹理单元激活,然后绑定相应纹理。当然在执行这些操作之前还需要告诉OpenGL每个着色器采样器属于哪个纹理单元。所以具体的流程如下所示
//绑定相应的纹理
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
Warning
为OpenGL要求y轴0.0
坐标是在图片的底部的,但是图片的y轴0.0
坐标通常在顶部。很幸运,stb_image.h
能够在图像加载时帮助我们翻转y轴,只需要在加载任何图像前加入以下语句即可: