cocos2d-js Shader系列1:cocos2d-js Shader和OpenGL ES2.0
cocos2d的Shader也就是差不多直接跟GPU打交道了,跟Flash的Stage3D(AGAL)类似,不过没有AGAL这么恶心,不需要直接编写汇编语言。而Fragment Shader又跟Flash的pixelbender类似。
本文以cocos2d-js为例,但cocos2dx其他版本也是同理的,只是函数名略有不同而已。
当然还是得先复习或者学习一下GPU的原理,至少得知道vertex shader和fragment shader的作用和区别。

详细可以看看大神的说明:
http://www.opengpu.org/bbs/forum.php?mod=viewthread&tid=7550&extra=page%3D1
http://www.opengpu.org/bbs/forum.php?mod=viewthread&tid=7376&extra=page%3D1
cocos2d的Shader步骤还是类似的:
1、编写vertex shader和fragment shader
2、定义顶点坐标和纹理坐标
3、定义纹理、绑定纹理
4、设置shader的参数
5、每帧draw的时候,gl.drawArrays推送到GPU绘制
1、Shader语法
语法有点类似Flash的pixelbender,但是一个更完整的C程序,可以按照C程序的语法来编写。main函数最终输出结果到一个指定变量中,都是矢量的点乘、加减等。
vertext shader最后赋值一个vec4给gl_Position,表示该点最终绘制到屏幕上的位置;fragment shader最后赋值vec4给gl_FragColor,表示颜色rgba。
详细介绍:
http://blog.csdn.net/hgl868/article/details/7846269
http://blog.csdn.net/wangyuchun_799/article/details/7770500
attribute、uniform、varying区别:http://blog.csdn.net/jackers679/article/details/6848085
uniform变量是外部application程序传递给(vertex和fragment)shader的变量,类似常量
attribute变量是只能在vertex shader中使用的变量。(它不能在fragment shader中声明attribute变量,也不能被fragment shader中使用)
varying变量是vertex和fragment shader之间做数据传递用的。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。Varying can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, mat4. (arrays of them too.)
2、定义顶点坐标和纹理坐标
var squareVertexPositionBuffer = this.squareVertexPositionBuffer = gl.createBuffer(); //创建一个buffer,并记录下来,后续每帧draw的时候调用
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); //绑定位置,后一句bufferData就设置这个位置的数据
vertices = [ //这里是4个顶点
256, 256,
0, 256,
256, 0,
0, 0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); /* gl.STATIC_DRAW The data store contents are modified once, and used many times as the source for WebGL drawing commands.
gl.DYNAMIC_DRAW The data store contents are repeatedly respecified, and used many times as the source for WebGL drawing commands.
gl.STREAM_DRAW The data store contents are specified once, and used occasionally as the source of a WebGL drawing command. */
gl.bindBuffer(gl.ARRAY_BUFFER, null);
3、绑定纹理
//定义纹理
var texture = this.my_texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture );
var pixels = new Uint8Array(4096); //正好是32*32的图片,每个像素4个byte
for( var i=0; i<pixels.length; ) {
pixels[i++] = i/4; // Red
pixels[i++] = i/16; // Green
pixels[i++] = i/8; // Blue
pixels[i++] = 255; // Alpha
}
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels); //每帧draw之前绑定纹理 gl.bindTexture(gl.TEXTURE_2D, this.my_texture);
对应的fragment shader写法
precision lowp float;
varying vec2 v_texCoord;
uniform sampler2D CC_Texture0; void main() {
gl_FragColor = texture2D(CC_Texture0, v_texCoord);
}
4、设置shader参数
//在初始化的时候记录shader程序,记录参数的入口位置
this.shader = cc.GLProgram.create(vertexShader, framentShader);
this.shader.retain();
this.shader.addAttribute("aVertex", cc.VERTEX_ATTRIB_POSITION); //添加一个新参数到shader中,并指定为第几个
this.shader.link();
this.shader.updateUniforms(); //表示使用cocos2d默认附加的一些参数,其实在_compileShader的时候添加到shader程序的
var program = this.shader.getProgram();
this.uniformCenter = gl.getUniformLocation( program, "center"); //记录Uniform参数入口
this.uniformResolution = gl.getUniformLocation( program, "resolution");
//override原来的draw函数,在每帧draw的时候调用:
this.shader.use();
this.shader.setUniformsForBuiltins(); //如果shader中使用了cocos2d默认附加的一些uniform参数,就需要每帧设置(例如TIME等),具体参数意义参考CCGLProgram.setUniformsForBuiltins
this.shader.setUniformLocationF32( this.uniformCenter, winSize.width/2, winSize.height/2);
this.shader.setUniformLocationF32( this.uniformResolution, 256, 256); //设置uniform参数,CCGLProgram类对opengl底层的接口做了封装。例如这个就是对应uniform2f
gl.bindBuffer(gl.ARRAY_BUFFER, this.squareVertexPositionBuffer);
gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, 0); //设置attribute参数
参数参考:
http://msdn.microsoft.com/zh-cn/library/ie/dn302460(v=vs.85).aspx
函数第一个参数:表示shader程序的第几个attribute参数
5、draw call
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
参数参考:
http://msdn.microsoft.com/zh-cn/library/ie/dn302460(v=vs.85).aspx
http://msdn.microsoft.com/zh-cn/library/ie/dn302395(v=vs.85).aspx

最后附上cocos2dx官方的一些教程:
http://cn.cocos2d-x.org/tutorial/show?id=1336
http://cn.cocos2d-x.org/tutorial/show?id=1337
cocos2d-js Shader系列1:cocos2d-js Shader和OpenGL ES2.0的更多相关文章
- Cocos2d-x中使用OpenGL ES2.0编写shader
这几天在看子龙山人的关于OpenGL的文章,先依葫芦画瓢,能看到些东西,才能慢慢深入了解,当入门文章不错,但是其中遇到的一些问题,折腾了一些时间,为了方便和我一样的小白们,在这篇文章中进行写补充. O ...
- js基础系列框架:JS重要知识点(转载)
这里列出了一些JS重要知识点(不全面,但自己感觉很重要).彻底理解并掌握这些知识点,对于每个想要深入学习JS的朋友应该都是必须的. 讲解还是以示例代码搭配注释的形式,这里做个小目录: JS代码预解析原 ...
- node.js入门系列(一)--Node.js简介
什么是NodeJS JS是脚本语言,脚本语言都需要一个解析器才能运行.对于写在HTML页面里的JS,浏览器充当了解析器的角色.而对于需要独立运行的JS,NodeJS就是一个解析器. 每一种解析器都是一 ...
- cocos2d-js Shader系列4:Shader、GLProgram在jsb(native、手机)和html5之间的兼容问题。cocos2d-js框架各种坑。
为了让jsb也能顺利跑起滤镜效果,在手机侧折腾了2天,因为每次在真机上运行总要耗那么半分钟,而且偶尔还遇到apk文件无法删除导致运行失败的情况. 这个调试起来,实在让人烦躁加沮丧. 还好,测试上百轮, ...
- cocos2d-js Shader系列3:多重纹理 multiple textures multiple samplers
上一篇,我们学习了怎么便捷的控制sprite的颜色,而这个都是默认一个texture的,如果要实现类似mask的效果,或者更个性化的多纹理效果,怎么实现呢? 这就是这一节需要介绍的内容. 例如上图的效 ...
- cocos2d-js Shader系列2:在cc.Sprite上使用Shader(黑白、灰度、造旧效果)
在Sprite中使用Shader做特殊的颜色处理比较简单,只需要把Shader程序绑定到Sprite上即可: sprite.shaderProgram = alphaTestShader; Cocos ...
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)
前言:出于某种原因,需要学习下Knockout.js,这个组件很早前听说过,但一直没尝试使用,这两天学习了下,觉得它真心不错,双向绑定的机制简直太爽了.今天打算结合bootstrapTable和Kno ...
- JS组件系列——BootstrapTable 行内编辑解决方案:x-editable
前言:之前介绍bootstrapTable组件的时候有提到它的行内编辑功能,只不过为了展示功能,将此一笔带过了,罪过罪过!最近项目里面还是打算将行内编辑用起来,于是再次研究了下x-editable组件 ...
- JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(四):自定义T4模板快速生成页面
前言:上篇介绍了下ko增删改查的封装,确实节省了大量的js代码.博主是一个喜欢偷懒的人,总觉得这些基础的增删改查效果能不能通过一个什么工具直接生成页面效果,啥代码都不用写了,那该多爽.于是研究了下T4 ...
随机推荐
- bat调用TexturePacker更新SpriteSheet
一款游戏会用到很多图片资源,通常我们会使用TexturePacker工具进行图片的拼接.压缩,为了考虑性能问题,单个SpriteSheet的尺寸不会设置的太大(最大1024 * 1024),这样就可能 ...
- c#录音和放音,超简单!不用DirectX
最近在做android与C#录音并互相通信的小东西.但是卡在C#录音这儿了.找了好久,说的都是DirectX,可是我总是安装不上,这才找到了这个简单的录音方法.当然,如果你想要录得好并且处理音频,那还 ...
- 在Redhat 7.3中采用离线方式安装Docker
本文环境 Redhat Linux 7.3.Docker 18. 写在前面 Docker CE默认是不支持Redhat的,如果你想在Redhat安装,可以使用静态二进制包.这是我多次尝试RPM后得出的 ...
- iOS:创建带logol的二维码
//二维码生成 实质: 把字符串转变为 图片 // 需要 coreImage框架, 已经包含在了 UIKit框架里面 //MARK: 二维码中间内置图片,可以是公司logo + (UIImage *) ...
- windows核心编程-互斥器(Mutexes)
线程同步的方式主要有:临界区.互斥区.事件.信号量四种方式. 前边讲过了临界区线程同步-----windows核心编程-关键段(临界区)线程同步,这章我来介绍一下互斥器(Mutexes)在线程同步中的 ...
- iOS开发-Certificates、Identifiers和Profiles详解
如果是才进入公司进行开发的iOS程序猿来说人难免会对苹果的证书.配置文件,尤其有的需要重头开始的公司来说,最简单的来说真机调试是免不了和这些东西打交道的,有的时候赶时间做完了可能心里也犯嘀咕,本文根据 ...
- sharding-jdbc之——分库分表实例
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/79368021 一.概述 之前,我们介绍了利用Mycat进行分库分表操作,Mycat ...
- ES6 主要的新特性
本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...
- SpringBoot整合Quartz定时任务 的简单实例 2
(1)什么是Quartz?(2)Quartz的特点:(3)Quartz专用词汇说明:(4)Quartz任务调度基本实现原理: 接下来看下具体的内容: (1)什么是Quartz? Quartz是一个完全 ...
- python3 验证码图片切割
切割前图片 切割后四个图片 代码 #coding:utf8 import os from PIL import Image,ImageDraw,ImageFile import numpy impor ...