module Webglimpse { function compileShader ( gl , shaderType , glsl ) { var shader = gl . createShader ( shaderType ) ; gl . shaderSource ( shader , glsl ) ; gl . compileShader ( shader ) ; if ( ! gl . getShaderParameter ( shader , GL . COMPILE_STATUS ) ) throw new Error ( gl . getShaderInfoLog ( shader ) ) ; return shader ; } function linkProgram ( gl , shaders ) { var program = gl . createProgram ( ) ; for ( var i = 0 ; i < shaders . length ; i ++ ) { gl . attachShader ( program , shaders [ i ] ) ; } try { gl . linkProgram ( program ) ; if ( ! gl . getProgramParameter ( program , GL . LINK_STATUS ) ) throw new Error ( gl . getProgramInfoLog ( program ) ) ; return program ; } finally { } } function createProgram ( gl , vertShaderSource , fragShaderSource ) { var shaders = [ ] ; try { shaders . push ( compileShader ( gl , GL . VERTEX_SHADER , vertShaderSource ) ) ; shaders . push ( compileShader ( gl , GL . FRAGMENT_SHADER , fragShaderSource ) ) ; return linkProgram ( gl , shaders ) ; } finally { } } class ProgramEntry { gl : WebGLRenderingContext ; program : WebGLProgram ; constructor ( gl , program ) { this . gl = gl ; this . program = program ; } } export class Program { private vertShaderSource : string ; private fragShaderSource : string ; private programs : StringMap < ProgramEntry > = { } ; constructor ( vertShaderSource , fragShaderSource ) { this . vertShaderSource = vertShaderSource ; this . fragShaderSource = fragShaderSource ; } _program ( gl ) { var glId = getObjectId ( gl ) ; if ( this . programs [ glId ] === undefined ) { var program = createProgram ( gl , this . vertShaderSource , this . fragShaderSource ) ; this . programs [ glId ] = new ProgramEntry ( gl , program ) ; } return this . programs [ glId ] . program ; } use ( gl ) { gl . useProgram ( this . _program ( gl ) ) ; } endUse ( gl ) { gl . useProgram ( null ) ; } dispose ( ) { for ( var glid in this . programs ) { if ( this . programs . hasOwnProperty ( glid ) ) { var en = this . programs [ glid ] ; en . gl . deleteProgram ( en . program ) ; } } this . programs = { } ; } } export class Uniform { private program : Program ; private name : string ; private optional : boolean ; private locations : StringMap < WebGLUniformLocation > = { } ; constructor ( program , name , optional ) { this . program = program ; this . name = name ; this . optional = optional ; } _location ( gl ) { var glId = getObjectId ( gl ) ; if ( this . locations [ glId ] === undefined ) { var location = gl . getUniformLocation ( this . program . _program ( gl ) , this . name ) ; if ( ! this . optional && ! hasval ( location ) ) throw new Error ( 'Uniform \'' + this . name + '\' not found' ) ; this . locations [ glId ] = location ; } return this . locations [ glId ] ; } } export class Uniform1f extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform1f ( location , x ) ; } } export class Uniform2f extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform2f ( location , x , y ) ; } } export class Uniform3f extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y , z ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform3f ( location , x , y , z ) ; } } export class Uniform4f extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y , z , w ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform4f ( location , x , y , z , w ) ; } } export class UniformMatrix4f extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , value , transpose = false ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniformMatrix4fv ( location , transpose , value ) ; } } export class Uniform1i extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform1i ( location , x ) ; } } export class Uniform2i extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform2i ( location , x , y ) ; } } export class Uniform3i extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y , z ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform3i ( location , x , y , z ) ; } } export class Uniform4i extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , x , y , z , w ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform4i ( location , x , y , z , w ) ; } } export class UniformColor extends Uniform { constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setData ( gl , color ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) gl . uniform4f ( location , color . r , color . g , color . b , color . a ) ; } } export class UniformSampler2D extends Uniform { private currentTexture : Texture ; constructor ( program , name , optional = false ) { super ( program , name , optional ) ; } setDataAndBind ( gl , textureUnit , texture ) { var location = this . _location ( gl ) ; if ( hasval ( location ) ) { texture . bind ( gl , textureUnit ) ; gl . uniform1i ( location , textureUnit ) ; this . currentTexture = texture ; } } unbind ( gl ) { if ( hasval ( this . currentTexture ) ) { this . currentTexture . unbind ( gl ) ; this . currentTexture = null ; } } } export class Attribute { private program : Program ; private name : string ; private locations : StringMap < number > = { } ; constructor ( program , name ) { this . program = program ; this . name = name ; } _location ( gl ) { var glId = getObjectId ( gl ) ; if ( this . locations [ glId ] === undefined ) { var location = gl . getAttribLocation ( this . program . _program ( gl ) , this . name ) ; if ( location === - 1 ) throw new Error ( 'Attribute "' + this . name + '" not found' ) ; this . locations [ glId ] = location ; } return this . locations [ glId ] ; } setDataAndEnable ( gl , buffer , size , type , normalized = false , stride = 0 , offset = 0 ) { var location = this . _location ( gl ) ; gl . enableVertexAttribArray ( location ) ; buffer . bind ( gl , GL . ARRAY_BUFFER ) ; gl . vertexAttribPointer ( location , size , type , normalized , stride , offset ) ; buffer . unbind ( gl , GL . ARRAY_BUFFER ) ; } disable ( gl ) { gl . disableVertexAttribArray ( this . _location ( gl ) ) ; } } }