More Colors!

  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                     gl.enable(gl.DEPTH_TEST);
 41 
 42                     return gl;
 43                 }
 44 
 45                 // Create and compile a vertex or fragment shader as given by the shader type.
 46                 function compileShader(gl, shaderSource, shaderType)
 47                 {
 48                     var shader = gl.createShader(shaderType);
 49                     gl.shaderSource(shader, shaderSource);
 50                     gl.compileShader(shader);
 51 
 52                     if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
 53                     {
 54                         alert(gl.getShaderInfoLog(shader));
 55                         shader = null;
 56                     }
 57 
 58                     return shader;
 59                 }
 60 
 61                 // Create a program from the shaders
 62                 function createProgram(gl, vertexShader, fragmentShader)
 63                 {
 64                     var program = gl.createProgram();
 65                     // The program consists of our shaders
 66                     gl.attachShader(program, vertexShader);
 67                     gl.attachShader(program, fragmentShader);
 68 
 69                     // Create a runnable program for our graphics hardware.
 70                     // Allocates and assigns memory for attributes and uniforms (explained later)
 71                     // Shaders are checked for consistency.
 72                     gl.linkProgram(program);
 73                     
 74                     if (!gl.getProgramParameter(program, gl.LINK_STATUS))
 75                     {
 76                         alert("Could not initialise shaders");
 77                     }
 78 
 79                     return program;
 80                 }
 81 
 82                 // Generate a buffer from a JS data array
 83                 function createBuffer(JSarray)
 84                 {
 85                     // This is a handle to what will be a buffer
 86                     var vertexBuffer = gl.createBuffer();
 87                     // Binding an object in Open GL creates it, and makes it the target of subsequent manipulations.
 88                     gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
 89                     // loads the current buffer, the vertexBuffer found above, with the vertex data.
 90                     // The gl bufer is strongly types with 32 bit floating data.
 91                     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(JSarray), gl.STATIC_DRAW);
 92 
 93                     return vertexBuffer;
 94                 }
 95 
 96                 // Bind a buffer to a vertex shader attribute,
 97                 // Each atttribute takes size elements of the given type.
 98                 // There are stride bytes separating the beginning of each element.
 99                 // Data begins offset bytes into the array.
100                 // Note that zero stride indicates also indicates values are adjacent.
101                 function bindBuffer(buffer, attribute, size, type, stride, offset)
102                 {
103                     // Lookup a shader attribute location
104                     var attributeLocation = gl.getAttribLocation(program, attribute);
105                     // enable that attribute (location) to receive data from an array
106                     // The vertexBuffer, defined above, is used because it is the currently bound buffer.
107                     gl.enableVertexAttribArray(attributeLocation);
108                     // Each element in the vector contains 3 floating point entries, they should not be normalized,
109                     // there are no array entries between attribute values, and the first element is at position
110                     //  0 in the array.
111                     gl.vertexAttribPointer(attributeLocation, size, type, false, stride, offset);
112                 }
113 
114                 var gl             = getGLContext('drawingSurface');
115 
116                 // Like any three dimensional polygon, we specify the vertices.
117                 var vertices       = [
118                                               -1.0, -1.0, 0.0,
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                 // And more of almost the same, but z=0.5.
127                 var moreVertices   =  [
128                                                     -1.0, -1.0,  0.5,
129                                                      0.0,  0.0,  1.0, 1.0,
130                                                      1.0, -1.0,  0.5,
131                                                      0.0,  1.0,  0.0, 1.0,
132                                                      0.0,  1.0,  0.5,
133                                                      1.0,  0.0,  0.0, 1.0
134                                                   ];
135                 
136                 // Shaders are, usually small, C like programs that are loaded onto the graphics card and control
137                 // how a 3D model is rendered, that is drawn to the scren.
138 
139                 // A Vertex shader does per vertex computations. Here we set the predefined variable
140                 // gl_Position to the position of the vertex. We will see many uses for the vertex shader later.
141                 // For example, vertices can be moved in the vertex shader, producing animation or motion.
142                 // When you move through a 3D game, you are seeing the effects of a vertex shader moving the
143                 // polygons around.
144                 var vertexShaderSource   = "attribute vec3 position;"
145                                            + "attribute vec4 color;"
146                                            + ""
147                                            + "varying vec4 vColor;"
148                                            + ""
149                                            + "void main()"
150                                            + "{"
151                                            + "    gl_Position = vec4(position, 1);"
152                                            + "    vColor      = color;"
153                                            + "}";
154 
155                 // The fragment shader can be thought of for now as doing per pixel computations. It is the
156                 // fragment shader the colors each pixel in a 3d scene.
157                 var fragmentShaderSource = "precision mediump float;"
158                                            + ""
159                                            + "varying vec4 vColor;"
160                                            + ""
161                                            + "void main()"
162                                            + "{"
163                                            + "    gl_FragColor = vColor;"
164                                            + "}";
165 
166                 // Here we create and compile the vertex shader. This will compile to code for your specific
167                 // graphics card.
168                 var vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
169 
170                 // And then compile the fragment shader too.
171                 var fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
172 
173                 // As you might expect, we are going to run some code, so we need a program.
174                 var program = createProgram(gl, vertexShader, fragmentShader);
175 
176                 // Make this the currently active program
177                 gl.useProgram(program);
178 
179                 // This is a handle to what will be a buffer
180                 var vertexBuffer = createBuffer(vertices);
181 
182                 // Bind the buffer to the positon attribute
183                 bindBuffer(vertexBuffer, 'position', 3, gl.FLOAT, 28, 0);
184 
185                 // And to the color attribute
186                 bindBuffer(vertexBuffer, 'color', 4, gl.FLOAT, 28, 12);
187 
188                 // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting
189                 // with element zero of the vertexBuffer, and that there are three vertices. So there is
190                 // one triangle.
191                 gl.drawArrays(gl.TRIANGLES, 0, 3);
192 
193 
194                 // Repeat the same process again, create another buffer with different vertices and draw them.
195                 var anotherBuffer = createBuffer(moreVertices);
196 
197                 // Bind the buffer to the positon attribute
198                 bindBuffer(anotherBuffer, 'position', 3, gl.FLOAT, 28, 0);
199 
200                 // And to the color attribute
201                 bindBuffer(anotherBuffer, 'color', 4, gl.FLOAT, 28, 12);
202 
203                 // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting
204                 // with element zero of the buffer, and that there are three vertices. So there is
205                 // one triangle.
206                 gl.drawArrays(gl.TRIANGLES, 0, 3);
207         </script>
208     </div>
209   </body>
210 </html>
(0,1) (-1,-1) (1,-1)

Notes

The full page displaying two triangles.