OpenGL排坑指南—贴图纹理绑定和使用

一、前言

        在OpenGL学习 的纹理这一章中讲述了纹理贴图的使用方式,主要步骤是先创建一个纹理的对象,和创建顶点VAO类似,然后就开始绑定这个纹理,最后在循环中使用,有时候可能还要用到激活纹理单元的函数。然而,对于何时应该激活如何和shader里的纹理编号进行绑定没有详细的说明,导致在使用的时候产生了不少困惑。比如何时应该绑定,绑定后的索引如何匹配。

        在这一章的第一个效果案例:显示一个带贴图纹理的箱子时只用到了绑定而没有用到激活,部分主要代码如下:即使这样,在shader中也能让贴图获取到这里写进去的数据。

   while (!glfwWindowShouldClose(window)){-----glBindVertexArray(VAO);-----}

其shader的片段着色器代码如下,这个片段的“texture1”数据在上述循环中并未明确指定传过来的

// texture sampler
uniform sampler2D texture1;void main()
{FragColor = texture(texture1, TexCoord);
}

这是我第一个猜想:如果C++代码中只创建了一个纹理数据,不用激活和指定传输到片段着色器中,使用“ glBindTexture(GL_TEXTURE_2D, texture);”函数可以默认将片段着色器中的贴图都填充同样的数据。带着这个猜想我开始验证我的想法。

二、实现

2.1、如果只有一个贴图数据,默认传输到片段着色器的每一个“uniform sampler2D”

        其他都不变,我只修改片段着色器代码,首先我创建了两个uniform sampler2D变量,分别为texture1和texture2,然后稍微修改其片段着色器代码如下:如果这两个片段都获取到同样的数据则显示两倍的贴图效果,如果不相等则屏幕显示一个绿色的片。

// texture sampler
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{vec4 tempColor1=texture(texture1, TexCoord);vec4 tempColor2=texture(texture2,TexCoord);if(tempColor1==tempColor2){FragColor =tempColor1+tempColor2;}elseFragColor=vec4(0,1,0,1);
}

试验的结果得到如下,明显比之前要亮一点,很显然两个贴图都获取到循环里传输过来的贴图数据,而且是一样的。

图2.1.1
2.2、如果C++代码只有一个贴图,但我就想传给片段着色器中指定的纹理

1)只激活第一个并不管用:这个时候我尝试使用激活,我只激活第一个试试,结果和图2.1.1是一样的,两个纹理还是被传输一样的纹理数据。

		glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture);

2)两个都激活,但只赋值给第二个贴图,结果两个都没有得到数据:再尝试不同的激活方式,保持只传输一个纹理数据的逻辑,将第一个激活然后不赋值,激活第二个并且赋值贴图纹理,理论上这样应该是可以的啊,结果变成了黑的,如图2.2.1所示

		glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture);
图2.2.1

是不是两个贴图都没有获取到数据呢,我还不确定,再修改片段着色器判断一下:如果确实没有获取到数据则让屏幕显示“黄色”的箱子,结果如图2.2.2所示,确实显示了黄色的箱子,这说明我们

uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{vec4 tempColor1=texture(texture1, TexCoord);vec4 tempColor2=texture(texture2,TexCoord);if(tempColor1==tempColor2){if(tempColor1==vec4(0,0,0,1)){FragColor=vec4(1,1,0,1);}elseFragColor =tempColor1+tempColor2;}elseFragColor=vec4(0,1,0,1);
}
图2.2.2

贴图数据始终还是以默认的方式进行传输,第二个激活并传输并没有奏效,始终还是第一个激活才奏效。

3)再增加一个贴图的索引,结果可以精准的将数据传输到第二个贴图:代码如下,在激活之前给

		ourShader.setInt("texture2", 1);// bind TextureglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture);

当前的shader指定一个索引1,并且这个索引数值“1”一定要和后续绑定的“GL_TEXTURE1”对应,最后得到的结果是绿色的一个箱子,说明在片段着色器中贴图的数据不一样了。

三、总结

3.1、如果只有一个贴图数据,在C++中只用默认的绑定操作,默认传输到片段着色器的每一个“uniform sampler2D”变量中。

3.2、如果要指定传输给片段着色器中一定要使用激活贴图 glActiveTexture(GL_TEXTURE1);和        设置索引号ourShader.setInt("texture2", 1);同时使用,并且激活的序列号和设置索引值要相等,只使用索引也不行。

3.3、激活和设置索引以及绑定都要在循环里每帧都使用,尝试将索引设置不放在循环里也不行。

3.4、激活和绑定都是默认的情况下,设置索引没有任何作用,可以不用。比如在文章后续做一个2D游戏中的一篇文章里渲染精灵 其最后的游戏类代码中初始化时设置了纹理"image"的数据索引为0,但是其着色器代码中并没有”image“这个变量,而且此处

void Game::Init()
{......ResourceManager::GetShader("sprite").Use().SetInteger("image", 0);.......
}

无论你修改”image"为任何变量,比如“imageeeeeeeeeeeeeeee",它依然能显示正确的结果,因为这一篇文章中就是一个默认的贴图,而且激活和绑定都是执行默认的0,这里的索引就不会发生任何作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/616073.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

练习-sizeof()和strlen()

目录 前言解题技巧一、sizeof()练习题1.1 整型数组1.1.1 一维整型数组1.1.2 二维整型数组 1.2 字符数组1.3 字符指针 二、strlen()练习题2.1 字符数组初始化时不包含\02.2 字符数组初始化包含\02.3 字符指针指向字符串常量 总结 前言 最近有点疲倦,啊啊啊&#xff…

电容的基础知识

一、电容单位 电容亦称作“电容量”,是指在给定电位差下的电荷储藏量,记为C,国际单位是法拉(F)。在国际单位制里,电容的单位是法拉,简称法,符号是F,由于法拉这个单位太大…

vue3项目部署到服务器,刚打开没事,一刷新页面就404

vue3项目部署到服务器,刚打开没事,一刷新页面就404 vue3项目,在本地调试时各方面都没毛病,刷新也没毛病,但是,扔到服务器上,第一次打开是正常的,再刷新下就404了,不知道什…

GLES学习笔记---立方体贴图(一张图)

一、首先看一张效果图 立方体贴图 二、纹理坐标划分 如上图是一张2D纹理,我们需要将这个2D纹理贴到立方体上,立方体有6个面,所以上面的2D图分成了6个面,共有14个纹理坐标 三、立方体 上边的立方体一共8个顶点坐标,范围…

地图多点自动缩放,居中,思路和手写

效果如下 多个标记点顺次标记连接起来zoom缩放到合适等级,刚好能放下那么多点视野刚好在正中间 zoom 实现思路 获取多点的最大经纬度点和最小经纬度点(这两个点相距离最远)计算2个这两点之间的距离地图是有比例尺的,根据比例尺…

1.傅里叶处理图片原理和代码实现

在这里首先声明,本文纯粹看了别的博主的文章,觉得博主写的原理清晰明了,容易理解,很详细,在这里写一遍是作为笔记,方便以后再翻看时容易查找。大家可以参考下面这个博文: 图像的傅里叶变换_图像…

SAP OData(二)Association

Entity之间用Association来表示关联关系,可以同CDS view中的Association一起理解。 我们在上次已经建好实体Item的基础上,再建一个Header,其方法的重写也参考Item即可,然后开始本篇的探索。 一,构建Association 1.1…

脑科学与人工神经网络ANN的发展历程与最新研究

本文深入研究了ANN的基本概念、发展背景、应用场景以及与人脑神经网络的关系。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的…

抽奖机制模型及算法

抽奖机制 连抽保底概率模型不中概率加大模型(抽卡保底) 抽奖概率为n%,在达到某次次数后,每次概率比上次高m%,直至达到保底次数(概率累加和为100%),当抽到极品道具时候,…

网络传输(TCP)

前言 我们tcpdump抓包时会看到除报文数据外,前面还有一段其他的数据,这段数据分为两部分,ip包头(一般20字节)和tcp包头(一般20字节),一般这两个头长度和为40,我们直接跳…

SQL-DQL-基础查询

🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客主页:小小恶斯法克的博客 🎈该系列文章专栏:重拾MySQL 🍹文章作者技术和水平很有限,如果文中出现错误&am…

制造业管理者必备技能:掌握6S管理!

当今竞争激烈的制造业领域,为了提高效率、优化流程,并实现持续创新,制造业管理者需要掌握一种全面、系统的管理方法——6S管理。6S管理是源自于日本的精益管理方法,通过整理、整顿、清扫、标准化、维持和安全这六个步骤&#xff0…

基于SkyEye仿真6678处理器:实现国产操作系统ReWorks仿真运行

信号处理的数据量以及实时性的要求随着嵌入式技术的发展不断提高,众多厂商和研究所选择多核DSP处理器芯片去替代原有的单核DSP,并运行嵌入式操作系统来保证信号处理的实时性以及精确性。然而受到硬件资源或者项目实施周期限制,软件工程师调试…

Jmerer之FTP测试

1、文件上传下载测试,可以使用sample:FTP请求,当然也可以使用HTTP Request采样器中的File Upload向服务器上传文件 2、本章重点介绍FTP请求进行文件的上传下载测试,添加 FTP请求,界面主要配置如下: Server Name or I…

Linux 软连接ln -s

什么是文件软链接? Linux 的“软连接”与windos 的"快捷方式"相似。文件软链接(Symbolic Link 或 SymLink)是一种特殊的文件类型,它实际上是一个指向另一个文件或目录的引用。创建软链接时,系统会建立一个新…

访问学者申请需要注意什么?

访问学者申请是一项复杂而重要的过程,需要申请人在准备材料和过程中注意一些关键事项,以确保顺利完成申请并提高成功率。以下是知识人网小编的一些建议,希望对你的访问学者申请有所帮助。 1. 详细了解目标学术机构: 在申请访问学…

SQL性能分析-整理

昨日对MySQL的索引整理了一份小文档,对结构/分类/语法等做了一个小总结,具体文章可点击:MySQL-索引回顾,索引知识固然很重要,但引入运用到实际工作中更重要。 参考之前的文章:SQL优化总结以及参考百度/CSDN…

深入探讨:开发连锁餐饮APP的关键技术要点

时下,开发一款功能强大、用户友好的连锁餐饮APP成为许多餐饮企业的当务之急。在本文中,我们将深入探讨开发连锁餐饮APP的关键技术要点,涵盖了前端、后端以及数据库等方面。 一、前端开发 前端是用户与APP交互的入口,因此设计良好…

比尔盖茨:如果只能解决一个问题,我的答案总是营养不良

谷禾健康 当地时间12月19日,微软联合创始人、亿万富翁比尔盖茨发布了对来年的年度预测,称 2024 年将是一个“转折点”。 在这封长达 10 页的信中他展示了对人工智能领域的更多创新、婴儿营养不良问题的突破、气候变化谈判的进展等多方面的期待。 人工智能…

【iOS】数据持久化(四)之FMDB

正如我们前面所看到的,原生SQLite API在使用时还是比较麻烦的,于是,开源社区就出现了一系列将SQLite API进行封装的库,其中FMDB的被大多数人所使用 FMDB和SQLite相比较,SQLite比较原始,操作比较复杂&#…