首页 > 代码库 > Cocos2d-x项目移植到WP8系列之九:使用自定义shader

Cocos2d-x项目移植到WP8系列之九:使用自定义shader

 

有时候想得到一些例如灰度图等特殊的渲染效果,就得用到自定义shader,关于shader的一些背景知识,自行谷歌,列出两篇cocos2dx里介绍shader的相关文章 http://blog.csdn.net/while0/article/details/9666829     http://blog.sina.com.cn/s/blog_aa01f7030101mdom.html

 

cocos2dx在wp8平台不知道是不是在渲染时OpenGL要转成D3D的原因还是其他原因,不能在运行时编译链接shader,cocos2dx的做法就是事先把相关的shader编译好成特定的机器码存放到 precompiledshaders.h 文件里,通过预先生成好的sha1码指向不同的shader,运行时直接获取,关于这部分,参考了: http://www.ispinel.com/2014/07/03/12393/。 现在需要做的工作就是,给出了顶点shader和片元shader,如何生成机器码,这部分参考了  http://cn.cocos2d-x.org/tutorial/show?id=1274 。 本文采用了第二种方法,使用winrtcompiler.exe生成shader的机器码,以使用自定义灰度图shader为例,具体做法如下。

 

顶点shader文件——myShader.vert:

 1 uniform mat4 CC_PMatrix; 2 uniform mat4 CC_MVMatrix; 3 uniform mat4 CC_MVPMatrix; 4 uniform vec4 CC_Time; 5 uniform vec4 CC_SinTime; 6 uniform vec4 CC_CosTime; 7 uniform vec4 CC_Random01; 8 attribute vec4 a_position;                             9 attribute vec2 a_texCoord;                            10 attribute vec4 a_color;                                11                                                     12 #ifdef GL_ES                                        13 varying lowp vec4 v_fragmentColor;                    14 varying mediump vec2 v_texCoord;                    15 #else                                                16 varying vec4 v_fragmentColor;                        17 varying vec2 v_texCoord;                            18 #endif19 20 void main()                                            21 {                                                    22     gl_Position = CC_MVPMatrix * a_position;        23     v_fragmentColor = a_color;                        24     v_texCoord = a_texCoord;                        25 }


片元shader文件——myShader.frag文件

 1 #ifdef GL_ES                                 2 precision lowp float;                         3 #endif                                         4  5 varying vec4 v_fragmentColor;                 6 varying vec2 v_texCoord;                     7 uniform sampler2D CC_Texture0;                 8  9 void main()                                10 {                                            11 vec4 texColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);            12 float gray = dot(texColor.rgb, vec3(0.299,0.587,0.114));13 gl_FragColor  = vec4(gray, gray, gray, texColor.a);14 }


winrtcompiler.exe 文件下载

 

使用命令行通过 顶点shader文件、片元shader文件和winrtcompiler.exe文件生成机器码文件:把winrtcompiler.exe 、顶点shader文件和片元shader文件拷到统一文件夹里,通过cd 命令进入到那个文件夹,然后输入命令行如下:winrtcompiler.exe -o=shader_wp8.h -p=wp8 -a=gProgram -v=myShader.vert -f=myShader.frag      ,生成的机器码就在 -o 参数所指向的 shader_wp8.h 文件里了。

 

把机器码更新到precompiledshaders.h 文件里,包括 num、length、program和programKey,programKey就是根据myShader.vert文件和myShader.frag文件得到的sha1码。最后一个问题,如何获取到这个sha1码? 

可以参考 http://www.cnblogs.com/yeshanghai/p/cocos2dx_shader.html 的 1~5 点,不过需要改动一下

第1点的改动:把我们上面的myShader.vert和myShader.frag文件改造一下,也就是前后加上双引号、最后加上分号、每一行(除了最后分号那行)后面加上 \n\ 符号,因为这次是需要在运行时被动态加载编译的。

其他步骤的改动就是,原文只有片元shader,需要补上顶点shader的相关信息。

最后,在 CCPrecompiledShaders.cpp 里的 bool CCPrecompiledShaders::loadProgram(GLuint program, const GLchar* vShaderByteArray, const GLchar* fShaderByteArray) 方法里的 std::string id = computeHash(vShaderByteArray, fShaderByteArray); 代码前断点, 这个id就是顶点shader文件和片元shader文件计算出来的 sha1 值。

 

Cocos2d-x项目移植到WP8系列之九:使用自定义shader