OpenGL:纹理Textures

参考资料:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/
学习笔记,不一当作参考教程,上面的参考资料是比较详细的参考教程

生成纹理

首先看一下生成纹理的代码片段,有个整体认识。

//生成纹理对象
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);
生成纹理对象

同样使用唯一ID引用的方法(需要了解以下怎么通过ID唯一引用的),和MFC的函数调用方式像不像

//生成纹理对象
unsigned int texture;
glGenTextures(1, &texture);
绑定纹理对象
//绑定纹理对象
glBindTexture(GL_TEXTURE_2D, texture);
为绑定的纹理对象设置环绕,过滤方式
设置环绕

当纹理坐标超过了0-1范围之后,OpenGL对纹理的处理。提供了四种方法,默认是GL_REPEAT重复纹理。
在这里插入图片描述
实现这个纹理环绕需要通过以下函数

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

glTexParameter*函数对单独的一个坐标轴设置(s、t(如果是使用3D纹理那么还有一个r)它们和x、y、z是等价的)。

尝试使用只对一个轴操作,和对两个轴操作的不同之处
设置过滤方式
邻近过滤

在这里插入图片描述

线性过滤

在这里插入图片描述

多级纹理

在这里插入图片描述
在这里插入图片描述

加载并生成纹理

需要使用一个第三方函数stb_image.hl这里帮忙加载纹理图片,读取数据。
注意使用这个头文件时应该如下:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
...
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);

注意读入图片的代码有的会这样写,但是可能会报错:

unsigned char *data = stbi_load(FileSystem::getPath("resources/textures/container.jpg").c_str(), &width, &height, &nrChannels, 0);

应用纹理

要想将生成的纹理应用到图形上,首先需要告诉OpenGL纹理映射坐标(纹理图像坐标),其次是利用采样器在对应位置采样纹理。

顶点着色器处理

在顶点上增加纹理映射坐标信息,顶点属性结构如下:
顶点属性坐标
用以下两行代码读取纹理坐标信息:

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()
{
    FragColor = texture(ourTexture, TexCoord);
}

Sample采样器,通过后缀1D 2D 3D决定是几维图像。

设置多个纹理

纹理单元:把纹理存在不同的位置(最多可以存16个)
通过激活不同的纹理单元实现对多个纹理的使用,需要按照对应顺序激活纹理。
一个纹理的默认纹理单元是0,它是默认的激活纹理单元,

// bind textures on corresponding texture units
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture1);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture2);

多个纹理下的片段着色器:

#version 330 core
...

uniform sampler2D texture1;
uniform sampler2D texture2;

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

补充

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值