代码摘自《WebGL Beginners Guide》一书第二章的ch2_RenderingModes.html
<html> <head> <title>WebGL Beginner's Guide - Chapter 2 - Rendering Modes</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/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.5,1.0, 1.0); } </script> <!-- Vertex Shader //--> <script id="shader-vs" type="x-shader/x-vertex"> attribute vec3 aVertexPosition; void main(void) { gl_Position = vec4(aVertexPosition, 1.0); gl_PointSize = 4.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 trapezoidVertexBuffer = null; //The vertex buffer for the trapezoid var trapezoidIndexBuffer = null; // The index buffer for the trapezoid var indices = []; //JavaScript array to store the indices of the trapezoid var vertices = []; //JavaScript array to store the vertices of the trapezoid var renderingMode = 'TRIANGLES'; /* * 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); //The following lines allow us obtaining a reference to the uniforms and attributes defined in the shaders. //This is a necessary step as the shaders are NOT written in JavaScript but in a //specialized language called GLSL. More about this on chapter 3. prg.vertexPositionAttribute = gl.getAttribLocation(prg, "aVertexPosition"); } /* * Creates the buffers that contain the geometry of the trapezoid * * #1 (-0.25,0.5) +--------------+ (0.25,0.5) #3 * / \ * / \ * / .(0,0) \ * / \ * / \ * #0(-0.5,-0.5) +------------+-------------+ (0.5,-0.5) #4 * #2(0,-0.5) */ function initBuffers() { vertices = [ -0.5,-0.5,0.0, //Vertex 0 -0.25,0.5,0.0, //Vertex 1 0.0,-0.5,0.0, //Vertex 2 0.25,0.5,0.0, //Vertex 3 0.5,-0.5,0.0 //Vertex 4 ]; indices = [0,1,2,0,2,3,2,3,4]; //For triangles //The following code snippet creates a vertex buffer and binds the vertices to it trapezoidVertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, trapezoidVertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, null); //The following code snippet creates a vertex buffer and binds the indices to it trapezoidIndexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, trapezoidIndexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.bindBuffer(gl.ELEMENT_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); gl.bindBuffer(gl.ARRAY_BUFFER, trapezoidVertexBuffer); gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(prg.vertexPositionAttribute); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, trapezoidIndexBuffer); switch(renderingMode){ case "TRIANGLES": { indices = [0,1,2,2,3,4]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0); break; } case "LINES": { indices = [1,3,0,4,1,2,2,3]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.LINES, indices.length, gl.UNSIGNED_SHORT,0); break; } case 'POINTS': { indices = [1,2,3]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.POINTS, indices.length, gl.UNSIGNED_SHORT,0); break; } case 'LINE_LOOP': { indices = [2,3,4,1,0]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.LINE_LOOP, indices.length, gl.UNSIGNED_SHORT,0); break; } case 'LINE_STRIP': { indices = [2,3,4,1,0]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.LINE_STRIP, indices.length, gl.UNSIGNED_SHORT,0); break; } case 'TRIANGLE_STRIP': { indices = [0,1,2,3,4]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.TRIANGLE_STRIP, indices.length, gl.UNSIGNED_SHORT,0); break; } case 'TRIANGLE_FAN': { indices = [0,1,2,3,4]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); gl.drawElements(gl.TRIANGLE_FAN, indices.length, gl.UNSIGNED_SHORT,0); break; } } } /** * Render Loop */ function renderLoop() { utils.requestAnimFrame(renderLoop); drawScene(); } /** * Updates the variable renderingMode with the combo box selection. */ function changeRenderingMode(op){ renderingMode = (op.options[op.selectedIndex].value); } /** * 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 trapezoid (vertex buffer and index buffer) initBuffers(); //Renders the trapezoid! renderLoop(); } </script> </head> <body onLoad='runWebGLApp()'> <div id='top'> <h1>WebGL Beginner's Guide - Chapter 2</h1> <h2>Rendering a trapezoid</h2> <div id='logo-packt'><img src='packt.gif'/></div> <p>WebGL uses buffers to store and process vertex and index data. The mechanism is the same whether we are rendering a simple object like a trapezoid or a racing car as we will see later on.</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'> Please select one option: <select onChange='changeRenderingMode(this)'> <option value='TRIANGLES' select='selected' >TRIANGLES</option> <option value='LINES'>LINES</option> <option value='POINTS'>POINTS</option> <option value='LINE_LOOP'>LINE_LOOP</option> <option value='LINE_STRIP'>LINE_STRIP</option> <option value='TRIANGLE_STRIP'>TRIANGLE_STRIP</option> <option value='TRIANGLE_FAN'>TRIANGLE_FAN</option> </select> </div> <script>cview.run();</script> </html>