API Docs for: 1.1.1
Show:

File: src\render\GLShaderManager.ts


/**
* GLSL ES Shaders are used for WebGL rendering.
* ShaderPair objects encapsulate GLSL ES vertex and fragment shader programs. 
*   ShaderPairs contain the GLSL code, provide an interface to uniforms and attributes, and have the ability to link and compile the shaders.
* The ShaderManager keeps track of each ShaderPair, and controls which one is bound for use at any particular time.
*   Only the ShaderManager can create ShaderPairs. When a renderer (see note on renderes below) requests a ShaderPair the ShaderManager will either
*       1) Return a reference to an already instantiated ShaderPair, and set the GL state to use the shader program or
*       2) Return a reference to a new ShaderPair, which will be linked and compiled and bound for use.
*   All ShaderPairs must be housed as properties of the Kiwi.Shaders object. 
* 
* Kiwi.Renderer objects use a ShaderPair to draw.
*   They must request a ShaderPair from the ShaderManager.
*   Many renderers may use the same ShaderPair.
*   Some renderers may at different times use multiple ShaderPairs (only one is possible at any given time)
* 
* @module Kiwi
* @submodule Shaders 
* @main Shaders
* @namespace Kiwi.Shaders
*/ 

module Kiwi.Shaders {

    /**
    * Manages all WebGL Shaders. Maintains a list of ShaderPairs 
    *  
    * Provides an interface for using a specific ShaderPair, adding new ShaderPairs, and requesting a reference to a ShaderPair instance.
    * Renderes use shaderPairs to draw. Multiple renderers may use the same compiled shader program.
    * This Manager ensures only one compiled instance of each program is created
    * @class ShaderManager
    * @extends IRenderer
    * @constructor
    * @return {Kiwi.Shaders.ShaderManager}
    */
    export class ShaderManager {

        constructor() {
            
        }
        

         /**
        * An object containing a set of properties each of which references a ShaderPair. 
        * @property _shaderPairs
        * @type Object
        * @private
        */
        private _shaderPairs: any = {};

        /**
        * The shader program that is currently set to be used useing gl.useProgram.
        * @property currentShader
        * @type Array
        * @private
        */

        public get currentShader(): ShaderPair {
            return this._currentShader;
        }
        private _currentShader: ShaderPair;


        /**
	    * Sets up a default shaderPair.
	    * @method init
        * @param {WebGLRenderingContext} gl
        * @param {String} defaultShaderID
        * @public
	    */
        public init(gl: WebGLRenderingContext, defaultShaderID: string) {
            this._currentShader = this.requestShader(gl, defaultShaderID);
        }


        /**
	    * Provides a reference to a ShaderPair. If the requested ShaderPair exists as a property on the _shaderPairs object it will be returned if already loaded,
        * otherwise it will be loaded, then returned.
        *
        * If the request is not on the list, the Kiwi.Shaders object will  be checked for a property name that matches shaderID and a new ShaderPair
        * will be instantiated, loaded, and set for use.

	    * @method requestShader
        * @param {WebGLRenderingContext} gl
        * @param {String} shaderID
        * @param {boolean} use
        * @return {Kiwi.Shaders.ShaderPair} a ShaderPair instance - null on fail
        * @public
	    */
        public requestShader(gl: WebGLRenderingContext,shaderID: string,use:boolean = true):ShaderPair {

            var shader: ShaderPair;
            //in list already?
            if (shaderID in this._shaderPairs) {
                shader = this._shaderPairs[shaderID];
                if (!shader.loaded) {
                    this._loadShader(gl, shader);
                }
                if(use)
                    this._useShader(gl, shader);
                return shader;
            } else {
                //not in list, does it exist?
                if ( this.shaderExists(gl, shaderID) ) {
                    shader = this._addShader(gl, shaderID);
                    this._loadShader(gl, shader);
                    if(use)
                        this._useShader(gl, shader);
                    return shader;
                } else {
                    console.log("Shader " + shaderID + " does not exist");
                }
            }
            //unsuccessful request
            return null;
        }

        /**
	    * Tests to see if a ShaderPair property named ShaderID exists on Kiwi.Shaders. Can be used to test for the availability of specific shaders (for fallback)
	    * @method shaderExists
        * @param {WebGLRenderingContext} gl
        * @param {String} shaderID
        * @return {Boolean} success
        * @public
	    */
        public shaderExists(gl: WebGLRenderingContext, shaderID: string):boolean {
            return shaderID in Kiwi.Shaders;
        }

        /**
	    * Creates a new instance of a ShaderPair and adds a reference to the _shaderPairs object
	    * @method _addShader
        * @param {WebGLRenderingContext} gl
        * @param {String} shaderID
        * @return {Kiwi.Shaders.ShaderPair} 
        * @private
	    */
        private _addShader(gl: WebGLRenderingContext, shaderID: string):ShaderPair {
            this._shaderPairs[shaderID] = new Kiwi.Shaders[shaderID]();
            return this._shaderPairs[shaderID];
        }

        /**
	    * Tells a ShaderPair to load (compile and link)
	    * @method _loadShader
        * @param {WebGLRenderingContext} gl
        * @param {Kiwi.Shaders.ShaderPair} shader
        * @private
	    */
        private _loadShader(gl: WebGLRenderingContext,shader:ShaderPair) {
            shader.init(gl);
        }

        /**
	    * Changes gl state so that the shaderProgram contined in a ShaderPir is bound for use
	    * @method _useShader
        * @param {WebGLRenderingContext} gl
        * @param {Kiwi.Shaders.ShaderPair} shader
        * @private
	    */
        private _useShader(gl: WebGLRenderingContext, shader: ShaderPair) {
            if (shader !== this._currentShader) {
                this._currentShader = shader;
            }
            gl.useProgram(shader.shaderProgram);
        }


    }

}