Skip to content

Instantly share code, notes, and snippets.

@Santarh
Created June 7, 2012 18:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Santarh/2890489 to your computer and use it in GitHub Desktop.
Save Santarh/2890489 to your computer and use it in GitHub Desktop.
JSX-WebGL
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