1 <!DOCTYPE html> 2 <html> 3 <head> 4 <link rel="stylesheet" type="text/css" href="presentation.css" /> 5 </head> 6 7 <body> 8 <div class="content"> 9 <div class="codeExample"> 10 </div> 11 <div> 12 <div class="canvasFigure"> 13 <span class="topCoordinate">(0,1)</span> 14 <!--A blank area we can draw on with Javascript. --> 15 <canvas id="drawingSurface" width="300" height="300"></canvas> 16 <span class="lowerLeftCoordinate">(-1,-1)</span> 17 <span class="lowerRightCoordinate">(1,-1)</span> 18 </div> 19 </div> 20 <script> 21 // Fetch a WebGL context from the identified canvas. 22 function getGLContext(elementID) 23 { 24 // Lookup the canvas just like any other element on a we page. 25 var drawingSurface = document.getElementById(elementID); 26 27 // Work with a canvas by getting a 2d or 3d context 28 // Here we get a 3d context, experimental-webgl. The context 29 // presents a javascript API that is used to draw into it. 30 // The webgl context API is very similar to OpenGL for Embedded Systems, 31 // or OpenGL ES. 32 var gl = drawingSurface.getContext('webgl') 33 || drawingSurface.getContext('experimental-webgl'); 34 35 if (!gl) 36 { 37 alert("Can not get WebGL context."); 38 } 39 40 return gl; 41 } 42 43 // Create and compile a vertex or fragment shader as given by the shader type. 44 function compileShader(gl, shaderSource, shaderType) 45 { 46 var shader = gl.createShader(shaderType); 47 gl.shaderSource(shader, shaderSource); 48 gl.compileShader(shader); 49 50 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 51 { 52 alert(gl.getShaderInfoLog(shader)); 53 shader = null; 54 } 55 56 return shader; 57 } 58 59 // Create a program from the shaders 60 function createProgram(gl, vertexShader, fragmentShader) 61 { 62 var program = gl.createProgram(); 63 // The program consists of our shaders 64 gl.attachShader(program, vertexShader); 65 gl.attachShader(program, fragmentShader); 66 67 // Create a runnable program for our graphics hardware. 68 // Allocates and assigns memory for attributes and uniforms (explained later) 69 // Shaders are checked for consistency. 70 gl.linkProgram(program); 71 72 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) 73 { 74 alert("Could not initialise shaders"); 75 } 76 77 return program; 78 } 79 80 // Generate a buffer from a JS data array 81 function createBuffer(JSarray) 82 { 83 // This is a handle to what will be a buffer 84 var vertexBuffer = gl.createBuffer(); 85 // Binding an object in Open GL creates it, and makes it the target of subsequent manipulations. 86 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 87 // loads the current buffer, the vertexBuffer found above, with the vertex data. 88 // The gl bufer is strongly types with 32 bit floating data. 89 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(JSarray), gl.STATIC_DRAW); 90 91 return vertexBuffer; 92 } 93 94 // Bind a buffer to a vertex shader attribute, 95 // Each atttribute takes size elements of the given type. 96 // There are stride bytes separating the beginning of each element. 97 // Data begins offset bytes into the array. 98 // Note that zero stride indicates also indicates values are adjacent. 99 function bindBuffer(buffer, attribute, size, type, stride, offset) 100 { 101 // Lookup a shader attribute location 102 var attributeLocation = gl.getAttribLocation(program, attribute); 103 // enable that attribute (location) to receive data from an array 104 // The vertexBuffer, defined above, is used because it is the currently bound buffer. 105 gl.enableVertexAttribArray(attributeLocation); 106 // Each element in the vector contains 3 floating point entries, they should not be normalized, 107 // there are no array entries between attribute values, and the first element is at position 108 // 0 in the array. 109 gl.vertexAttribPointer(attributeLocation, size, gl.FLOAT, false, stride, offset); 110 } 111 112 var gl = getGLContext('drawingSurface'); 113 114 // Like any three dimensional polygon, we specify the vertices. 115 var vertices = [ 116 // Vetex coordinate 117 -1.0, -1.0, 0.0, 118 // Vertex color 119 1.0, 0.0, 0.0, 1.0, 120 1.0, -1.0, 0.0, 121 0.0, 1.0, 0.0, 1.0, 122 0.0, 1.0, 0.0, 123 0.0, 0.0, 1.0, 1.0 124 ]; 125 126 // Shaders are, usually small, C like programs that are loaded onto the graphics card and control 127 // how a 3D model is rendered, that is drawn to the scren. 128 129 // A Vertex shader does per vertex computations. Here we set the predefined variable 130 // gl_Position to the position of the vertex. We will see many uses for the vertex shader later. 131 // For example, vertices can be moved in the vertex shader, producing animation or motion. 132 // When you move through a 3D game, you are seeing the effects of a vertex shader moving the 133 // polygons around. 134 var vertexShaderSource = "attribute vec3 position;" 135 + "attribute vec4 color;" 136 + "" 137 + "varying vec4 vColor;" 138 + "" 139 + "void main()" 140 + "{" 141 + " gl_Position = vec4(position, 1);" 142 + " vColor = color;" 143 + "}"; 144 145 // The fragment shader can be thought of for now as doing per pixel computations. It is the 146 // fragment shader the colors each pixel in a 3d scene. 147 var fragmentShaderSource = "precision mediump float;" 148 + "" 149 + "varying vec4 vColor;" 150 + "" 151 + "void main()" 152 + "{" 153 + " gl_FragColor = vColor;" 154 + "}"; 155 156 // Here we create and compile the vertex shader. This will compile to code for your specific 157 // graphics card. 158 var vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER); 159 160 // And then compile the fragment shader too. 161 var fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER); 162 163 // As you might expect, we are going to run some code, so we need a program. 164 var program = createProgram(gl, vertexShader, fragmentShader); 165 166 // Make this the currently active program 167 gl.useProgram(program); 168 169 // This is a handle to what will be a buffer 170 var vertexBuffer = createBuffer(vertices); 171 172 // Bind the buffer to the positon attribute 173 bindBuffer(vertexBuffer, 'position', 3, gl.FLOAT, 28, 0); 174 175 // And to the color attribute 176 bindBuffer(vertexBuffer, 'color', 4, gl.FLOAT, 28, 12); 177 178 // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting 179 // with element zero of the vertexBuffer, and that there are three vertices. So there is 180 // one triangle. 181 gl.drawArrays(gl.TRIANGLES, 0, 3); 182 </script> 183 </div> 184 </body> 185 </html>
The full program with colored vertices on one page.