天天看點

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;
}