1 /*************************************** 2 * Copyright 2011, 2012 GlobWeb contributors. 3 * 4 * This file is part of GlobWeb. 5 * 6 * GlobWeb is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * GlobWeb is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with GlobWeb. If not, see <http://www.gnu.org/licenses/>. 18 ***************************************/ 19 20 define(['./Program','./Tile'], function(Program,Tile) { 21 22 //************************************************************************* 23 24 /** 25 @constructor 26 */ 27 var GroundOverlayRenderer = function(tileManager) 28 { 29 this.renderContext = tileManager.renderContext; 30 this.tileIndexBuffer = tileManager.tileIndexBuffer; 31 32 var vertexShader = "\ 33 attribute vec3 vertex;\n\ 34 attribute vec2 tcoord;\n\ 35 uniform mat4 modelViewMatrix;\n\ 36 uniform mat4 projectionMatrix;\n\ 37 uniform vec4 extent; \n\ 38 \ 39 varying vec2 texCoord;\n\ 40 \ 41 void main(void) \n\ 42 {\n\ 43 gl_Position = projectionMatrix * modelViewMatrix * vec4(vertex, 1.0);\n\ 44 texCoord.x = tcoord.x * (extent[1] - extent[0]) + extent[0];\n\ 45 texCoord.y = tcoord.y * (extent[3] - extent[2]) + extent[2];\n\ 46 }\n\ 47 "; 48 49 var fragmentShader = "\ 50 #ifdef GL_ES\n\ 51 precision highp float;\n\ 52 #endif\n\ 53 \n\ 54 varying vec2 texCoord;\n\ 55 uniform sampler2D overlayTexture;\n\ 56 uniform mat3 transform;\n\ 57 uniform float opacity; \n\ 58 \n\ 59 void main(void)\n\ 60 {\n\ 61 vec3 tc = transform * vec3(texCoord,1.0); \n\ 62 tc.xy /= tc.z; \n\ 63 gl_FragColor.rgba = texture2D(overlayTexture, tc.xy); \n\ 64 gl_FragColor.a = (tc.x >= 0.0 && tc.x <= 1.0 && tc.y >= 0.0 && tc.y <= 1.0) ? opacity * gl_FragColor.a : 0.0; \n\ 65 }\n\ 66 "; 67 68 this.program = new Program(this.renderContext); 69 this.program.createFromSource( vertexShader, fragmentShader ); 70 71 this.groundOverlays = []; 72 73 this.needsOffset = true; 74 } 75 76 //************************************************************************* 77 78 /* 79 Render the ground overlays above the tiles in parameter 80 */ 81 GroundOverlayRenderer.prototype.render = function( tiles ) 82 { 83 var gl = this.renderContext.gl; 84 85 // Setup program 86 this.program.apply(); 87 88 var attributes = this.program.attributes; 89 90 gl.uniformMatrix4fv(this.program.uniforms["projectionMatrix"], false, this.renderContext.projectionMatrix); 91 gl.uniform1i(this.program.uniforms["overlayTexture"], 0); 92 gl.enable(gl.BLEND); 93 gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA ); 94 gl.depthFunc( gl.LEQUAL ); 95 96 var modelViewMatrix = mat4.create(); 97 98 var currentIB = null; 99 100 for ( var j=0; j < this.groundOverlays.length; j++ ) 101 { 102 var go = this.groundOverlays[j]; 103 104 // Image is not loaded, nothing to be done 105 if ( !go.image.complete ) 106 { 107 continue; 108 } 109 110 if ( !go.texture ) 111 { 112 if ( go.flipY ) 113 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true ); 114 go.texture = this.renderContext.createNonPowerOfTwoTextureFromImage(go.image); 115 if ( go.flipY ) 116 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false ); 117 } 118 119 var initialized = false; 120 121 for ( var i = 0; i < tiles.length; i++ ) 122 { 123 var tile = tiles[i]; 124 if ( go.geoBound.intersects( tile.geoBound ) ) 125 { 126 if (!initialized) 127 { 128 gl.uniformMatrix3fv(this.program.uniforms["transform"], false, go.inverseTransform ); 129 gl.uniform1f(this.program.uniforms["opacity"], go.opacity ); 130 131 gl.activeTexture(gl.TEXTURE0); 132 gl.bindTexture(gl.TEXTURE_2D, go.texture); 133 134 initialized = true; 135 } 136 137 var extent = (tile.state == Tile.State.LOADED) ? tile.geoBound : tile.parent.geoBound; 138 139 gl.uniform4f(this.program.uniforms["extent"], extent.west, extent.east, extent.north, extent.south ); 140 mat4.multiply( this.renderContext.viewMatrix, tile.matrix, modelViewMatrix ); 141 gl.uniformMatrix4fv(this.program.uniforms["modelViewMatrix"], false, modelViewMatrix); 142 143 // Bind the vertex buffer 144 gl.bindBuffer(gl.ARRAY_BUFFER, tile.vertexBuffer); 145 gl.vertexAttribPointer(attributes['vertex'], 3, gl.FLOAT, false, 0, 0); 146 147 // Bind the index buffer only if different (index buffer is shared between tiles) 148 var indexBuffer = ( tile.state == Tile.State.LOADED ) ? this.tileIndexBuffer.getSolid() : this.tileIndexBuffer.getSubSolid(tile.parentIndex); 149 if ( currentIB != indexBuffer ) 150 { 151 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 152 currentIB = indexBuffer; 153 } 154 155 // Finally draw the tiles 156 gl.drawElements(gl.TRIANGLES, indexBuffer.numIndices, gl.UNSIGNED_SHORT, 0); 157 } 158 } 159 } 160 161 gl.disable(gl.BLEND); 162 } 163 164 //************************************************************************* 165 166 return GroundOverlayRenderer; 167 168 });