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(function() { 21 22 /**************************************************************************************************************/ 23 24 /** 25 @constructor TileIndexBuffer 26 TileIndexBuffer 27 */ 28 var TileIndexBuffer = function( renderContext, config ) 29 { 30 this.renderContext = renderContext; 31 this.config = config; 32 this.solidIndexBuffer = null; 33 this.subSolidIndexBuffer = [ null, null, null, null ]; 34 this.subIndices = [ null, null, null, null ]; 35 } 36 37 /**************************************************************************************************************/ 38 39 /** 40 * Reset the index buffers. 41 */ 42 TileIndexBuffer.prototype.reset = function() 43 { 44 var gl = this.renderContext.gl; 45 for ( var i=0; i < 4; i++ ) 46 { 47 if ( this.subSolidIndexBuffer[i] ) 48 { 49 gl.deleteBuffer( this.subSolidIndexBuffer[i] ); 50 this.subSolidIndexBuffer[i] = null; 51 } 52 } 53 if ( this.solidIndexBuffer ) 54 { 55 gl.deleteBuffer( this.solidIndexBuffer ); 56 this.solidIndexBuffer = null; 57 } 58 } 59 60 /**************************************************************************************************************/ 61 62 /** 63 * Get index buffer for sub solid 64 */ 65 TileIndexBuffer.prototype.getSubSolid = function(ii) 66 { 67 if ( this.subSolidIndexBuffer[ii] == null ) 68 { 69 var i = ii % 2; 70 var j = Math.floor( ii / 2 ); 71 72 var size = this.config.tesselation; 73 var halfTesselation = (size-1) / 2; 74 75 // Build the sub grid for 'inside' tile 76 var indices = []; 77 for ( var n=halfTesselation*j; n < halfTesselation*(j+1); n++) 78 { 79 for ( var k=halfTesselation*i; k < halfTesselation*(i+1); k++) 80 { 81 indices.push( n * size + k ); 82 indices.push( (n+1) * size + k ); 83 indices.push( n * size + k + 1 ); 84 85 indices.push( n * size + k + 1 ); 86 indices.push( (n+1) * size + k ); 87 indices.push( (n+1) * size + k + 1 ); 88 } 89 } 90 91 this.subIndices[ii] = indices; 92 93 if (this.config.skirt) 94 { 95 // Build skirts 96 // Top skirt 97 var start = (j == 0) ? size * size : size * size + 4 * size; 98 var src = (j == 0) ? 0 : halfTesselation * size; 99 for ( var n = halfTesselation*i; n < halfTesselation*(i+1); n++) 100 { 101 indices.push( start + n ); 102 indices.push( src + n ); 103 indices.push( start + n + 1 ); 104 105 indices.push( start + n + 1 ); 106 indices.push( src + n ); 107 indices.push( src + n + 1 ); 108 } 109 110 // Bottom skirt 111 start = (j == 0) ? size * size + 4 * size : size * size + size; 112 src = (j == 0) ? halfTesselation * size : (size-1) * size; 113 for ( var n = halfTesselation*i; n < halfTesselation*(i+1); n++) 114 { 115 indices.push( src + n ); 116 indices.push( start + n ); 117 indices.push( src + n + 1 ); 118 119 indices.push( src + n + 1 ); 120 indices.push( start + n ); 121 indices.push( start + n + 1 ); 122 } 123 124 // Left skirt 125 start = (i == 0) ? size * size + 2 * size : size * size + 5 * size; 126 src = (i == 0) ? 0 : halfTesselation; 127 for ( var k=halfTesselation*j; k < halfTesselation*(j+1); k++) 128 { 129 indices.push( start + k ); 130 indices.push( start + k + 1 ); 131 indices.push( src + k * size ); 132 133 indices.push( src + k * size ); 134 indices.push( start + k + 1); 135 indices.push( src + (k+1) * size ); 136 } 137 138 // Right skirt 139 start = (i == 0) ? size * size + 5 * size : size * size + 3 * size; 140 src = (i == 0) ? halfTesselation : size - 1; 141 for ( var k=halfTesselation*j; k < halfTesselation*(j+1); k++) 142 { 143 indices.push( k * size + src ); 144 indices.push( (k+1) * size + src ); 145 indices.push( start + k ); 146 147 indices.push( start + k ); 148 indices.push( (k+1) * size + src ); 149 indices.push( start + k + 1 ); 150 } 151 } 152 153 var gl = this.renderContext.gl; 154 var ib = gl.createBuffer(); 155 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ib); 156 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 157 ib.numIndices = indices.length; 158 this.subSolidIndexBuffer[ii] = ib; 159 } 160 161 return this.subSolidIndexBuffer[ii]; 162 } 163 164 /**************************************************************************************************************/ 165 166 /* 167 Build index buffer 168 */ 169 TileIndexBuffer.prototype.getSolid = function() 170 { 171 if ( this.solidIndexBuffer == null ) 172 { 173 var size = this.config.tesselation; 174 var indices = []; 175 // Build the grid 176 for ( var j=0; j < size-1; j++) 177 { 178 for ( var i=0; i < size-1; i++) 179 { 180 indices.push( j * size + i ); 181 indices.push( (j+1) * size + i ); 182 indices.push( j * size + i + 1 ); 183 184 indices.push( j * size + i + 1 ); 185 indices.push( (j+1) * size + i ); 186 indices.push( (j+1) * size + i + 1 ); 187 } 188 } 189 190 if (this.config.skirt) 191 { 192 // Top skirt 193 var start = size * size; 194 for ( var i = 0; i < size-1; i++) 195 { 196 indices.push( start + i ); 197 indices.push( i ); 198 indices.push( start + i + 1 ); 199 200 indices.push( start + i + 1 ); 201 indices.push( i ); 202 indices.push( i + 1 ); 203 } 204 205 // Bottom skirt 206 start += size; 207 for ( var i=0; i < size-1; i++) 208 { 209 indices.push( (size-1) * size + i ); 210 indices.push( start + i ); 211 indices.push( (size-1) * size + i + 1 ); 212 213 indices.push( (size-1) * size + i + 1 ); 214 indices.push( start + i ); 215 indices.push( start + i + 1 ); 216 } 217 218 // Left skirt 219 start += size; 220 for ( var j=0; j < size-1; j++) 221 { 222 indices.push( start + j ); 223 indices.push( start + j + 1 ); 224 indices.push( j * size ); 225 226 indices.push( j * size ); 227 indices.push( start + j + 1); 228 indices.push( (j+1) * size ); 229 } 230 231 // Right skirt 232 start += size; 233 for ( var j=0; j < size-1; j++) 234 { 235 indices.push( j * size + size - 1 ); 236 indices.push( (j+1) * size + size - 1 ); 237 indices.push( start + j ); 238 239 indices.push( start + j ); 240 indices.push( (j+1) * size + size - 1 ); 241 indices.push( start + j + 1 ); 242 } 243 } 244 245 var gl = this.renderContext.gl; 246 var ib = gl.createBuffer(); 247 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ib); 248 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); 249 this.numIndices = indices.length; 250 251 this.solidIndexBuffer = ib; 252 this.solidIndexBuffer.numIndices = indices.length; 253 } 254 255 return this.solidIndexBuffer; 256 } 257 258 /**************************************************************************************************************/ 259 260 return TileIndexBuffer; 261 262 }); 263