1 /* 2 Copyright (c) 2008 Seneca College 3 Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) 4 */ 5 6 7 /* 8 */ 9 c3dl.cartoon_callback = function(renderingObj) 10 { 11 var renderer = renderingObj.getRenderer(); 12 var gl = renderingObj.getContext(); 13 var geometry = renderingObj.getGeometry(); 14 var effect = geometry.getEffect(); 15 var programObjID = renderingObj.getProgramObjectID(); 16 17 gl.useProgram(programObjID); 18 19 if(effect.getParameter("qMap") == null) 20 { 21 c3dl.debug.logWarning('"qMap" is a required parameter for c3dl.effects.CARTOON'); 22 return; 23 } 24 25 var modelViewMatrix = c3dl.peekMatrix(); 26 c3dl.matrixMode(c3dl.PROJECTION); 27 var projectionMatrix = c3dl.peekMatrix(); 28 c3dl.matrixMode(c3dl.MODELVIEW); 29 30 // create a ModelViewProjection matrix. By doing this, we can multiply 31 // 3 matrices together once per model instead of once per vertex 32 var modelViewProjMatrix = c3dl.multiplyMatrixByMatrix(projectionMatrix, modelViewMatrix); 33 renderer.setUniformMatrix(programObjID, "modelViewMatrix", modelViewMatrix); 34 renderer.setUniformMatrix(programObjID, "modelViewProjMatrix", modelViewProjMatrix); 35 36 // Commenting out until a fix is solved for the 2-object outline bug 37 38 // Only render the outline, which is a single pixel thick if the user 39 // wants it and the effect exists. 40 if(effect.getParameter("outline") == true && renderer.SOLID_COLOR_EFFECT_ID) 41 { 42 gl.enable(gl.POLYGON_OFFSET_FILL); 43 gl.polygonOffset(2.0, 2.0); 44 45 // use the solid color effect since it's fast and we don't have 46 // to send unnecessary data. 47 var outlineProgID = renderer.SOLID_COLOR_EFFECT_ID; 48 49 gl.enable(gl.CULL_FACES); 50 gl.cullFace(gl.FRONT); 51 gl.useProgram(outlineProgID); 52 renderer.setUniformf(outlineProgID, "color",[0,0,0]); 53 54 var modelViewMatrix = c3dl.peekMatrix(); 55 c3dl.matrixMode(c3dl.PROJECTION); 56 var projectionMatrix = c3dl.peekMatrix(); 57 c3dl.matrixMode(c3dl.MODELVIEW); 58 59 var MVPMatrix = c3dl.multiplyMatrixByMatrix(projectionMatrix, modelViewMatrix); 60 renderer.setUniformMatrix(outlineProgID, "modelViewProjMatrix", MVPMatrix); 61 62 var contextWidth = renderer.getContextWidth(); 63 var contextHeight = renderer.getContextHeight(); 64 65 for(var primSet = 0; primSet < geometry.getPrimitiveSets().length; primSet++) 66 { 67 var currColl = geometry.getPrimitiveSets()[primSet]; 68 69 // Prevent C3DL from reporting an error, so check if attrib exsits 70 // before trying to set it. 71 // This is a kludge for Safari and Chrome since they want these attributes 72 //////////////////////////// 73 var normalAttribLoc = gl.getAttribLocation(outlineProgID,"Normal"); 74 if(normalAttribLoc != -1 && currColl.getNormals()) 75 { 76 renderer.setVertexAttribArray(outlineProgID, "Normal", 3, currColl.getVBONormals()); 77 } 78 var texAttribLoc = gl.getAttribLocation(outlineProgID, "Texture"); 79 if(texAttribLoc != -1 && currColl.getTexCoords()) 80 { 81 renderer.setVertexAttribArray(outlineProgID, "Texture", 2, currColl.getVBOTexCoords()); 82 } 83 ////////////////////////// End kludge 84 85 86 renderer.setVertexAttribArray(outlineProgID, "Vertex", 3, currColl.getVBOVertices()); 87 88 gl.viewport( 1,-1, contextWidth,contextHeight); 89 gl.drawArrays(renderer.getFillMode(), 0, currColl.getVertices().length/3); 90 91 gl.viewport(-1,-1, contextWidth,contextHeight); 92 gl.drawArrays(renderer.getFillMode(), 0, currColl.getVertices().length/3); 93 94 gl.viewport(-1, 1, contextWidth,contextHeight); 95 gl.drawArrays(renderer.getFillMode(), 0, currColl.getVertices().length/3); 96 97 gl.viewport( 1, 1,contextWidth,contextHeight); 98 gl.drawArrays(renderer.getFillMode(), 0, currColl.getVertices().length/3); 99 } 100 101 // restore normal backface culling 102 gl.cullFace(gl.BACK); 103 gl.viewport(0,0,contextWidth,contextHeight); 104 105 gl.disable(gl.POLYGON_OFFSET_FILL); 106 gl.polygonOffset(0.0, 0.0); 107 gl.useProgram(programObjID); 108 } 109 110 renderer.setUniformi(programObjID, "lightingOn", true); 111 // render all the collation elements. Every collation element in an object will 112 // have the same tranformation 113 for(var coll = 0; coll < geometry.getPrimitiveSets().length; coll++) 114 { 115 var currColl = geometry.getPrimitiveSets()[coll]; 116 117 var normalAttribLoc = gl.getAttribLocation(programObjID, "Normal"); 118 119 // if the object acutally has normals and the normal attribute was found 120 // NORMALS 121 if(currColl.getNormals()) 122 { 123 // the top matrix is the modelview matrix. 124 var NormalMatrix = c3dl.inverseMatrix(modelViewMatrix); 125 NormalMatrix = c3dl.transposeMatrix(NormalMatrix); 126 renderer.setUniformMatrix(programObjID, "normalMatrix", NormalMatrix); 127 renderer.setVertexAttribArray(programObjID, "Normal", 3, currColl.getVBONormals()); 128 } 129 else 130 { 131 gl.disableVertexAttribArray(normalAttribLoc); 132 } 133 134 // TEXTURE 135 var texAttribLoc = gl.getAttribLocation(programObjID, "Texture"); 136 var texID = renderer.getTextureID(currColl.getTexture()); 137 138 // if the texture isn't loaded, but this collation element has one, 139 // queue one up 140 if(texID == -1 && currColl.getTexture()) 141 { 142 renderer.addTexture(currColl.getTexture()); 143 } 144 145 if( texID != -1 && currColl.getTexture() && currColl.getTexCoords() && texAttribLoc != -1 ) 146 { 147 // make texture unit 0 active 148 gl.activeTexture(gl.TEXTURE0); 149 150 // bind the collations texture object to texture unit 0 and make it active. 151 gl.bindTexture(gl.TEXTURE_2D, texID); 152 153 renderer.setVertexAttribArray(programObjID, "Texture", 2, currColl.getVBOTexCoords()); 154 155 renderer.setUniformi(programObjID, "myTex", 0); 156 renderer.setUniformi(programObjID, "usingTexture", true); 157 } 158 else 159 { 160 gl.disableVertexAttribArray(texAttribLoc); 161 renderer.setUniformi(programObjID, "usingTexture", false); 162 } 163 164 // Quantization Map 165 var qMap = effect.getParameter("qMap"); 166 shadesTexID = renderer.getTextureID(qMap); 167 168 // if the user added the parameter, but didn't add the texture 169 // to the renderer with renderer.addTexture. 170 if(shadesTexID == -1) 171 { 172 renderer.addTexture(qMap); 173 } 174 175 gl.activeTexture(gl.TEXTURE1); 176 177 // Minefield is throwing an exception here, but still running? 178 gl.bindTexture(gl.TEXTURE_2D, shadesTexID); 179 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 180 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 181 renderer.setUniformi(programObjID, "celShadeTex", 1); 182 183 // VERTICES 184 renderer.setVertexAttribArray(programObjID, "Vertex", 3, currColl.getVBOVertices()); 185 gl.drawArrays(renderer.getFillMode(), 0, currColl.getVertices().length/3); 186 } 187 } 188