UNPKG

laya-coreui-es

Version:

laya核心库、ui库es版本,剔除了媒体、TTF等功能。基于 LayaAir-release_2.12.0 修改

410 lines (409 loc) 17.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Shader = void 0; const ILaya_1 = require("../../../ILaya"); const Stat_1 = require("../../utils/Stat"); const StringKey_1 = require("../../utils/StringKey"); const WebGLContext_1 = require("../WebGLContext"); const BaseShader_1 = require("./BaseShader"); const LayaGL_1 = require("../../layagl/LayaGL"); class Shader extends BaseShader_1.BaseShader { static getShader(name) { return Shader.sharders[name]; } static create(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { return new Shader(vs, ps, saveName, nameMap, bindAttrib); } static withCompile(nameID, define, shaderName, createShader) { if (shaderName && Shader.sharders[shaderName]) return Shader.sharders[shaderName]; var pre = Shader._preCompileShader[Shader.SHADERNAME2ID * nameID]; if (!pre) throw new Error("withCompile shader err!" + nameID); return pre.createShader(define, shaderName, createShader, null); } static withCompile2D(nameID, mainID, define, shaderName, createShader, bindAttrib = null) { if (shaderName && Shader.sharders[shaderName]) return Shader.sharders[shaderName]; var pre = Shader._preCompileShader[Shader.SHADERNAME2ID * nameID + mainID]; if (!pre) throw new Error("withCompile shader err!" + nameID + " " + mainID); return pre.createShader(define, shaderName, createShader, bindAttrib); } static addInclude(fileName, txt) { ILaya_1.ILaya.ShaderCompile.addInclude(fileName, txt); } static preCompile(nameID, vs, ps, nameMap) { var id = Shader.SHADERNAME2ID * nameID; Shader._preCompileShader[id] = new ILaya_1.ILaya.ShaderCompile(vs, ps, nameMap); } static preCompile2D(nameID, mainID, vs, ps, nameMap) { var id = Shader.SHADERNAME2ID * nameID + mainID; Shader._preCompileShader[id] = new ILaya_1.ILaya.ShaderCompile(vs, ps, nameMap); } constructor(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { super(); this._attribInfo = null; this.customCompile = false; this._curActTexIndex = 0; this.tag = {}; this._program = null; this._params = null; this._paramsMap = {}; if ((!vs) || (!ps)) throw "Shader Error"; this._attribInfo = bindAttrib; this._id = ++Shader._count; this._vs = vs; this._ps = ps; this._nameMap = nameMap ? nameMap : {}; saveName != null && (Shader.sharders[saveName] = this); this.recreateResource(); this.lock = true; } recreateResource() { this._compile(); this._setGPUMemory(0); } _disposeResource() { WebGLContext_1.WebGLContext.mainContext.deleteShader(this._vshader); WebGLContext_1.WebGLContext.mainContext.deleteShader(this._pshader); WebGLContext_1.WebGLContext.mainContext.deleteProgram(this._program); this._vshader = this._pshader = this._program = null; this._params = null; this._paramsMap = {}; this._setGPUMemory(0); this._curActTexIndex = 0; } _compile() { if (!this._vs || !this._ps || this._params) return; this._reCompile = true; this._params = []; var result; if (this.customCompile) result = ILaya_1.ILaya.ShaderCompile.preGetParams(this._vs, this._ps); var gl = WebGLContext_1.WebGLContext.mainContext; this._program = gl.createProgram(); this._vshader = Shader._createShader(gl, this._vs, gl.VERTEX_SHADER); this._pshader = Shader._createShader(gl, this._ps, gl.FRAGMENT_SHADER); gl.attachShader(this._program, this._vshader); gl.attachShader(this._program, this._pshader); var one, i, j, n, location; var attribDescNum = this._attribInfo ? this._attribInfo.length : 0; for (i = 0; i < attribDescNum; i += 2) { gl.bindAttribLocation(this._program, this._attribInfo[i + 1], this._attribInfo[i]); } gl.linkProgram(this._program); if (!this.customCompile && !gl.getProgramParameter(this._program, gl.LINK_STATUS)) { throw gl.getProgramInfoLog(this._program); } var nUniformNum = this.customCompile ? result.uniforms.length : gl.getProgramParameter(this._program, gl.ACTIVE_UNIFORMS); for (i = 0; i < nUniformNum; i++) { var uniform = this.customCompile ? result.uniforms[i] : gl.getActiveUniform(this._program, i); location = gl.getUniformLocation(this._program, uniform.name); one = { vartype: "uniform", glfun: null, ivartype: 1, location: location, name: uniform.name, type: uniform.type, isArray: false, isSame: false, preValue: null, indexOfParams: 0 }; if (one.name.indexOf('[0]') > 0) { one.name = one.name.substr(0, one.name.length - 3); one.isArray = true; one.location = gl.getUniformLocation(this._program, one.name); } this._params.push(one); } for (i = 0, n = this._params.length; i < n; i++) { one = this._params[i]; one.indexOfParams = i; one.index = 1; one.value = [one.location, null]; one.codename = one.name; one.name = this._nameMap[one.codename] ? this._nameMap[one.codename] : one.codename; this._paramsMap[one.name] = one; one._this = this; one.uploadedValue = []; switch (one.type) { case gl.INT: one.fun = one.isArray ? this._uniform1iv : this._uniform1i; break; case gl.FLOAT: one.fun = one.isArray ? this._uniform1fv : this._uniform1f; break; case gl.FLOAT_VEC2: one.fun = one.isArray ? this._uniform_vec2v : this._uniform_vec2; break; case gl.FLOAT_VEC3: one.fun = one.isArray ? this._uniform_vec3v : this._uniform_vec3; break; case gl.FLOAT_VEC4: one.fun = one.isArray ? this._uniform_vec4v : this._uniform_vec4; break; case gl.SAMPLER_2D: one.fun = this._uniform_sampler2D; break; case gl.SAMPLER_CUBE: one.fun = this._uniform_samplerCube; break; case gl.FLOAT_MAT4: one.glfun = gl.uniformMatrix4fv; one.fun = this._uniformMatrix4fv; break; case gl.BOOL: one.fun = this._uniform1i; break; case gl.FLOAT_MAT2: case gl.FLOAT_MAT3: throw new Error("compile shader err!"); default: throw new Error("compile shader err!"); } } } static _createShader(gl, str, type) { var shader = gl.createShader(type); gl.shaderSource(shader, str); gl.compileShader(shader); if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { return shader; } else { console.log(gl.getShaderInfoLog(shader)); return null; } } getUniform(name) { return this._paramsMap[name]; } _uniform1f(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value) { WebGLContext_1.WebGLContext.mainContext.uniform1f(one.location, uploadedValue[0] = value); return 1; } return 0; } _uniform1fv(one, value) { if (value.length < 4) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { WebGLContext_1.WebGLContext.mainContext.uniform1fv(one.location, value); uploadedValue[0] = value[0]; uploadedValue[1] = value[1]; uploadedValue[2] = value[2]; uploadedValue[3] = value[3]; return 1; } return 0; } else { WebGLContext_1.WebGLContext.mainContext.uniform1fv(one.location, value); return 1; } } _uniform_vec2(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) { WebGLContext_1.WebGLContext.mainContext.uniform2f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]); return 1; } return 0; } _uniform_vec2v(one, value) { if (value.length < 2) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { WebGLContext_1.WebGLContext.mainContext.uniform2fv(one.location, value); uploadedValue[0] = value[0]; uploadedValue[1] = value[1]; uploadedValue[2] = value[2]; uploadedValue[3] = value[3]; return 1; } return 0; } else { WebGLContext_1.WebGLContext.mainContext.uniform2fv(one.location, value); return 1; } } _uniform_vec3(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) { WebGLContext_1.WebGLContext.mainContext.uniform3f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]); return 1; } return 0; } _uniform_vec3v(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform3fv(one.location, value); return 1; } _uniform_vec4(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { WebGLContext_1.WebGLContext.mainContext.uniform4f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]); return 1; } return 0; } _uniform_vec4v(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform4fv(one.location, value); return 1; } _uniformMatrix2fv(one, value) { WebGLContext_1.WebGLContext.mainContext.uniformMatrix2fv(one.location, false, value); return 1; } _uniformMatrix3fv(one, value) { WebGLContext_1.WebGLContext.mainContext.uniformMatrix3fv(one.location, false, value); return 1; } _uniformMatrix4fv(one, value) { WebGLContext_1.WebGLContext.mainContext.uniformMatrix4fv(one.location, false, value); return 1; } _uniform1i(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value) { WebGLContext_1.WebGLContext.mainContext.uniform1i(one.location, uploadedValue[0] = value); return 1; } return 0; } _uniform1iv(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform1iv(one.location, value); return 1; } _uniform_ivec2(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) { WebGLContext_1.WebGLContext.mainContext.uniform2i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]); return 1; } return 0; } _uniform_ivec2v(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform2iv(one.location, value); return 1; } _uniform_vec3i(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) { WebGLContext_1.WebGLContext.mainContext.uniform3i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]); return 1; } return 0; } _uniform_vec3vi(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform3iv(one.location, value); return 1; } _uniform_vec4i(one, value) { var uploadedValue = one.uploadedValue; if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { WebGLContext_1.WebGLContext.mainContext.uniform4i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]); return 1; } return 0; } _uniform_vec4vi(one, value) { WebGLContext_1.WebGLContext.mainContext.uniform4iv(one.location, value); return 1; } _uniform_sampler2D(one, value) { var gl = WebGLContext_1.WebGLContext.mainContext; var uploadedValue = one.uploadedValue; if (uploadedValue[0] == null) { uploadedValue[0] = this._curActTexIndex; gl.uniform1i(one.location, this._curActTexIndex); WebGLContext_1.WebGLContext.activeTexture(gl, gl.TEXTURE0 + this._curActTexIndex); WebGLContext_1.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value); this._curActTexIndex++; return 1; } else { WebGLContext_1.WebGLContext.activeTexture(gl, gl.TEXTURE0 + uploadedValue[0]); WebGLContext_1.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value); return 0; } } _uniform_samplerCube(one, value) { var gl = WebGLContext_1.WebGLContext.mainContext; var uploadedValue = one.uploadedValue; if (uploadedValue[0] == null) { uploadedValue[0] = this._curActTexIndex; gl.uniform1i(one.location, this._curActTexIndex); WebGLContext_1.WebGLContext.activeTexture(gl, gl.TEXTURE0 + this._curActTexIndex); WebGLContext_1.WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value); this._curActTexIndex++; return 1; } else { WebGLContext_1.WebGLContext.activeTexture(gl, gl.TEXTURE0 + uploadedValue[0]); WebGLContext_1.WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value); return 0; } } _noSetValue(one) { console.log("no....:" + one.name); } uploadOne(name, value) { WebGLContext_1.WebGLContext.useProgram(WebGLContext_1.WebGLContext.mainContext, this._program); var one = this._paramsMap[name]; one.fun.call(this, one, value); } uploadTexture2D(value) { var CTX = WebGLContext_1.WebGLContext; if (CTX._activeTextures[0] !== value) { CTX.bindTexture(WebGLContext_1.WebGLContext.mainContext, LayaGL_1.LayaGL.instance.TEXTURE_2D, value); CTX._activeTextures[0] = value; } } upload(shaderValue, params = null) { BaseShader_1.BaseShader.activeShader = BaseShader_1.BaseShader.bindShader = this; var gl = WebGLContext_1.WebGLContext.mainContext; WebGLContext_1.WebGLContext.useProgram(gl, this._program); if (this._reCompile) { params = this._params; this._reCompile = false; } else { params = params || this._params; } var one, value, n = params.length, shaderCall = 0; for (var i = 0; i < n; i++) { one = params[i]; if ((value = shaderValue[one.name]) !== null) shaderCall += one.fun.call(this, one, value); } Stat_1.Stat.shaderCall += shaderCall; } uploadArray(shaderValue, length, _bufferUsage) { BaseShader_1.BaseShader.activeShader = this; BaseShader_1.BaseShader.bindShader = this; WebGLContext_1.WebGLContext.useProgram(WebGLContext_1.WebGLContext.mainContext, this._program); var params = this._params, value; var one, shaderCall = 0; for (var i = length - 2; i >= 0; i -= 2) { one = this._paramsMap[shaderValue[i]]; if (!one) continue; value = shaderValue[i + 1]; if (value != null) { _bufferUsage && _bufferUsage[one.name] && _bufferUsage[one.name].bind(); shaderCall += one.fun.call(this, one, value); } } Stat_1.Stat.shaderCall += shaderCall; } getParams() { return this._params; } setAttributesLocation(attribDesc) { this._attribInfo = attribDesc; } } exports.Shader = Shader; Shader._count = 0; Shader._preCompileShader = {}; Shader.SHADERNAME2ID = 0.0002; Shader.nameKey = new StringKey_1.StringKey(); Shader.sharders = new Array(0x20);