// 给节点设置自定义的Shader
cc.Node.prototype.setCustomShader = function (vsh, fsh, enable) {
var node = this;
var children;
var i;
// 现在写的这些shader在web版中不兼容,一下子没找到兼容方法,
// 暂时先把web版屏蔽一下,不然点击之后就不显示了,不太爽
if (! cc.sys.isNative) {
return;
}
// 判断是不是widget
if (this.getVirtualRenderer != null && this.getVirtualRenderer().getSprite != null) {
node = this.getVirtualRenderer().getSprite();
} else if (this.getVirtualRenderer != null) {
node = this.getVirtualRenderer();
}
_nodeSetCustomShader(node, vsh, fsh, enable);
children = this.getChildren();
for (i in children) {
if (children[i] instanceof ccui.TextAtlas) {
// todo 高亮效果会导致数字标签不显示,所以暂时屏蔽掉,对效果也没什么影响
continue;
}
children[i].setCustomShader(vsh, fsh, enable);
}
//控件内部节点
if (this.getProtectedChildren != null) {
children = this.getProtectedChildren();
for (i in children) {
children[i].setCustomShader(vsh, fsh, enable);
}
}
};
// 给动画设置Shaer, 动画的置灰跟普通节点的置灰不太一样,所以需要特殊设置
ccs.Armature.prototype.setCustomShader = function (vsh, fsh, enable) {
var bones; // 动画的骨骼
var bone;
var key;
var list, display, i;
// 现在写的这些shader在web版中不兼容,一下子没找到兼容方法,
// 暂时先把web版屏蔽一下,不然点击之后就不显示了,在太爽
if (! cc.sys.isNative) {
return;
}
bones = this.getBoneDic();
for (key in bones) {
bone = bones[key];
// 因为我们是序列动画,如果只取当前显示的node进行处理的话,只有当动画
// 播放到当前帧时才会有效果,播放到其他帧时没有效果,所以要取整个list进行处理
list = bone.getDisplayManager().getDecorativeDisplayList();
for (i in list) {
display = list[i].getDisplay();
_nodeSetCustomShader(display, vsh, fsh, enable);
}
}
};
// 一个基础函数,用于实现下面的setCustomShader功能
var _nodeSetCustomShader = function (node, vsh, fsh, enable) {
var nodeProgram, program, _fsh;
if (node == null) {
return;
}
nodeProgram = node.getShaderProgram();
// 创建shader
if (enable === true) {
_fsh = fsh;
// 为ETCA特殊处理一下
if (nodeProgram === cc.shaderCache.getProgram("ShaderPositionTextureColorEtcAlpha_noMVP")) {
node.__alphaTexture = true;
if (_fsh === res.HighlightFsh)
_fsh = res.HighlightEtcaFsh;
}
program = cc.shaderCache.getProgram(vsh + _fsh);
if (program == null) {
program = new cc.GLProgram(vsh, _fsh);
program.link();
program.updateUniforms();
// shader创建后缓存起来,之后要用时每次从缓存中取,之前每次都创建一次,导致内存泄漏
cc.shaderCache.addProgram(program, vsh + _fsh);
}
} else {
if (node.__alphaTexture) {
program = cc.shaderCache.getProgram("ShaderPositionTextureColorEtcAlpha_noMVP");
} else {
program = cc.shaderCache.getProgram("ShaderPositionTextureColor_noMVP");
}
}
if (program != null/* && nodeProgram != null*/)
node.setShaderProgram(program);
};
// 效果脚本
灰化:
gray.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = vec3(0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b);
gl_FragColor.w = c.w;
}
gray.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
// 将一个节点高亮
highlight.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = c.xyz * 2.0;
gl_FragColor.w = c.w;
}
highlight.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
highlightEtca.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 v4Colour = texture2D(CC_Texture0, v_texCoord);
v4Colour.a = texture2D(CC_Texture1, v_texCoord).r;
vec4 c = v_fragmentColor * v4Colour;
gl_FragColor.xyz = c.xyz * 2.0;
gl_FragColor.w = c.w;
}
// 将一个节点高亮, 主要是针对IU条件
uihighlight.fsh
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.xyz = c.xyz * 1.2;
gl_FragColor.w = c.w;
}
uihighlight.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}
// 将一个节点按照sin曲线高亮
highlightSin.fsh
#ifdef GL_ES
precision mediump float;
#endif
#define speed 15
#define scale 1.5
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
void main()
{
vec4 c = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
gl_FragColor.rgb = c.rgb * (1 + abs(sin(CC_Time.x * speed)) * scale);
gl_FragColor.a = c.a;
}
highlightSin.vsh
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
#ifdef GL_ES
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
#else
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
#endif
void main()
{
gl_Position = CC_PMatrix * a_position;
v_fragmentColor = a_color;
v_texCoord = a_texCoord;
}