From 073de0b28faf0eedc536f469a1324e091d630890 Mon Sep 17 00:00:00 2001
From: Pasi Keranen <pasi.keranen@digia.com>
Date: Tue, 11 Nov 2014 10:21:20 +0200
Subject: [PATCH] Cleaning up.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Removed unnecessary/duplicate logging. Added clearing of the FBOs to prevent random junk appearing on the screen on Mac OS X before first frame is rendered.
Log all calls and log all errors of context now follows automatically the canvas which is more logical.

Change-Id: I3279e8ae02be8ffc1be6655f1c6c0047ea68364f
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Reviewed-by: Pasi Keränen <pasi.keranen@digia.com>
---
 examples/canvas3d/jsonmodels/jsonmodels.js | 733 +++++++++++----------
 src/canvas3d.cpp                           |  77 ++-
 src/context3d.cpp                          |   7 -
 src/texture3d.cpp                          |   2 +-
 4 files changed, 453 insertions(+), 366 deletions(-)

diff --git a/examples/canvas3d/jsonmodels/jsonmodels.js b/examples/canvas3d/jsonmodels/jsonmodels.js
index bca47dd..0e6c427 100644
--- a/examples/canvas3d/jsonmodels/jsonmodels.js
+++ b/examples/canvas3d/jsonmodels/jsonmodels.js
@@ -129,12 +129,6 @@ function initGL(canvas) {
 }
 
 function renderGL(canvas) {
-    // draw only when we have the meshes and textures
-    if (modelOne.count <= 0 || modelTwo.count <= 0 || modelThree.count <= 0 || modelFour.count <= 0
-            || modelFive.count <= 0 || modelOneTexture == 0 || modelTwoTexture == 0
-            || modelThreeTexture == 0 || modelFourTexture == 0 || modelFiveTexture == 0)
-        return;
-
     // draw
     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
 
@@ -163,343 +157,365 @@ function renderGL(canvas) {
     else
         drawMode = gl.TRIANGLES;
 
-    // Draw model one
-    // Bind the correct buffers
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.verticesVBO);
-    gl.enableVertexAttribArray(vertexPositionAttribute);
-    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+    if (modelOne.count > 0 && modelOneTexture !== 0 ) {
+        // Draw model one
+        log("   model one count:"+modelOne.count+" texture:"+modelOneTexture.name);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.normalsVBO);
-    gl.enableVertexAttribArray(vertexNormalAttribute);
-    gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+        // Bind the correct buffers
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.verticesVBO);
+        gl.enableVertexAttribArray(vertexPositionAttribute);
+        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.texCoordVBO);
-    gl.enableVertexAttribArray(textureCoordAttribute);
-    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, modelOneTexture);
-    gl.uniform1i(textureSamplerUniform, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posOne);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelOne.indexVBO);
-    gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posTwo);
-    mat4.rotateY(mMatrix, mMatrix, rotTwo);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posThree);
-    mat4.rotateY(mMatrix, mMatrix, rotThree);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
-
-    // Draw model two
-    // Bind the correct buffers
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.verticesVBO);
-    gl.enableVertexAttribArray(vertexPositionAttribute);
-    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.normalsVBO);
+        gl.enableVertexAttribArray(vertexNormalAttribute);
+        gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.normalsVBO);
-    gl.enableVertexAttribArray(vertexNormalAttribute);
-    gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelOne.texCoordVBO);
+        gl.enableVertexAttribArray(textureCoordAttribute);
+        gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.texCoordVBO);
-    gl.enableVertexAttribArray(textureCoordAttribute);
-    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, modelTwoTexture);
-    gl.uniform1i(textureSamplerUniform, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posOne);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelTwo.indexVBO);
-    gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posTwo);
-    mat4.rotateY(mMatrix, mMatrix, rotTwo);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posThree);
-    mat4.rotateY(mMatrix, mMatrix, rotThree);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
-
-    // Draw model four
-    // Bind the correct buffers
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.verticesVBO);
-    gl.enableVertexAttribArray(vertexPositionAttribute);
-    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, modelOneTexture);
+        gl.uniform1i(textureSamplerUniform, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posOne);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelOne.indexVBO);
+        gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posTwo);
+        mat4.rotateY(mMatrix, mMatrix, rotTwo);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posThree);
+        mat4.rotateY(mMatrix, mMatrix, rotThree);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
+    }
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.normalsVBO);
-    gl.enableVertexAttribArray(vertexNormalAttribute);
-    gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.texCoordVBO);
-    gl.enableVertexAttribArray(textureCoordAttribute);
-    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, modelFourTexture);
-    gl.uniform1i(textureSamplerUniform, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posFive);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelFour.indexVBO);
-    gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posSix);
-    mat4.rotateY(mMatrix, mMatrix, rotFour);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posSeven);
-    mat4.rotateY(mMatrix, mMatrix, rotOne);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posEight);
-    mat4.rotateY(mMatrix, mMatrix, rotFive);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
-
-    // Draw model five
-    // Bind the correct buffers
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.verticesVBO);
-    gl.enableVertexAttribArray(vertexPositionAttribute);
-    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+    if (modelTwo.count > 0 && modelTwoTexture !== 0 ) {
+        // Draw model two
+        log("   model two count:"+modelTwo.count+" texture:"+modelTwoTexture.name);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.normalsVBO);
-    gl.enableVertexAttribArray(vertexNormalAttribute);
-    gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+        // Bind the correct buffers
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.verticesVBO);
+        gl.enableVertexAttribArray(vertexPositionAttribute);
+        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.texCoordVBO);
-    gl.enableVertexAttribArray(textureCoordAttribute);
-    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, modelFiveTexture);
-    gl.uniform1i(textureSamplerUniform, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posNine);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelFive.indexVBO);
-    gl.drawElements(drawMode, modelFive.count, gl.UNSIGNED_SHORT, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posTen);
-    mat4.rotateX(mMatrix, mMatrix, rotFour);
-    mat4.rotateY(mMatrix, mMatrix, rotFive);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.drawElements(drawMode, modelFive.count, gl.UNSIGNED_SHORT, 0);
-
-    // Draw model three (Includes transparency, must be drawn last)
-    // Bind the correct buffers
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.verticesVBO);
-    gl.enableVertexAttribArray(vertexPositionAttribute);
-    gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.normalsVBO);
+        gl.enableVertexAttribArray(vertexNormalAttribute);
+        gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.normalsVBO);
-    gl.enableVertexAttribArray(vertexNormalAttribute);
-    gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelTwo.texCoordVBO);
+        gl.enableVertexAttribArray(textureCoordAttribute);
+        gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
 
-    gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.texCoordVBO);
-    gl.enableVertexAttribArray(textureCoordAttribute);
-    gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, modelThreeTexture);
-    gl.uniform1i(textureSamplerUniform, 0);
-
-    // Calculate the modelview matrix
-    mat4.identity(mMatrix);
-    mat4.translate(mMatrix, mMatrix, posFour);
-    // Calculate normal matrix before scaling, to keep lighting in order
-    // Scale normal matrix with distance instead
-    mat4.copy(nMatrix, mMatrix);
-    mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
-    mat4.invert(nMatrix, nMatrix);
-    mat4.transpose(nMatrix, nMatrix);
-    gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
-    // Scale the modelview matrix, and apply the matrix
-    mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
-    mat4.multiply(mvMatrix, vMatrix, mMatrix);
-    gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
-
-    // Draw the model
-    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelThree.indexVBO);
-    gl.drawElements(drawMode, modelThree.count, gl.UNSIGNED_SHORT, 0);
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, modelTwoTexture);
+        gl.uniform1i(textureSamplerUniform, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posOne);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelTwo.indexVBO);
+        gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posTwo);
+        mat4.rotateY(mMatrix, mMatrix, rotTwo);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posThree);
+        mat4.rotateY(mMatrix, mMatrix, rotThree);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelTwo.count, gl.UNSIGNED_SHORT, 0);
+    }
+
+    if (modelFour.count > 0 && modelFourTexture !== 0 ) {
+        // Draw model four
+        log("   model four count:"+modelFour.count+" texture:"+modelFourTexture.name);
+
+        // Bind the correct buffers
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.verticesVBO);
+        gl.enableVertexAttribArray(vertexPositionAttribute);
+        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.normalsVBO);
+        gl.enableVertexAttribArray(vertexNormalAttribute);
+        gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFour.texCoordVBO);
+        gl.enableVertexAttribArray(textureCoordAttribute);
+        gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, modelFourTexture);
+        gl.uniform1i(textureSamplerUniform, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posFive);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelFour.indexVBO);
+        gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posSix);
+        mat4.rotateY(mMatrix, mMatrix, rotFour);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posSeven);
+        mat4.rotateY(mMatrix, mMatrix, rotOne);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posEight);
+        mat4.rotateY(mMatrix, mMatrix, rotFive);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelFour.count, gl.UNSIGNED_SHORT, 0);
+    }
+
+    if (modelFive.count > 0 && modelFiveTexture !== 0 ) {
+        // Draw model five
+        log("   model five count:"+modelFive.count+" texture:"+modelFiveTexture.name);
+
+        // Bind the correct buffers
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.verticesVBO);
+        gl.enableVertexAttribArray(vertexPositionAttribute);
+        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.normalsVBO);
+        gl.enableVertexAttribArray(vertexNormalAttribute);
+        gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelFive.texCoordVBO);
+        gl.enableVertexAttribArray(textureCoordAttribute);
+        gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, modelFiveTexture);
+        gl.uniform1i(textureSamplerUniform, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posNine);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelFive.indexVBO);
+        gl.drawElements(drawMode, modelFive.count, gl.UNSIGNED_SHORT, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posTen);
+        mat4.rotateX(mMatrix, mMatrix, rotFour);
+        mat4.rotateY(mMatrix, mMatrix, rotFive);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.drawElements(drawMode, modelFive.count, gl.UNSIGNED_SHORT, 0);
+    }
+
+
+    if (modelThree.count > 0 && modelThreeTexture !== 0 ) {
+        // Draw model three (Includes transparency, must be drawn last)
+        log("   model three count:"+modelThree.count+" texture:"+modelThreeTexture.name);
+
+        // Bind the correct buffers
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.verticesVBO);
+        gl.enableVertexAttribArray(vertexPositionAttribute);
+        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.normalsVBO);
+        gl.enableVertexAttribArray(vertexNormalAttribute);
+        gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
+
+        gl.bindBuffer(gl.ARRAY_BUFFER, modelThree.texCoordVBO);
+        gl.enableVertexAttribArray(textureCoordAttribute);
+        gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+
+        gl.activeTexture(gl.TEXTURE0);
+        gl.bindTexture(gl.TEXTURE_2D, modelThreeTexture);
+        gl.uniform1i(textureSamplerUniform, 0);
+
+        // Calculate the modelview matrix
+        mat4.identity(mMatrix);
+        mat4.translate(mMatrix, mMatrix, posFour);
+        // Calculate normal matrix before scaling, to keep lighting in order
+        // Scale normal matrix with distance instead
+        mat4.copy(nMatrix, mMatrix);
+        mat4.scale(nMatrix, nMatrix, [canvas.distance, canvas.distance, canvas.distance]);
+        mat4.invert(nMatrix, nMatrix);
+        mat4.transpose(nMatrix, nMatrix);
+        gl.uniformMatrix4fva(nMatrixUniform, false, nMatrix);
+        // Scale the modelview matrix, and apply the matrix
+        mat4.scale(mMatrix, mMatrix, [canvas.itemSize, canvas.itemSize, canvas.itemSize]);
+        mat4.multiply(mvMatrix, vMatrix, mMatrix);
+        gl.uniformMatrix4fva(mvMatrixUniform, false, mvMatrix);
+
+        // Draw the model
+        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelThree.indexVBO);
+        gl.drawElements(drawMode, modelThree.count, gl.UNSIGNED_SHORT, 0);
+    }
 }
 
 //! [8]
@@ -538,25 +554,25 @@ function handleLoadedModel(jsonObj) {
 //! [4]
 function fillModel(modelData, model) {
     log("   fillModel...");
-    log("   "+model.verticesVBO);
+    log("   "+model.verticesVBO.name);
     gl.bindBuffer(gl.ARRAY_BUFFER, model.verticesVBO);
     gl.bufferData(gl.ARRAY_BUFFER,
                   Arrays.newFloat32Array(modelData.vertices),
                   gl.STATIC_DRAW);
 
-    log("   "+model.normalsVBO);
+    log("   "+model.normalsVBO.name);
     gl.bindBuffer(gl.ARRAY_BUFFER, model.normalsVBO);
     gl.bufferData(gl.ARRAY_BUFFER,
                   Arrays.newFloat32Array(modelData.normals),
                   gl.STATIC_DRAW);
 
-    log("   "+model.texCoordVBO);
+    log("   "+model.texCoordVBO.name);
     gl.bindBuffer(gl.ARRAY_BUFFER, model.texCoordVBO);
     gl.bufferData(gl.ARRAY_BUFFER,
                   Arrays.newFloat32Array(modelData.texCoords[0]),
                   gl.STATIC_DRAW);
 
-    log("   "+model.indexVBO);
+    log("   "+model.indexVBO.name);
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.indexVBO);
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
                   Arrays.newUint16Array(modelData.indices),
@@ -612,6 +628,7 @@ function initShaders()
                                 }", gl.FRAGMENT_SHADER);
 
     texturedShaderProgram = gl.createProgram();
+    texturedShaderProgram.name = "texturedShaderProgram";
     gl.attachShader(texturedShaderProgram, vertexShader);
     gl.attachShader(texturedShaderProgram, fragmentShader);
     gl.linkProgram(texturedShaderProgram);
@@ -625,52 +642,86 @@ function initShaders()
 
     // look up where the vertex data needs to go.
     vertexPositionAttribute = gl.getAttribLocation(texturedShaderProgram, "aVertexPosition");
+    vertexPositionAttribute.name = "aVertexPosition";
     gl.enableVertexAttribArray(vertexPositionAttribute);
     vertexNormalAttribute = gl.getAttribLocation(texturedShaderProgram, "aVertexNormal");
+    vertexNormalAttribute.name = "aVertexNormal";
     gl.enableVertexAttribArray(vertexNormalAttribute);
     textureCoordAttribute = gl.getAttribLocation(texturedShaderProgram, "aTextureCoord");
+    textureCoordAttribute.name = "aTextureCoord";
     gl.enableVertexAttribArray(textureCoordAttribute);
 
     pMatrixUniform = gl.getUniformLocation(texturedShaderProgram, "uPMatrix");
+    pMatrixUniform.name = "uPMatrix";
     mvMatrixUniform = gl.getUniformLocation(texturedShaderProgram, "uMVMatrix");
+    mvMatrixUniform.name = "uMVMatrix";
     textureSamplerUniform = gl.getUniformLocation(texturedShaderProgram, "uSampler")
+    textureSamplerUniform.name = "uSampler";
     nMatrixUniform = gl.getUniformLocation(texturedShaderProgram, "uNormalMatrix");
+    nMatrixUniform.name = "uNormalMatrix";
     eyeUniform = gl.getUniformLocation(texturedShaderProgram, "eyePos");
+    eyeUniform.name = "eyePos";
     log("   ...initShaders");
 }
 
 //! [1]
 function initBuffers() {
     modelOne.verticesVBO = gl.createBuffer();
+    modelOne.verticesVBO.name = "modelOne.verticesVBO";
     modelOne.normalsVBO  = gl.createBuffer();
+    modelOne.normalsVBO.name = "modelOne.normalsVBO";
     modelOne.texCoordVBO = gl.createBuffer();
+    modelOne.texCoordVBO.name = "modelOne.texCoordVBO";
     modelOne.indexVBO    = gl.createBuffer();
+    modelOne.indexVBO.name = "modelOne.indexVBO";
+
     modelTwo.verticesVBO = gl.createBuffer();
+    modelTwo.verticesVBO.name = "modelTwo.verticesVBO";
     modelTwo.normalsVBO  = gl.createBuffer();
+    modelTwo.normalsVBO.name = "modelTwo.normalsVBO";
     modelTwo.texCoordVBO = gl.createBuffer();
+    modelTwo.texCoordVBO.name = "modelTwo.texCoordVBO";
     modelTwo.indexVBO    = gl.createBuffer();
+    modelTwo.indexVBO.name = "modelTwo.indexVBO";
+
     //! [1]
     modelThree.verticesVBO = gl.createBuffer();
+    modelThree.verticesVBO.name = "modelThree.verticesVBO";
     modelThree.normalsVBO  = gl.createBuffer();
+    modelThree.normalsVBO.name = "modelThree.normalsVBO";
     modelThree.texCoordVBO = gl.createBuffer();
+    modelThree.texCoordVBO.name = "modelThree.texCoordVBO";
     modelThree.indexVBO    = gl.createBuffer();
+    modelThree.indexVBO.name = "modelThree.indexVBO";
+
     modelFour.verticesVBO = gl.createBuffer();
+    modelFour.verticesVBO.name = "modelFour.verticesVBO";
     modelFour.normalsVBO  = gl.createBuffer();
+    modelFour.normalsVBO.name = "modelFour.normalsVBO";
     modelFour.texCoordVBO = gl.createBuffer();
+    modelFour.texCoordVBO.name = "modelFour.texCoordVBO";
     modelFour.indexVBO    = gl.createBuffer();
+    modelFour.indexVBO.name = "modelFour.indexVBO";
+
     modelFive.verticesVBO = gl.createBuffer();
+    modelFive.verticesVBO.name = "modelFive.verticesVBO";
     modelFive.normalsVBO  = gl.createBuffer();
+    modelFive.normalsVBO.name = "modelFive.normalsVBO";
     modelFive.texCoordVBO = gl.createBuffer();
+    modelFive.texCoordVBO.name = "modelFive.texCoordVBO";
     modelFive.indexVBO    = gl.createBuffer();
+    modelFive.indexVBO.name = "modelFive.indexVBO";
 }
 
 //! [5]
 function loadTextures() {
     // Load the first texture
     var goldImage = TextureImageFactory.newTexImage();
+    goldImage.name = "goldImage";
     goldImage.imageLoaded.connect(function() {
         log("    creating model one texture");
         modelOneTexture = gl.createTexture();
+        modelOneTexture.name = "modelOneTexture";
         gl.bindTexture(gl.TEXTURE_2D, modelOneTexture);
         gl.texImage2D(gl.TEXTURE_2D,    // target
                       0,                // level
@@ -690,9 +741,11 @@ function loadTextures() {
 
     // Load the second texture
     var woodBoxImage = TextureImageFactory.newTexImage();
+    woodBoxImage.name = "woodBoxImage";
     woodBoxImage.imageLoaded.connect(function() {
         log("    creating model two texture");
         modelTwoTexture = gl.createTexture();
+        modelTwoTexture.name = "modelTwoTexture";
         gl.bindTexture(gl.TEXTURE_2D, modelTwoTexture);
         gl.texImage2D(gl.TEXTURE_2D,    // target
                       0,                // level
@@ -713,9 +766,11 @@ function loadTextures() {
 
     // Load the third texture
     var bushImage = TextureImageFactory.newTexImage();
+    bushImage.name = "bushImage";
     bushImage.imageLoaded.connect(function() {
         log("    creating model three texture");
         modelThreeTexture = gl.createTexture();
+        modelThreeTexture.name = "modelThreeTexture";
         gl.bindTexture(gl.TEXTURE_2D, modelThreeTexture);
         gl.texImage2D(gl.TEXTURE_2D,    // target
                       0,                // level
@@ -735,9 +790,11 @@ function loadTextures() {
 
     // Load the fourth texture
     var palletImage = TextureImageFactory.newTexImage();
+    palletImage.name = "palletImage";
     palletImage.imageLoaded.connect(function() {
         log("    creating model four texture");
         modelFourTexture = gl.createTexture();
+        modelFourTexture.name = "modelFourTexture";
         gl.bindTexture(gl.TEXTURE_2D, modelFourTexture);
         gl.texImage2D(gl.TEXTURE_2D,    // target
                       0,                // level
@@ -757,9 +814,11 @@ function loadTextures() {
 
     // Load the fifth texture
     var rockImage = TextureImageFactory.newTexImage();
+    rockImage.name = "rockImage";
     rockImage.imageLoaded.connect(function() {
         log("    creating model five texture");
         modelFiveTexture = gl.createTexture();
+        modelFiveTexture.name = "modelFiveTexture";
         gl.bindTexture(gl.TEXTURE_2D, modelFiveTexture);
         gl.texImage2D(gl.TEXTURE_2D,    // target
                       0,                // level
diff --git a/src/canvas3d.cpp b/src/canvas3d.cpp
index e161522..5937bac 100644
--- a/src/canvas3d.cpp
+++ b/src/canvas3d.cpp
@@ -268,12 +268,16 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option
 {
     Q_UNUSED(type);
 
-    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << "(" << type << ", " << options << ")";
+    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                << "("
+                                << type << ", " << options
+                                << ")";
 
     if (!m_isContextAttribsSet) {
         m_isContextAttribsSet = true;
         m_contextAttribs.setFrom(options);
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Attribs:" << m_contextAttribs;
+        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                    << " Attribs:" << m_contextAttribs;
 
         // If we can't do antialiasing, ensure we don't even try to enable it
         if (m_maxSamples == 0)
@@ -343,7 +347,9 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option
         else
             surfaceFormat.setStencilBufferSize(-1);
 
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " QOpenGLContext with surfaceFormat :" << surfaceFormat;
+        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                    << " Creating QOpenGLContext with surfaceFormat :"
+                                    << surfaceFormat;
 
         m_contextWindow = window();
         m_contextThread = QThread::currentThread();
@@ -352,8 +358,6 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option
         m_glContext->setShareContext(m_glContextQt);
         m_glContext->create();
 
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " QOffscreenSurface with surfaceFormat :" << surfaceFormat;
-
         m_offscreenSurface = new QOffscreenSurface();
         m_offscreenSurface->setFormat(m_glContext->format());
         m_offscreenSurface->create();
@@ -364,18 +368,30 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option
         initializeOpenGLFunctions();
 
         // Create the FBOs
-        QOpenGLFramebufferObjectFormat fmt = format;
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Creating FBO's with attachment format of :" << fmt.attachment();
-        m_displayFbo = new QOpenGLFramebufferObject(m_initialisedSize, fmt);
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " m_displayFbo handle:" << m_displayFbo->handle() << " isValid" << m_displayFbo->isValid();
-
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Creating FBO's with attachment format of :" << format.attachment();
+        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                    << " Creating front and back FBO's with attachment format of :"
+                                    << format.attachment();
+        m_displayFbo = new QOpenGLFramebufferObject(m_initialisedSize, format);
         m_renderFbo  = new QOpenGLFramebufferObject(m_initialisedSize,  format);
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " m_renderFbo handle:" << m_renderFbo->handle() << " isValid" << m_renderFbo->isValid();
+
+        // Clear the FBOs to prevent random junk appearing on the screen
+        glClearColor(0,0,0,0);
+        m_displayFbo->bind();
+        glClear(GL_COLOR_BUFFER_BIT);
+        m_renderFbo->bind();
+        glClear(GL_COLOR_BUFFER_BIT);
+
+        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                    << " Render FBO handle:" << m_renderFbo->handle()
+                                    << " isValid:" << m_renderFbo->isValid();
         m_renderFbo->bind();
 
         if (m_contextAttribs.antialias()) {
-            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Creating MSAA buffer with samples:" << antialiasFboFormat.samples() << "and attachment format of :" << antialiasFboFormat.attachment();
+            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                        << " Creating MSAA buffer with "
+                                        << antialiasFboFormat.samples() << "samples "
+                                        << "and attachment format of :"
+                                        << antialiasFboFormat.attachment();
             m_antialiasFbo = new QOpenGLFramebufferObject(m_initialisedSize, antialiasFboFormat);
         }
 
@@ -386,10 +402,18 @@ CanvasContext *Canvas::getContext(const QString &type, const QVariantMap &option
         m_context3D->setCanvas(this);
         m_context3D->setDevicePixelRatio(m_devicePixelRatio);
         m_context3D->setContextAttributes(m_contextAttribs);
+        m_context3D->setLogAllCalls(this->logAllCalls());
+        m_context3D->setLogAllErrors(this->logAllErrors());
+        connect(this, &Canvas::logAllCallsChanged, m_context3D, &CanvasContext::setLogAllCalls);
+        connect(this, &Canvas::logAllErrorsChanged, m_context3D, &CanvasContext::setLogAllErrors);
+
 
         emit contextChanged(m_context3D);
     }
 
+    glFlush();
+    glFinish();
+
     return m_context3D;
 }
 
@@ -495,10 +519,14 @@ void Canvas::ready()
  */
 QSGNode *Canvas::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
 {
-    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << "("<<oldNode<<", " << data << ")";
+    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                << "("
+                                << oldNode <<", " << data
+                                << ")";
     updateWindowParameters();
     m_initialisedSize = boundingRect().size().toSize()  * m_devicePixelRatio;
-    if (m_logAllCalls) qDebug() << "    m_initialisedSize:" << m_initialisedSize << "devicePixelRatio:" << m_devicePixelRatio;
+    if (m_logAllCalls) qDebug() << "    m_initialisedSize:" << m_initialisedSize
+                                << " devicePixelRatio:" << m_devicePixelRatio;
     if (m_runningInDesigner
             || m_initialisedSize.width() <= 0
             || m_initialisedSize.height() <= 0
@@ -577,22 +605,26 @@ void Canvas::renderNext()
 
     // Don't try to do anything before the render node has been created
     if (!m_renderNodeReady) {
-        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Render node not ready, returning";
+        if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                    << " Render node not ready, returning";
         return;
     }
 
     if (!m_glContext) {
-        // Call the initialize function from QML/JavaScript until it calls the getContext() that in turn creates the buffers
+        // Call the initialize function from QML/JavaScript until it calls the getContext()
+        // that in turn creates the buffers.
         // Allow the JavaScript code to call the getContext() to create the context object and FBOs
         emit initGL();
 
         if (!m_isContextAttribsSet) {
-            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Context attributes not set, returning";
+            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                        << " Context attributes not set, returning";
             return;
         }
 
         if (!m_glContext) {
-            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " GLContext3D not created, returning";
+            if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                        << " QOpenGLContext not created, returning";
             return;
         }
     }
@@ -613,7 +645,8 @@ void Canvas::renderNext()
     // Ensure we have correct clip rect set in the context
     QRect viewport = m_context3D->glViewportRect();
     glViewport(viewport.x(), viewport.y(), viewport.width(), viewport.height());
-    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " viewport set to " << viewport;
+    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                << " viewport set to " << viewport;
 
     // Check that we're complete component before drawing
     if (!isComponentComplete())
@@ -639,7 +672,9 @@ void Canvas::renderNext()
     glFlush();
     glFinish();
     qSwap(m_renderFbo, m_displayFbo);
-    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__ << " Displaying texture " << m_displayFbo->texture() << " from FBO: " << m_displayFbo->handle();
+    if (m_logAllCalls) qDebug() << "Canvas3D::" << __FUNCTION__
+                                << " Displaying texture: " << m_displayFbo->texture()
+                                << " From FBO: " << m_displayFbo->handle();
 
     // Rebind default FBO
     QOpenGLFramebufferObject::bindDefault();
diff --git a/src/context3d.cpp b/src/context3d.cpp
index 9fbedea..71dd317 100644
--- a/src/context3d.cpp
+++ b/src/context3d.cpp
@@ -3529,13 +3529,6 @@ void CanvasContext::bufferData(glEnums target, long size, glEnums usage)
     delete tempArray;
 }
 
-/*!
- * \qmlmethod TypedArray Context3D::createTypedArray(glEnums dataType, long size)
- * Returns a new TypedArray of the given \a dataType with the given \a size. Type must be one of
- * \c{Context3D.BYTE}, \c{Context3D.UNSIGNED_BYTE}, \c{Context3D.SHORT},
- * \c{Context3D.UNSIGNED_SHORT}, \c{Context3D.INT}, \c{Context3D.UNSIGNED_INT},
- * or \c{Context3D.FLOAT}.
- */
 /*!
  * \internal
  */
diff --git a/src/texture3d.cpp b/src/texture3d.cpp
index cfcef46..1a482db 100644
--- a/src/texture3d.cpp
+++ b/src/texture3d.cpp
@@ -113,7 +113,7 @@ void CanvasTexture::del()
 QDebug operator<<(QDebug dbg, const CanvasTexture *texture)
 {
     if (texture)
-        dbg.nospace() << "Texture3D("<< ((void*) texture) << texture->name() << ")";
+        dbg.nospace() << "Texture3D("<< ((void*) texture) << ", name:" << texture->name() << ")";
     else
         dbg.nospace() << "Texture3D("<< ((void*) texture) <<")";
     return dbg.maybeSpace();
-- 
GitLab