范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

一看就懂的OpenGLES教程这或许是你遇过最难画的三角形(五)

  通过阅读本文,你将获得以下收获:
  1.客户端程序使用uniform变量指定颜色值
  2.客户端程序使用顶点属性数组指定图形的渲染颜色
  3.OpenGL es光栅化的插值现象
  天青色等烟雨, 而我在等你
  月色被打捞起, 晕开了结局
  OpenGL ES绘制三角形的博文已经到了第五篇了, 今天也正是要揭开结局——绘制完成之前指定的目标三角形。  上篇回顾
  上一篇文章 已经详细展示了OpenGL如何绘制各种的基本图元。之前定的绘制三角形任务已经完成了绘制,不过万事俱备只欠东风,上一篇里三角形用的是单一颜色 ,而我们一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)在指定的三角形终极任务是这样的:
  所以我们还差给三角形上这种渐变色效果 ,一旦加上渐变色效果,那么这个绘制三角形的小系列就剧终了,入门OpenGL es我觉得至少算成功一半了吧。 客户端程序指定渲染颜色
  之前的例子片段着色器都是将颜色写固定在代码中的: FragColor = vec4(1.0,0.5,0.5,1.0);
  这样的话客户端就无权控制绘制的颜色了,显然不符合广大人民群众的需要,从客户端传颜色到着色器中就成了必需项。
  这么传呢? 使用uniform变量传单一颜色值
  之前文章对GLSL的叙述中,我们已经接触过了out、in修饰的变量,那么今天要再认识一个变量修饰符了,名曰:uniform
  "uniform"的英文单词有一致的,统一的意思,在这里也算是描述很精准,它表示在一次渲染中不会被改变的变量,类似Java中的final修饰符。所以相对于之前的out、in修饰的变量,它比较牛逼,它是一个渲染管线中的全局常量。 一般用于储存变换矩阵、光参数和颜色等。
  那么怎么理解渲染管线中的全局常量呢?
  C++音视频学习资料免费获取方法:关注音视频开发T哥  ,+「链接」 即可免费获取2023年最新 C++音视频开发进阶独家免费学习大礼包!
  这里的全局是相对一个渲染阶段的一次着色器执行周期而言的。比如在先前文章的例子中,我们传了三个顶点坐标给着色器的vertex 变量,会导致执行三次顶点着色器代码,三次执行中的vertex 变量值都是不一样的,所以vertex 变量就不是一个全局变量。
  但是对于用uniform 修饰的全局常量来说,在一次渲染中,不管执行多少次着色器代码,它都是同一个值,而且是在整个渲染管线内保持同一个值的。
  之所以uniform 全局常量有这种功能,是因为它是保存在着色器程序对象中的,在硬件上体现在全局数据区中 。 uniform全局常量代码实例
  顶点着色器不用改动:         #version 300 es         layout (location = 0)          in vec4 aPosition;//输入的顶点坐标,会在程序指定layout将数据输入到该字段          void main() {            //直接把传入的坐标值作为传入渲染管线。gl_Position是OpenGL内置的表示坐标的变量             gl_Position = aPosition;                        }"
  对于片段着色器来说,新增一个uniform变量 uTextColor,类型为vec4,用来接收客户端程序传入的颜色值:         #version 300 es         precision mediump float;          uniform vec4 uTextColor;//输出的颜色         out vec4 FragColor;          void main() {             FragColor = uTextColor;         };
  对了,因为uniform独特的全局地位,所以客户端程序传值的时候并不用从渲染管线头部开始传 ,而是直接一步到位将数据丢给uniform变量 ,所谓可以直捣黄龙: static float color[] = {         //表示RGBA         0.0f, 1.0f, 0.0f,1.0f };  //获取到uTextColor在着色器程序中的location int colorLocation = glGetUniformLocation(program, "uTextColor"); //通过location去传入一个color向量 glUniform4fv(colorLocation,1, color);
  这里首先还是熟悉的老套路,欲得到一个变量的修改权,必先拿到它的location ,location就是它的引用,这也是OpenGL惯用的套路,拿到引用后,再通过修改方法就可以给其赋值。
  这里通过glGetUniformLocation 方法拿到location ,然后通过glUniform4fv 方法来修改。
  glUniform4fv 是OpenGL中对uniform变量赋值全家桶 的其中一个方法,最后的v表示uniform变量类型为向量vec ,对于全家桶中修改向量的方法系列,其基本格式为: glUniform + n维向量 + 向量元素数据类型 + v
  (glUniform*系列方法详细可见官方文档:registry.khronos.org/OpenGL-Refp…)
  着色器中的vec变量在客户端程序可以通过数组来表示 ,所以这里传入color数组即可,color数组就是一个rgba的颜色值 。
  运行一下,果然是一个绿油油的三角形:
  使用顶点属性传颜色值
  之前强调过,我们传给顶点着色器的叫做顶点属性数组 ,而不是顶点数组 ,因为顶点坐标是一个属性,那么我们是不是可以添加一个颜色属性呢?
  怎么添加颜色属性呢?
  第一种方式 是增加一个颜色的数组,这样就有两个数组: static float triangleVer[] = {         0.0f, 0.8f, 0.0f,//顶点         -0.8f, -0.8f, 0.0f,//顶点         0.8f, -0.8f, 0.0f,//顶点 };  static float colors[] = {         1.0, 0.0, 0.0,//颜色         0.0, 1.0, 0.0,//颜色         0.0, 0.0, 1.0,//颜色 };
  然后调用2次glVertexAttribPointer方法分别解析这2个数组: //解析顶点坐标数据 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, triangleVer); //解析颜色数据 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, colors); //分别打开着色器中layout为0,1的变量开关 glEnableVertexAttribArray(0); glEnableVertexAttribArray(1);
  此时顶点着色器相应地增加一个输入变量aColor来接受颜色属性 ,并且增加一个输出给后面阶段着色器的out变量vTextColor :         #version 300 es         layout (location = 0)          in vec4 aPosition;//输入的顶点坐标,会在程序指定layout将数据输入到该字段                  layout (location = 1)           in vec4 aColor;//输入的顶点的颜色                  out vec4 vTextColor;//输出的颜色          void main() {            //直接把传入的坐标值作为传入渲染管线。gl_Position是OpenGL内置的表示坐标的变量             gl_Position = aPosition;                //颜色传给下一个阶段             vTextColor = aColor;          }
  片段着色器代码如下所示,关键是定义一个接受上个阶段输入的颜色的in修饰的上个阶段着色器同名的变量vTextColor :        #version 300 es        precision mediump float;        out vec4 FragColor;                in vec4 vTextColor;//从上个阶段输入的颜色          void main() {            //输入的颜色给当前片段赋颜色值            FragColor = vTextColor;          }
  简单来说,就是在流水线上,前面工序的工人吼一声,后面拥有vTextColor盒子(变量)的工序的人记得接住我这里的vTextColor物料(变量值) 。
  这种方式没问题,但是每次增加一个属性就要增加一个数组 ,显示不符合资深程序员的身份。于是乎第二种方式 更加科学一些,这个方法可以叫做见缝插针法,在每个顶点坐标中间插一个rgb的颜色值 : static float triangleVerWithColor[] = {         0.0f, 0.8f, 0.0f,//顶点         1.0, 0.0, 0.0,//颜色                  -0.8f, -0.8f, 0.0f,//顶点         0.0, 1.0, 0.0,//颜色                  0.8f, -0.8f, 0.0f,//顶点         0.0, 0.0, 1.0,//颜色 };
  这样子依旧是三个顶点,但是每个顶点分别有两个属性:坐标和颜色 ,这样子的好处是无论多少个属性,都可以用一个顶点属性数组解决 。
  解析逻辑要怎么调整呢? //解析顶点坐标数据 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, triangleVerWithColor); //解析颜色数据 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, triangleVerWithColor + 3); //分别打开着色器中layout为0,1的变量开关 glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); 复制代码
  在一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(二) 中的传递数据给着色器 章节曾分析过glVertexAttribPointer方法是如何解析顶点属性数组的,那么现在多了一个颜色属性,解析顶点属性就变成:
  顶点属性数组每3个元素为一个顶点坐标 ,从数组的第0个元素 开始取,每间隔4*6 (一个float4个字节,一个顶点开头到下一个顶点开头距离6个浮点数)取一次。 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, triangleVerWithColor);
  这是原来只有坐标属性的顶点属性数组:
  那么接下来取颜色属性就依葫芦画瓢即可:
  顶点属性数组每3个元素 为一个顶点颜色值,从数组的第4个元素(注意数组地址偏移+3) 开始取,每间隔4*6 (一个float4个字节,一个顶点开头到下一个顶点开头距离6个浮点数)取一次。 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, triangleVerWithColor + 3);
  如今添加了颜色属性,于是数组摇身一变:
  而客户端程序,就是要把这个结构清晰地告诉给OpenGL ,而具体的表达方法,就是通过glVertexAttribPointer 方法。总之,你要玩几个数组随你,但是要明确告诉OpenGL怎么解析即可~
  一切貌似很顺利,不过聪明的你可能已经觉察到了一丝不对劲……
  按照如上做法,也不过每个顶点传了一个颜色属性 ,一个三角形像素那么多,你只给顶点传了颜色,其他点咋整啊?
  管那么多,先运行看看效果
  这不就是一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一) 里面提到的绘制三角形的任务的终极目标么。
  但是这种有点酷毙的渐变颜色是怎么形成的呢?光栅化的插值现象
  不知各位记得不,在 一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(三) 中,我曾埋过一个小小的彩蛋:
  每个光栅化产生的片段,会携带位置信息 ,以及顶点着色器产生的数据的插值信息 。
  这里的插值信息 如何理解?
  我们在看下这张经典的图形渲染管线图:
  在光栅化中,光栅化器将装配好的图元切成一个个片段,但是我们在外部传入的是顶点属性,但是这些属性往往不是只有顶点才需要的,而是每个片段都需要的,那么光栅化器是如何把这些属性带给每个片段呢?答案便是:线性插值大法 。
  【文章福利】 免费领取 更多 音视频学习资料包 、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hlsrtsp ffplay srs 等等)有需要的可以点击「链接」加君羊领取哦~
  线段的线性插值
  让我们再回到线段的绘制,只是这次改用类似上面的方式给线段2个顶点传入不同的颜色值,比如左边红色(1.0, 0.0, 0.0),右边为蓝色(0.0, 0.0, 1.0),绘制出来的线段如下图所示:
  通过线段,能够比较明显看出颜色渐变的规律了。 左端最红,然后从左往右逐步蓝色化,直到最右最蓝。
  聪明的你可能可以看出是呈现线性变化的,那么用数学语言表示即为:
  假如线段上的某个点距离左端点的距离占线段长度比例为a,距离右端点的距离占线段长度比例为b,且左端点的属性为r,右端点属性为g,则该点上的属性c为: c = r*a + g*b
  在上面的例子中,对于线段中点来说,它的颜色便是: (1.0, 0.0, 0.0)*0.5 + (0.0, 0.0, 1.0)*0.5 = (0.5,0.0,0.5)三角形的线性插值
  对于三角形来说,同理,只是它不再是看距离,而是看面积占比 。
  假如当前点如图所示,Aa,Ab,Ac分别为该点和其他另外2个点连成的三角形面积,则比例系数分别为:
  则对于该点来说,它的某个属性值为三个顶点该属性的线性插值:
  按照这个公式,则我们上面绘制的三角形内部的中心点颜色值为: (1.0, 0.0, 0.0)*0.5 + (0.0, 1.0, 0.0)*0.5 + (0.0, 0.0, 1.0)*0.5 = (0.5,0.5,0.5)
  加餐:如何证明片段着色器每个片段执行一次?
  这个结论其实在之前的博文已经讲过,不过如何去证明呢?
  经过上文描述的线性插值,我们直到了所有顶点属性都会在光栅化阶段被线性插值处理,那么定带你坐标自然也会被处理,处理之后的结果是每个片段上的获取到的坐标就是它的中心点的坐标 。所以将顶点坐标作为一个out类型变量传给片段着色器,那么片段片段着色器拿到的就是当前片段的坐标点 。
  那么如果这里突发奇想,将坐标值作为颜色值赋值给片段颜色,那么如果显示的颜色和对应坐标的一一对应的,就能说明片段着色器是每个片段执行一次 。
  修改顶点着色器代码如下所示:
  顶点着色器:          #version 300 es                 layout (location = 0)                  in vec4 aPosition;//输入的顶点坐标,会在程序指定将数据输入到该字段                         out vec4 vTextColor;//输出的颜色                  out vec4 vPosition;//输出的坐标                          void main() {                    //直接把传入的坐标值作为传入渲染管线。gl_Position是OpenGL内置的                     gl_Position = aPosition;                     //把坐标输出给片段着色器                     vPosition = aPosition;                                  };   #version 300 es   precision  mediump float;    in vec4 vTextColor;//输入的颜色   out vec4 FragColor;//最终的片段颜色    in vec4 vPosition;//输入的坐标,注意这里得到的是顶点的坐标插值的结果,即当前片段的坐标值    void main() {        //确定当前片段颜色,这里设置为传入的坐标值        FragColor = vec4(vPosition.x ,vPosition.y ,vPosition.z,1.0);   };
  因为是作为颜色值,所以就都传入正数的坐标,为了控制变量使得观察方便,所以蓝色分量设置为0: static float triangleVer[] = {        0.8f, 0.0f, 0.0f,        0.0f, 0.0f, 0.0f,        0.0f, 0.8f, 0.0f,  };
  再次敲黑板,这里最需要注意的点,就是顶点着色器传过来的vPosition变量是经过光栅化线性插值过的,所以拿到的是当前片段的坐标,而不是三个顶点的坐标(当然三个顶点所在的片段拿到的就是对应顶点的坐标)。
  运行结果:
  又是一个渐变色的三角形映入眼帘。我们细细观察一下,可以看到越接近(0,0)点的颜色越接近黑色,越接近顶部的点越绿色,因为此时横坐标越接近0,纵坐标越大,所以红色分量越少,绿色分量越大。反之,越靠右的点越红 。
  所以可以证明片段着色器每个片段执行一次!
  总结
  本文主要讲uniform类型变量的特点和使用,以及讲解了OpenGL一个很重要的特性,即光栅化中的线性差值效应,本文终于完成了渐变色三角形的绘制,下一篇文章讲将关注新的内容:一看就懂的OpenGL ES教程——缓冲对象优化程序(一) 代码地址
  opengl-es-study-demo (不断更新中) 参考
  《OpenGL超级宝典》第五版 你好,三角形 Uniform (GLSL)
  作者:半岛铁盒里的猫 链接:https://juejin.cn/post/7145094035521470500 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  在开发的路上你不是一个人,欢迎加入 C++音视频开发交流群大家庭「链接」讨论交流!

美媒列出了202120212022赛季也差不多要结束了,对于不少球队打造的球星组合,或许我们应该认真评估一下了。因此,美媒列出了20212022赛季目前最好的十组双巨头,究竟哪组实力最强,让我们来看恭喜詹姆斯!恭喜浓眉!佩林卡钦点留队第一人,他是老詹带刀侍卫恭喜詹姆斯!恭喜浓眉!佩林卡钦点留队第一人,他是老詹带刀侍卫!毫无疑问,湖人去年休赛期的引援补强是极其失败的!尽管在自由市场大张旗鼓地捞得众多老将,但这并没有为他们带来想要的结果!否认让西蒙斯走恩比德我不明白发生什么事NBA年度MVP热门人选费城76人一哥恩比德在和金州勇士好友格林视频连线时,否认自己让西蒙斯离开,强调2人之间完全没问题,自己根本不明白发生什么是导致西蒙斯不愿为76人上场比赛。格黄晓明的婚礼有毒吧!嘉宾不是离婚就是被封杀老话说得好,世事无常,我们永远都不知道下一秒会发生什么,这句话用在黄晓明的身上是再合适不过了,想当初,黄晓明和杨颖的世纪婚礼不知道吸引了多少人的目光,然而仅仅6年的时间,一切都已经贝克汉姆一家过节,贝嫂小七戴兔耳朵超可爱,老大与儿媳狂撒狗粮近日,贝克汉姆一家团聚,一起过复活节,贝克汉姆携全家举行复活节聚会,其中,马上要举行婚礼的贝克汉姆的大儿子布鲁克林,带着他的未婚妻妮可拉,也来与贝克汉姆一家一起过节。照片中,贝嫂与谁说五官立体才是美?这10位大饼脸女星,个个都难以超越如今很多人认为五官立体浓眉大眼才是美,但其实圈中不少大饼脸的女星,虽然侧脸不够突出,但也美得别有韵味。今天就来说说圈中10位大饼脸的女星,她们的美各有特色,个个都难以超越,不是如今城厢镇李子花开似雪海春光明媚,百花争艳,城厢镇李子花也悄然缀满枝头,漫山遍野,似雪落山间,形成一片雪海,如梦如幻。一起云游花海据了解,目前城厢镇种植青脆李1。6万亩,投产面积9600亩。今年,在镇党委在线音乐这半年版权停火,神曲搅局图片来源视觉中国文深燃(shenrancaijing),作者李秋涵,编辑魏佳在线音乐行业正在暗流涌动。距离国家版权局责令腾讯音乐解除独家版权,已经过去了半年多时间。这个久未起波澜的小米MIX5渲染图首发2亿主摄5500mAh,强悍配置售价可能要涨了还记得去年小米mix4发布的时候意气风发,带来了全陶瓷工艺的外观让不少米粉都是眼前一亮,其次去年8月份小米mix4的发布也在掀起了整个八月份的数码热潮,而在今年不少朋友都在猜测小米多国出现德尔塔克戎,专家目前不必过度担忧(人民日报健康客户端记者孔天骄)由德尔塔和奥密克戎重组的新病毒变体德尔塔克戎(Deltacron)已经在法国荷兰巴西和丹麦等多个国家被检测到。有人会发出疑问,当德尔塔奥密克戎这两个人生下半场,活出孤独力伴随手机功能的提升社交软件的应用,我们处在一个无时无刻不与他人连接的时代,孤独的定义也变得和以前不一样了。以前,孤独是一个人吃饭逛街去医院,现在,孤独是精心挑选照片撰写文案发朋友圈
世界上最贵的钻石,约合人民币4亿元,快来一饱眼福问题怎么才能每天都收到这种文章呢?答案只需要点击右上角关注即可。大家好,我是东方,今天我们来聊一聊世界上最贵的钻石。论珠宝中的奢侈品,肯定有钻石的一席之地了,钻石的品质和价值依据纯上班族的咖啡怎么选?来看看这4款,醇香浓郁,大碗便宜,超实惠上班族的咖啡怎么选?来看看这4款,醇香浓郁,大碗便宜,超实惠作为一名上班族,每天工作的精力全都是咖啡给予的,每天早上被闹钟强制叫醒,拖着疲惫并且没有精神的身躯前去上班打卡,等到办公茅台酒茅台集团酒茅台镇酒,三者有啥区别?弄懂再买不吃亏常言道一人得道,全家升天。不知道各位酒友听过这句老话没?不过它用在茅台身上也是极其合适的。作为大曲酱香型白酒的鼻祖,茅台今日的地位,在整个酒界中可以说是至高无上的。它在酒圈更是有着欧米茄计时三问表,开辟制表业前所未有的超级复杂腕表欧米茄于10月末推出品牌的非凡新作计时三问表,开创了制表史上首次可以鸣报计时时间的超级大复杂表,这一消息的发布如同在表坛投下了一枚重磅炸弹。该款腕表结合了计时和三问的功能,但完全突更时髦的卡罗拉?第五代普锐斯发布,居然有四驱近日,丰田汽车对外发布了第五代Prius和PriusPrime的官图(国内称之为普锐斯),和国内的卡罗拉三厢一样,新车基于TNGA架构GAC平台,但在设计层面上更偏个性化和前卫气质人类进入太空是否安全?国际空间站的实验揭示未来太空飞行的风险一个国际科学家小组在国际空间站上进行了一项长期实验,研究空间辐射对小鼠胚胎干细胞的影响。他们的研究将帮助科学家对未来人类太空飞行的空间辐射的风险和安全性做出更准确的评估。该团队最近吃鸡怎么判断队友是菜鸡?10个细节道出真相,不服不行欢迎诸位小伙伴们来到天哥开讲的和平精英精英小课堂众所周知,由于这款游戏本身的机制设定缘故,导致大多数玩家都以随机匹配为主。也正因此,我们总能遇到许多菜鸡队友。大多数情况下,判断队友王鸥何九华同居了!女方曾婚前当落跑新娘,当众向包贝尔索吻王鸥和何九华之间的感情纠葛,已经持续了一年多的时间,两人多次被拍到一起约会,还一起参加妹妹的婚礼,何九华被曝随了66万的礼金。虽然两个人没有承认恋情,但德云社的师兄弟们已经默认了,2天6个瓜,刘恺威大方承认恋情,袁冰妍疑似复出,都是大瓜近两天,娱乐圈可以说相当不太平,仅仅两天,又出现了多个大瓜,复出,官宣恋情,可以说每一件都很劲爆!1央视频官宣王冰冰复出这几天,相信大家也都看到了一条热搜,叫做王冰冰真的回来了,应牛顿如何炒股破产的?我们一起来揭秘牛顿是一位了不起的科学家,它的背景不用说大家肯定都了解,下面说的是牛顿炒股。说起牛顿炒股,得先说下1720年,英国南海公司的泡沫事件。这是历史上第一次重大的金融危机。1701年至12022。11。19上证指数接下来怎么走11月上半个月基本都是赚钱行情,接下来怎么走?先简单说说我的观点上证指数年底有望在3000点附近筑底成功,然后一路涨到3400如果在3000点筑底失败,真正的底部可能在2863以下