scripts/machine.js
author Eugen Sawin <sawine@me73.com>
Sat, 02 Apr 2011 00:31:54 +0200
changeset 7 12bb629d22b3
parent 6 cd14e5b5296c
child 8 287fcb0e8f60
permissions -rwxr-xr-x
Rotation.
     1 var machine;
     2 var render;
     3 
     4 function main()
     5 {
     6     var canvas = document.getElementById("machine");
     7     window.onresize = resize;
     8     var context = new Context(canvas);
     9     make_fullscreen(context);
    10     var gl = context.gl;
    11     var object = new Cube(1, context);
    12     object.rotation = 0.01;
    13     gl.clearColor(0.0, 0.0, 0.0, 1.0);
    14     gl.enable(gl.DEPTH_TEST);
    15     machine = new Machine(object);
    16     render = new Render(context);    
    17     update();
    18 }
    19 
    20 function update()
    21 {    
    22     requestAnimFrame(update);
    23     //machine.scene.rotation *= 1.003;
    24     render.draw(machine.scene);
    25 }
    26 
    27 function resize()
    28 {
    29     make_fullscreen(render.context);
    30     update();
    31 }
    32 
    33 function make_fullscreen(context)
    34 {
    35     var width = window.innerWidth;
    36     var height = window.innerHeight;
    37     context.canvas.width = width;
    38     context.canvas.height = height;
    39     context.viewport.width = width;
    40     context.viewport.height = height;
    41 }
    42 
    43 function Render(context)
    44 {
    45     this.context = context;
    46     this.gl = context.gl;
    47     this.matrixStack = [];
    48 }
    49 Render.prototype.draw = function(scene)
    50 { 
    51     var gl = this.context.gl;
    52     var viewport = this.context.viewport;
    53     var shader = this.context.shader;
    54     var mvMatrix = this.context.mvMatrix;
    55     var pMatrix = this.context.pMatrix;
    56 
    57     gl.viewport(0, 0, viewport.width, viewport.height);
    58     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    59     mat4.perspective(45, viewport.width / viewport.height, 0.1, 100.0, pMatrix);
    60 
    61     mat4.identity(mvMatrix);
    62     mat4.translate(mvMatrix, [0.0, 0.0, -7.0]);
    63 
    64     this.pushMatrix(mvMatrix);
    65 
    66     mat4.rotate(mvMatrix, scene.rotation, [1, 1, 1]);
    67     //mat4.rotate(mvMatrix, scene.rotation, [1, 0, 0]);
    68 
    69     gl.bindBuffer(gl.ARRAY_BUFFER, scene.positionBuffer);
    70     gl.vertexAttribPointer(shader.vertexPosition, scene.positionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    71 
    72     gl.bindBuffer(gl.ARRAY_BUFFER, scene.colourBuffer);
    73     gl.vertexAttribPointer(shader.vertexColour, scene.colourBuffer.itemSize, gl.FLOAT, false, 0, 0);
    74 
    75     this.context.updateMatrixUniforms();
    76     gl.drawArrays(gl.TRIANGLE_STRIP, 0, scene.positionBuffer.numItems);
    77     
    78     mvMatrix = this.popMatrix();
    79 
    80     if (this.next) this.next.draw(scene);
    81 }
    82 Render.prototype.pushMatrix = function(matrix)
    83 {
    84     var copy = mat4.create();
    85     mat4.set(matrix, copy);
    86     this.matrixStack.push(copy);
    87 }
    88 Render.prototype.popMatrix = function()    
    89 {
    90     if (this.matrixStack.length > 0) return this.matrixStack.pop();
    91 }
    92 
    93 function Machine(scene)
    94 {
    95     this.scene = scene;
    96 }
    97 Machine.prototype.draw = function(render)
    98 {
    99     render.draw(this.scene);
   100 }
   101 
   102 function Context(canvas)
   103 {
   104     this.canvas = canvas;
   105     try 
   106     {
   107 	this.gl = canvas.getContext("experimental-webgl");
   108 	this.viewport = {'width': canvas.width,
   109 			 'height': canvas.height};
   110     } 
   111     catch(e) 
   112     {
   113 	alert(e);
   114     }
   115     if (!this.gl) alert("Failed: WebGL init.");
   116     this.mvMatrix = mat4.create();
   117     this.pMatrix = mat4.create();
   118     this.shader = new Shader(this);    
   119 }
   120 Context.prototype.updateMatrixUniforms = function()
   121 {
   122     var gl = this.gl;
   123     var program = this.shader;
   124     var pMatrix = this.pMatrix;
   125     var mvMatrix = this.mvMatrix;
   126     gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
   127     gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
   128 }
   129 
   130 function Shader(context)
   131 {
   132     var gl = context.gl;
   133     var fragment = load_shader(gl, "fragment-shader");
   134     var vertex = load_shader(gl, "vertex-shader");
   135     this.program = gl.createProgram();
   136     gl.attachShader(this.program, vertex);
   137     gl.attachShader(this.program, fragment);
   138     gl.linkProgram(this.program);
   139 
   140     if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
   141     {
   142 	alert("Failed: Shader init.");
   143     }
   144 
   145     gl.useProgram(this.program);
   146     this.vertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
   147     gl.enableVertexAttribArray(this.vertexPosition);
   148     
   149     this.vertexColour = gl.getAttribLocation(this.program, "aVertexColour");
   150     gl.enableVertexAttribArray(this.vertexColour);
   151 
   152     this.pMatrixUniform = gl.getUniformLocation(this.program, "uPMatrix");
   153     this.mvMatrixUniform = gl.getUniformLocation(this.program, "uMVMatrix");
   154 
   155     function load_shader(gl, id)
   156     {
   157 	var script = document.getElementById(id);
   158 	if (!script) return null;
   159 	
   160 	var str = "";
   161 	var child = script.firstChild;
   162 	while (child)
   163 	{
   164 	    if (child.nodeType == 3) str += child.textContent;
   165 	    child = child.nextSibling;
   166 	}
   167 	
   168 	var shader;
   169 	var common = "x-shader/x-";
   170 	if (script.type == common + "fragment") shader = gl.createShader(gl.FRAGMENT_SHADER);
   171 	else if (script.type == common + "vertex") shader = gl.createShader(gl.VERTEX_SHADER);
   172 	else return null;
   173 
   174 	gl.shaderSource(shader, str);
   175 	gl.compileShader(shader);
   176 
   177 	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
   178         {
   179 	    alert(gl.getShaderInfoLog(shader));
   180 	    return null;
   181 	}
   182 
   183 	return shader;
   184     }
   185 }
   186 
   187 
   188 function Cube(size, context)
   189 {
   190     var gl = context.gl;
   191     this.size = size || 1;
   192     this.rotation = 0;
   193     
   194     this.positionBuffer = gl.createBuffer();
   195     gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
   196     var vertices = [1.0, 1.0, 0.0,
   197 		    -1.0, 1.0, 0.0,
   198 		    1.0, -1.0, 0.0,
   199 		    -1.0, -1.0, 0.0];
   200     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
   201     this.positionBuffer.itemSize = 3;
   202     this.positionBuffer.numItems = 4;
   203 
   204     this.colourBuffer = gl.createBuffer();
   205     gl.bindBuffer(gl.ARRAY_BUFFER, this.colourBuffer);
   206     var colours = [1.0, 0.0, 0.0, .5,
   207 		   0.0, 1.0, 0.0, .5,
   208 		   0.0, 0.0, 1.0, .5,
   209 		   1.0, 0.0, 1.0, .5];
   210     //colours = [];
   211     for (var i = 0; i < 4; i++)
   212     {
   213 	//	colours = colours.concat([0.5, 0.5, 1.0, 1.0]);
   214     }
   215     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colours), gl.STATIC_DRAW);
   216     this.colourBuffer.itemSize = 4;
   217     this.colourBuffer.numItems = 4;
   218 }