Created
June 7, 2012 18:06
-
-
Save Santarh/2890489 to your computer and use it in GitHub Desktop.
JSX-WebGL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "js/web.jsx"; | |
import "js.jsx"; | |
class _Main | |
{ | |
static function getRequestAnimationFrame() : function( tick : function(:number) : void ) : void | |
{ | |
if ( js.global["requestAnimationFrame"] != undefined ) | |
{ | |
return function( tick : function(:number) : void ) : void | |
{ | |
dom.window.requestAnimationFrame( tick ); | |
}; | |
} | |
else if ( js.global["webkitRequestAnimationFrame"] != undefined ) | |
{ | |
return function( tick : function(:number) : void ) : void | |
{ | |
dom.window.webkitRequestAnimationFrame( tick ); | |
}; | |
} | |
else if ( js.global["mozRequestAnimationFrame"] != undefined ) | |
{ | |
return function( tick : function(:number) : void ) : void | |
{ | |
dom.window.mozRequestAnimationFrame( tick ); | |
}; | |
} | |
else | |
{ | |
return function( tick : function(:number) : void ) : void | |
{ | |
dom.window.setTimeout( function() : void { tick(0); }, 1000/60 ); | |
}; | |
} | |
} | |
static const requestAnimationFrame = _Main.getRequestAnimationFrame(); | |
static function main() : void | |
{ | |
var div = dom.window.document.getElementById("webgl-container") as HTMLDivElement; | |
var canvas = dom.createElement( "canvas" ) as HTMLCanvasElement; | |
div.appendChild( canvas ); | |
canvas.width = dom.window.innerWidth; | |
canvas.height = dom.window.innerHeight; | |
var renderer = new WebGLRenderer( canvas ); | |
var loop = function( n : number ) : void | |
{ | |
renderer.render(); | |
_Main.requestAnimationFrame( loop ); | |
}; | |
_Main.requestAnimationFrame( loop ); | |
//Timer.setInterval( function():void{ renderer.render(); }, 30 ); | |
} | |
} | |
class Vertex | |
{ | |
var position : number[]; // 3 | |
var color : number[]; // 3 | |
var uv : number[]; // 2 | |
function constructor( position : number[], color : number[], uv : number[] ) | |
{ | |
this.position = position; | |
this.color = color; | |
this.uv = uv; | |
} | |
} | |
class Shader | |
{ | |
var gl : WebGLRenderingContext; | |
var shaderObject : WebGLShader; | |
var shaderText : string; | |
function constructor( gl : WebGLRenderingContext, shaderText : string ) | |
{ | |
this.shaderText = shaderText; | |
this.gl = gl; | |
} | |
function compileShader() : void | |
{ | |
this.gl.shaderSource( this.shaderObject, this.shaderText ); | |
this.gl.compileShader( this.shaderObject ); | |
if ( false == this.gl.getShaderParameter( this.shaderObject, this.gl.COMPILE_STATUS ) ) | |
{ | |
log "Shader Compile Error"; | |
} | |
} | |
function reloadShader( shaderText : string ) : void | |
{ | |
this.shaderText = shaderText; | |
this.compileShader(); | |
} | |
} | |
class VertexShader extends Shader | |
{ | |
function constructor( gl : WebGLRenderingContext, shaderText : string ) | |
{ | |
super( gl, shaderText ); | |
this.shaderObject = gl.createShader( gl.VERTEX_SHADER ); | |
this.compileShader(); | |
} | |
} | |
class FragmentShader extends Shader | |
{ | |
function constructor( gl : WebGLRenderingContext, shaderText : string ) | |
{ | |
super( gl, shaderText ); | |
this.shaderObject = gl.createShader( gl.FRAGMENT_SHADER ); | |
this.compileShader(); | |
} | |
} | |
class Effect | |
{ | |
var gl : WebGLRenderingContext; | |
var program : WebGLProgram; | |
var vertexShader : VertexShader; | |
var fragmentShader : FragmentShader; | |
var uniformLocations : Map.<WebGLUniformLocation>; | |
function constructor( gl : WebGLRenderingContext, v : VertexShader, f : FragmentShader ) | |
{ | |
this.gl = gl; | |
this.program = this.gl.createProgram(); | |
this.vertexShader = v; | |
this.fragmentShader = f; | |
this.gl.attachShader( this.program, v.shaderObject ); | |
this.gl.attachShader( this.program, f.shaderObject ); | |
this.gl.linkProgram( this.program ); | |
this.uniformLocations = new Map.<WebGLUniformLocation>; | |
if ( false == this.gl.getProgramParameter( this.program, this.gl.LINK_STATUS ) ) | |
{ | |
log "Shader Program Error"; | |
} | |
} | |
function active() : void | |
{ | |
this.gl.useProgram( this.program ); | |
} | |
function enableShaderAttribute( index : int ) : void | |
{ | |
this.gl.enableVertexAttribArray( index ); | |
} | |
function bindShaderAttributeLocation( position : int, name : string ) : void | |
{ | |
this.gl.bindAttribLocation( this.program, position, name ); | |
} | |
function getShaderUniformLocation( name : string ) : WebGLUniformLocation | |
{ | |
if ( undefined == this.uniformLocations[name] ) | |
{ | |
this.uniformLocations[name] = this.gl.getUniformLocation( this.program, name ); | |
} | |
return this.uniformLocations[name]; | |
} | |
} | |
class FloatStaticBuffer | |
{ | |
var gl : WebGLRenderingContext; | |
var bufferObject : WebGLBuffer; | |
var bufferType : int; | |
function constructor( gl : WebGLRenderingContext ) | |
{ | |
this.gl = gl; | |
this.bufferObject = this.gl.createBuffer(); | |
this.bufferType = this.gl.ARRAY_BUFFER; | |
} | |
function active() : void | |
{ | |
this.gl.bindBuffer( this.bufferType, this.bufferObject ); | |
} | |
function applyData( data : Float32Array ) : void | |
{ | |
this.active(); | |
this.gl.bufferData( this.gl.ARRAY_BUFFER, data, this.gl.STATIC_DRAW ); | |
} | |
function render() : void | |
{ | |
} | |
} | |
class VertexBuffer extends FloatStaticBuffer | |
{ | |
function constructor( gl : WebGLRenderingContext, vertices : Vertex[] ) | |
{ | |
super( gl ); | |
var data : number[] = new number[]; | |
vertices.forEach( function( v : MayBeUndefined.<Vertex> ) : void | |
{ | |
data = data.concat( v.position ); | |
data = data.concat( v.color ); | |
data = data.concat( v.uv ); | |
}); | |
this.applyData( new Float32Array( data ) ); | |
} | |
function active( positionAttr : int, colorAttr : int, uvAttr : int ) : void | |
{ | |
super.active(); | |
var sizeF = 4; | |
this.gl.vertexAttribPointer( positionAttr, 3, this.gl.FLOAT, false, sizeF * 8, sizeF * 0 ); | |
this.gl.vertexAttribPointer( colorAttr, 3, this.gl.FLOAT, false, sizeF * 8, sizeF * 3 ); | |
this.gl.vertexAttribPointer( uvAttr, 2, this.gl.FLOAT, false, sizeF * 8, sizeF * 6 ); | |
} | |
override function render() : void | |
{ | |
this.gl.drawArrays( this.gl.TRIANGLE_STRIP, 0, 4 ); | |
} | |
} | |
class WebGLRenderer | |
{ | |
var canvas : HTMLCanvasElement; | |
var gl : WebGLRenderingContext; | |
var effect : Effect; | |
var squareBuffer : VertexBuffer; | |
function constructor( canvas : HTMLCanvasElement ) | |
{ | |
this.canvas = canvas; | |
this.gl = canvas.getContext( "experimental-webgl" ) as WebGLRenderingContext; | |
this.gl.clearColor( 0.0, 0.0, 0.0, 0.0 ); | |
this.gl.enable( this.gl.DEPTH_TEST ); | |
this.gl.depthFunc( this.gl.LEQUAL ); | |
this.gl.clear( this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT ); | |
log this.canvas.width; | |
var v_dom : HTMLScriptElement = dom.getElementById( "v-shader" ) as HTMLScriptElement; | |
var f_dom : HTMLScriptElement = dom.getElementById( "f-shader" ) as HTMLScriptElement; | |
var v : VertexShader = new VertexShader( this.gl, v_dom.text ); | |
var f : FragmentShader = new FragmentShader( this.gl, f_dom.text ); | |
this.effect = new Effect( this.gl, v, f ); | |
this.effect.active(); | |
this.effect.bindShaderAttributeLocation( 0, "aVertexPosition" ); | |
this.effect.bindShaderAttributeLocation( 1, "aVertexColor" ); | |
this.effect.bindShaderAttributeLocation( 2, "aVertexUv" ); | |
this.effect.getShaderUniformLocation( "resolution" ); | |
var data : Vertex[] = | |
[ | |
new Vertex( [+1.0, +1.0, 0.0], [1.0, 0.0, 0.0], [1.0, 1.0] ), | |
new Vertex( [-1.0, +1.0, 0.0], [0.0, 1.0, 0.0], [0.0, 1.0] ), | |
new Vertex( [+1.0, -1.0, 0.0], [0.0, 0.0, 1.0], [1.0, 0.0] ), | |
new Vertex( [-1.0, -1.0, 0.0], [1.0, 1.0, 1.0], [0.0, 0.0] ) | |
]; | |
this.squareBuffer = new VertexBuffer( this.gl, data ); | |
} | |
function resize() : void | |
{ | |
var scale : number = 2.0; | |
var w = dom.window.innerWidth / scale; | |
var h = dom.window.innerHeight / scale; | |
var scalePer = "100%"; | |
this.canvas.width = w; | |
this.canvas.height = h; | |
this.gl.viewport( 0, 0, w, h ); | |
this.canvas.style.width = scalePer; | |
this.canvas.style.height = scalePer; | |
} | |
function render() : void | |
{ | |
this.resize(); | |
this.gl.clear( this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT ); | |
this.effect.active(); | |
this.effect.enableShaderAttribute( 0 ); | |
this.effect.enableShaderAttribute( 1 ); | |
this.effect.enableShaderAttribute( 2 ); | |
var resolution : number[] = [ this.canvas.width as number, this.canvas.height as number ]; | |
this.gl.uniform2fv( this.effect.getShaderUniformLocation( "resolution" ), resolution ); | |
var date = new Date(); | |
var time = date.getUTCMilliseconds(); | |
time += date.getUTCSeconds() * 1000.0; | |
time = time * 3.14 / ( 6.0 * 1000.0 ); | |
this.gl.uniform1f( this.effect.getShaderUniformLocation( "time" ), time ); | |
this.squareBuffer.active( 0, 1, 2 ); | |
this.squareBuffer.render(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment