scripts/machine.js
author Eugen Sawin <sawine@me73.com>
Sat, 02 Apr 2011 15:17:52 +0200
changeset 9 610eb11054aa
parent 8 287fcb0e8f60
child 10 9c21841b3ef9
permissions -rwxr-xr-x
Cube.
     1 var machine;
     2 var renderer;
     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     renderer = new Renderer(context);    
    17     update();
    18 }
    19 
    20 function update()
    21 {    
    22     requestAnimFrame(update);
    23     machine.scene.rotation += 0.0001;
    24     machine.update(new Date().getTime());
    25     renderer.update(machine.scene);
    26 }
    27 
    28 function resize()
    29 {
    30     make_fullscreen(renderer.context);
    31     update();
    32 }
    33 
    34 function make_fullscreen(context)
    35 {
    36     var width = window.innerWidth;
    37     var height = window.innerHeight;
    38     context.canvas.width = width;
    39     context.canvas.height = height;
    40     context.viewport.width = width;
    41     context.viewport.height = height;
    42 }
    43 
    44 function random(min, max)
    45 {
    46     return (min + Math.random() * (max - min + 1));
    47 }
    48 
    49 function Renderer(context)
    50 {
    51     this.context = context;
    52     this.gl = context.gl;
    53     this.matrixStack = [];
    54 }
    55 Renderer.prototype.update = function(scene)
    56 { 
    57     var gl = this.context.gl;
    58     var viewport = this.context.viewport;
    59     var shader = this.context.shader;
    60     var mvMatrix = this.context.mvMatrix;
    61     var pMatrix = this.context.pMatrix;
    62 
    63     gl.viewport(0, 0, viewport.width, viewport.height);
    64     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    65     mat4.perspective(45, viewport.width / viewport.height, 0.1, 100.0, pMatrix);
    66 
    67     mat4.identity(mvMatrix);
    68     mat4.translate(mvMatrix, [0.0, 0.0, -7.0]);
    69 
    70     this.pushMatrix(mvMatrix);
    71 
    72     mat4.rotate(mvMatrix, scene.rotation, [random(0, 1), random(0, 1), random(0, 1)]);
    73 
    74     gl.bindBuffer(gl.ARRAY_BUFFER, scene.positionBuffer);
    75     gl.vertexAttribPointer(shader.vertexPosition, scene.positionBuffer.itemSize, gl.FLOAT, false, 0, 0);
    76 
    77     gl.bindBuffer(gl.ARRAY_BUFFER, scene.colourBuffer);
    78     gl.vertexAttribPointer(shader.vertexColour, scene.colourBuffer.itemSize, gl.FLOAT, false, 0, 0);
    79     
    80     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, scene.indexBuffer);
    81     this.context.updateMatrixUniforms();
    82     gl.drawElements(gl.TRIANGLES, scene.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
    83     //gl.drawArrays(gl.TRIANGLE_STRIP, 0, scene.positionBuffer.numItems);
    84     
    85     mvMatrix = this.popMatrix();
    86 
    87     if (this.next) this.next.draw(scene);
    88 }
    89 Renderer.prototype.pushMatrix = function(matrix)
    90 {
    91     var copy = mat4.create();
    92     mat4.set(matrix, copy);
    93     this.matrixStack.push(copy);
    94 }
    95 Renderer.prototype.popMatrix = function()    
    96 {
    97     if (this.matrixStack.length > 0) return this.matrixStack.pop();
    98 }
    99 
   100 function Machine(scene)
   101 {
   102     this.scene = scene;
   103     this.lastUpdate = 0;
   104 }
   105 Machine.prototype.update = function(time)
   106 {
   107     if (this.lastUpdate != 0)
   108     {
   109 	var diff = time - this.lastUpdate;
   110 	
   111     }
   112     this.lastUpdate = time;
   113 }
   114 
   115 function Context(canvas)
   116 {
   117     this.canvas = canvas;
   118     try 
   119     {
   120 	this.gl = canvas.getContext("experimental-webgl");
   121 	this.viewport = {'width': canvas.width,
   122 			 'height': canvas.height};
   123     } 
   124     catch(e) 
   125     {
   126 	alert(e);
   127     }
   128     if (!this.gl) alert("Failed: WebGL init.");
   129     this.mvMatrix = mat4.create();
   130     this.pMatrix = mat4.create();
   131     this.shader = new Shader(this);    
   132 }
   133 Context.prototype.updateMatrixUniforms = function()
   134 {
   135     var gl = this.gl;
   136     var program = this.shader;
   137     var pMatrix = this.pMatrix;
   138     var mvMatrix = this.mvMatrix;
   139     gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
   140     gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
   141 }
   142 
   143 function Shader(context)
   144 {
   145     var gl = context.gl;
   146     var fragment = loadShader(gl, "fragment-shader");
   147     var vertex = loadShader(gl, "vertex-shader");
   148     this.program = gl.createProgram();
   149     gl.attachShader(this.program, vertex);
   150     gl.attachShader(this.program, fragment);
   151     gl.linkProgram(this.program);
   152 
   153     if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
   154     {
   155 	alert("Failed: Shader init.");
   156     }
   157 
   158     gl.useProgram(this.program);
   159     this.vertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
   160     gl.enableVertexAttribArray(this.vertexPosition);
   161     
   162     this.vertexColour = gl.getAttribLocation(this.program, "aVertexColour");
   163     gl.enableVertexAttribArray(this.vertexColour);
   164 
   165     this.pMatrixUniform = gl.getUniformLocation(this.program, "uPMatrix");
   166     this.mvMatrixUniform = gl.getUniformLocation(this.program, "uMVMatrix");
   167 
   168     function loadShader(gl, id)
   169     {
   170 	var script = document.getElementById(id);
   171 	if (!script) return null;
   172 	
   173 	var str = "";
   174 	var child = script.firstChild;
   175 	while (child)
   176 	{
   177 	    if (child.nodeType == 3) str += child.textContent;
   178 	    child = child.nextSibling;
   179 	}
   180 	
   181 	var shader;
   182 	var common = "x-shader/x-";
   183 	if (script.type == common + "fragment") shader = gl.createShader(gl.FRAGMENT_SHADER);
   184 	else if (script.type == common + "vertex") shader = gl.createShader(gl.VERTEX_SHADER);
   185 	else return null;
   186 
   187 	gl.shaderSource(shader, str);
   188 	gl.compileShader(shader);
   189 
   190 	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
   191         {
   192 	    alert(gl.getShaderInfoLog(shader));
   193 	    return null;
   194 	}
   195 
   196 	return shader;
   197     }
   198 }
   199 
   200 
   201 function Cube(size, context)
   202 {
   203     var gl = context.gl;
   204     this.size = size || 1;
   205     this.rotation = 0;
   206     
   207     this.positionBuffer = gl.createBuffer();
   208     gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
   209     var vertices = [
   210 	     // Front face
   211             -1.0, -1.0,  1.0,
   212              1.0, -1.0,  1.0,
   213              1.0,  1.0,  1.0,
   214             -1.0,  1.0,  1.0,
   215  
   216             // Back face
   217             -1.0, -1.0, -1.0,
   218             -1.0,  1.0, -1.0,
   219              1.0,  1.0, -1.0,
   220              1.0, -1.0, -1.0,
   221  
   222             // Top face
   223             -1.0,  1.0, -1.0,
   224             -1.0,  1.0,  1.0,
   225              1.0,  1.0,  1.0,
   226              1.0,  1.0, -1.0,
   227  
   228             // Bottom face
   229             -1.0, -1.0, -1.0,
   230              1.0, -1.0, -1.0,
   231              1.0, -1.0,  1.0,
   232             -1.0, -1.0,  1.0,
   233  
   234             // Right face
   235              1.0, -1.0, -1.0,
   236              1.0,  1.0, -1.0,
   237              1.0,  1.0,  1.0,
   238              1.0, -1.0,  1.0,
   239  
   240             // Left face
   241             -1.0, -1.0, -1.0,
   242             -1.0, -1.0,  1.0,
   243             -1.0,  1.0,  1.0,
   244             -1.0,  1.0, -1.0];
   245     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
   246     this.positionBuffer.itemSize = 3;
   247     this.positionBuffer.numItems = 24;
   248 
   249     this.colourBuffer = gl.createBuffer();
   250     gl.bindBuffer(gl.ARRAY_BUFFER, this.colourBuffer);
   251     var alpha = 1.0;
   252     var colours = [[1.0, 0.0, 0.0, alpha],
   253 		   [0.0, 1.0, 0.0, alpha],
   254 		   [0.0, 0.0, 1.0, alpha],
   255 		   [1.0, 0.0, 1.0, alpha],
   256 		   [1.0, 1.0, 0.0, alpha],
   257 		   [0.0, 1.0, 1.0, alpha]];
   258     var unpackedColours = [];
   259     for (var i in colours)
   260     {
   261 	var colour = colours[i];
   262 	for (var j = 0; j < 4; j++)
   263 	{
   264 	    unpackedColours = unpackedColours.concat(colour);
   265 	}
   266 	//colours = colours.concat([0.5, 0.5, 1.0, 1.0]);
   267     }
   268     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColours), gl.STATIC_DRAW);
   269     this.colourBuffer.itemSize = 4;
   270     this.colourBuffer.numItems = 24;
   271 
   272     this.indexBuffer = gl.createBuffer();
   273     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
   274     var indices = [0, 1, 2, 0, 2, 3,
   275 		   4, 5, 6, 4, 6, 7,
   276 		   8, 9, 10, 8, 10, 11,
   277 		   12, 13, 14, 12, 14, 15,
   278 		   16, 17, 18, 16, 18, 19,
   279 		   20, 21, 22, 20, 22, 23];
   280     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
   281     this.indexBuffer.itemSize = 1;
   282     this.indexBuffer.numItems = 36;
   283 }