首页 > 代码库 > cocos2dx在wp上使用自定义shader

cocos2dx在wp上使用自定义shader

实践cocos2dx 2.x版本wp上增加自定义shader

根据cocos2dx 的官方文档http://www.cocos2d-x.org/wiki/How_to_update_wp8_shader

(吐个槽:不知道为什么cocos2dx团队做事总是做一半,实际上直接使用angle 是不能用的,需要修改)

1,首先从github上下载一个angle工程https://github.com/google/angle,

2.打开src\winrtcompiler\winrtcompiler_vs2013.sln 工程文件

3,修改main.cpp

enum{	VERTEX_ATTRIB_POSITION,	VERTEX_ATTRIB_COLOR,	VERTEX_ATTRIB_TEX_COORD,};void bindPredefinedVertexAttribs(GLuint program){	static const struct {		const char *attributeName;		int location;	} attribute_locations[] =	{		{ "a_position", VERTEX_ATTRIB_POSITION },		{ "a_color", VERTEX_ATTRIB_COLOR },		{ "a_texCoord", VERTEX_ATTRIB_TEX_COORD },	};	const int size = sizeof(attribute_locations) / sizeof(attribute_locations[0]);	for (int i = 0; i<size; i++) {		glBindAttribLocation(program, attribute_locations[i].location, attribute_locations[i].attributeName);	}}

上述vertex属性定义可以在cocos源代码中找到。name和id,也是未来保持跟cocos一致

 

1 [Platform::MTAThread]2 int __cdecl main(int argc, char* argv[])
View Code

之前即可,因为要在main中调用

4.在main函数中的glLinkProgram(program);之前调用bindPredefinedVertexAttribs(program);来实现绑定预定义的vertex 属性

另外发现在cocos加载编译过的shader还需要知道二进制的长度,就是需要修改main.cpp,增加导出时候的信息,修改后main中部分代码如下:

if(outputToHeaderFile)
{
FILE *fp = fopen(outputFile.c_str(), "w");
fprintf(fp, "unsigned char %s[] = {\n", variableName);
fprintf(fp, "%3i, ", binary[0]);
for(int i = 1; i < linkStatus - 1; ++i)
{
if(i % 8 == 0)
fprintf(fp, "\n");
fprintf(fp, "%3i, ", binary[i]);
}
if((linkStatus - 1) % 8 == 0)
fprintf(fp, "\n");
fprintf(fp, "%3i\n};\n", binary[linkStatus - 1]);
fprintf(fp, "unsigned int %s_len = %d;\n", variableName, linkStatus);
fclose(fp);
}

5.编译exe

注意:在编译shader是需要使用cocos增加了shader头部的代码,

例如:fragment shader

 1 precision mediump float; 2  3 //CC INCLUDES END 4  5  6 /* 7  * cocos2d for iPhone: http://www.cocos2d-iphone.org 8  * 9  * Copyright (c) 2011 Ricardo Quesada10  * Copyright (c) 2012 Zynga Inc.11  *12  * Permission is hereby granted, free of charge, to any person obtaining a copy13  * of this software and associated documentation files (the "Software"), to deal14  * in the Software without restriction, including without limitation the rights15  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell16  * copies of the Software, and to permit persons to whom the Software is17  * furnished to do so, subject to the following conditions:18  *19  * The above copyright notice and this permission notice shall be included in20  * all copies or substantial portions of the Software.21  *22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE25  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,27  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN28  * THE SOFTWARE.29  */30 31                                             32                                             33                                 34 35                                             36                                             37 varying vec4 v_fragmentColor;                38 39 varying vec2 v_texCoord;                    40 41 uniform sampler2D CC_Texture0;                42 43                                             44                                             45 void main()                                    46 47 {48 49     vec4 color = texture2D(CC_Texture0, v_texCoord);50     51     float grey = color.r * 0.299 + color.g * 0.587 + color.b * 0.114;52     53     gl_FragColor = vec4(grey*1.13, grey*1.13, grey*1.13,color.a);54     55     56 }                                            

vertex shader

 1 precision highp float; 2  3 uniform mat4 CC_PMatrix; 4  5 uniform mat4 CC_MVMatrix; 6  7 uniform mat4 CC_MVPMatrix; 8  9 uniform vec4 CC_Time;10 11 uniform vec4 CC_SinTime;12 13 uniform vec4 CC_CosTime;14 15 uniform vec4 CC_Random01;16 17 //CC INCLUDES END18 19 20 /*21  * cocos2d for iPhone: http://www.cocos2d-iphone.org22  *23  * Copyright (c) 2011 Ricardo Quesada24  * Copyright (c) 2012 Zynga Inc.25  *26  * Permission is hereby granted, free of charge, to any person obtaining a copy27  * of this software and associated documentation files (the "Software"), to deal28  * in the Software without restriction, including without limitation the rights29  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell30  * copies of the Software, and to permit persons to whom the Software is31  * furnished to do so, subject to the following conditions:32  *33  * The above copyright notice and this permission notice shall be included in34  * all copies or substantial portions of the Software.35  *36  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR37  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,38  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE39  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER40  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,41  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN42  * THE SOFTWARE.43  */44 45                                                     46                                                     47 attribute vec4 a_position;                            48 49 attribute vec2 a_texCoord;                            50 51 attribute vec4 a_color;                                52 53                                                     54                                                     55 #ifdef GL_ES                                        56 57 varying lowp vec4 v_fragmentColor;                    58 59 varying mediump vec2 v_texCoord;                    60 61 #else                                                62 63 varying vec4 v_fragmentColor;                        64 65 varying vec2 v_texCoord;                            66 67 #endif                                                68 69                                                     70                                                     71 void main()                                            72 73 {                                                    74 75     gl_Position = CC_MVPMatrix * a_position;        76     77     v_fragmentColor = a_color;                        78     79     v_texCoord = a_texCoord;                        80     81 }                                                    
vertex shader

命令行:winrtcompiler.exe -p=wp8 -o=shader_gray_wp.h -a=g_xc_gray_Program -v=vert_src.h -f=frag_src.h 

可以查看编译出来文件:shader_gray_wp.h

unsigned char g_xc_gray_Program[] = {166, 147,   0,   0, 142,   9,   2,   1,   0, 128,   0,   0,  82, 139,   0,   0,  10,   0,   0,   0,  97,  95, 112, 111, 115, 105, 116, 105, 111, 110,   1,   0,   0,   0,  82, 139,   0,   0,   7,   0,   0,   0,  97,  95,  99, 111, 108, 111, 114,   0,   0,   0,   0,  80, 139,   0,   0,  10,   0,   0,   0,  97,  95, 116, 101, 120,  67, 111, 111, 114, 100,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255,   0, ....};unsigned int g_xc_gray_Program_len = 2954;

 

这样的shader才能编译后给cocos2dx使用,

使用:

我的做法是修改加载shader的代码,来加载编译出来的二进制

CCGLProgram增加bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, GLint buffsize); 可以使用导出的文件的两个变量来加载一个shader

 1 bool CCGLProgram::initWithPrecompiledProgramByteArray(const GLchar* vShaderByteArray, GLint buffsize) 2 { 3     bool haveProgram = false; 4  5     m_uProgram = glCreateProgram(); 6     CHECK_GL_ERROR_DEBUG(); 7  8     m_uVertShader = m_uFragShader = 0; 9 10     haveProgram = CCPrecompiledShaders::sharedPrecompiledShaders()->loadProgram(m_uProgram, (const GLvoid*)vShaderByteArray, buffsize);11 12     CHECK_GL_ERROR_DEBUG();13     m_pHashForUniforms = NULL;14 15     CHECK_GL_ERROR_DEBUG();16 17     return haveProgram;18 }
initWithPrecompiledProgramByteArray

在ccshaderCache.cpp中loadDefaultShaders()中增加

 1 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) 2     CCGLProgram* pProgram = new CCGLProgram(); 3     #include "shader_xc_wp.h" 4     pProgram->initWithVertexShaderByteArray((const GLchar*)g_xc_gray_Program, g_xc_gray_Program_len); 5  6     pProgram->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); 7     pProgram->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); 8     pProgram->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); 9     pProgram->link();10     pProgram->updateUniforms();11 12 13     m_pPrograms->setObject(pProgram, "greysprite");14 15     pProgram->release();16 #endif
add shader

在reloadDefaultShaders中增加

 1 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) 2     CCGLProgram* pProgram = programForKey("greysprite"); 3     pProgram->reset(); 4     #include "shader_xc_wp.h" 5     pProgram->initWithVertexShaderByteArray((const GLchar*)g_xc_gray_Program, g_xc_gray_Program_len); 6  7     pProgram->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); 8     pProgram->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); 9     pProgram->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);10     pProgram->link();11     pProgram->updateUniforms();12     CHECK_GL_ERROR_DEBUG();13 #endif
reload shader

 

这样就可以使用了,当然要把.h拷贝到shader目录或者能包含到的目录中

happy coding!

cocos2dx在wp上使用自定义shader