Architectural updates

As we move from chapter to chapter and study different WebGL concepts, we should also update our architecture to reflect what we have learned. In this occasion as we are handling a lot of uniforms, we will add support for multiple lights and will improve the way we pass uniforms to the program.

Adding support for light objects

The following diagram shows the changes and additions that we have implemented in the architecture of our exercises. We have updated Program.js to simplify how we handle uniforms and we have included a new file: Ligths.js. Also, we have modified the configure function to use the changes implemented in the Program object. We will discuss these improvements next.

Adding support for light objects

We have created a new JavaScript module Lights.js that has two objects:

  • Light — aggregates lights properties (position, diffuse, specular, and so on) in one single entity.
  • Lights — contain the lights in our scene. It allows us to retrieve each light by index and by name.

Lights — also contains the getArray method to flatten the arrays of properties by type:

getArray: function(type){ //type = 'diffuse' or 'position' or ..
var a = [];
for(var i = 0, max = this.list.length; i < max; i+=1){
a = a.concat(this.list[i][type]); //list: the list of lights
}
return a;
}

This will be useful when we use uniform arrays later on.

Improving how we pass uniforms to the program

We have also improved the way we pass uniforms to the program. In WebGLApp.js we have removed the call to Program.load().

function WebGLApp(canvas) {
this.loadSceneHook = undefined;
this.configureGLHook = undefined;
gl = Utils.getGLContext(canvas);
Program.load();
}

And we have deferred this call to the configure function in the web page. Remember that WebGLApp will call three functions in the web page: configure, load, and draw. These three functions define the life cycle of our application.

The configure function is the appropriate place to load the program. We are also going to create a dynamic mapping between JavaScript variables and uniforms. With this in mind, we have updated the Program.load method to receive two arrays:

  • attributeList — an array containing the names of the attributes that we will map between JavaScript and ESSL
  • uniformList — an array containing the names of the uniforms that we will map between JavaScript and ESSL

The implementation of the function now looks as follows:

load : function(attributeList, uniformList) {
var fragmentShader = Program.getShader(gl, "shader-fs");
var vertexShader = Program.getShader(gl, "shader-vs");
prg = gl.createProgram();
gl.attachShader(prg, vertexShader);
gl.attachShader(prg, fragmentShader);
gl.linkProgram(prg);
if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(prg);
this.setAttributeLocations(attributeList);
this.setUniformLocations(uniformList);

}

The last two lines correspond to the two new functions setAttributeLocations and setUniformLocations:

setAttributeLocations: function (attrList){
for(var i=0, max = attrList.length; i <max; i+=1){
this[attrList[i]] = gl.getAttribLocation(prg, attrList[i]);
}
},
setUniformLocations: function (uniformList){
for(var i=0, max = uniformList.length; i < max; i +=1){
this[uniformList[i]] = gl.getUniformLocation(prg,
uniformList[i]);
}
}

As you can see, these functions read the attribute and uniform lists, respectively, and after obtaining the location for each element of the list, attach the location as a property of the object Program.

This way, if we include the uniform name uLightPosition in the list uniformList that we pass to Program.load, then we will have a property Program.uLightPosition that will contain the location of the respective uniform! Neat, isn't it?

Once we load the program in the configure function, we can also initialize the values of the uniforms that we want right there by writing something as follows:

gl.uniform3fv(Program.uLightPosition, value);
..................Content has been hidden....................

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