415 lines
12 KiB
JavaScript
415 lines
12 KiB
JavaScript
var renderEngine = cc.renderer.renderEngine;
|
|
var Material = renderEngine.Material;
|
|
|
|
|
|
|
|
|
|
|
|
const MVP = `
|
|
uniform mat4 viewProj;
|
|
#ifdef use2DPos
|
|
attribute vec2 a_position;
|
|
#else
|
|
attribute vec3 a_position;
|
|
#endif
|
|
attribute lowp vec4 a_color;
|
|
#ifdef useModel
|
|
uniform mat4 model;
|
|
#endif
|
|
#ifdef useTexture
|
|
attribute mediump vec2 a_uv0;
|
|
varying mediump vec2 uv0;
|
|
#endif
|
|
#ifndef useColor
|
|
varying lowp vec4 v_fragmentColor;
|
|
#endif
|
|
|
|
attribute mediump vec2 a_uv1;
|
|
attribute mediump vec2 a_uv2;
|
|
attribute mediump vec2 a_uv3;
|
|
|
|
varying mediump vec2 uv1;
|
|
varying mediump vec2 uv2;
|
|
varying mediump vec2 uv3;
|
|
|
|
void main () {
|
|
mat4 mvp;
|
|
#ifdef useModel
|
|
mvp = viewProj * model;
|
|
#else
|
|
mvp = viewProj;
|
|
#endif
|
|
#ifdef use2DPos
|
|
vec4 pos = mvp * vec4(a_position, 0, 1);
|
|
#else
|
|
vec4 pos = mvp * vec4(a_position, 1);
|
|
#endif
|
|
#ifndef useColor
|
|
v_fragmentColor = a_color;
|
|
#endif
|
|
#ifdef useTexture
|
|
uv0 = a_uv0;
|
|
#endif
|
|
uv1 = a_uv1;
|
|
uv2 = a_uv2;
|
|
uv3 = a_uv3;
|
|
|
|
gl_Position = pos;
|
|
}`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var ShaderMaterial = cc.Class({
|
|
extends: Material,
|
|
properties: {
|
|
|
|
},
|
|
|
|
setUVoffset(frame,sp)
|
|
{
|
|
let rect = frame.getRect();
|
|
let texture = frame.getTexture();
|
|
let texw = texture.width;
|
|
let texh = texture.height;
|
|
let l = 0, r = 0, b = 1, t = 1;
|
|
l = texw && rect.x / texw;
|
|
t = texh && rect.y / texh;
|
|
if(frame.isRotated())
|
|
{
|
|
r = texw && (rect.x+rect.height)/texw;
|
|
b = texh && (rect.y+rect.width)/texh;
|
|
}
|
|
else
|
|
{
|
|
r = texw && (rect.x+rect.width)/texw;
|
|
b = texh && (rect.y+rect.height)/texh;
|
|
}
|
|
this._UVoffset={}
|
|
this._UVoffset.x = l;
|
|
this._UVoffset.y = t;
|
|
this._UVoffset.z = r;
|
|
this._UVoffset.w = b;
|
|
// this._rotated = frame.isRotated() ? 1.0 : 0.0;
|
|
|
|
this._effect.setProperty('UVoffset', this._UVoffset);
|
|
this._effect.setProperty('rotated', frame.isRotated() ? 1.0 : 0.0);
|
|
|
|
sp.srotated = frame.isRotated() ? 1.0 : 0.0
|
|
sp.sUVoffset = {x:l,y:t,z:r,w:b}
|
|
|
|
},
|
|
initspine(shaderName,params){
|
|
var renderer = renderEngine.renderer;
|
|
var gfx = renderEngine.gfx;
|
|
var pass = new renderer.Pass(shaderName);
|
|
pass.setDepth(false, false);
|
|
pass.setCullMode(gfx.CULL_NONE);
|
|
pass.setBlend(
|
|
gfx.BLEND_FUNC_ADD,
|
|
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
|
|
gfx.BLEND_FUNC_ADD,
|
|
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
|
|
);
|
|
|
|
var techParams = [
|
|
{ name: 'texture', type: renderer.PARAM_TEXTURE_2D },
|
|
];
|
|
if (params) {
|
|
techParams = techParams.concat(params);
|
|
}
|
|
|
|
var mainTech = new renderer.Technique(
|
|
['transparent'],
|
|
techParams,
|
|
[pass]
|
|
);
|
|
|
|
this.effect = this._effect = new renderer.Effect(
|
|
[mainTech ],
|
|
{},
|
|
[
|
|
{ name: 'useModel', value: true },
|
|
{ name: 'alphaTest', value: false },
|
|
{ name: 'use2DPos', value: true },
|
|
{ name: 'useTint', value: false } ]
|
|
);
|
|
this.name = shaderName;
|
|
this._mainTech = mainTech;
|
|
this._texture = null;
|
|
|
|
},
|
|
|
|
|
|
init (shaderName,params,defines,passdata) {
|
|
var renderer = renderEngine.renderer;
|
|
var gfx = renderEngine.gfx;
|
|
var pass = new renderer.Pass(shaderName);
|
|
pass.setDepth(false, false);
|
|
pass.setCullMode(gfx.CULL_NONE);
|
|
if(passdata == null){
|
|
pass.setBlend(
|
|
gfx.BLEND_FUNC_ADD,
|
|
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA,
|
|
gfx.BLEND_FUNC_ADD,
|
|
gfx.BLEND_SRC_ALPHA, gfx.BLEND_ONE_MINUS_SRC_ALPHA
|
|
);
|
|
}
|
|
else{
|
|
pass.setBlend(
|
|
passdata[0],
|
|
passdata[1], passdata[2],
|
|
passdata[3],
|
|
passdata[4], passdata[5]
|
|
);
|
|
}
|
|
|
|
var techParams = [
|
|
{ name: 'texture', type: renderer.PARAM_TEXTURE_2D },
|
|
{ name: 'color', type: renderer.PARAM_COLOR4 },
|
|
{ name:'UVoffset', type: renderer.PARAM_FLOAT4 },
|
|
{ name:'rotated', type: renderer.PARAM_FLOAT },
|
|
];
|
|
if (params) {
|
|
techParams = techParams.concat(params);
|
|
}
|
|
var mainTech = new renderer.Technique(
|
|
['transparent'],
|
|
techParams,
|
|
[pass]
|
|
);
|
|
|
|
this.name = shaderName;
|
|
|
|
this.effect = this._effect = new renderer.Effect(
|
|
[ mainTech ],
|
|
{},
|
|
[
|
|
{ name: 'useTexture', value: true },
|
|
{ name: 'useModel', value: false },
|
|
{ name: 'alphaTest', value: false },
|
|
{ name: 'use2DPos', value: true },
|
|
{ name: 'useColor', value: true }
|
|
],
|
|
);
|
|
this._texture = null;
|
|
this._color = { r: 1, g: 1, b: 1, a: 1 };
|
|
|
|
this._mainTech = mainTech;
|
|
},
|
|
|
|
setParamValue(name, value) {
|
|
this._effect.setProperty(name, value);
|
|
},
|
|
|
|
|
|
getParamValue(name) {
|
|
return this._effect.getProperty(name);
|
|
},
|
|
|
|
|
|
setDefine(name, value) {
|
|
this._effect.define(name, value);
|
|
},
|
|
|
|
|
|
setTexture(texture) {
|
|
this._texture = texture;
|
|
this._texture.update({ flipY: false, mipmap: false });
|
|
this._effect.setProperty('texture', texture.getImpl());
|
|
this._texIds['texture'] = texture.getId();
|
|
},
|
|
|
|
bindShader(name,parmas,pass){
|
|
var sconfig = ShaderMaterial.getShader(name);
|
|
this.init(name,sconfig.params,sconfig.defines||[],pass);
|
|
sconfig.start&&sconfig.start(this,parmas);
|
|
if(sconfig.update){
|
|
this.needUpdate = true;
|
|
this.isAni = true
|
|
ShaderMaterial.pushUpdate(this);
|
|
}
|
|
},
|
|
|
|
bindShader2(name,parmas,pass){
|
|
var sconfig = ShaderMaterial.getShader(name);
|
|
this.initspine(name,sconfig.params);
|
|
sconfig.start&&sconfig.start(this,parmas);
|
|
if(sconfig.update){
|
|
this.needUpdate = true;
|
|
this.shadercfg = sconfig
|
|
}
|
|
},
|
|
|
|
restartShadre(){
|
|
if(this.isAni){
|
|
ShaderMaterial.pushUpdate(this);
|
|
}
|
|
},
|
|
applaySpine(sp,name,parmas){
|
|
var texture = sp._material._texture
|
|
parmas = parmas||{}
|
|
sp._shaderMeterial = this
|
|
sp._updateMaterial(this)
|
|
this.bindShader2(name,parmas);
|
|
|
|
|
|
this.setTexture(texture);
|
|
this.updateHash();
|
|
|
|
},
|
|
applaySprite(sp,name,parmas){
|
|
// if(sp.node.active ==false){
|
|
// return;
|
|
// }
|
|
if(!sp._renderData){
|
|
return;
|
|
}
|
|
parmas = parmas||{}
|
|
if(sp.node){
|
|
parmas.width = sp.node.width;
|
|
parmas.height = sp.node.height;
|
|
parmas.color = sp.node.color;
|
|
parmas.color.r = parmas.color.r/255;
|
|
parmas.color.g = parmas.color.g/255;
|
|
parmas.color.b = parmas.color.b/255;
|
|
parmas.color.a = parmas.color.a/255;
|
|
}
|
|
this.bindShader(name,parmas);
|
|
|
|
var texture = sp.spriteFrame.getTexture();
|
|
this.setTexture(texture);
|
|
this.updateHash();
|
|
if(sp._shaderMeterial&&sp._shaderMeterial.needUpdate){
|
|
ShaderMaterial.cleanUpdate(sp._shaderMeterial);
|
|
}
|
|
sp._state = 2;
|
|
sp._material = this;
|
|
sp._renderData.material = this;
|
|
sp._shaderMeterial = this
|
|
//this.setUVoffset(sp._spriteFrame,sp)
|
|
},
|
|
applaySpriteOnce(sp,name,parmas){
|
|
if(!this.hasinit){
|
|
this.applaySprite(sp,name,parmas)
|
|
}else{
|
|
sp._state = 2;
|
|
sp._material = this;
|
|
sp._renderData.material = this;
|
|
sp._shaderMeterial = this
|
|
}
|
|
this.hasinit = true
|
|
|
|
},
|
|
|
|
|
|
applayLabel(sp,name,parmas){
|
|
if(sp.node.active ==false||!sp._frame||!sp._frame._texture){
|
|
return;
|
|
}
|
|
parmas = parmas||{}
|
|
if(sp.node){
|
|
parmas.width = sp.node.width;
|
|
parmas.height = sp.node.height;
|
|
parmas.color = sp.node.color;
|
|
parmas.color.r = parmas.color.r/255;
|
|
parmas.color.g = parmas.color.g/255;
|
|
parmas.color.b = parmas.color.b/255;
|
|
parmas.color.a = parmas.color.a/255;
|
|
}
|
|
this.bindShader(name,parmas);
|
|
|
|
var texture = sp._frame._texture;
|
|
this.setTexture(texture);
|
|
this.updateHash();
|
|
if(sp._material&&sp._material.needUpdate){
|
|
ShaderMaterial.cleanUpdate(sp._material);
|
|
}
|
|
sp._material = this;
|
|
sp._renderData.material = this;
|
|
sp._shaderMeterial = this
|
|
},
|
|
|
|
applayButton(btn,name,parmas){
|
|
if(btn.node.active ==false){
|
|
return;
|
|
}
|
|
|
|
this.applaySprite(btn._sprite,name,parmas)
|
|
btn.useShader = true
|
|
|
|
},
|
|
cleanUp(){
|
|
if(this.needUpdate){
|
|
ShaderMaterial.cleanUpdate(this);
|
|
this.needUpdate = false;
|
|
}
|
|
},
|
|
reset(parmas){
|
|
var sconfig = ShaderMaterial.getShader(this.name);
|
|
sconfig.reset&&sconfig.reset(this,parmas);
|
|
},
|
|
});
|
|
|
|
var g_shaders = {};
|
|
var mtArr =[];
|
|
ShaderMaterial.addShader = function(shader){
|
|
|
|
|
|
|
|
|
|
if (g_shaders[shader.name]) {
|
|
console.log("addShader - shader already exist: ", shader.name);
|
|
return;
|
|
}
|
|
var def=[
|
|
{ name: 'useTexture', value: true },
|
|
{ name: 'useModel', value: false },
|
|
{ name: 'alphaTest', value: false },
|
|
{ name: 'use2DPos', value: true },
|
|
{ name: 'useColor', value: true }
|
|
]
|
|
if (cc.renderer._forward) {
|
|
cc.renderer._forward._programLib.define(shader.name, shader.vert||MVP, shader.frag, def);
|
|
g_shaders[shader.name] = shader;
|
|
} else {
|
|
|
|
cc.game.once(cc.game.EVENT_ENGINE_INITED, function () {
|
|
cc.renderer._forward._programLib.define(shader.name, shader.vert||MVP, shader.frag, def);
|
|
g_shaders[shader.name] = shader;
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
ShaderMaterial.getShader = function(name) {
|
|
return g_shaders[name];
|
|
};
|
|
|
|
|
|
ShaderMaterial.pushUpdate = function(mat){
|
|
mtArr.push(mat);
|
|
};
|
|
ShaderMaterial.cleanUpdate = function(mat){
|
|
for(var i = 0;i<mtArr.length;i++){
|
|
if(mtArr[i] == mat){
|
|
mtArr.splice(i,1);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
ShaderMaterial.cleanAll= function(){
|
|
mtArr.length = 0
|
|
}
|
|
ShaderMaterial.update = function(dt){
|
|
for(var i = 0;i<mtArr.length;i++){
|
|
var sconfig = this.getShader(mtArr[i].name);
|
|
sconfig.update(mtArr[i],dt);
|
|
}
|
|
}
|
|
ShaderMaterial.spinevert = '\n \nuniform mat4 viewProj;\n\n#ifdef use2DPos\n attribute vec2 a_position;\n#else\n attribute vec3 a_position;\n#endif\n\nattribute lowp vec4 a_color;\n#ifdef useTint\n attribute lowp vec4 a_color0;\n#endif\n\n#ifdef useModel\n uniform mat4 model;\n#endif\n\nattribute mediump vec2 a_uv0;\nvarying mediump vec2 uv0;\n\nvarying lowp vec4 v_light;\n#ifdef useTint\n varying lowp vec4 v_dark;\n#endif\n\nvoid main () {\n mat4 mvp;\n #ifdef useModel\n mvp = viewProj * model;\n #else\n mvp = viewProj;\n #endif\n\n #ifdef use2DPos\n vec4 pos = mvp * vec4(a_position, 0, 1);\n #else\n vec4 pos = mvp * vec4(a_position, 1);\n #endif\n\n v_light = a_color;\n #ifdef useTint\n v_dark = a_color0;\n #endif\n\n uv0 = a_uv0;\n\n gl_Position = pos;\n}'
|
|
module.exports = ShaderMaterial;
|