着色器在OpenGL中发挥着重要作用,它就像一个画笔,将输入的数据流,转为数学坐标,再将三维坐标变成二维坐标(针对我们现在用的二维显示器,全息显示器肯是三维的),再把二维坐标实际的像素点位置(这里面肯定存在的粗略的误差,比如(3.423,234.232)肯定在实际像素中不存在,要转换成邻近的),然后再往里面填充色彩,透明度之类的参数。      准确来说其实就是两步工作1.确定位置2.填充色彩。       处于输入输出与处理接口分开的原则,我们不考虑输入的数据具体是什么,这里只讨论如何去处理数据。

这里先上一张图,着色器程序分为六个小着色器部分,每个负责一部分

       这里先解释一个专业术语“图形渲染管线”,这个就是上图显示的,像生产线一样的一条“管道”,进去数据流,出来一个像素画面。
当然咱们只可以编写三个着色器阶段,其中顶点着色器和片段着色器没有默认的,所以我们一开始只需要编写这两个简单的就可以了。
注意着色器严格来讲不是用c语言去编写的,而是一种GLSL的类c语言,它是c语言的变种,我们常把写好的着色器程序作为一个字符串,再运行的时候用一个函数(c语言编译器肯定没法编译glsl,需要一个函数进行转换)动态编译,然后将机器码放在GPU显存上运行。

接下来我们讨论如何去写着色器:

一个典型的着色器有下面的结构:
#version version_number//版本声明。一般版本必须和opengl一致,此外还有模式声明
in type in_variable_name;//输入变量类型声明
in type in_variable_name; out type out_variable_name;//输出变量类型声明 uniform type uniform_name; int main(){
// 处理输入并进行一些图形操作
...
// 输出处理过的结果到输出变量
out_variable_name = weird_stuff_we_processed;
}
看得出着色器语言的程序,关键在于1.得到上一阶段的数据2,将数据处理3,把数据交给下一阶段
对于实现第一步和第三步,GLSL语言都有方便手段,就是IN,OUT关键字。只要在main函数前面声明的out 都将自动传递给接下来的着色器
同样着色器必须接受相同的in 同名变量数据输入。
也就是说,如果在顶点着色器声明了一个out vec3 aaa变量,那么接下来在片段着色器声明一个in vec aaa变量,那么自动这两个变量都会链接在一
起,数据自动传递过来。
//注意在着色器程序中,六个着色器都是独立的,in out是它们的通讯手段,它们本身是六个独立的小程序,变量都是独立的,传递是一种赋值
手段。

Uniform: 在程序中,我们想要实现动画,也就是说每次渲染都有变化,这种变化是连续的,那么我们就需要程序CPU和着色器(渲染),相互配合,在每次渲染中都改变,也就是我们需要一种可以在着色器程序和CPU程序相互交流的工具。所以我们需要一种独立于六个小程序,处于着色器程序的全局变量用来交流,否则我们无法告知CPU的程序如何去联系位于哪个小着色器上的变量(别忘了,我们在构建好着色器程序后,就删除了六个小程序编译的码)。

      uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你
把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。我们可以在任何着色器中定义它们,而无需通过顶点着
色器作为中介。
#version 330 core
out vec4 FragColor;
uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量
void main() {
FragColor = ourColor;
} 接下来我们跳出来,在CPU上改变我们的数据,然后再传入着色器里好了。
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
这个函数得到了着色器这个变量的索引,我们用它就可以修改着色器上的uniform了。
glUseProgram(shaderProgram); //先启动这个着色器
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
//glUniform函数就是用来修改的,4f是因为c语言不存在重载,所以我们只能命名n个类似函数名函数了 我们加入一些随时间改变的量,在每次渲染时都改变一点颜色(一秒钟五十次),就可以看到这样动画了。
float timeValue = glfwGetTime();
float greenValue = sin(timeValue) / 2.0f + 0.5f;
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

uniform对于设置一个在渲染迭代中会改变的属性是一个非常有用的工具,它也是一个在程序和着色器间数据交互的很好工具

LearnOpenGL学习笔记(二)——着色器简单理解的更多相关文章

  1. Android学习笔记二:activity的理解

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7513290.html 一:activity定义了app的页面 一个app有很多个页面组成,一个页面其实就是一个 ...

  2. spring in action 学习笔记二:aop的理解

    一: aop的思想的来在哪里? 一个系统一般情况下由多个组件组成,而每一个组件除了干自己的本职工作以外,有时还会干一些杂活(如:日志(logging).事务管理(transaction manager ...

  3. Html学习笔记(二) 简单标签

    标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...

  4. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  5. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  6. HTML DOM(学习笔记二)

    嗯,在HTML DOM(学习笔记一)中简单描述了一下HTML DOM 是什么,这一篇将记录下来有关HTML DOM的内容! 1:DOM节点 首先,再来看一下HTML DOM的树状结构,如下图所示: 这 ...

  7. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  8. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  9. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

随机推荐

  1. Quartz.Net进阶之二:关于触发器的更多信息

    与作业一样,触发器相对容易使用,但是在您可以充分利用Quartz.NET之前,确实需要了解和理解各种可自定义的选项. 此外,如前所述,您可以选择不同类型的触发器来满足不同的调度需求. 1.常见触发器属 ...

  2. eclipse中将一个项目作为library导入另一个项目中

    1. github上搜索viewpagerIndicator: https://github.com/JakeWharton/ViewPagerIndicator2. 下载zip包,解压,eclips ...

  3. Django跨域(前端跨域)

    前情回顾 在说今天的问题之前先来回顾一下有关Ajax的相关内容 Ajax的优缺点 AJAX使用Javascript技术向服务器发送异步请求: AJAX无须刷新整个页面: 因为服务器响应内容不再是整个页 ...

  4. 复制命令(XCOPY)

    XCOPY 命令: // 描述: 将文件或目录(包括子目录)从一个位置复制到另一个位置. // 语法: Xcopy <Source> [<Destination>] [/w] ...

  5. lamp环境搭建(apache安装,mysql安装,php安装)

    1.卸载系统内置的LAMP环境 1)卸载httpd服务(内置Apache) ① 使用rpm指令查询安装的httpd服务 ② 卸载httpd服务 如果出现以上提示,代表系统默认不允许我们卸载软件,使用强 ...

  6. 在linux中文件的权限讲解

    1.d:directory(目录): 表示这个文件是个目录,其他的还有f(file文件)等等: 2.r:read(可读) 3.w:write(可写) 4 x :execute(可执行) 一般Linux ...

  7. PowerShell 命令行调试指引(转)

    How to manage a debugging session Before you start debugging, you must set one or more breakpoints. ...

  8. <Listener>HttpSessionListener和HttpSessionAttributeListener区别

    一.HttpSessionListener HttpSessionListener是对Session的一个监听,主要监听关于Session的两个事件,即初始化和销毁.HttpSessionListen ...

  9. 解决 asp.net core 中下载 exe 文件返回 404

    在 StartUp 中的 Configure 方法添加如下代码即可 app.UseStaticFiles(new StaticFileOptions() { ContentTypeProvider = ...

  10. Linux 查看IP

    UBuntu 系统下 按Ctrl+Alt+T 唤出终端 在终端输入: ifconfig 命令 点击回车 就可以看到自己电脑在局域网的IP地址了 图中第二行 inet 地址:192.168.1.101 ...