scripts/renderer.js
author Eugen Sawin <sawine@me73.com>
Wed, 27 Apr 2011 00:45:37 +0200
changeset 27 130cff40c734
parent 25 3b66f92dbc4d
child 28 9df7034275e8
permissions -rw-r--r--
Object camera.
sawine@24
     1
function Context(canvas)
sawine@24
     2
{
sawine@24
     3
    this.canvas = canvas;
sawine@24
     4
    try 
sawine@24
     5
    {
sawine@24
     6
	this.gl = canvas.getContext("experimental-webgl");
sawine@24
     7
	this.viewport = {'width': canvas.width,
sawine@24
     8
			 'height': canvas.height};
sawine@24
     9
    } 
sawine@24
    10
    catch(e) 
sawine@24
    11
    {
sawine@24
    12
	alert(e);
sawine@24
    13
    }
sawine@24
    14
    if (!this.gl) alert("Failed: WebGL init.");
sawine@24
    15
    this.mvMatrix = mat4.create();
sawine@24
    16
    this.pMatrix = mat4.create();
sawine@24
    17
    this.shader = new Shader(this);  
sawine@24
    18
}
sawine@24
    19
Context.prototype.updateMatrixUniforms = function()
sawine@24
    20
{
sawine@24
    21
    var gl = this.gl;
sawine@24
    22
    var program = this.shader;
sawine@24
    23
    var pMatrix = this.pMatrix;
sawine@24
    24
    var mvMatrix = this.mvMatrix;
sawine@25
    25
sawine@24
    26
    gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
sawine@24
    27
    gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
sawine@24
    28
    var normalMatrix = mat3.create();
sawine@24
    29
    mat4.toInverseMat3(mvMatrix, normalMatrix);
sawine@24
    30
    mat3.transpose(normalMatrix);
sawine@24
    31
    gl.uniformMatrix3fv(program.nMatrixUniform, false, normalMatrix);
sawine@24
    32
}
sawine@24
    33
Context.prototype.expand = function()
sawine@24
    34
{ 
sawine@24
    35
    var width = window.innerWidth;
sawine@24
    36
    var height = window.innerHeight;
sawine@24
    37
    this.canvas.width = width;
sawine@24
    38
    this.canvas.height = height;
sawine@24
    39
    this.viewport.width = width;
sawine@24
    40
    this.viewport.height = height;
sawine@24
    41
}
sawine@24
    42
sawine@24
    43
function Shader(context)
sawine@24
    44
{
sawine@24
    45
    var gl = context.gl;
sawine@24
    46
    var fragment = loadShader(gl, "fragment-shader");
sawine@24
    47
    var vertex = loadShader(gl, "vertex-shader");
sawine@24
    48
    this.program = gl.createProgram();
sawine@24
    49
    gl.attachShader(this.program, vertex);
sawine@24
    50
    gl.attachShader(this.program, fragment);
sawine@24
    51
    gl.linkProgram(this.program);
sawine@24
    52
sawine@24
    53
    if (!gl.getProgramParameter(this.program, gl.LINK_STATUS))
sawine@24
    54
    {
sawine@24
    55
	alert("Failed: Shader init.");
sawine@24
    56
    }
sawine@24
    57
sawine@24
    58
    gl.useProgram(this.program);
sawine@24
    59
    this.vertexPosition = gl.getAttribLocation(this.program, "aVertexPosition");
sawine@24
    60
    gl.enableVertexAttribArray(this.vertexPosition);
sawine@24
    61
sawine@24
    62
    this.vertexNormal = gl.getAttribLocation(this.program, "aVertexNormal");
sawine@24
    63
    gl.enableVertexAttribArray(this.vertexNormal);
sawine@25
    64
    
sawine@25
    65
    this.vertexColour = gl.getAttribLocation(this.program, "aVertexColour");
sawine@25
    66
    gl.enableVertexAttribArray(this.vertexColour);    
sawine@24
    67
sawine@24
    68
    this.pMatrixUniform = gl.getUniformLocation(this.program, "uPMatrix");
sawine@24
    69
    this.mvMatrixUniform = gl.getUniformLocation(this.program, "uMVMatrix");    
sawine@24
    70
    this.nMatrixUniform = gl.getUniformLocation(this.program, "uNMatrix");
sawine@24
    71
    //this.samplerUniform = gl.getUniformLocation(this.program, "uSampler");
sawine@24
    72
    this.useLightingUniform = gl.getUniformLocation(this.program, "uUseLighting");
sawine@24
    73
    this.ambientColourUniform = gl.getUniformLocation(this.program, "uAmbientColour");
sawine@24
    74
    this.lightingDirectionUniform = gl.getUniformLocation(this.program, "uLightingDirection");
sawine@24
    75
    this.directionalColourUniform = gl.getUniformLocation(this.program, "uDirectionalColour");
sawine@24
    76
    
sawine@24
    77
    function loadShader(gl, id)
sawine@24
    78
    {
sawine@24
    79
	var script = document.getElementById(id);
sawine@24
    80
	if (!script) return null;
sawine@24
    81
	
sawine@24
    82
	var str = "";
sawine@24
    83
	var child = script.firstChild;
sawine@24
    84
	while (child)
sawine@24
    85
	{
sawine@24
    86
	    if (child.nodeType == 3) str += child.textContent;
sawine@24
    87
	    child = child.nextSibling;
sawine@24
    88
	}
sawine@24
    89
	
sawine@24
    90
	var shader;
sawine@24
    91
	var common = "x-shader/x-";
sawine@24
    92
	if (script.type == common + "fragment") shader = gl.createShader(gl.FRAGMENT_SHADER);
sawine@24
    93
	else if (script.type == common + "vertex") shader = gl.createShader(gl.VERTEX_SHADER);
sawine@24
    94
	else return null;
sawine@24
    95
sawine@24
    96
	gl.shaderSource(shader, str);
sawine@24
    97
	gl.compileShader(shader);
sawine@24
    98
sawine@24
    99
	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
sawine@24
   100
        {
sawine@24
   101
	    alert(gl.getShaderInfoLog(shader));
sawine@24
   102
	    return null;
sawine@24
   103
	}
sawine@24
   104
sawine@24
   105
	return shader;
sawine@24
   106
    }
sawine@24
   107
}
sawine@24
   108
sawine@24
   109
function Renderer(camera, context)
sawine@24
   110
{
sawine@24
   111
    this.camera = camera;
sawine@24
   112
    this.context = context;
sawine@24
   113
    this.gl = context.gl;
sawine@24
   114
    this.matrixStack = [];
sawine@24
   115
}
sawine@24
   116
Renderer.prototype.update = function(scene)
sawine@24
   117
{ 
sawine@24
   118
    var gl = this.context.gl;
sawine@24
   119
    var viewport = this.context.viewport;
sawine@24
   120
    var shader = this.context.shader;
sawine@24
   121
    var mvMatrix = this.context.mvMatrix;
sawine@24
   122
    var pMatrix = this.context.pMatrix;
sawine@24
   123
    var camera = this.camera;
sawine@24
   124
sawine@24
   125
    gl.viewport(0, 0, viewport.width, viewport.height);
sawine@24
   126
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
sawine@24
   127
    mat4.perspective(45, viewport.width / viewport.height, 0.1, 100.0, pMatrix);
sawine@24
   128
sawine@24
   129
    mat4.identity(mvMatrix);
sawine@27
   130
    camera.update();
sawine@27
   131
    mat4.multiply(mvMatrix, camera.matrix); 
sawine@24
   132
    //this.pushMatrix(mvMatrix);
sawine@24
   133
sawine@24
   134
    gl.bindBuffer(gl.ARRAY_BUFFER, scene.positionBuffer);
sawine@24
   135
    gl.vertexAttribPointer(shader.vertexPosition, scene.positionBuffer.itemSize, gl.FLOAT, false, 0, 0);
sawine@24
   136
    
sawine@24
   137
    gl.bindBuffer(gl.ARRAY_BUFFER, scene.normalBuffer);
sawine@24
   138
    gl.vertexAttribPointer(shader.vertexNormal, scene.normalBuffer.itemSize, gl.FLOAT, false, 0, 0);
sawine@24
   139
sawine@24
   140
    gl.bindBuffer(gl.ARRAY_BUFFER, scene.colourBuffer);
sawine@24
   141
    gl.vertexAttribPointer(shader.vertexColour, scene.colourBuffer.itemSize, gl.FLOAT, false, 0, 0);
sawine@24
   142
sawine@24
   143
    var lighting = true;
sawine@24
   144
    gl.uniform1i(shader.useLightingUniform, lighting);
sawine@24
   145
   
sawine@24
   146
    if (lighting)
sawine@24
   147
    {   
sawine@25
   148
	var uni = 0.02;
sawine@25
   149
	var ambient = {"r": uni, "g": uni, "b": uni};
sawine@25
   150
   	gl.uniform3f(shader.ambientColourUniform, ambient.r, ambient.g, ambient.b);
sawine@24
   151
sawine@24
   152
	var lightingDir = vec3.create();
sawine@25
   153
	vec3.add(lightingDir, [0.0, -1.0, 0.0]);
sawine@24
   154
	vec3.normalize(lightingDir);
sawine@24
   155
	vec3.scale(lightingDir, -1);     
sawine@24
   156
	gl.uniform3fv(shader.lightingDirectionUniform, lightingDir);
sawine@24
   157
	
sawine@25
   158
	uni = 0.5;
sawine@25
   159
	var directional =  {"r": uni, "g": uni, "b": uni};
sawine@24
   160
	gl.uniform3f(shader.directionalColourUniform, directional.r, directional.g, directional.b);
sawine@24
   161
    }
sawine@24
   162
   
sawine@24
   163
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, scene.indexBuffer);
sawine@24
   164
    this.context.updateMatrixUniforms();
sawine@24
   165
    gl.drawElements(gl.TRIANGLES, scene.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
sawine@24
   166
    //gl.drawArrays(gl.TRIANGLE_STRIP, 0, scene.positionBuffer.numItems);
sawine@24
   167
    
sawine@24
   168
    //mvMatrix = this.popMatrix();
sawine@24
   169
sawine@24
   170
    if (this.next) this.next.draw(scene);
sawine@24
   171
}
sawine@24
   172
Renderer.prototype.pushMatrix = function(matrix)
sawine@24
   173
{
sawine@24
   174
    var copy = mat4.create();
sawine@24
   175
    mat4.set(matrix, copy);
sawine@24
   176
    this.matrixStack.push(copy);
sawine@24
   177
}
sawine@24
   178
Renderer.prototype.popMatrix = function()    
sawine@24
   179
{
sawine@24
   180
    if (this.matrixStack.length > 0) return this.matrixStack.pop();
sawine@24
   181
}