在cocos2d中添加自己的shader教程

1.cocos2d的shader都是共用的, 存放在 GLProgramCache 中。 当setGLProgram() 的时候是从GLProgramStateCache 中寻找是否有这个shader的State, 有就返回,这个也是共用的,任意一个GLProgramState修改了, 都会影响到使用这个shader的对象

添加shader的方法:

先编写shader: (直接复制cocos/renderer/ 下的 .frag或者.vert ) frag是PS阶段的shader .vert是VS,然后按照自己的修改。
注意 这些shader在加载的时候,cocos2d会自动添加几个必须的属性变量:

const GLchar *sources] = {

#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
(type == GL_VERTEX_SHADER ? “precision highp float;\n” : “precision mediump float;\n”),
#endif
“uniform mat4 CC_PMatrix;\n”
“uniform mat4 CC_MVMatrix;\n”
“uniform mat4 CC_MVPMatrix;\n”
“uniform vec4 CC_Time;\n”
“uniform vec4 CC_SinTime;\n”
“uniform vec4 CC_CosTime;\n”
“uniform vec4 CC_Random01;\n”
“uniform sampler2D CC_Texture0;\n”
“uniform sampler2D CC_Texture1;\n”
“uniform sampler2D CC_Texture2;\n”
“uniform sampler2D CC_Texture3;\n”
“//CC INCLUDES END\n\n”,
source,
};

这段代码在: bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source) 中,所以你在编写自己的shader时候要注意不要和上面的变量重名
编写方式:
现在ccShaders.h中添加shader的编码保存的变量:(拿做的灰度效果为列:)
extern CC_DLL const GLchar * ccPositionTextureColor_noMVP_gray_frag;

我直接修改 ccShader_PositionTextureColor_noMVP.frag 这个文件的
源文件:

const char* ccPositionTextureColor_noMVP_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform int n_isGray;

void main()
{
if (n_isGray == 1)
{
float alpha = texture2D(CC_Texture0, v_texCoord).a;
float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(1, grey, grey, 0.0);
}
else
{
gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
}

}
);

修改后:
const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n

varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

void main()
{
float alpha = texture2D(CC_Texture0, v_texCoord).a;
float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
gl_FragColor = vec4(grey, grey, grey, alpha);
}
);

红色部分是修改掉的 注意 const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY( 红色部分要和你在ccShaders.h中声明的变量一致!
然后在ccShaders.cpp中引用 编写好的shader文件 : #include “ccShader_PositionTextureColor_noMVP_gray.frag”

这样编写部分就结束

现在开始添加到默认shader里面:
先到 CCGLProgram.h GLProgram 中添加添加我们这个shader的名字:(这个名字只是对外使用的键值)
static const char* SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY;
在.cpp中加上:
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY = “ShaderPositionTextureColor_noMVP_gray”;

然后到CCGLProgramCache.cpp 中的 最上面有一堆枚举, 添加一个自己shader的枚举 比如我添加的 kShaderType_PositionTextureColor_noMVP_gray,

然后在 void GLProgramCache::loadDefaultGLPrograms() 中写加载我们shader的代码:
p = new GLProgram();
loadDefaultGLProgram(p, kShaderType_PositionTextureColor_noMVP_gray);
_programs.insert( std::make_pair( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY, p ) );

到void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type) 中,配置我们shader用的VS 和PS阶段的 的相关代码:(因为做灰度只需要改动pos部分,所以可以直接用cocos2d现有的VS阶段的代码ccPositionTextureColor_noMVP_vert)

case kShaderType_PositionTextureColor_noMVP_gray:
p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_gray_frag);
break;

这样shader就添加好了, 使用方法:

GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY);
sprite->setGLProgram(program);

还原的话就
GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP);
sprite->setGLProgram(program);

你可以脱离这套共用GLProgramState的方式 直接用: (这样你就可以控制这个shader某一个值,而不影响其他使用这个shader的对象了)
GLProgram program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY);
GLProgramState
state = GLProgramState::create(program);
sprite->setGLProgramState(state):

本人没学过opengel今天ui那边需要灰度,才开始看的, 写得不好,大家就将就看吧~
还要说一个地方

std::string GLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const
{
std::string ret;
GLint logLength = 0, charsWritten = 0;

//infoFunc(object, GL_INFO_LOG_LENGTH, &logLength);        //编译错误的话,到这里就崩溃了~~  不知道为什么, 

glGetShaderiv(object, GL_INFO_LOG_LENGTH, &logLength); //我直接改成调用opengel函数,
if (logLength < 1)
return “”;

char *logBytes = (char*)malloc(logLength);

// logFunc(object, logLength, &charsWritten, logBytes);
glGetShaderInfoLog(object, logLength, &charsWritten, logBytes);
ret = logBytes;

free(logBytes);
return ret;

}

这里是我这篇笔记的地址: http://note.youdao.com/share/?id=f72378178898d34affe13a6dddd75df3&type=note

infoFunc(object, GL_INFO_LOG_LENGTH, &logLength);
一样是到这里崩溃,调试发现读取 Shader.vsh的时候行首出现几个字符的乱码, 各种编码试过,目前无解

:6:沉了~~~~~

http://ycool.com/post/eq476cx
http://ycool.com/post/86wuj5m
http://ycool.com/post/byxjj96
http://ycool.com/post/s6h62ef
http://ycool.com/post/he9m5qs
http://ycool.com/post/zm5eb9c
http://ycool.com/post/6sxszq7
http://ycool.com/post/bmbdf9b
http://ycool.com/post/xm89yzx
http://ycool.com/post/q2enkgr
http://ycool.com/post/87d2sep
http://ycool.com/post/cqsv8g6
http://ycool.com/post/zh4du4g
http://ycool.com/post/fgusya4
http://ycool.com/post/3h8jt9q
http://ycool.com/post/aar6cgg
http://ycool.com/post/wfbrhvm
http://ycool.com/post/7ht7w3y
http://ycool.com/post/xh89qbx
http://ycool.com/post/5wr55kc
http://ycool.com/post/7xtjwvm
http://ycool.com/post/mj6hdh4
http://ycool.com/post/kbtztb3
http://ycool.com/post/u3z4fe7
http://ycool.com/post/g9pzvj3
http://ycool.com/post/v4b9qej
http://ycool.com/post/bav56t9
http://ycool.com/post/zguymt5
http://ycool.com/post/3h5zfhh
http://ycool.com/post/q5k86vn
http://ycool.com/post/jykyvb5
http://ycool.com/post/cujazxg
http://ycool.com/post/7g4usgf
http://ycool.com/post/6nsddcu
http://ycool.com/post/axpn2mg
http://ycool.com/post/55xz4vc
http://ycool.com/post/p93v4zs
http://ycool.com/post/gp35ru9
http://ycool.com/post/f2vebtd
http://ycool.com/post/3pc78tk
http://ycool.com/post/nec7f3g
http://ycool.com/post/cyrhy33
http://ycool.com/post/xd972zw
http://ycool.com/post/2uvewqm
http://ycool.com/post/x9p9v46
http://ycool.com/post/knmfpfa
http://zhan.renren.com/2014714905?gid=3602888498056558215

赞一个,讲得好呀,我都明白了

:5::5::5::5::5::5::5::5::5::5::5::5: