天天看点

cocos2dx-js灰化高亮等等

// 给节点设置自定义的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;
}