Source

WebGL Beginner's Guide - Code / 1727_02 / ch2_Nissan.html

<html>

<head>
<title>WebGL Beginner's Guide - Chapter 2 - Nissan GTS</title>

<!-- CSS Styles //-->
<link href='css/style.css' 		type='text/css' rel='stylesheet'>
<link href='css/desert.css' 	type='text/css' rel='stylesheet'/>
<link href='css/smoothness/jquery-ui-1.8.13.custom.css' type='text/css' rel='stylesheet' />

<!-- JavaScript Libraries //-->
<script type='text/javascript' src='js/gl-matrix-min.js'></script>
<script type='text/javascript' src='js/jquery-1.5.1.min.js'></script>
<script type='text/javascript' src='js/jquery-ui-1.8.13.custom.min.js'></script> 
<script type='text/javascript' src='js/prettify.js'></script>
<script type='text/javascript' src='js/utils.js'></script>
<script type='text/javascript' src='js/codeview.js'></script>


<!-- Fragment Shader //-->
<script id="shader-fs" type="x-shader/x-fragment">
    #ifdef GL_ES
    precision highp float;
    #endif

    void main(void) {
        gl_FragColor = vec4(1.0,1.0,1.0, 0.1);
    }
</script>

<!-- Vertex Shader //-->
<script id="shader-vs" type="x-shader/x-vertex">
	attribute vec3 aVertexPosition;
	uniform mat4 uMVMatrix;
	uniform mat4 uPMatrix;

	void main(void) {
		gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
	}
</script>

<script id="code-js" type="text/javascript">
	
var gl = null; // WebGL context
var prg = null; // The program (shaders)
var c_width = 0; // Variable to store the width of the canvas
var c_height = 0; // Variable to store the height of the canvas

var part = [];    //PARTS LOADED
var vbo = [];
var ibo = [];


var mvMatrix = mat4.create(); // The Model-View matrix
var pMatrix = mat4.create(); // The projection matrix


var angle = 0;

    
/*
* The program contains a series of instructions that tell the Graphic Processing Unit (GPU)
* what to do with every vertex and fragment that we pass it. (more about this on chapter 3)
* The vertex shader and the fragment shader together are called the program.
*/
function initProgram() {
    var fgShader = utils.getShader(gl, "shader-fs");
    var vxShader = utils.getShader(gl, "shader-vs");

    prg = gl.createProgram();
    gl.attachShader(prg, vxShader);
    gl.attachShader(prg, fgShader);
    gl.linkProgram(prg);

    if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
        alert("Could not initialise shaders");
    }

    gl.useProgram(prg);

    prg.aVertexPosition    = gl.getAttribLocation(prg, "aVertexPosition");
    prg.uPMatrix           = gl.getUniformLocation(prg, "uPMatrix");
    prg.uMVMatrix          = gl.getUniformLocation(prg, "uMVMatrix");
}		
	
/**
* Creates an AJAX request to load a model asynchronously
*/
function loadModel(){
  for(var i = 1; i < 179; i++){
        var filename = 'models/nissan_gts/pr'+i+'.json';
        loadPart(filename);
   }
}

function loadPart(filename){
    var request = new XMLHttpRequest();
    console.info('Requesting ' + filename);
    request.open("GET",filename);
    
    request.onreadystatechange = function() {
      if (request.readyState == 4) {
        if(request.status == 404) {
            console.info(filename + ' does not exist');
         }
        else {
            handleLoadedPart(filename,JSON.parse(request.responseText));
        }
      }
    }
    request.send();
}

/**
* Creates the buffers that contain the geometry of the model
*/
function handleLoadedPart(filename,payload) {
    
    console.info(filename + ' has been retrieved from the server');
    
    var vertexBufferObject = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferObject);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(payload.vertices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER,null);
    
    var indexBufferObject = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(payload.indices), gl.STATIC_DRAW);
	gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);	
   
    vbo.push(vertexBufferObject);
    ibo.push(indexBufferObject);
    part.push(payload);
    
}

	
/**
* Draws the scene
*/
function drawScene(){
    
    gl.clearColor(0.5, 0.2, 0.2, 1.0);
    gl.enable(gl.DEPTH_TEST);
    
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.viewport(0,0,c_width, c_height);
    
    mat4.perspective(45, c_width / c_height, 10, 10000.0, pMatrix);
    mat4.identity(mvMatrix);
    mat4.translate(mvMatrix, [0.0, -200.0, -2300.0]); //Sets the camera to a reasonable distance to view the part
    mat4.rotate(mvMatrix, 30 * Math.PI /180, [1,0,0]);
    mat4.rotate(mvMatrix, 30 * Math.PI /180, [0,1,0]);
    
    gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
    
    for(var i = 0; i < part.length; i++){
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo[i]);
        gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(prg.aVertexPosition);
        
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo[i]);
        gl.drawElements(gl.LINES, part[i].indices.length, gl.UNSIGNED_SHORT,0);
    }
    
}


/**
* Render Loop
*/
function renderLoop() {
    utils.requestAnimFrame(renderLoop);
    drawScene();
}
/**
* Executes the WebGL application
* This function is invoked on the onLoad event of the webpage. 
*/
function runWebGLApp(){
    //Obtains a WebGL context
    gl = utils.getGLContext('canvas-element-id');
    //Initializes the program (shaders). More about this on chapter 3!
    initProgram();
    //Initializes the buffers that we are going to use to draw the part (vertex buffer and index buffer)
    loadModel();
    //Draws the part!
    renderLoop();
}
</script>
</head>

<body onLoad='runWebGLApp()'>
<div id='top'>
	<h1>WebGL Beginner's Guide - Chapter 2</h1>
	<h2>Rendering a Nissan GTX</h2>
	<div id='logo-packt'><img src='packt.gif'/></div>
	<p></p>
</div>

<div id='contents'>
	<div id='canvasContainer'>
		<canvas id='canvas-element-id' width='480' height='400'>
			Your browser does not support the HTML5 canvas element.
		</canvas>
	</div>
</div>

<div id='bottom'>
</div>
<script>cview.run();</script>
</html>