Structure of the WebGL examples

We have improved the structure of the code examples in this chapter. As the complexity of our WebGL applications increases, it is wise to have a good, maintainable, and clear design. We have left this section at the end of the chapter so you can use it as a reference when working on the exercises.

Structure of the WebGL examples

Just like in previous exercises, our entry point is the runWebGLApp function which is called when the page is loaded. There we create an instance of WebGLApp, as shown in the previous diagram.

WebGLApp

This class encapsulates some of the utility functions that were present in our examples in previous chapters. It also declares a clear and simple life cycle for a WebGL application. WebGLApp has three function hooks that we can map to functions in our web page. These hooks determine what functions will be called for each stage in the life cycle of the app. In the examples of this chapter, we have created the following mappings:

  • configureGLHook: which points to the configure function in the web page
  • loadSceneHook: which is mapped to the load function in the webpage
  • drawSceneHook: which corresponds to the draw function in the webpage

Note

A function hook can be described as a pointer to a function. In JavaScript, you can write:

function foo(){alert("function foo invoked");} var hook = foo; hook();

This fragment of code will execute foo when hook() is executed. This allows a pluggable behavior that is more difficult to express in fully typed languages.

WebGLApp will use the function hooks to call configure, load, and draw in our page in that order.

After setting these hooks, the run method is invoked.

Note

The source code for WebGLApp and other supporting objects can be found in /js/webgl

Supporting objects

We have created the following objects, each one in its own file:

  • Globals.js: Contains the global variables used in the example.
  • Program.js: Creates the program using the shader definitions. Provides the mapping between JavaScript variables (prg.*) and program attributes and uniforms.
  • Scene.js: Maintains a list of objects to be rendered. Contains the AJAX/JSON functionality to retrieve remote objects. It also allows adding local objects to the scene.
  • Floor.js: Defines a grid on the X-Z plane. This object is added to the Scene to have a reference of where the floor is.
  • Axis.js: Represents the axis in world space. When added to the scene, we will have a reference of where the origin is.
  • WebGLApp.js: Represents a WebGL application. It has three function hooks that define the configuration stage, the scene loading stage, and the rendering stage. These hooks can be connected to functions in our web page.
  • Utils.js: Utility functions such as obtaining a gl context.

Note

You can refer to Globals.js to find the global variables used in this example (the definition of the JavaScript matrices is there) and Program.js to find the prg.* JavaScript variables that map to attributes and uniforms in the shaders.

Life-cycle functions

The following are the functions that define the life-cycle of a WebGLApp application:

Configure

The configure function sets some parameters of our gl context, such as the color for clearing the canvas, and then it calls the initTransforms function.

Load

The load function sets up the objects Floor and Axis. These two locally-created objects are added to the Scene by calling the addObject method. After that, a remote object (AJAX call) is loaded using the Scene.loadObject method.

Draw

The draw function calls updateTransforms to calculate the matrices for the new position (that is, when we move), then iterates over the objects in the Scene to render them. Inside this loop, it calls setMatrixUniforms for every object to be rendered.

Matrix handling functions

The following are the functions that initialize, update, and pass matrices to the shaders:

initTransforms

As you can see, the Model-View matrix, the Camera matrix, the Perspective matrix, and the Normal matrix are set up here:

function initTransforms(){
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, home);
displayMatrix(mvMatrix);
mat4.identity(cMatrix);
mat4.inverse(mvMatrix,cMatrix);
mat4.identity(pMatrix);
mat4.perspective(30, c_width / c_height, 0.1, 1000.0, pMatrix);
mat4.identity(nMatrix);
mat4.set(mvMatrix, nMatrix);
mat4.inverse(nMatrix);
mat4.transpose(nMatrix);
coords = COORDS_WORLD;
}

updateTransforms

In updateTransforms, we use the contents of the global variables position and rotation to update the matrices. This is, of course, if the requestUpdate variable is set to true. We set requestUpdate to true from the GUI controls. The code for these is located at the bottom of the webpage (for instance, check the file ch4_ModelView_Rotation.html).

function updateTransforms(){
mat4.perspective(30, c_width / c_height, 0.1, 1000.0, pMatrix);
if (coords == COORDS_WORLD){
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, position);
mat4.rotateX(mvMatrix,rotation[0]*Math.PI/180);
mat4.rotateY(mvMatrix,rotation[1]*Math.PI/180);
mat4.rotateZ(mvMatrix,rotation[2]*Math.PI/180);
}
else{
mat4.identity(cMatrix);
mat4.rotateX(cMatrix,rotation[0]*Math.PI/180);
mat4.rotateY(cMatrix,rotation[1]*Math.PI/180);
mat4.rotateZ(cMatrix,rotation[2]*Math.PI/180);
mat4.translate(cMatrix,position);
}
}

setMatrixUniforms

This function performs the mapping:

function setMatrixUniforms(){
if (coords == COORDS_WORLD){
mat4.inverse(mvMatrix, cMatrix);
displayMatrix(mvMatrix);
gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
}
else{
mat4.inverse(cMatrix, mvMatrix);
displayMatrix(cMatrix);
}
gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);
mat4.transpose(cMatrix, nMatrix);
gl.uniformMatrix4fv(prg.uNMatrix, false, nMatrix);
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.222.47