As sort of a self-teaching exercise I'm trying to three draw quads using WebGL...each quad has its own texture with its own model matrix (rotating on its own axis). The code works but I'm trying to reduce the number of calls to the GL context and better understand how texture binding/drawing works. A picture if it helps...
http://i295.photobucket.com/albums/mm151/coffeeaddict21/webglexper2_ss_zps897ba55e.jpg
I'm re-using gl.TEXTURE0 unit for every texture...could I load each texture into its own unit (TEXTURE0, TEXTURE1, TEXTURE2) and not do all the binding over and over again?
This is called before each call to gl.drawArrays (draw command) to load the texture I want to use in drawArrays and I'm not sure if all of it is necessary or if there is another way around it...can I reduce the number of GL calls or optimize this?
//NAME: loadTexture
//PURPOSE: tell GL how to load the specified texture into GL sampler
//IN: WebGL context, GL texture obj, sampler handle, image object, texture unit to use
//RETURN: void
function loadTexture(gl, texture, u_Sampler, image, texUnit){
//make texture unit specified active
gl.activeTexture(texUnit);
//bind and activate texture
gl.bindTexture(gl.TEXTURE_2D, texture);
//tell GL what parameters to use to map the texture to the geometry
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
//tell GL to bind the specified image to the target
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
//set specifed texture unit index to the sampler
gl.uniform1i(u_Sampler, 0);
}
The code that calls loadTexture (see the bottom for the important stuff)...
//NAME: renderImages
//PURPOSE: load images into textures, apply tranaformations and then draw
//IN: array of pre-loaded images
//RETURN: none
function renderImages(images){
console.log('render...');
//get a pointer to the canvas
var canvas = document.getElementById('webgl');
//get the graphics context from the canvas
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
//initialize shaders specified in this document
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders.');
return;
}
//initialize vertex buffers
var n = initVertexBuffers(gl);
if (n < 0){
console.log('Failed to set the position of the vertices.');
return;
}
if(!images){
console.log('Failed to load images.');
return;
}
if(images.length != 3){
console.log('Failed to load all 3 images we need.');
return;
}
var texture = gl.createTexture();
if(!texture){
console.log('CreateTexture GL call failed on texture initialization.');
return false;
}
var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');
if(!u_Sampler){
console.log('Unable to get storage location of u_Sampler during texture initialization.');
return false;
}
var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
if (u_ModelMatrix == null){
console.log('Failed to get the storage location of u_ModelMatrix');
return;
}
var modelMatrixes = [];
var modelMatrix1 = new Matrix4();
modelMatrix1.setIdentity();
modelMatrix1.translate(0.0, 0.5, 0.0);
modelMatrixes.push(modelMatrix1);
var modelMatrix2 = new Matrix4();
modelMatrix2.setIdentity();
modelMatrix2.translate(0.5, 0.0, 0.0);
modelMatrixes.push(modelMatrix2);
var modelMatrix3 = new Matrix4();
modelMatrix3.setIdentity();
modelMatrix3.translate(-0.5, 0.0, 0.0);
modelMatrixes.push(modelMatrix3);
//set the color to use on gl.clear
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//flip the image on axis on load
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
var lastTick1 = 0;
var lastTick2 = 0;
var lastTick3 = 0;
var frameTick = 0;
var tick = function(){
var timeElapsed = getElapsed();
lastTick1 = lastTick1 + timeElapsed;
lastTick2 = lastTick2 + timeElapsed;
lastTick3 = lastTick3 + timeElapsed;
frameTick = frameTick + timeElapsed;
//run this code when counter exceeds 100ms
if(lastTick1 > 30){
lastTick1 = 0;
modelMatrix1.translate(-0.05, 0.0, 0.0);
modelMatrix1.rotate(5, 0, 0, 1);
}
//run this code when counter exceeds 50ms
if(lastTick2 > 50){
lastTick2 = 0;
modelMatrix2.rotate(3 * DIRECTION, 0, 0, 1);
}
//run this code when counter exceeds 30ms
if(lastTick3 > 100){
lastTick3 = 0;
modelMatrix3.rotate(-1 * DIRECTION, 0, 0, 1);
}
//run this code when counter exceeds 20ms
if(frameTick > 20){
frameTick = 0;
console.log('frame');
//clear the color buffer
gl.clear(gl.COLOR_BUFFER_BIT);
//draw everything
for(var matrixIndex = 0; matrixIndex < modelMatrixes.length; matrixIndex++){
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrixes[matrixIndex].elements);
loadTexture(gl, texture, u_Sampler, images[matrixIndex], gl.TEXTURE0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
}
requestAnimationFrame(tick);
};
tick();
}