////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2014-present, Egret Technology. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Egret nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////////////// namespace egret.web { /** * @private */ export enum WEBGL_UNIFORM_TYPE { FLOAT_VEC2 = 0x8B50, FLOAT_VEC3 = 0x8B51, FLOAT_VEC4 = 0x8B52, INT_VEC2 = 0x8B53, INT_VEC3 = 0x8B54, INT_VEC4 = 0x8B55, BOOL = 0x8B56, BOOL_VEC2 = 0x8B57, BOOL_VEC3 = 0x8B58, BOOL_VEC4 = 0x8B59, FLOAT_MAT2 = 0x8B5A, FLOAT_MAT3 = 0x8B5B, FLOAT_MAT4 = 0x8B5C, SAMPLER_2D = 0x8B5E, SAMPLER_CUBE = 0x8B60, BYTE = 0xffff, UNSIGNED_BYTE = 0x1401, SHORT = 0x1402, UNSIGNED_SHORT = 0x1403, INT = 0x1404, UNSIGNED_INT = 0x1405, FLOAT = 0x1406 } /** * @private */ export class EgretWebGLUniform { private gl:WebGLRenderingContext; private name:string; public type:WEBGL_UNIFORM_TYPE; private size:number; private location:WebGLUniformLocation; constructor(gl:WebGLRenderingContext, program:WebGLProgram, uniformData:any) { this.gl = gl; this.name = uniformData.name; this.type = uniformData.type; this.size = uniformData.size; this.location = gl.getUniformLocation(program, this.name); this.setDefaultValue(); this.generateSetValue(); this.generateUpload(); } public value:any; private setDefaultValue():void { let type = this.type; switch (type) { case WEBGL_UNIFORM_TYPE.FLOAT: case WEBGL_UNIFORM_TYPE.SAMPLER_2D: case WEBGL_UNIFORM_TYPE.SAMPLER_CUBE: case WEBGL_UNIFORM_TYPE.BOOL: case WEBGL_UNIFORM_TYPE.INT: this.value = 0; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC2: case WEBGL_UNIFORM_TYPE.BOOL_VEC2: case WEBGL_UNIFORM_TYPE.INT_VEC2: this.value = [0, 0]; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC3: case WEBGL_UNIFORM_TYPE.BOOL_VEC3: case WEBGL_UNIFORM_TYPE.INT_VEC3: this.value = [0, 0, 0]; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC4: case WEBGL_UNIFORM_TYPE.BOOL_VEC4: case WEBGL_UNIFORM_TYPE.INT_VEC4: this.value = [0, 0, 0, 0]; break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT2: this.value = new Float32Array([ 1, 0, 0, 1 ]); break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT3: this.value = new Float32Array([ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]); break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT4: this.value = new Float32Array([ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]); break; } } public setValue:Function; private generateSetValue():void { let type = this.type; switch (type) { case WEBGL_UNIFORM_TYPE.FLOAT: case WEBGL_UNIFORM_TYPE.SAMPLER_2D: case WEBGL_UNIFORM_TYPE.SAMPLER_CUBE: case WEBGL_UNIFORM_TYPE.BOOL: case WEBGL_UNIFORM_TYPE.INT: this.setValue = function(value) { let notEqual = this.value !== value; this.value = value; notEqual && this.upload(); } break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC2: case WEBGL_UNIFORM_TYPE.BOOL_VEC2: case WEBGL_UNIFORM_TYPE.INT_VEC2: this.setValue = function(value) { let notEqual = this.value[0] !== value.x || this.value[1] !== value.y; this.value[0] = value.x; this.value[1] = value.y; notEqual && this.upload(); } break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC3: case WEBGL_UNIFORM_TYPE.BOOL_VEC3: case WEBGL_UNIFORM_TYPE.INT_VEC3: this.setValue = function(value) { this.value[0] = value.x; this.value[1] = value.y; this.value[2] = value.z; this.upload(); } break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC4: case WEBGL_UNIFORM_TYPE.BOOL_VEC4: case WEBGL_UNIFORM_TYPE.INT_VEC4: this.setValue = function(value) { this.value[0] = value.x; this.value[1] = value.y; this.value[2] = value.z; this.value[3] = value.w; this.upload(); } break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT2: case WEBGL_UNIFORM_TYPE.FLOAT_MAT3: case WEBGL_UNIFORM_TYPE.FLOAT_MAT4: this.setValue = function(value) { this.value.set(value); this.upload(); } break; } } public upload:Function; private generateUpload():void { let gl = this.gl; let type = this.type; let location = this.location; switch (type) { case WEBGL_UNIFORM_TYPE.FLOAT: this.upload = function() { var value = this.value; gl.uniform1f(location, value); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC2: this.upload = function() { var value = this.value; gl.uniform2f(location, value[0], value[1]); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC3: this.upload = function() { var value = this.value; gl.uniform3f(location, value[0], value[1], value[2]); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_VEC4: this.upload = function() { var value = this.value; gl.uniform4f(location, value[0], value[1], value[2], value[3]); }; break; case WEBGL_UNIFORM_TYPE.SAMPLER_2D: case WEBGL_UNIFORM_TYPE.SAMPLER_CUBE: case WEBGL_UNIFORM_TYPE.BOOL: case WEBGL_UNIFORM_TYPE.INT: this.upload = function() { var value = this.value; gl.uniform1i(location, value); }; break; case WEBGL_UNIFORM_TYPE.BOOL_VEC2: case WEBGL_UNIFORM_TYPE.INT_VEC2: this.upload = function() { var value = this.value; gl.uniform2i(location, value[0], value[1]); }; break; case WEBGL_UNIFORM_TYPE.BOOL_VEC3: case WEBGL_UNIFORM_TYPE.INT_VEC3: this.upload = function() { var value = this.value; gl.uniform3i(location, value[0], value[1], value[2]); }; break; case WEBGL_UNIFORM_TYPE.BOOL_VEC4: case WEBGL_UNIFORM_TYPE.INT_VEC4: this.upload = function() { var value = this.value; gl.uniform4i(location, value[0], value[1], value[2], value[3]); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT2: this.upload = function() { var value = this.value; gl.uniformMatrix2fv(location, false, value); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT3: this.upload = function() { var value = this.value; gl.uniformMatrix3fv(location, false, value); }; break; case WEBGL_UNIFORM_TYPE.FLOAT_MAT4: this.upload = function() { var value = this.value; gl.uniformMatrix4fv(location, false, value); }; break; } } } }