OpenGL学习4——纹理

2021-06-16  本文已影响0人  蓬篙人

纹理(Texture)

float texCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.5f, 1.0f
}

1. 纹理扭曲(texture wrapping)

// 设置x坐标轴范围外坐标处理方式为重复镜像纹理图形
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
// 设置y坐标轴范围外坐标处理方式为重复镜像纹理图形
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
1. 第一个参数设置纹理目标,该示例指定2D纹理坐标。
2. 第二个参数指定要设置的坐标轴。
3. 第三个参数指定纹理扭曲选项。
float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
glRexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

2. 纹理过滤(texture filtering)

// 缩减时使用最邻近过滤
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// 放大时使用线性过滤
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

3. 加载和创建纹理

4. 生成一个纹理

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
// 生成当前绑定纹理所需的mipmaps
glGenerateMipmap(GL_TEXTURE_2D);
1. 第1个参数:指定纹理目标。
2. 第2个参数:指定我们创建的纹理的mipmap层级。
3. 第3个参数:告诉OpenGL纹理的存储格式。
4. 第4和5个参数:纹理的宽高。
5. 第6个参数:总是0.
6. 第7和8个参数:指定源图像的格式和数据类型。
7. 最后一个参数:实际图像数据。
stbi_image_free(data);

5. 应用纹理

float vertices[] = {
    // positions            // colors         // texture
     0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,
     0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,
    -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,
    -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f
};
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
#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 ourTexture;

void main()
{
    // 使用GLSL内置的texture函数从纹理取样颜色
    FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
}
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// 片元着色器修改
FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
纹理和顶点颜色混合

6. 纹理单元(Texture Units)

glActiveTexture(GL_TEXTURE0);     // 先激活纹理单元
glBindTexture(GL_TEXTURE_2D, texture1);
#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D texture1;
uniform sampler2D texture2;

void main()
{
    // 第一个纹理取色80%,第二个纹理取色20%
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}
unsigned char* data2 = stbi_load("./Panda.png", &width, &height, &nChannels, 0);
if (data2)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Failed to load texture2" << std::endl;
}   
stbi_image_free(data2);
ourShader.use();
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);  // 手工设置
ourShader.setInt("texture2", 1);   // 使用自定义着色器类设置
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
上一篇下一篇

猜你喜欢

热点阅读