认识着色器

理解OpenGL渲染管线,对于学习OpenGL非常重要。下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段)

此图是从wiki中拿过来的,OpenGL的渲染管线主要包括:

  1. 准备顶点数据(通过VBO、VAO和Vertex attribute来传递数据给OpenGL)

  2. 顶点处理(这里主要由Vertex Shader来完成,从上图中可以看出,它还包括可选的Tessellation和Geometry shader阶段)

  3. 顶点后处理(主要包括Clipping,顶点坐标归一化和viewport变换)

  4. Primitive组装(比如3点组装成一个3角形)

  5. 光栅化成一个个像素

  6. 使用Fragment shader来处理这些像素

  7. 采样处理(主要包括Scissor Test, Depth Test, Blending, Stencil Test等)。

OpenGL Shader Language,简称GLSL,它是一种类似于C语言的专门为GPU设计的语言,它可以放在GPU里面被并行运行。
 
opengl es的着色器有.fsh和.vsh两个文件。这两个文件在被编译和链接后就可以产生可执行程序与GPU交互。
.vsh 是 vertex shader,用与顶点计算,可以理解控制顶点的位置,在这个文件中我们通常会传入当前顶点的位置,和纹理的坐标。
例如:
 1 attribute vec4 position;
2 attribute vec4 inputTextureCoordinate;
3
4 varying vec2 textureCoordinate;
5
6 precision mediump float;
7 uniform float overTurn;
8
9 void main()
10 {
11 gl_Position = position;
12 if (overTurn>0.0) {
13 textureCoordinate = vec2(inputTextureCoordinate.x,overTurn-inputTextureCoordinate.y);
14 }
15 else
16 textureCoordinate = vec2(inputTextureCoordinate.x,inputTextureCoordinate.y);
17 }

首先,每一个Shader程序都有一个main函数,这一点和c语言是一样的。

这里面有两种类型的变量,一种是attribute,另一种是varying.

attribute是从外部传进来的,每一个顶点都会有这两个属性,所以它也叫做vertex attribute(顶点属性)。

而varying类型的变量是在vertex shader和fragment shader之间传递数据用的。

这里的变量命名规则保持跟c一样就行了,注意gl_开头的变量名是系统内置的变量,所以大家在定义自己的变量名时,请不要以gl_开头。

而CC_MVPMatrix是一个mat4类型的变量,它是在cocos2d-x内部设置进来的。

即:

attribute:外部传入vsh文件的变量 每帧的渲染的可变参数 变化率高 用于定义每个点。

varying:用于 vsh和fsh之间相互传递的参数。

precision mediump float 定义中等精度的浮点数。

uniform 外部传入vsh文件的变量 变化率较低 对于可能在整个渲染过程没有改变 只是个常量。

在main()当overTurn大于0的时候,函数里面做的事情就是将纹理y轴反转。

vertex shader是作用于每一个顶点的,如果vertex有三个点,那么vertex shader会被执行三次。

.fsh 是片段shader。在这里面我可以对于每一个像素点进行重新计算。

 1 varying highp vec2 textureCoordinate;
2 precision mediump float;
3 uniform sampler2D videoFrame;
4
5 vec4 memoryRender(vec4 color)
6 {
7 float gray;
8 gray = color.r*0.3+color.g*0.59+color.b*0.11;
9 color.r = gray;
10 color.g = gray;
11 color.b = gray;
12
13 color.r += color.r*1.5;
14 color.g = color.g*2.0;
15
16 if(color.r > 255.0)
17 color.r = 255.0;
18 if(color.g > 255.0)
19 color.g = 255.0;
20
21 return color;
22 }
23
24 void main()
25 {
26 vec4 pixelColor;
27
28 pixelColor = texture2D(videoFrame, textureCoordinate);
29
30 gl_FragColor = memoryRender(pixelColor);
31 }

varying highp vec2 textureCoordinate 就是从vsh中传过来了纹理坐标。

uniform sampler2D videoFrame 是我们真正的纹理贴图。

texture2D(videoFrame, textureCoordinate) 将纹理中的每个像素点颜色取出到pixelColor。

可以用memoryRender(pixelColor)将取到像素点重新加工。

fragment shader中也有一个main函数,同时我们看到这里也声明了一个与vertex shader相同的变量textureCoordinate。前面我们讲过,这个变量是用来在vertex shader和fragment shader之间传递数据用的。所以,它们的参数类型必须完全相同。如果一个是vec3,一个是vec4,shader编译的时候是会报错的。

而gl_FragColor我们知道它肯定是一个系统内置变量了,它的作用是定义最终画在屏幕上面的像素点的颜色。

总结:

对于着色器的编程并不是很困难,完全是C的语法。但是debug比较麻烦,对于类型的约束也很严格,必须是相同类型的才能进行算术运算。我们理解了这两个文件之后,就可以发挥我们的想象对纹理图片做出各种的处理。

另有人总结:

vsh 负责搞定像素位置 ,填写  gl_Posizion 变量,偶尔搞定一下点大小的问题,填写 gl_PixelSize。

fsh 负责搞定像素外观,填写 gl_FragColor ,偶尔配套填写另外一组变量。

他们都是一个像素运行一次的,也可能运行多次。为了“这一像素”而努力计算。

程序的版本是cocos2dx 3.0.vs 2012.

代码如下:

 GLTestingLayer
 GLTestingLayer.cpp

内有利用shader使得sprite变灰的代码。

下面是变灰所用到的vsh和fsh文件。

 1 attribute vec4 a_position;
2 attribute vec2 a_texCoord;
3 attribute vec4 a_color;
4
5
6 varying vec4 v_fragmentColor;
7 varying vec2 v_texCoord;
8
9 void main()
10 {
11 gl_Position = CC_PMatrix * a_position;
12 v_fragmentColor = a_color;
13 v_texCoord = a_texCoord;
14 }
 gray.fsh

opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰的更多相关文章

  1. 关于cocos2d-x精灵加亮及变灰效果

    //根据现有CCSprite,变亮和变灰 static CCSprite* graylightWithCCSprite(CCSprite* oldSprite,bool isLight) { //CC ...

  2. 2、Cocos2dx 3.0游戏开发找小三之引擎简单介绍

    尊重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27094663 引擎简单介绍 Cocos2d-x 的 ...

  3. 5、Cocos2dx 3.0小游戏开发的例子寻找测试三个简单的介绍和总结

    繁重的劳动开发商,当转载请注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 測试例子简单介绍 Cocos2d-x 为我们提供了 ...

  4. cocos2d-x入门学习笔记,主要介绍cocos2d-x的基本结构,并且介绍引擎自带的示例

    cocos2d-x 3.0 制作横版格斗游戏 http://philon.cn/post/cocos2d-x-3.0-zhi-zuo-heng-ban-ge-dou-you-xi http://blo ...

  5. 5、Cocos2dx 3.0游戏开发找小三之測试例子简单介绍及小结

    重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 測试例子简单介绍 Cocos2d-x ...

  6. 视频和音频播放的演示最简单的例子6:OpenGL广播YUV420P(T经exture,采用Shader)

    ===================================================== 最简单的视频和音频播放的演示样品系列列表: 最简单的视音频播放演示样例1:总述 最简单的视音 ...

  7. 3 cocos2dx 3.0 源码分析-mainLoop详细

    简述:   我靠上面图是不是太大了, 有点看不清了.  总结一下过程: 之前说过的appController 之后经过了若干初始化, 最后调用了displayLinker 的定时调用, 这里调用了函数 ...

  8. COCOS2DX 3.0 优化提升渲染速度 Auto-batching

    COCOS2DX 3.0 优化提升渲染速度 Auto-batching 近期在看COCOS2DX 3.0的Auto-batching合批与Auto Culling动态缩减功能以下就来细致看看吧:整合好 ...

  9. Cocos2d-x 3.0 事件系统【转】

    事件系统,是一个软件的核心组成部分.从小处讲它是应用程序内部各模块交互的设计模式,从大处讲,它是软件架构的组成模块.在现代软件开发中,操作系统通常通过一些预定义的事件,告知应用程序发生的一些事情如用户 ...

随机推荐

  1. 【脚本语言对比】BASH,PERL以及PYTHON

    据说: BASH能调用linux的应用程序,这是其最大的优点,也是其最大的缺点. PERL那复杂的语法确实看得让人想吐. python很优美,但是据说对正则的支持不够,没有perl强大. 总结一下学习 ...

  2. 在Mac OS X 10.9上安装 Thrift 0.9.1

    Thrift 0.9.1 官方文档中对于Mac OS X上的安装描述适合 10.8,但不适用于10.9. Homebrew  macport 默认都不能在 10.9上安装Thrift 0.9.1成功 ...

  3. WS之cxf与spring整合1

    1.在web.xml中加入CXFServlet: <!-- 下面表示所有来自/cxfservice/*的请求,都交给 CXFServlet来处理 .--> <servlet>  ...

  4. Java(jdk1.7) 陷阱

    String[] strA = new String[4]; for(int i=0; i<4; i++) { strA[i] = String.valueOf(i); } strA[0] = ...

  5. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  6. Git 的核心概念解读

    本文不是Git使用教学篇,而是偏向理论方面,旨在更加深刻的理解Git,这样才能更好的使用它,让工具成为我们得力的助手. 版本控制系统 Git 是目前世界上最优秀的分布式版本控制系统.版本控制系统是能够 ...

  7. 第二百三十一天 how can I 坚持

    哎,蛋疼的一天,一点破问题搞了一下午,还没搞利索. 他们要组织出去玩,我没有参加啊,随便找了个借口. 博客园的字体怎么变小了呢,看着好难受啊,昨天传照片传的? 睡觉.外边下着雨呢,喜欢下雨的夏天还有下 ...

  8. Attach source code to a Netbeans Library Wrapper Module

    http://rubenlaguna.com/wp/2008/02/22/attach-source-code-to-a-netbeans-library-wrapper-module/ Attach ...

  9. RFID第二次作业

    1.简述智能卡的发展,以及射频电子标签在其中所处的位置. 智能卡(Smart Card)又称为集成电路卡(IC卡),内部带有微处理器和存储单元等部件. 射频电子标签是一种非接触式的IC卡,是后期发展起 ...

  10. 让MySQL支持中文

    这两天在学习webpy,把webpy的一个blog例子扒下来学习一下,默认创建的table当存入中文的时候是乱码,研究了一下这个问题. 1,创建table的时候就使用utf8编码 举个例子: crea ...