|
- /*
- * TSDGLShader.js
- * Keynote HTML Player
- *
- * Created by Tungwei Cheng
- * Copyright (c) 2018-2019 Apple Inc. All rights reserved.
- */
-
- // Uniforms
- var kTSDGLShaderUniformColor = "Color";
- var kTSDGLShaderUniformDuration = "Duration";
- var kTSDGLShaderUniformMotionBlurVector = "MotionBlurVector";
- var kTSDGLShaderUniformMVPMatrix = "MVPMatrix";
- var kTSDGLShaderUniformOpacity = "Opacity";
- var kTSDGLShaderUniformParticleTexture = "ParticleTexture";
- var kTSDGLShaderUniformPercent = "Percent";
- var kTSDGLShaderUniformPreviousMVPMatrix = "PreviousMVPMatrix";
- var kTSDGLShaderUniformTexture = "Texture";
- var kTSDGLShaderUniformTextureMatrix = "TextureMatrix";
- var kTSDGLShaderUniformTextureSize = "TextureSize";
- var kTSDGLShaderUniformTexture2 = "Texture2";
- var kTSDGLShaderUniformTexture2Matrix = "Texture2Matrix";
- var kTSDGLShaderUniformTexture2Size = "Texture2Size";
- var kTSDGLShaderUniformVelocityScale = "VelocityScale";
- var kTSDGLShaderUniformVelocityTexture = "VelocityTexture";
-
- // Attributes
- var kTSDGLShaderAttributeCenter = "Center"; // center point of this particle
- var kTSDGLShaderAttributeColor = "Color";
- var kTSDGLShaderAttributeLifeSpan = "LifeSpan";
- var kTSDGLShaderAttributeNormal = "Normal";
- var kTSDGLShaderAttributeParticleTexCoord = "ParticleTexCoord";
- var kTSDGLShaderAttributePosition = "Position";
- var kTSDGLShaderAttributePreviousPosition = "PreviousPosition";
- var kTSDGLShaderAttributeRotation = "Rotation";
- var kTSDGLShaderAttributeScale = "Scale";
- var kTSDGLShaderAttributeSpeed = "Speed";
- var kTSDGLShaderAttributeTexCoord = "TexCoord";
- var kTSDGLShaderUniformRotationMax = "RotationMax";
- var kTSDGLShaderUniformSpeedMax = "SpeedMax";
-
- var TSDGLShaderQualifierType = {
- Unknown: 0, ///< ERROR
- Int: 1, // < GLSL type "int"
- Float: 2, // < GLSL type "float"
- Vec2: 3, // < GLSL type "vec2"
- Vec3: 4, // < GLSL type "vec3"
- Vec4: 5, // < GLSL type "vec4"
- Mat3: 6, // < GLSL type "mat3"
- Mat4: 7 // < GLSL type "mat4"
- };
-
- function TSDGLShaderQualifierTypeFromGLenum(type) {
- var result = TSDGLShaderQualifierType.Unknown;
-
- switch (type) {
- case GL_FLOAT:
- result = TSDGLShaderQualifierType.Float;
- break;
- case GL_FLOAT_VEC2:
- result = TSDGLShaderQualifierType.Vec2;
- break;
- case GL_FLOAT_VEC3:
- result = TSDGLShaderQualifierType.Vec3;
- break;
- case GL_FLOAT_VEC4:
- result = TSDGLShaderQualifierType.Vec4;
- break;
- case GL_BOOL:
- case GL_SAMPLER_2D:
- case GL_INT:
- result = TSDGLShaderQualifierType.Int;
- break;
- case GL_FLOAT_MAT3:
- result = TSDGLShaderQualifierType.Mat3;
- break;
- case GL_FLOAT_MAT4:
- result = TSDGLShaderQualifierType.Mat4;
- break;
-
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- case GL_FLOAT_MAT2:
- case GL_SAMPLER_CUBE:
- default:
- console.log("Unimplemented GLenum type " + type);
- break;
- }
-
- return result;
- }
-
- var TSDGLShader = Class.create({
- initialize: function(gl) {
- this.gl = gl;
-
- this._uniforms = {};
- this.name = "";
- this.programObject = null;
- this.isActive = false;
-
- this._uniformsNeedingUpdate = [];
- },
-
- initWithDefaultTextureShader: function() {
- this.initWithShaderFileNames("defaultTexture", "defaultTexture");
- this.setGLint(0, kTSDGLShaderUniformTexture);
- },
-
- initWithDefaultTextureAndOpacityShader: function() {
- this.initWithShaderFileNames("defaultTexture", "defaultTextureAndOpacity");
- },
-
- initWithDefaultHorizontalBlurShader: function() {
- this.initWithShaderFileNames("horizontalGaussianBlur", "horizontalGaussianBlur");
- this.setGLint(0, kTSDGLShaderUniformTexture);
- },
-
- initWithDefaultVerticalBlurShader: function() {
- this.initWithShaderFileNames("verticalGaussianBlur", "verticalGaussianBlur");
- this.setGLint(0, kTSDGLShaderUniformTexture);
- },
-
- initWithContentsShader: function() {
- this.initWithShaderFileNames("contents", "contents");
- },
-
- initWithContentsAndOpacityShader: function() {
- this.initWithShaderFileNames("contentsAndOpacity", "contentsAndOpacity");
- },
-
- initWithShaderFileNames: function(vertexShaderFileName, fragmentShaderFileName) {
- var vertexString = KNWebGLShader[vertexShaderFileName].vertex;
- var fragmentString = KNWebGLShader[fragmentShaderFileName].fragment;
-
- this.initWithShaders(vertexString, fragmentString);
- },
-
- initWithShaders: function(vertexString, fragmentString) {
- var gl = this.gl;
-
- var vertexShader = KNWebGLUtil.loadShader(gl, gl.VERTEX_SHADER, vertexString);
- var fragmentShader = KNWebGLUtil.loadShader(gl, gl.FRAGMENT_SHADER, fragmentString);
-
- this.programObject = KNWebGLUtil.createShaderProgram(gl, vertexShader, fragmentShader);
-
- this.p_updateUniformsAndAttributesFromShader();
- },
-
- p_updateUniformsAndAttributesFromShader: function() {
- var gl = this.gl;
- var programObject = this.programObject;
- var uniformsCount = -1;
-
- uniformsCount = gl.getProgramParameter(programObject, gl.ACTIVE_UNIFORMS);
-
- for (var i = 0; i < uniformsCount; i++) {
- var activeInfo = gl.getActiveUniform(programObject, i);
- var name = activeInfo.name;
- var type = activeInfo.type;
- var size = activeInfo.size;
-
- // Add uniform to cache
- var qualifierType = TSDGLShaderQualifierTypeFromGLenum(type);
- this.shaderQualifierForUniform(name, qualifierType);
- }
-
- // Update attributes
- var attributesCount = -1;
-
- attributesCount = gl.getProgramParameter(programObject, gl.ACTIVE_ATTRIBUTES);
-
- for (var i = 0; i < attributesCount; i++) {
- var activeInfo = gl.getActiveAttrib(programObject, i);
- var name = activeInfo.name;
- var type = activeInfo.type;
- var size = activeInfo.size;
-
- // Add attribute location to cache
- this.locationForAttribute(name);
- }
- },
-
- shaderQualifierForUniform: function(uniform, qualifierType) {
- var gl = this.gl;
- var qualifier = this._uniforms[uniform];
-
- if (!qualifier) {
- switch (qualifierType) {
- case TSDGLShaderQualifierType.Unknown:
- console.log("Unknown Shader Qualifier Type!");
- break;
- case TSDGLShaderQualifierType.Int:
- qualifier = new TSDGLShaderQualifierInt(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Float:
- qualifier = new TSDGLShaderQualifierFloat(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Vec2:
- qualifier = new TSDGLShaderQualifierPoint2D(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Vec3:
- qualifier = new TSDGLShaderQualifierPoint3D(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Vec4:
- qualifier = new TSDGLShaderQualifierPoint4D(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Mat3:
- qualifier = new TSDGLShaderQualifierMat3(gl, uniform);
- break;
- case TSDGLShaderQualifierType.Mat4:
- qualifier = new TSDGLShaderQualifierMat4(gl, uniform);
- break;
- }
-
- qualifier.updateUniformLocationWithShaderProgramObject(this.programObject);
- this._uniforms[uniform] = qualifier;
- }
-
- return qualifier;
- },
-
- setGLint: function(newInt, uniform) {
- var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Int);
-
- qualifier.setProposedGLintValue(newInt);
-
- if (qualifier._needsUpdate) {
- this._uniformsNeedingUpdate.push(qualifier);
- }
-
- this.p_setQualifiersIfNecessary();
- },
-
- setGLFloat: function(newFloat, uniform) {
- var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Float);
-
- qualifier.setProposedGLfloatValue(newFloat);
-
- if (qualifier._needsUpdate) {
- this._uniformsNeedingUpdate.push(qualifier);
- }
-
- this.p_setQualifiersIfNecessary();
- },
-
- setPoint2D: function(newPoint2D, uniform) {
- var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Vec2);
-
- qualifier.setProposedGLPoint2DValue(newPoint2D);
-
- if (qualifier._needsUpdate) {
- this._uniformsNeedingUpdate.push(qualifier);
- }
-
- this.p_setQualifiersIfNecessary();
- },
-
- setMat4WithTransform3D: function(aTransform3D, uniform) {
- var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Mat4);
-
- qualifier.setProposedTransform3D(aTransform3D);
-
- if (qualifier._needsUpdate) {
- this._uniformsNeedingUpdate.push(qualifier);
- }
-
- this.p_setQualifiersIfNecessary();
- },
-
- locationForUniform: function(uniform) {
- var location;
- var shaderQualifier = this._uniforms[uniform];
-
- if (shaderQualifier) {
- location = shaderQualifier._uniformLocation;
- }
-
- if (!location) {
- location = this.gl.getUniformLocation(this.programObject, uniform);
- }
-
- return location;
- },
-
- locationForAttribute: function(attribute) {
- if (!this._attributeLocations) {
- this._attributeLocations = {};
- }
-
- var location = this._attributeLocations[attribute];
-
- if (location === undefined) {
- location = -1;
- }
-
- if (location < 0) {
- location = this.gl.getAttribLocation(this.programObject, attribute);
- this._attributeLocations[attribute] = location;
- }
-
- return location;
- },
-
- p_setQualifiersIfNecessary: function() {
- if (!this.isActive) {
- return;
- }
- if (this._uniformsNeedingUpdate.length === 0) {
- return;
- }
-
- // Look through all the newly-set qualifiers
- for (var i = 0, length = this._uniformsNeedingUpdate.length; i < length; i++) {
- var proposedQualifier = this._uniformsNeedingUpdate[i];
-
- if (proposedQualifier._uniformLocation === -1) {
- proposedQualifier.updateUniformLocationWithShaderProgramObject(this.programObject);
- }
-
- proposedQualifier.setGLUniformWithShader(this.gl, this);
- }
-
- this._uniformsNeedingUpdate = [];
- },
-
- activate: function() {
- var gl = this.gl;
-
- if (!this.isActive) {
- gl.useProgram(this.programObject);
- this.isActive = true;
- }
-
- this.p_setQualifiersIfNecessary();
- },
-
- deactivate: function() {
- if (this.isActive) {
- //gl.useProgram(0);
- this.isActive = false;
- }
- }
-
- });
-
- var TSDGLShaderQualifier = Class.create({
- initialize: function(gl, qualifierName) {
- this.gl = gl;
- this._uniformLocation = -1;
- this._needsUpdate = true;
- this._name = qualifierName;
- },
-
- updateUniformLocationWithShaderProgramObject: function(shaderProgramObject) {
- if (this._uniformLocation === -1) {
- this._uniformLocation = this.gl.getUniformLocation(shaderProgramObject, this._name);
- }
- }
- });
-
- var TSDGLShaderQualifierInt = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._GLintValue = 0;
- this._proposedGLintValue = 0;
-
- $super(gl, qualifierName);
- },
-
- setProposedGLintValue: function(proposedGLintValue) {
- if (this._proposedGLintValue !== proposedGLintValue) {
- this._proposedGLintValue = proposedGLintValue;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniform1i(this._uniformLocation, this._proposedGLintValue);
- this._GLintValue = this._proposedGLintValue;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierFloat = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._GLfloatValue = 0;
- this._proposedGLfloatValue = 0;
-
- $super(gl, qualifierName);
- },
-
- setProposedGLfloatValue: function(proposedGLfloatValue) {
- if (this._proposedGLfloatValue !== proposedGLfloatValue) {
- this._proposedGLfloatValue = proposedGLfloatValue;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniform1f(this._uniformLocation, this._proposedGLfloatValue);
- this._GLfloatValue = this._proposedGLfloatValue;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierPoint2D = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._GLPoint2DValue = {};
- this._proposedGLPoint2DValue = {};
-
- $super(gl, qualifierName);
- },
-
- setProposedGLPoint2DValue: function(proposedGLPoint2DValue) {
- if (!(this._proposedGLPoint2DValue.x === proposedGLPoint2DValue.x && this._proposedGLPoint2DValue.y === proposedGLPoint2DValue.y)) {
- this._proposedGLPoint2DValue = proposedGLPoint2DValue;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniform2fv(this._uniformLocation, [this._proposedGLPoint2DValue.x, this._proposedGLPoint2DValue.y]);
- this._GLPoint2DValue = this._proposedGLPoint2DValue;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierPoint3D = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._GLPoint3DValue = {};
- this._proposedGLPoint3DValue = {};
-
- $super(gl, qualifierName);
- },
-
- setProposedGLPoint3DValue: function(proposedGLPoint3DValue) {
- if (!(this._proposedGLPoint3DValue.x === proposedGLPoint3DValue.x && this._proposedGLPoint3DValue.y === proposedGLPoint3DValue.y && this._proposedGLPoint3DValue.z === proposedGLPoint3DValue.z)) {
- this._proposedGLPoint3DValue = proposedGLPoint3DValue;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniform3fv(this._uniformLocation, [this._proposedGLPoint3DValue.x, this._proposedGLPoint3DValue.y, this._proposedGLPoint3DValue.z]);
- this._GLPoint3DValue = this._proposedGLPoint3DValue;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierPoint4D = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._GLPoint4DValue = {};
- this._proposedGLPoint4DValue = {};
-
- $super(gl, qualifierName);
- },
-
- setProposedGLPoint4DValue: function(proposedGLPoint4DValue) {
- if (!(this._proposedGLPoint4DValue.x === proposedGLPoint4DValue.x && this._proposedGLPoint4DValue.y === proposedGLPoint4DValue.y && this._proposedGLPoint4DValue.z === proposedGLPoint4DValue.z && this._proposedGLPoint4DValue.w === proposedGLPoint4DValue.w)) {
- this._proposedGLPoint4DValue = proposedGLPoint4DValue;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniform4fv(this._uniformLocation, [this._proposedGLPoint4DValue.x, this._proposedGLPoint4DValue.y, this._proposedGLPoint4DValue.z, this._proposedGLPoint4DValue.w]);
- this._GLPoint4DValue = this._proposedGLPoint4DValue;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierMat3 = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._affineTransform = new Float32Array(9) ;
- this._proposedAffineTransform = new Float32Array(9);
-
- $super(gl, qualifierName);
- },
-
- setProposedAffineTransform: function(proposedAffineTransform) {
- if (!CGAffineTransformEqualToTransform(this._proposedAffineTransform, proposedAffineTransform)) {
- this._proposedAffineTransform = proposedAffineTransform;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- var mat = [
- this._proposedAffineTransform.a, this._proposedAffineTransform.b, 0,
- this._proposedAffineTransform.c, this._proposedAffineTransform.d, 0,
- this._proposedAffineTransform.tx, this._proposedAffineTransform.ty, 1
- ];
-
- gl.uniformMatrix3fv(this._uniformLocation, false, mat);
- this._affineTransform = this._proposedAffineTransform;
- this._needsUpdate = false;
- }
- });
-
- var TSDGLShaderQualifierMat4 = Class.create(TSDGLShaderQualifier, {
- initialize: function($super, gl, qualifierName) {
- this._transform3D = new Float32Array(16);
- this._proposedTransform3D = new Float32Array(16);
-
- $super(gl, qualifierName);
- },
-
- setProposedTransform3D: function(proposedTransform3D) {
- if (!CATransform3DEqualToTransform(this._proposedTransform3D, proposedTransform3D)) {
- this._proposedTransform3D = proposedTransform3D;
- this._needsUpdate = true;
- }
- },
-
- setGLUniformWithShader: function(gl, shader) {
- gl.uniformMatrix4fv(this._uniformLocation, false, this._proposedTransform3D);
- this._transform3D = this._proposedTransform3D;
- this._needsUpdate = false;
- }
- });
|