OpenGL笔记(4)纹理
纹理单元的理解
Shader中要用到纹理:
uniform sampler2D texture1;
Main读取图片数据,创建了纹理:
unsigned int texture1;
怎么把c++里加载的纹理传给shader程序里呢?
这就要用到纹理单元。
glBindTexture(GL_TEXTURE_2D, texture1);
这条代码将纹理texture1传递给了正在使用的着色器程序里的uniform sampler2D texture1
中间隐含过程是,opengl有许多默认的纹理单元(GL_TEXTURE0,GL_TEXTURE1,GL_TEXTURE2~GL_TEXTUREn),
其中,默认激活的是纹理单元0——GL_TEXTURE0,上面的代码就把纹理传递给了这个默认激活的纹理单元0;
另一方面,在shader里声明的采样器——unigorm sampler,他会从一个特定的纹理单元里取得纹理数据,而这个特定的纹理单元是GL_TEXTURE0~n中的哪一个呢?
答案是,在shader里声明的每一个采样器,其默认对应的纹理单元是GL_TEXTURE0;
所以,使用上面的一行代码,其中的过程是这样的:
1、没有选择激活纹理单元,所以使用默认的纹理单元0
2、把纹理texture1传递给了纹理单元0
3、没有设置shader里的采样器对应的纹理单元,所以采样器从默认的纹理单元0读取数据
这样会使shader里所有的采样器(如果声明多个的话)都从纹理单元0中获取纹理数据,很明显这样就会使声明的采样器都一样了。
但是我们声明多个采样器明显是想在一个着色器里使用多个不同的纹理,那么该怎么做?
着色器里有多个采样器,像是这样:
#version 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.5);
//FragColor=texture(texture1,TexCoord);
}
回头看之前的步骤,只要完成原先省略做的事就好了

1、绑定纹理时,先选择激活相应的纹理单元
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
2、设置shader里声明的采样器所对应的纹理单元
glUniform1i(glGetUniformLocation(myShader.ID, "texture1"), );
myShader.setInt("texture2", ); // 或者使用着色器类设置
两中方法,都是先找到shader中的采样器”texture1”/”texture2”的地址,然后设置其对应的纹理单元,0是指GL_TEXTURE0,1对应GL_TEXTURE1,2、3以此类推。
Texture类
模仿Shader类写了自己的Texture类(重复操作实在太多了
class lxlTexture {
public:
unsigned int Id;
lxlTexture(){}
lxlTexture(const GLchar* texPath,GLint format) {
glGenTextures(, &Id);
glBindTexture(GL_TEXTURE_2D, Id);
// 为当前绑定的纹理对象设置环绕、过滤方式
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;//颜色通道个数
stbi_set_flip_vertically_on_load(false);
unsigned char* data = stbi_load(texPath, &width, &height, &nrChannels, );
//导入读取的图片文件数据,处理生成纹理
glTexImage2D(GL_TEXTURE_2D, , format, width, height, , format, GL_UNSIGNED_BYTE, data);
////-解释-
//上面把纹理绑定到了GL_TEXTURE_2D,现在这个参数选择了GL_TEXTURE_2D为目标,处理绑定在上面的纹理
//参数为纹理指定多级渐远纹理的级别,如果你希望单独手动设置每个多级渐远纹理的级别的话。这里我们填0,也就是基本级别。
//第三个参数告诉OpenGL我们希望把纹理储存为何种格式。我们的图像只有RGB值,因此我们也把纹理储存为RGB值。
//第四个和第五个参数设置最终的纹理的宽度和高度。我们之前加载图像的时候储存了它们,所以我们使用对应的变量。
//下个参数应该总是被设为0(历史遗留的问题)。
//第七第八个参数定义了源图的格式和数据类型。我们使用RGB值加载这个图像,并把它们储存为char(byte)数组
//最后一个参数是真正的图像数据。
//自动生成多级纹理
glGenerateMipmap(GL_TEXTURE_2D);
//释放
stbi_image_free(data);
std::cout << Id << std::endl;
}
void bindTexture(int num) {
switch (num) {
case :
glActiveTexture(GL_TEXTURE0);
break;
case :
glActiveTexture(GL_TEXTURE1);
break;
case :
glActiveTexture(GL_TEXTURE2);
break;
case :
glActiveTexture(GL_TEXTURE3);
break;
case :
glActiveTexture(GL_TEXTURE4);
break;
case :
glActiveTexture(GL_TEXTURE5);
break;
case :
glActiveTexture(GL_TEXTURE6);
break;
case :
glActiveTexture(GL_TEXTURE7);
break;
default:
std::cout << "纹理绑定支持0~7"<<std::endl;
}
glBindTexture(GL_TEXTURE_2D, Id);
}
void SetWrap(GLint pname) {
if (pname == GL_REPEAT || pname == GL_MIRRORED_REPEAT || pname == GL_CLAMP_TO_EDGE || pname==GL_CLAMP_TO_BORDER) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, pname);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, pname);
}
else {
std::cout << "输入不是设置环绕方式" << std::endl;
}
}
void SetWrapS(GLint pname) {
if (pname == GL_REPEAT || pname == GL_MIRRORED_REPEAT || pname == GL_CLAMP_TO_EDGE || pname == GL_CLAMP_TO_BORDER) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, pname);
}
else {
std::cout << "输入不是设置环绕方式" << std::endl;
}
}
void SetWrapT(GLint pname) {
if (pname == GL_REPEAT || pname == GL_MIRRORED_REPEAT || pname == GL_CLAMP_TO_EDGE || pname == GL_CLAMP_TO_BORDER) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, pname);
}
else {
std::cout << "输入不是设置环绕方式" << std::endl;
}
}
void SetFilterMag(GLint pname) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, pname);
}
void SetFilterMin(GLint pname) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
};
使用
//初始化
mytexture1 = Texture("Resource/Texture/container.jpg",GL_RGB);
mytexture2 = Texture("Resource/Texture/awesomeface.png",GL_RGBA);
//传递
mytexture1.bindTexture();
mytexture2.bindTexture();
OpenGL笔记(4)纹理的更多相关文章
- Opengl ES之纹理贴图
纹理可以理解为一个二维数组,它可以存储大量的数据,这些数据可以发送到着色器上.一般情况下我们所说的纹理是表示一副2D图,此时纹理存储的数据就是这个图的像素数据. 所谓的纹理贴图,就是使用Opengl将 ...
- opengl笔记——旋转,一段代码的理解
重看:opengl笔记——OpenGL好资料备忘 在找到这段代码,对理解opengl旋转很有帮助 ... glPushMatrix(); // initialze ModelView matrix g ...
- Android OpenGL ES(八)----纹理编程框架
1.把纹理载入进OpenGL中 我们的第一个任务就是把一个图像文件的数据载入到一个OpenGL的纹理中. 作为開始.让我们又一次舍弃第二篇的框架.又一次创建一个程序,新建一个util工具包,在该包下创 ...
- Linux OpenGL 实践篇-5 纹理
纹理 在之前的实践中,我们所渲染的物体的表面颜色都是纯色或者根据顶点位置计算出的一个颜色,这种方式在表现物体细节方面是比较吃资源的,因为我们每增加一个细节,我们就需要定义更多的顶点及其属性.所以美术人 ...
- OpenGL 多线程共享纹理
1:opengl 多线程共享纹理纹理: //解码时候使用opengl进行绘制,需要构建队列和两个线程,分别用于解码数据并且填充纹理和渲染. 主线程常见两个共享上下文: main() { ⋯⋯⋯⋯ gH ...
- OpenGL笔记(一) 绘制三角形
GLTools: 一些有用且可复用的函数 GLEW: OpenGL API的一些扩展机制 GLUT: OpenGL Utility toolkit, OpenGL跨平台相关,隐藏平台相关细节 RC代表 ...
- OpenGL学习笔记(3) 纹理
关于纹理 一般游戏里的物体不一定都是纯色的物体,物体上面会有一些图片贴在上面,比如墙壁,箱子,地板,可以看到砖头.木板和大理石组成的图片,要把图片贴到计算机里的几何图形的话,就要把图片的颜色采样贴到几 ...
- OpenGL超级宝典笔记——深度纹理和阴影 【转】
目录[-] 光源视角 新型的纹理 深度纹理的大小 首先绘制阴影 然后是光照 投影阴影贴图 阴影比较 之前我们介绍过简单的把物体压平到投影平面来制造阴影.但这种阴影方式有其局限性(如投影平面须是平面). ...
- OpenGL的glTexCoord2f纹理坐标配置
纹理坐标配置函数,先看定义: void glTexCoord2f (GLfloat s, GLfloat t); 1.glTexCoord2f()函数 有两个参数:GLfloat s, GLfloat ...
随机推荐
- CSS3 边框 border-image
border-image:xx xx xx 是一系列参数的简写,该属性将图片作为边框修饰 border-image-source:url(border.png); 图片url地址 border-ima ...
- rhel7学习第一天
今天是在线学习刘遄老师<Linux就该这么学>的第一天,对Linux的发展和优越性有了进一步的了解.
- 以太网PHY寄存器分析【转】
转自:https://blog.csdn.net/Firefly_cjd/article/details/79825869 以太网PHY寄存器分析 1 1.以太网PHY标准寄存器分析 2 ...
- Linux命令——ethtool
转自:https://www.cnblogs.com/kelamoyujuzhen/p/10116423.html 参考:9 Linux ethtool Examples to Manipulate ...
- Centos 7 修改网卡名称、静态IP
修改内核选项 # vim /etc/sysconfig/grub GRUB_TIMEOUT= GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc ...
- Eyoo大学生交友平台
团队简介 团队名称 golden express 队员学号列表 王伟 201731062214 刘冬 201731062227 张旭 201731062129 秦裕航 201731062432 (组长 ...
- flask 上下文
上文:找到被创建成字典形式的东西 下文: 找到request并执行
- 201777010217-金云馨《面向对象程序设计(java)》第十三周学习
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- java执行hive命令或者脚本
java执行脚本 import java.io.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...
- Eclipse的server选项卡中找不到tomcat配置项
1.在Eclipse中,如果想开发j2ee,必须要先安装插件.至于具体的插件安装方法,这里不再赘述. 2.当进行到配置tomcat服务器的时候,有时候会出现这种情况: 3.在server选项卡的Run ...