The Full Page With Motion

  1 <!DOCTYPE html>
  2 <html>
  3   <head>
  4     <link rel="stylesheet" type="text/css" href="presentation.css" />
  5     <script src="html5slider.js"></script>
  6     <script type="text/javascript">
  7       onload = function()
  8                {
  9                  document.getElementById('slider').onchange = function()
 10                  {
 11                     sliderChanged(this.value);
 12                  };
 13                };
 14     </script>
 15   </head>
 16 
 17   <body>
 18       <div class="content">
 19         <div class="codeExample">
 20         </div>
 21         <div>
 22             <div class="canvasFigure">
 23               <!--A blank area we can draw on with Javascript. -->
 24               <canvas id="drawingSurface" width="300" height="300"></canvas>
 25               <input id="slider" type="range" min="-1" max="1" step=".02" value="0" />
 26             </div>
 27         </div>
 28         <script>
 29                 // Global variables used to render a frame.
 30                 var vertexBuffer,    anotherBuffer;
 31 
 32                 // Fetch a WebGL context from the identified canvas.
 33                 function getGLContext(elementID)
 34                 {
 35                     // Lookup the canvas just like any other element on a we page.
 36                     var drawingSurface = document.getElementById(elementID);
 37 
 38                     // Work with a canvas by getting a 2d or 3d context
 39                     // Here we get a 3d context, experimental-webgl. The context
 40                     // presents a javascript API that is used to draw into it.
 41                     // The webgl context API is very similar to OpenGL for Embedded Systems,
 42                     // or OpenGL ES.
 43                     var gl             = drawingSurface.getContext('experimental-webgl');
 44                     
 45                     if (gl)
 46                     {
 47                         // Enable depth testing
 48                         gl.enable(gl.DEPTH_TEST);
 49                         // Draw a pixel if its depth less or eual to the current one. Less depth means closer to the view point.
 50                         gl.depthFunc(gl.LEQUAL);
 51                     }
 52 
 53                     return gl;
 54                 }
 55 
 56                 // Create and compile a vertex or fragment shader as given by the shader type.
 57                 function compileShader(gl, shaderSource, shaderType)
 58                 {
 59                     var shader = gl.createShader(shaderType);
 60                     gl.shaderSource(shader, shaderSource);
 61                     gl.compileShader(shader);
 62 
 63                     return shader;
 64                 }
 65 
 66 
 67                 // Create a program from the shaders
 68                 function createProgram(gl, vertexShader, fragmentShader)
 69                 {
 70                     var program = gl.createProgram();
 71                     // The program consists of our shaders
 72                     gl.attachShader(program, vertexShader);
 73                     gl.attachShader(program, fragmentShader);
 74 
 75                     // Create a runnable program for our graphics hardware.
 76                     // Allocates and assigns memory for attributes and uniforms (explained later)
 77                     // Shaders are checked from consistency.
 78                     gl.linkProgram(program);
 79 
 80                     return program;
 81                 }
 82 
 83 
 84                 // Generate a buffer from a JS data array
 85                 function createBuffer(JSarray)
 86                 {
 87                     // This is a handle to what will be a buffer
 88                     var vertexBuffer = gl.createBuffer();
 89                     // Binding an object in Open GL creates it, and makes it the target of subsequent manipulations.
 90                     gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
 91                     // loads the current buffer, the vertexBuffer found above, with the vertex data.
 92                     // The gl bufer is strongly types with 32 bit floating data.
 93                     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(JSarray), gl.STATIC_DRAW);
 94 
 95                     return vertexBuffer;
 96                 }
 97 
 98                 // Bind a buffer to a vertex shader attribute,
 99                 // Each atttribute takes size elements of the given type.
100                 // There are stride bytes separating the beginning of each element.
101                 // Data begins offset bytes into the array.
102                 // Note that zero stride indicates also indicates values are adjacent.
103                 function bindBuffer(vertexBuffer, attribute, size, type, stride, offset)
104                 {
105                     // Binding an object in Open GL makes it the target of subsequent operations.
106                     gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
107 
108                     // Lookup a shader attribute location
109                     var attributeLocation = gl.getAttribLocation(program, attribute);
110 
111                     // enable that attribute (location) to receive data from an array
112                     // The vertexBuffer, defined above, is used because it is the currently bound buffer.
113                     gl.enableVertexAttribArray(attributeLocation);
114 
115                     // Each element in the vector contains 3 floating point entries, they should not be normalized,
116                     // there are no array entries between attribute values, and the first element is at position
117                     //  0 in the array.
118                     gl.vertexAttribPointer(attributeLocation, size, gl.FLOAT, false, stride, offset);
119                 }
120 
121                 function generateModelViewMatrix(t)
122                 {
123                     return new Float32Array([1, 0, 0, 0,
124                                              0, 1, 0, 0,
125                                              0, 0, 1, 0,
126                                              t, 0, 0, 1]);
127                 }
128 
129                 function drawFrame(gl, modelViewMatrix, animationMatrix, vertexBuffer, anotherBuffer)
130                 {
131                     // Clear previous color and depth values.
132                     gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
133 
134                     // Gets reference on the modelViewMatrix uniform
135                     var modelViewReference = gl.getUniformLocation(program, 'modelViewMatrix');
136                     if(modelViewReference == -1)
137                     {
138                         alert('Can not find uniform modelViewMatrix.');
139                         return;
140                     }
141 
142                     // Load the matrix into the shader
143                     gl.uniformMatrix4fv(modelViewReference, false, modelViewMatrix);
144 
145                     // Bind the buffer to the positon attribute
146                     bindBuffer(vertexBuffer, 'position', 3, gl.FLOAT, 28, 0);
147 
148                     // And to the color attribute
149                     bindBuffer(vertexBuffer, 'color', 4, gl.FLOAT, 28, 12);
150 
151                     // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting
152                     // with element zero of the vertexBuffer, and that there are three vertices. So there is
153                     // one triangle.
154                     gl.drawArrays(gl.TRIANGLES, 0, 3);
155 
156                     // Load the matrix into the shader
157                     gl.uniformMatrix4fv(modelViewReference, false, animationMatrix);
158 
159                     // Bind the buffer to the positon attribute
160                     bindBuffer(anotherBuffer, 'position', 3, gl.FLOAT, 28, 0);
161 
162                     // And to the color attribute
163                     bindBuffer(anotherBuffer, 'color', 4, gl.FLOAT, 28, 12);
164 
165                     // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting
166                     // with element zero of the buffer, and that there are three vertices. So there is
167                     // one triangle.
168                     gl.drawArrays(gl.TRIANGLES, 0, 3);
169                 }
170 
171                 function sliderChanged(position)
172                 {
173                     var animationMatrix = generateModelViewMatrix(position);
174                     drawFrame(gl, identityMatrix, animationMatrix, vertexBuffer, anotherBuffer);
175                 }
176 
177                 
178                 var gl             = getGLContext('drawingSurface');
179 
180                 var identityMatrix = new Float32Array([1, 0, 0, 0,
181                                                        0, 1, 0, 0,
182                                                        0, 0, 1, 0,
183                                                        0, 0, 0, 1]);
184 
185                 // Like any three dimensional polygon, we specify the vertices.
186                 var vertices       = [
187                                       -1.0, -1.0, 0.0,
188                                        1.0,  0.0, 0.0, 1.0,
189                                        1.0, -1.0, 0.0,
190                                        0.0,  1.0, 0.0, 1.0,
191                                        0.0,  1.0, 0.0,
192                                        0.0,  0.0, 1.0, 1.0
193                                     ];
194 
195                 // Like any three dimensional polygon, we specify the vertices.
196                 var moreVertices   =  [
197                                       -1.0, -1.0,  0.5,
198                                        0.0,  0.0,  1.0, 1.0,
199                                        1.0, -1.0,  0.5,
200                                        0.0,  1.0,  0.0, 1.0,
201                                        0.0,  1.0,  0.5,
202                                        1.0,  0.0,  0.0, 1.0
203                                     ];
204                 
205 
206                 // Shaders are, usually small, C like programs that are loaded onto the graphics card and control
207                 // how a 3D model is rendered, that is drawn to the scren.
208 
209                 // A Vertex shader does per vertex computations. Here we set the predefined variable
210                 // gl_Position to the position of the vertex. We will see many uses for the vertex shader later.
211                 // For example, vertices can be moved in the vertex shader, producing animation or motion.
212                 // When you move through a 3D game, you are seeing the effects of a vertex shader moving the
213                 // polygons around.
214                 var vertexShaderSource   = "attribute vec3 position;"
215                                            + "attribute vec4 color;"
216                                            + "uniform   mat4 modelViewMatrix;"
217                                            + ""
218                                            + "varying vec4 vColor;"
219                                            + ""
220                                            + "void main()"
221                                            + "{"
222                                            + "    gl_Position = modelViewMatrix * vec4(position, 1);"
223                                            + "    vColor      = color;"
224                                            + "}";
225 
226                 // The fragment shader can be thought of for now as doing per pixel computations. It is the
227                 // fragment shader the colors each pixel in a 3d scene.
228                 var fragmentShaderSource = "precision mediump float;"
229                                            + ""
230                                            + "varying vec4 vColor;"
231                                            + ""
232                                            + "void main()"
233                                            + "{"
234                                            + "    gl_FragColor = vColor;"
235                                            + "}";
236 
237                 // Here we create and compile the vertex shader. This will compile to code for your specific
238                 // graphics card.
239                 var vertexShader    = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
240 
241                 // And then compile the fragment shader too.
242                 var fragmentShader  = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
243 
244                 // As you might expect, we are going to run some code, so we need a program.
245                 var program         = createProgram(gl, vertexShader, fragmentShader);
246 
247                 // Make this the currently active program
248                 gl.useProgram(program);
249 
250                 // This is a handle to what will be a buffer
251                 vertexBuffer    = createBuffer(vertices);
252 
253                 // Repeat the same process again, create another buffer with different vertices and draw them.
254                 anotherBuffer   = createBuffer(moreVertices);
255 
256                 var animationMatrix = generateModelViewMatrix(0.0);
257 
258                 drawFrame(gl, identityMatrix, animationMatrix, vertexBuffer, anotherBuffer);
259         </script>
260     </div>
261   </body>
262 </html>

Notes