Source

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

<html>

<head>
<title>WebGL Beginner's Guide - Chapter 2 - Cone example</title>
<meta http-equiv='content-type' content='text/html; charset=ISO-8859-1'>

<!-- 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(0.5, 0.9, 0.2, 1.0); //Green
    }
</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);
        gl_PointSize = 3.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 coneVertexBuffer = null; //The vertex buffer for the cone
var coneIndexBuffer = null; // The index buffer for the cone

var indices = [];
var vertices = [];

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

/**
* 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.vertexPositionAttribute = gl.getAttribLocation(prg, 'aVertexPosition');
    prg.pMatrixUniform          = gl.getUniformLocation(prg, 'uPMatrix');
    prg.mvMatrixUniform         = gl.getUniformLocation(prg, 'uMVMatrix');
}		

/**
* Creates the buffers that contain the geometry of the cone
*/
function initBuffers() {

    vertices =[1.5, 0, 0, 
    -1.5, 1, 0, 
    -1.5, 0.809017,	0.587785,
    -1.5, 0.309017,	0.951057, 
    -1.5, -0.309017, 0.951057, 
    -1.5, -0.809017, 0.587785,
    -1.5, -1, 0, 
    -1.5, -0.809017, -0.587785,
    -1.5, -0.309017, -0.951057, 
    -1.5, 0.309017,	-0.951057, 
    -1.5, 0.809017,	-0.587785];

    indices = [0, 1, 2,
    0, 2, 3,
    0, 3, 4,
    0, 4, 5,
    0, 5, 6,
    0, 6, 7,
    0, 7, 8,
    0, 8, 9,
    0, 9, 10,
    0, 10, 1];

    //The following code snippet creates a vertex buffer and binds data to it
    coneVertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, coneVertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    
    
    coneIndexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, coneIndexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
    
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
    gl.bindBuffer(gl.ARRAY_BUFFER,null);

}

/**
* Draws the scene
*/
function drawScene(){

    gl.clearColor(0.0, 0.0, 0.0, 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, 0.1, 10000.0, pMatrix);
    mat4.identity(mvMatrix);	
    mat4.translate(mvMatrix, [0.0, 0.0, -5.0]);

    gl.uniformMatrix4fv(prg.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(prg.mvMatrixUniform, false, mvMatrix);

    gl.bindBuffer(gl.ARRAY_BUFFER, coneVertexBuffer);
    gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(prg.vertexPositionAttribute);

    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, coneIndexBuffer);
    gl.drawElements(gl.LINE_LOOP, indices.length, gl.UNSIGNED_SHORT,0);
}

/**
* Render Loop
*/
function renderLoop() {
    requestAnimFrame(renderLoop);
    drawScene();
}

/**
* Executes the WebGL application
* This function is invoked on the onLoad event of the web page. 
*/
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 cone (vertex buffer and index buffer)
    initBuffers();
    //Renders the scene!
    renderLoop();
}
</script>
</head>


<body onLoad='runWebGLApp()'>
<div id='top'>
    <h1>WebGL Beginner's Guide - Chapter 2</h1>
    <h2>Rendering a Cone</h2>
    <div id='logo-packt'><img src='packt.gif'/></div>
    <p>This example shows how to render a cone in WebGL. (functions initBuffers and drawScene).</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>
</body>
</html>