1 /* 2 SpiderGL Computer Graphics Library 3 Copyright (c) 2010, Marco Di Benedetto - Visual Computing Lab, ISTI - CNR 4 All rights reserved. 5 6 Redistribution and use in source and binary forms, with or without 7 modification, are permitted provided that the following conditions are met: 8 * Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright 11 notice, this list of conditions and the following disclaimer in the 12 documentation and/or other materials provided with the distribution. 13 * Neither the name of SpiderGL nor the 14 names of its contributors may be used to endorse or promote products 15 derived from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @fileOverview Model 31 */ 32 33 /** 34 * The SpiderGL.Model namespace. 35 * 36 * @namespace The SpiderGL.Model namespace. 37 */ 38 SpiderGL.Model = { }; 39 40 /** 41 * Creates a SpiderGL.Model.Model. 42 * 43 * A SpiderGL.Model.Model is a layered data structure that represents a geometric model. 44 * Through the model descriptor, it provides the elements needed to form a 3D model, e.g. raw data, semantic bindings, logical sub-structures, and higher level information. 45 * Bottom to top, each layer in the stack relies at most on the previous one. While layer flexibility decreases bottom to top, their expressiveness increases. 46 * 47 * @class The SpiderGL.Model.Model represents a complex geometric model. 48 * 49 * @augments SpiderGL.Core.ObjectBase 50 */ 51 SpiderGL.Model.Model = function (gl, descriptor, options) { 52 SpiderGL.Core.ObjectBase.call(this); 53 54 options = SpiderGL.Utility.getDefaultObject({ 55 }, options); 56 57 if (descriptor && ("vertices" in descriptor)) { 58 descriptor = SpiderGL.Model.Model._createSimpleDescriptor(descriptor); 59 } 60 61 this._descriptor = SpiderGL.Model.Model._fixDescriptor(descriptor); 62 this._gl = null; 63 this._renderData = { }; 64 65 if (gl) { 66 this.updateGL(gl, options); 67 this.updateRenderData(); 68 } 69 }; 70 71 SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_SIZE = 3; 72 SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE = SpiderGL.Type.FLOAT32; 73 SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_NORMALIZED = false; 74 SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_STRIDE = 0; 75 SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_OFFSET = 0; 76 77 SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_MODE = SpiderGL.Type.TRIANGLES; 78 SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_FIRST = 0; 79 SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_COUNT = -1; 80 SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE = SpiderGL.Type.UINT16; 81 SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_OFFSET = 0; 82 83 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP = { }; 84 85 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["position"] = { 86 size : 3, 87 type : SpiderGL.Type.FLOAT32, 88 normalized : false, 89 semantic : "POSITION", 90 index : 0, 91 value : [0.0, 0.0, 0.0, 1.0] 92 }; 93 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["normal"] = { 94 size : 3, 95 type : SpiderGL.Type.FLOAT32, 96 normalized : false, 97 semantic : "NORMAL", 98 index : 0, 99 value : [0.0, 0.0, 1.0, 0.0] 100 }; 101 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["color"] = { 102 size : 4, 103 type : SpiderGL.Type.UINT8, 104 normalized : true, 105 semantic : "COLOR", 106 index : 0, 107 value : [0, 0, 0, 255] 108 }; 109 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["texcoord"] = { 110 size : 2, 111 type : SpiderGL.Type.FLOAT32, 112 normalized : false, 113 semantic : "TEXCOORD", 114 index : 0, 115 value : [0.0, 0.0, 0.0, 1.0] 116 }; 117 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["user"] = { 118 size : 3, 119 type : SpiderGL.Type.FLOAT32, 120 normalized : false, 121 semantic : "USER", 122 index : 0, 123 value : [0.0, 0.0, 0.0, 1.0] 124 }; 125 126 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP = { }; 127 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["triangles"] = { 128 mode : SpiderGL.Type.TRIANGLES, 129 type : SpiderGL.Type.UINT16, 130 count : -1, 131 semantic : "FILL" 132 }; 133 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["triangleStrip"] = { 134 mode : SpiderGL.Type.TRIANGLE_STRIP, 135 type : SpiderGL.Type.UINT16, 136 count : -1, 137 semantic : "FILL" 138 }; 139 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["triangleFan"] = { 140 mode : SpiderGL.Type.TRIANGLE_FAN, 141 type : SpiderGL.Type.UINT16, 142 count : -1, 143 semantic : "FILL" 144 }; 145 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["lines"] = { 146 mode : SpiderGL.Type.LINES, 147 type : SpiderGL.Type.UINT16, 148 count : -1, 149 semantic : "LINE" 150 }; 151 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["lineStrip"] = { 152 mode : SpiderGL.Type.LINE_STRIP, 153 type : SpiderGL.Type.UINT16, 154 count : -1, 155 semantic : "LINE" 156 }; 157 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["lineLoop"] = { 158 mode : SpiderGL.Type.LINE_LOOP, 159 type : SpiderGL.Type.UINT16, 160 count : -1, 161 semantic : "LINE" 162 }; 163 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["points"] = { 164 mode : SpiderGL.Type.POINTS, 165 type : SpiderGL.Type.UINT16, 166 count : -1, 167 semantic : "POINT" 168 }; 169 SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["user"] = { 170 mode : SpiderGL.Type.TRIANGLES, 171 type : SpiderGL.Type.UINT16, 172 count : -1, 173 semantic : "FILL" 174 }; 175 176 SpiderGL.Model.Model._fixDescriptor = function (d) { 177 d = SpiderGL.Utility.getDefaultObject({ 178 version : "0.0.0.1 EXP", 179 meta : null, 180 data : null, 181 access : null, 182 semantic : null, 183 logic : null 184 }, d); 185 186 d.meta = SpiderGL.Model.Model._fixDescriptorMeta (d.meta); 187 d.data = SpiderGL.Model.Model._fixDescriptorData (d.data); 188 d.access = SpiderGL.Model.Model._fixDescriptorAccess (d.access); 189 d.semantic = SpiderGL.Model.Model._fixDescriptorSemantic (d.semantic); 190 d.logic = SpiderGL.Model.Model._fixDescriptorLogic (d.logic); 191 192 return d; 193 }; 194 195 SpiderGL.Model.Model._fixDescriptorMeta = function (d) { 196 d = SpiderGL.Utility.getDefaultObject({ 197 author : null, 198 date : null, 199 description : null 200 }, d); 201 return d; 202 }; 203 204 SpiderGL.Model.Model._fixDescriptorData = function (d) { 205 d = SpiderGL.Utility.getDefaultObject({ 206 vertexBuffers : null, 207 indexBuffers : null 208 }, d); 209 210 d.vertexBuffers = SpiderGL.Model.Model._fixDescriptorDataVertexBuffers (d.vertexBuffers); 211 d.indexBuffers = SpiderGL.Model.Model._fixDescriptorDataIndexBuffers (d.indexBuffers); 212 213 return d; 214 }; 215 216 SpiderGL.Model.Model._fixDescriptorDataVertexBuffers = function (d) { 217 d = SpiderGL.Utility.getDefaultObject({ }, d); 218 for (var x in d) { 219 d[x] = SpiderGL.Model.Model._fixDescriptorDataVertexBuffer(d[x]); 220 } 221 return d; 222 }; 223 224 SpiderGL.Model.Model._fixDescriptorDataVertexBuffer = function (d) { 225 return SpiderGL.Model.Model._fixDescriptorDataBuffer(d); 226 }; 227 228 SpiderGL.Model.Model._fixDescriptorDataIndexBuffers = function (d) { 229 d = SpiderGL.Utility.getDefaultObject({ }, d); 230 for (var x in d) { 231 d[x] = SpiderGL.Model.Model._fixDescriptorDataIndexBuffer(d[x]); 232 } 233 return d; 234 }; 235 236 SpiderGL.Model.Model._fixDescriptorDataIndexBuffer = function (d) { 237 return SpiderGL.Model.Model._fixDescriptorDataBuffer(d); 238 }; 239 240 SpiderGL.Model.Model._fixDescriptorDataBuffer = function (d) { 241 d = SpiderGL.Utility.getDefaultObject({ 242 type : SpiderGL.Type.NO_TYPE, 243 glType : WebGLRenderingContext.NONE, 244 untypedArray : null, 245 typedArray : null, 246 glBuffer : null 247 }, d); 248 return d; 249 }; 250 251 SpiderGL.Model.Model._fixDescriptorAccess = function (d) { 252 d = SpiderGL.Utility.getDefaultObject({ 253 vertexStreams : null, 254 primitiveStreams : null 255 }, d); 256 257 d.vertexStreams = SpiderGL.Model.Model._fixDescriptorAccessVertexStreams (d.vertexStreams); 258 d.primitiveStreams = SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStreams (d.primitiveStreams); 259 260 return d; 261 }; 262 263 SpiderGL.Model.Model._fixDescriptorAccessVertexStreams = function (d) { 264 d = SpiderGL.Utility.getDefaultObject({ }, d); 265 for (var x in d) { 266 d[x] = SpiderGL.Model.Model._fixDescriptorAccessVertexStream(d[x]); 267 } 268 return d; 269 }; 270 271 SpiderGL.Model.Model._fixDescriptorAccessVertexStream = function (d) { 272 d = SpiderGL.Utility.getDefaultObject({ 273 buffer : null, 274 size : SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_SIZE, 275 type : SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE, 276 glType : SpiderGL.Type.typeToGL(SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE), 277 normalized : SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_NORMALIZED, 278 stride : SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_STRIDE, 279 offset : SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_OFFSET 280 }, d); 281 return d; 282 }; 283 284 SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStreams = function (d) { 285 d = SpiderGL.Utility.getDefaultObject({ }, d); 286 for (var x in d) { 287 d[x] = SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStream(d[x]); 288 } 289 return d; 290 }; 291 292 SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStream = function (d) { 293 d = SpiderGL.Utility.getDefaultObject({ 294 buffer : null, 295 mode : SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_MODE, 296 first : SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_FIRST, 297 count : SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_COUNT, 298 type : SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE, 299 glType : SpiderGL.Type.typeToGL(SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE), 300 offset : SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_OFFSET 301 }, d); 302 return d; 303 }; 304 305 SpiderGL.Model.Model._fixDescriptorSemantic = function (d) { 306 d = SpiderGL.Utility.getDefaultObject({ 307 bindings : null, 308 chunks : null 309 }, d); 310 311 d.bindings = SpiderGL.Model.Model._fixDescriptorSemanticBindings (d.bindings); 312 d.chunks = SpiderGL.Model.Model._fixDescriptorSemanticChunks (d.chunks); 313 314 return d; 315 }; 316 317 SpiderGL.Model.Model._fixDescriptorSemanticBindings = function (d) { 318 d = SpiderGL.Utility.getDefaultObject({ }, d); 319 for (var x in d) { 320 d[x] = SpiderGL.Model.Model._fixDescriptorSemanticBinding(d[x]); 321 } 322 return d; 323 }; 324 325 SpiderGL.Model.Model._fixDescriptorSemanticBinding = function (d) { 326 d = SpiderGL.Utility.getDefaultObject({ 327 vertexStreams : null, 328 primitiveStreams : null 329 }, d); 330 331 d.vertexStreams = SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStreams (d.vertexStreams); 332 d.primitiveStreams = SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStreams (d.primitiveStreams); 333 334 return d; 335 }; 336 337 SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStreams = function (d) { 338 d = SpiderGL.Utility.getDefaultObject({ }, d); 339 for (var x in d) { 340 d[x] = SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStream(d[x]); 341 } 342 return d; 343 }; 344 345 SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStream = function (d) { 346 if (!d) return null; 347 if (SpiderGL.Type.isArray(d)) return d.slice(); 348 return [ d ]; 349 }; 350 351 SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStreams = function (d) { 352 d = SpiderGL.Utility.getDefaultObject({ }, d); 353 for (var x in d) { 354 d[x] = SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStream(d[x]); 355 } 356 return d; 357 }; 358 359 SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStream = function (d) { 360 if (!d) return null; 361 if (SpiderGL.Type.isArray(d)) return d.slice(); 362 return [ d ]; 363 }; 364 365 SpiderGL.Model.Model._fixDescriptorSemanticChunks = function (d) { 366 d = SpiderGL.Utility.getDefaultObject({ }, d); 367 for (var x in d) { 368 d[x] = SpiderGL.Model.Model._fixDescriptorSemanticChunk(d[x]); 369 } 370 return d; 371 }; 372 373 SpiderGL.Model.Model._fixDescriptorSemanticChunk = function (d) { 374 d = SpiderGL.Utility.getDefaultObject({ 375 techniques : null 376 }, d); 377 378 d.techniques = SpiderGL.Model.Model._fixDescriptorSemanticChunkTechniques(d.techniques); 379 380 return d; 381 }; 382 383 SpiderGL.Model.Model._fixDescriptorSemanticChunkTechniques = function (d) { 384 d = SpiderGL.Utility.getDefaultObject({ }, d); 385 for (var x in d) { 386 d[x] = SpiderGL.Model.Model._fixDescriptorSemanticChunkTechnique(d[x]); 387 } 388 return d; 389 }; 390 391 SpiderGL.Model.Model._fixDescriptorSemanticChunkTechnique = function (d) { 392 d = SpiderGL.Utility.getDefaultObject({ 393 binding : null 394 }, d); 395 return d; 396 }; 397 398 SpiderGL.Model.Model._fixDescriptorLogic = function (d) { 399 d = SpiderGL.Utility.getDefaultObject({ 400 parts : null 401 }, d); 402 403 d.parts = SpiderGL.Model.Model._fixDescriptorLogicParts(d.parts); 404 405 return d; 406 }; 407 408 SpiderGL.Model.Model._fixDescriptorLogicParts = function (d) { 409 d = SpiderGL.Utility.getDefaultObject({ }, d); 410 for (var x in d) { 411 d[x] = SpiderGL.Model.Model._fixDescriptorLogicPart(d[x]); 412 } 413 return d; 414 }; 415 416 SpiderGL.Model.Model._fixDescriptorLogicPart = function (d) { 417 d = SpiderGL.Utility.getDefaultObject({ 418 chunks : null 419 }, d); 420 421 d.chunks = SpiderGL.Model.Model._fixDescriptorLogicPartChunks(d.chunks); 422 423 return d; 424 }; 425 426 SpiderGL.Model.Model._fixDescriptorLogicPartChunks = function (d) { 427 if (!d) return null; 428 if (SpiderGL.Type.isArray(d)) return d.slice(); 429 return [ d ]; 430 }; 431 432 SpiderGL.Model.Model._createSimpleDescriptor = function (options) { 433 options = SpiderGL.Utility.getDefaultObject({ 434 vertices : null, 435 primitives : null, 436 options : null 437 }, options); 438 439 var bindingName = "mainBinding"; 440 var chunkName = "mainChunk"; 441 var partName = "mainPart"; 442 var vertexBufferSuffix = "VertexBuffer"; 443 var indexBufferSuffix = "IndexBuffer"; 444 445 var d = { 446 data : { 447 vertexBuffers : { 448 }, 449 indexBuffers : { 450 }, 451 }, 452 access : { 453 vertexStreams : { 454 }, 455 primitiveStreams : { 456 } 457 }, 458 semantic : { 459 bindings : { 460 }, 461 chunks : { 462 } 463 }, 464 logic : { 465 parts : { 466 } 467 } 468 }; 469 470 var binding = { 471 vertexStreams : { 472 }, 473 primitiveStreams : { 474 } 475 }; 476 d.semantic.bindings[bindingName] = binding; 477 478 var chunk = { 479 techniques : { 480 "common" : { 481 binding : bindingName 482 } 483 } 484 }; 485 d.semantic.chunks[chunkName] = chunk; 486 487 var part = { 488 chunks : [ chunkName ] 489 }; 490 d.logic.parts[partName] = part; 491 492 var minBufferedCount = -1; 493 var hasBuffered = false; 494 var hasConstant = false; 495 496 for (var x in options.vertices) { 497 var src = options.vertices[x]; 498 if (!src) continue; 499 500 if (SpiderGL.Type.isArray(src) || SpiderGL.Type.isTypedArray(src) || SpiderGL.Type.instanceOf(src, ArrayBuffer)) { 501 src = { data : src }; 502 } 503 504 var map = SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP[x]; 505 var mapSemantic = null; 506 if (!map) { 507 map = SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP["user"]; 508 mapSemantic = x.toUpperCase(); 509 } 510 else { 511 mapSemantic = map.semantic; 512 } 513 514 var info = SpiderGL.Utility.getDefaultObject({ 515 size : map.size, 516 type : map.type, 517 normalized : map.normalized, 518 semantic : mapSemantic, 519 index : map.index, 520 data : null, 521 value : map.value.slice() 522 }, src); 523 524 var accessor = { 525 buffer : null, 526 size : info.size, 527 type : info.type, 528 normalized : info.normalized, 529 stride : 0, 530 offset : 0, 531 value : info.value.slice(), 532 }; 533 534 if (info.data) { 535 var buffer = { 536 type : info.type 537 }; 538 var count = 0; 539 if (SpiderGL.Type.isArray(info.data)) { 540 buffer.untypedArray = info.data; 541 count = buffer.untypedArray.length / accessor.size; 542 } 543 else if (SpiderGL.Type.isTypedArray(src) || SpiderGL.Type.instanceOf(src, ArrayBuffer)) { 544 buffer.typedArray = info.data; 545 count = (buffer.typedArray.byteLength - accessor.offset) / (accessor.size * SpiderGL.Type.typeSize(accessor.type)); 546 } 547 else { 548 continue; 549 } 550 count = SpiderGL.Math.floor(count); 551 hasBuffered = true; 552 minBufferedCount = (minBufferedCount >= 0) ? (SpiderGL.Math.min(minBufferedCount, count)) : (count); 553 var bufferName = x + vertexBufferSuffix; 554 d.data.vertexBuffers[bufferName] = buffer; 555 accessor.buffer = bufferName; 556 } 557 else { 558 hasConstant = true; 559 } 560 561 var streamName = x; 562 d.access.vertexStreams[streamName] = accessor; 563 564 var streams = new Array(info.index + 1); 565 streams[info.index] = streamName; 566 binding.vertexStreams[info.semantic] = streams; 567 } 568 569 var minCount = 0; 570 if (hasBuffered) { 571 minCount = minBufferedCount; 572 } 573 else if (hasConstant) { 574 minCount = 1; 575 } 576 577 var optionsPrimitives = options.primitives; 578 if (SpiderGL.Type.isString(optionsPrimitives)) { 579 optionsPrimitives = [ optionsPrimitives ]; 580 } 581 if (SpiderGL.Type.isArray(optionsPrimitives)) { 582 var op = optionsPrimitives; 583 optionsPrimitives = { }; 584 for (var i=0, n=op.length; i<n; ++i) { 585 var pn = op[i]; 586 if (!SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP[pn]) continue; 587 optionsPrimitives[pn] = { }; 588 } 589 } 590 591 for (var x in optionsPrimitives) { 592 var src = optionsPrimitives[x]; 593 if (!src) continue; 594 595 if (SpiderGL.Type.isArray(src) || SpiderGL.Type.isTypedArray(src) || SpiderGL.Type.instanceOf(src, ArrayBuffer)) { 596 src = { data : src }; 597 } 598 599 var map = SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP[x]; 600 if (!map) map = SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP["user"]; 601 602 var info = SpiderGL.Utility.getDefaultObject({ 603 mode : map.mode, 604 type : map.type, 605 count : ((map.count >= 0) ? (map.count) : (minCount)), 606 semantic : map.semantic 607 }, src); 608 609 var accessor = { 610 buffer : null, 611 mode : info.mode, 612 first : 0, 613 count : info.count, 614 type : info.type, 615 offset : 0 616 }; 617 618 if (info.data) { 619 var buffer = { 620 type : info.type 621 }; 622 var count = 0 623 if (SpiderGL.Type.isArray(info.data)) { 624 buffer.untypedArray = info.data; 625 count = buffer.untypedArray.length; 626 } 627 else if (SpiderGL.Type.isTypedArray(src) || SpiderGL.Type.instanceOf(src, ArrayBuffer)) { 628 buffer.typedArray = info.data; 629 count = (buffer.typedArray.byteLength - accessor.offset) / (SpiderGL.Type.typeSize(accessor.type)); 630 } 631 else { 632 continue; 633 } 634 count = SpiderGL.Math.floor(count); 635 var bufferName = x + indexBufferSuffix; 636 d.data.indexBuffers[bufferName] = buffer; 637 accessor.buffer = bufferName; 638 accessor.count = count; 639 } 640 641 var streamName = x; 642 d.access.primitiveStreams[streamName] = accessor; 643 644 var streams = new Array(1); 645 streams[0] = streamName; 646 binding.primitiveStreams[info.semantic] = streams; 647 } 648 649 return d; 650 }; 651 652 SpiderGL.Model.Model.prototype = { 653 get descriptor() { 654 return this._descriptor; 655 }, 656 657 get isReady() { 658 return !!this._descriptor; 659 }, 660 661 get gl() { 662 return this._gl; 663 }, 664 665 get renderData() { 666 return this._renderData; 667 }, 668 669 updateTypedArrays : function () { 670 var d = this._descriptor; 671 if (!d) return false; 672 673 var buffer = null; 674 var ctor = null; 675 676 var vertexBuffers = d.data.vertexBuffers; 677 for (var x in vertexBuffers) { 678 buffer = vertexBuffers[x]; 679 if (!buffer.untypedArray) continue; 680 ctor = SpiderGL.Type.typeToTypedArrayConstructor(buffer.type); 681 buffer.typedArray = new ctor(buffer.untypedArray); 682 } 683 684 var indexBuffers = d.data.indexBuffers; 685 for (var x in indexBuffers) { 686 buffer = indexBuffers[x]; 687 if (!buffer.untypedArray) continue; 688 ctor = SpiderGL.Type.typeToTypedArrayConstructor(buffer.type); 689 buffer.typedArray = new ctor(buffer.untypedArray); 690 } 691 692 return true; 693 }, 694 695 updateGL : function (gl, options) { 696 if (!gl) return false; 697 698 var d = this._descriptor; 699 if (!d) return false; 700 701 this._gl = gl; 702 703 var buffer = null; 704 var typedArray = null; 705 var ctor = null; 706 707 var bufferOptions = SpiderGL.Utility.getDefaultObject({ 708 data : null, 709 usage : SpiderGL.Core.DEFAULT 710 }, options); 711 bufferOptions.data = null; 712 713 for (var x in d.data.vertexBuffers) { 714 buffer = d.data.vertexBuffers[x]; 715 bufferOptions.data = buffer.typedArray; 716 if (!bufferOptions.data) { 717 ctor = SpiderGL.Type.typeToTypedArrayConstructor(buffer.type); 718 bufferOptions.data = new ctor(buffer.untypedArray); 719 } 720 if (buffer.glBuffer) { 721 buffer.glBuffer.destroy(); 722 buffer.glBuffer = null; 723 } 724 buffer.glBuffer = new SpiderGL.WebGL.VertexBuffer(gl, bufferOptions); 725 } 726 727 for (var x in d.data.indexBuffers) { 728 buffer = d.data.indexBuffers[x]; 729 bufferOptions.data = buffer.typedArray; 730 if (!bufferOptions.data) { 731 ctor = SpiderGL.Type.typeToTypedArrayConstructor(buffer.type); 732 bufferOptions.data = new ctor(buffer.untypedArray); 733 } 734 if (buffer.glBuffer) { 735 buffer.glBuffer.destroy(); 736 buffer.glBuffer = null; 737 } 738 buffer.glBuffer = new SpiderGL.WebGL.IndexBuffer(gl, bufferOptions); 739 } 740 741 var stream = null; 742 743 for (var x in d.access.vertexStreams) { 744 stream = d.access.vertexStreams[x]; 745 stream.glType = SpiderGL.Type.typeToGL(stream.type); 746 } 747 748 for (var x in d.access.primitiveStreams) { 749 stream = d.access.primitiveStreams[x]; 750 stream.glMode = SpiderGL.Type.primitiveToGL(stream.mode); 751 stream.glType = SpiderGL.Type.typeToGL(stream.type); 752 } 753 754 return true; 755 }, 756 757 destroyGL : function () { 758 var d = this._descriptor; 759 if (!d) return false; 760 761 var buffer = null; 762 763 for (var x in d.data.vertexBuffers) { 764 buffer = d.data.vertexBuffers[x]; 765 if (buffer.glBuffer) { 766 buffer.glBuffer.destroy(); 767 buffer.glBuffer = null; 768 } 769 } 770 771 for (var x in d.data.indexBuffers) { 772 buffer = d.data.indexBuffers[x]; 773 if (buffer.glBuffer) { 774 buffer.glBuffer.destroy(); 775 buffer.glBuffer = null; 776 } 777 } 778 }, 779 780 updateRenderData : function () { 781 var d = this._descriptor; 782 if (!d) return false; 783 784 var renderData = { 785 partMap : { } 786 }; 787 788 for (var partName in d.logic.parts) { 789 var part = d.logic.parts[partName]; 790 var chunkNames = part.chunks; 791 var partInfo = { }; 792 renderData.partMap[partName] = partInfo; 793 794 for (var i=0, n=chunkNames.length; i<n; ++i) { 795 var chunkName = chunkNames[i]; 796 var chunk = d.semantic.chunks[chunkName]; 797 var chunkInfo = { }; 798 partInfo[chunkName] = chunkInfo; 799 800 var techniques = chunk.techniques; 801 for (var techniqueName in techniques) { 802 var techique = techniques[techniqueName]; 803 var techiqueInfo = { 804 vertexStreams : { 805 buffered : [ ], 806 constant : [ ] 807 }, 808 primitiveStreams : { } 809 }; 810 chunkInfo[techniqueName] = techiqueInfo; 811 812 var binding = d.semantic.bindings[techique.binding]; 813 814 var streams = binding.vertexStreams; 815 var bufferMap = { }; 816 for (var semantic in streams) { 817 var streamNames = streams[semantic]; 818 for (var j=0, m=streamNames.length; j<m; ++j) { 819 var streamName = streamNames[j]; 820 var stream = d.access.vertexStreams[streamName]; 821 var streamInfo = { 822 semantic : semantic, 823 index : j, 824 stream : stream 825 } 826 var bufferName = stream.buffer; 827 if (bufferName) { 828 bufferMap[bufferName] = bufferMap[bufferName] || [ ]; 829 bufferMap[bufferName].push(streamInfo); 830 } 831 else { 832 techiqueInfo.vertexStreams.constant.push(streamInfo); 833 } 834 } 835 } 836 for (var bufferName in bufferMap) { 837 var bufferInfo = { 838 buffer : d.data.vertexBuffers[bufferName], 839 streams : bufferMap[bufferName].slice() 840 }; 841 techiqueInfo.vertexStreams.buffered.push(bufferInfo); 842 } 843 844 var streams = binding.primitiveStreams; 845 for (var semantic in streams) { 846 var bufferMap = { }; 847 var primitiveStreamsInfo = { 848 buffered : [ ], 849 array : [ ] 850 }; 851 techiqueInfo.primitiveStreams[semantic] = primitiveStreamsInfo; 852 853 var streamNames = streams[semantic]; 854 for (var j=0, m=streamNames.length; j<m; ++j) { 855 var streamName = streamNames[j]; 856 var stream = d.access.primitiveStreams[streamName]; 857 var bufferName = stream.buffer; 858 if (bufferName) { 859 bufferMap[bufferName] = bufferMap[bufferName] || [ ]; 860 bufferMap[bufferName].push(stream); 861 } 862 else { 863 primitiveStreamsInfo.array.push(stream); 864 } 865 } 866 for (var bufferName in bufferMap) { 867 var bufferInfo = { 868 buffer : d.data.indexBuffers[bufferName], 869 streams : bufferMap[bufferName].slice() 870 }; 871 primitiveStreamsInfo.buffered.push(bufferInfo); 872 } 873 } 874 } 875 } 876 } 877 878 this._renderData = renderData; 879 } 880 }; 881 882 SpiderGL.Type.extend(SpiderGL.Model.Model, SpiderGL.Core.ObjectBase); 883 884 /** 885 * Creates a SpiderGL.Model.Technique. 886 * 887 * @class The SpiderGL.Model.Technique handles the way a model is drawn. 888 * 889 * @augments SpiderGL.Core.ObjectBase 890 */ 891 SpiderGL.Model.Technique = function (gl, descriptor, options) { 892 SpiderGL.Core.ObjectBase.call(this); 893 894 options = SpiderGL.Utility.getDefaultObject({ 895 }, options); 896 897 if (descriptor && ("vertexShader" in descriptor) && ("fragmentShader" in descriptor)) { 898 descriptor = SpiderGL.Model.Technique._createSimpleDescriptor(gl, descriptor); 899 } 900 901 this._descriptor = SpiderGL.Model.Technique._fixDescriptor(descriptor); 902 this._gl = this._descriptor.program.gl; 903 this._renderData = { }; 904 905 if (gl) { 906 this.updateRenderData(); 907 } 908 }; 909 910 SpiderGL.Model.Technique._fixDescriptor = function (d) { 911 d = SpiderGL.Utility.getDefaultObject({ 912 name : "common", 913 program : null, 914 semantic : { } 915 }, d); 916 917 if (d.vertexStreams) { 918 d.semantic.vertexStreams = d.vertexStreams; 919 delete d.vertexStreams; 920 } 921 922 if (d.globals) { 923 d.semantic.globals = d.globals; 924 delete d.globals; 925 } 926 927 d.semantic = SpiderGL.Model.Technique._fixSemantic(d.program, d.semantic); 928 929 return d; 930 }; 931 932 SpiderGL.Model.Technique._fixSemantic = function (p, d) { 933 d = SpiderGL.Utility.getDefaultObject({ 934 vertexStreams : null, 935 globals : null 936 }, d); 937 938 d.vertexStreams = SpiderGL.Model.Technique._fixVertexStreams (p, d.vertexStreams); 939 d.globals = SpiderGL.Model.Technique._fixGlobals (p, d.globals); 940 941 return d; 942 }; 943 944 SpiderGL.Model.Technique._fixVertexStreams = function (p, d) { 945 var num = "0123456789"; 946 //var lwr = "abcdefghijklmnopqrstuvwxyz"; 947 //var upr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 948 949 var attribNames = p.getAttributesNames(); 950 var requiredAttribs = { }; 951 for (var i=0, n=attribNames.length; i<n; ++i) { 952 var attribName = attribNames[i]; 953 954 var semanticStr = ""; 955 var indexStr = ""; 956 957 for (var j=attribName.length-1; j>=0; --j) { 958 var ch = attribName.charAt(j); 959 if (num.indexOf(ch, 0) == -1) { 960 semanticStr = attribName.substring(0, j + 1); 961 break; 962 } 963 indexStr = ch + indexStr; 964 } 965 var index = ((indexStr.length > 0) ? (parseInt(indexStr)) : (0)); 966 967 var len = semanticStr.length; 968 if (len >= 2) { 969 if (semanticStr.charAt(0) == "a") { 970 var ch = semanticStr.charAt(1); 971 if ((ch == "_") && (len > 2)) { 972 semanticStr = semanticStr.substring(2); 973 } 974 else if (ch == semanticStr.charAt(1).toUpperCase()) { 975 semanticStr = semanticStr.substring(1); 976 } 977 } 978 } 979 var semantic = semanticStr.toUpperCase(); 980 requiredAttribs[attribName] = { 981 semantic : semantic, 982 index : index, 983 value : [0.0, 0.0, 0.0, 1.0] 984 }; 985 } 986 987 var dd = { }; 988 for (var x in d) { 989 var r = requiredAttribs[x]; 990 if (!r) continue; 991 992 var s = d[x]; 993 if (SpiderGL.Type.isString(s)) { 994 s = { semantic : s }; 995 } 996 else if (SpiderGL.Type.isArray(s) || SpiderGL.Type.isTypedArray(s)) { 997 s = { value : s }; 998 } 999 else if (SpiderGL.Type.isNumber(s)) { 1000 s = { value : [s, s, s, s] }; 1001 } 1002 dd[x] = SpiderGL.Utility.getDefaultObject({ 1003 semantic : r.semantic, 1004 index : r.index, 1005 value : r.value 1006 }, s); 1007 } 1008 1009 d = SpiderGL.Utility.getDefaultObject(requiredAttribs, dd); 1010 return d; 1011 }; 1012 1013 SpiderGL.Model.Technique._fixGlobals = function (p, d) { 1014 var uniformValues = p.getUniformsValues(); 1015 var requiredUniforms = { }; 1016 for (var uniformName in uniformValues) { 1017 var semanticStr = uniformName; 1018 var len = semanticStr.length; 1019 if (len >= 2) { 1020 if (semanticStr.charAt(0) == "u") { 1021 var ch = semanticStr.charAt(1); 1022 if ((ch == "_") && (len > 2)) { 1023 semanticStr = semanticStr.substring(2); 1024 } 1025 else if (ch == semanticStr.charAt(1).toUpperCase()) { 1026 semanticStr = semanticStr.substring(1); 1027 } 1028 } 1029 } 1030 var semantic = semanticStr.toUpperCase(); 1031 requiredUniforms[uniformName] = { 1032 semantic : semantic, 1033 value : uniformValues[uniformName] 1034 }; 1035 }; 1036 1037 d = SpiderGL.Utility.getDefaultObject(requiredUniforms, d); 1038 return d; 1039 }; 1040 1041 SpiderGL.Model.Technique._createSimpleDescriptor = function (gl, options) { 1042 options = SpiderGL.Utility.getDefaultObject({ 1043 name : "common", 1044 vertexShader : null, 1045 fragmentShader : null, 1046 attributes : null, 1047 uniforms : null, 1048 semantic : { }, 1049 vertexStreams : null, 1050 globals : null, 1051 options : null 1052 }, options); 1053 1054 if (options.vertexStreams) { 1055 options.semantic.vertexStreams = options.vertexStreams; 1056 delete options.vertexStreams; 1057 } 1058 1059 if (options.globals) { 1060 options.semantic.globals = options.globals; 1061 delete options.globals; 1062 } 1063 1064 var d = { 1065 name : options.name, 1066 program : null, 1067 semantic : options.semantic 1068 }; 1069 1070 if (!gl) { 1071 return d; 1072 } 1073 1074 var vertexShader = options.vertexShader; 1075 var fragmentShader = options.fragmentShader; 1076 1077 if (!vertexShader || !fragmentShader) { 1078 return d; 1079 } 1080 1081 if (SpiderGL.Type.isString(vertexShader)) { 1082 vertexShader = new SpiderGL.WebGL.VertexShader(gl, vertexShader); 1083 } 1084 else if (!SpiderGL.Type.instanceOf(vertexShader, SpiderGL.WebGL.VertexShader)) { 1085 return d; 1086 } 1087 1088 if (SpiderGL.Type.isString(fragmentShader)) { 1089 fragmentShader = new SpiderGL.WebGL.FragmentShader(gl, fragmentShader); 1090 } 1091 else if (!SpiderGL.Type.instanceOf(fragmentShader, SpiderGL.WebGL.FragmentShader)) { 1092 return d; 1093 } 1094 1095 var program = new SpiderGL.WebGL.Program(gl, { 1096 shaders : [ vertexShader, fragmentShader ], 1097 attributes : options.attributes, 1098 uniforms : options.uniforms 1099 }); 1100 1101 d.program = program; 1102 1103 return d; 1104 }; 1105 1106 SpiderGL.Model.Technique.prototype = { 1107 get descriptor() { 1108 return this._descriptor; 1109 }, 1110 1111 get isReady() { 1112 return !!this._descriptor; 1113 }, 1114 1115 get gl() { 1116 return this._gl; 1117 }, 1118 1119 get name() { 1120 return this._descriptor.name; 1121 }, 1122 1123 get renderData() { 1124 return this._renderData; 1125 }, 1126 1127 get program() { 1128 return this._descriptor.program; 1129 }, 1130 1131 setUniforms : function (uniforms) { 1132 this._descriptor.program.setUniforms(uniforms); 1133 }, 1134 1135 updateRenderData : function () { 1136 var d = this._descriptor; 1137 1138 var renderData = { }; 1139 this._renderData = renderData; 1140 1141 var attributesMap = { }; 1142 renderData.attributesMap = attributesMap; 1143 var attributesIndices = d.program.getAttributesIndices(); 1144 for (var attribName in d.semantic.vertexStreams) { 1145 var semanticInfo = d.semantic.vertexStreams[attribName]; 1146 var semanticName = semanticInfo.semantic; 1147 var attribs = attributesMap[semanticName]; 1148 if (!attribs) { 1149 attribs = [ ]; 1150 attributesMap[semanticName] = attribs; 1151 } 1152 attribs[semanticInfo.index] = { 1153 index : attributesIndices[attribName], 1154 value : semanticInfo.value 1155 }; 1156 } 1157 1158 var globalsMap = { }; 1159 renderData.globalsMap = globalsMap; 1160 for (var uniformName in d.semantic.globals) { 1161 var semanticInfo = d.semantic.globals[uniformName]; 1162 globalsMap[semanticInfo.semantic] = { 1163 name : uniformName, 1164 value : semanticInfo.value 1165 }; 1166 } 1167 } 1168 }; 1169 1170 /** 1171 * Creates a SpiderGL.Model.Technique. 1172 * 1173 * @class The SpiderGL.Model.Technique handles the way a model is drawn. 1174 * 1175 * @augments SpiderGL.Core.ObjectBase 1176 */ 1177 SpiderGL.Model.ModelRenderer = function (gl) { 1178 this._gl = gl; 1179 this._vertexAttributesCount = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); 1180 this._textureUnitsCount = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 1181 this._internalFramebuffer = new SpiderGL.WebGL.Framebuffer(gl); 1182 this._reset(); 1183 }; 1184 1185 SpiderGL.Model.ModelRenderer.prototype = { 1186 _reset : function () { 1187 this._technique = null; 1188 this._model = null; 1189 this._partName = null; 1190 this._chunkName = null; 1191 this._primMode = null; 1192 this._framebuffer = null; 1193 1194 this._inBegin = false; 1195 1196 this._enabledArrays = [ ]; 1197 this._boundTextures = [ ]; 1198 this._attribValues = [ ]; 1199 this._primitiveStreams = [ ]; 1200 1201 this._techniqueDirty = true; 1202 this._modelDirty = true; 1203 this._modelPartDirty = true; 1204 this._modelChunkDirty = true; 1205 this._primModeDirty = true; 1206 this._framebufferDirty = true; 1207 this._viewportDirty = true; 1208 1209 this._dirty = true; 1210 }, 1211 1212 _resetContext : function () { 1213 var gl = this._gl; 1214 1215 for (var i=0, n=this._vertexAttributesCount; i<n; ++i) { 1216 gl.disableVertexAttribArray(i); 1217 } 1218 1219 for (var i=this._textureUnitsCount-1; i>=0; --i) { 1220 gl.activeTexture(gl.TEXTURE0 + i); 1221 gl.bindTexture(gl.TEXTURE_2D, null); 1222 gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); 1223 } 1224 1225 SpiderGL.WebGL.VertexBuffer .unbind(gl); 1226 SpiderGL.WebGL.IndexBuffer .unbind(gl); 1227 SpiderGL.WebGL.Program .unbind(gl); 1228 SpiderGL.WebGL.Framebuffer .unbind(gl); 1229 }, 1230 1231 _update : function () { 1232 if (!this._dirty) return true; 1233 1234 var gl = this._gl; 1235 1236 if (this._techniqueDirty) { 1237 var technique = this._technique; 1238 if (!technique) return false; 1239 1240 var techniqueRenderData = technique.renderData; 1241 var attributesMap = techniqueRenderData.attributesMap; 1242 var attribValues = [ ]; 1243 for (var semantic in attributesMap) { 1244 var attribs = attributesMap[semantic]; 1245 for (var i in attribs) { 1246 var attribInfo = attribs[i]; 1247 var attribData = null; 1248 if (attribInfo) { 1249 attribData = { 1250 index : attribInfo.index, 1251 value : attribInfo.value 1252 }; 1253 } 1254 attribValues.push(attribData); 1255 } 1256 } 1257 this._attribValues = attribValues; 1258 1259 technique.program.bind(); 1260 1261 this._techniqueDirty = false; 1262 } 1263 1264 if (this._modelDirty) { 1265 var model = this._model; 1266 if (!model) return false; 1267 1268 // default vertex attributes 1269 ////////////// 1270 var attribValues = this._attribValues; 1271 for (var i=0, n=attribValues.length; i<n; ++i) { 1272 var attribData = attribValues[i]; 1273 if (!attribData) continue; 1274 gl.vertexAttrib4fv(attribData.index, attribData.value); 1275 } 1276 ////////////// 1277 1278 var modelRenderData = model.renderData; 1279 1280 var technique = this._technique; 1281 if (!technique) return false; 1282 1283 var techniqueRenderData = technique.renderData; 1284 if (!techniqueRenderData) return false; 1285 var attributesMap = techniqueRenderData.attributesMap; 1286 1287 if (this._modelPartDirty) { 1288 var partName = this._partName; 1289 if (!partName) return false; 1290 this._modelPartDirty = false; 1291 } 1292 1293 if (this._modelChunkDirty) { 1294 var chunkName = this._chunkName; 1295 if (!chunkName) return false; 1296 1297 var partInfo = modelRenderData.partMap[this._partName]; 1298 if (!partInfo) return false; 1299 1300 var chunkInfo = partInfo[chunkName]; 1301 if (!chunkInfo) return false; 1302 1303 var techniqueInfo = chunkInfo[technique.name]; 1304 if (!techniqueInfo) { 1305 techniqueInfo = chunkInfo["common"]; 1306 } 1307 if (!techniqueInfo) return false; 1308 1309 // buffered vertex streams 1310 ////////////// 1311 var enabledArrays = this._enabledArrays; 1312 for (var i=0, n=enabledArrays.length; i<n; ++i) { 1313 gl.disableVertexAttribArray(enabledArrays[i]); 1314 } 1315 enabledArrays = [ ]; 1316 var streams = techniqueInfo.vertexStreams.buffered; 1317 for (var i=0, n=streams.length; i<n; ++i) { 1318 var data = streams[i]; 1319 var buffer = data.buffer.glBuffer; 1320 buffer.bind(); 1321 1322 var infos = data.streams; 1323 for (var j=0, m=infos.length; j<m; ++j) { 1324 var info = infos[j]; 1325 if (!attributesMap[info.semantic] || !attributesMap[info.semantic][info.index]) continue; 1326 var index = attributesMap[info.semantic][info.index].index; 1327 var stream = info.stream; 1328 stream.index = index; 1329 enabledArrays.push(index); 1330 buffer.vertexAttribPointer(stream); 1331 //gl.enableVertexAttribArray(index); 1332 //gl.vertexAttribPointer(index, stream.size, stream.glType, stream.normalized, stream.stride, stream.offset); 1333 } 1334 } 1335 this._enabledArrays = enabledArrays; 1336 ////////////// 1337 1338 // constant vertex streams 1339 ////////////// 1340 var infos = techniqueInfo.vertexStreams.constant; 1341 for (var j=0, n=infos.length; j<n; ++j) { 1342 var info = infos[j]; 1343 if (!attributesMap[info.semantic] || !attributesMap[info.semantic][info.index]) continue; 1344 var index = attributesMap[info.semantic][info.index].index; 1345 var stream = info.stream; 1346 gl.vertexAttrib4fv(index, stream.value); 1347 } 1348 ////////////// 1349 1350 this._modelChunkDirty = false; 1351 } 1352 1353 if (this._primModeDirty) { 1354 var primMode = this._primMode; 1355 if (!primMode) return false; 1356 1357 var partInfo = modelRenderData.partMap[this._partName]; 1358 if (!partInfo) return false; 1359 1360 var chunkInfo = partInfo[this._chunkName]; 1361 if (!chunkInfo) return false; 1362 1363 var techniqueInfo = chunkInfo[technique.name]; 1364 if (!techniqueInfo) { 1365 techniqueInfo = chunkInfo["common"]; 1366 } 1367 if (!techniqueInfo) return false; 1368 1369 var primitiveStreams = techniqueInfo.primitiveStreams[primMode]; 1370 if (!primitiveStreams) return false; 1371 1372 // primitive streams 1373 ///////////////////////////////////////////////// 1374 this._primitiveStreams = primitiveStreams; 1375 1376 this._primModeDirty = false; 1377 } 1378 1379 this._modelDirty = false; 1380 } 1381 1382 if (this._framebufferDirty) { 1383 if (this._framebuffer) { 1384 this._framebuffer.bind(); 1385 } 1386 else { 1387 SpiderGL.WebGL.Framebuffer.unbind(gl); 1388 } 1389 this._framebufferDirty = false; 1390 } 1391 1392 if (this._viewportDirty) { 1393 if (this._framebuffer) { 1394 if (this._framebuffer.autoViewport) { 1395 this._framebuffer.applyViewport(); 1396 } 1397 } 1398 this._viewportDirty = false; 1399 } 1400 1401 this._dirty = false; 1402 1403 return true; 1404 }, 1405 1406 get gl() { 1407 return this._gl; 1408 }, 1409 1410 get isValid() { 1411 return (!!this._gl); 1412 }, 1413 1414 destroy : function () { 1415 this.end(); 1416 this._internalFramebuffer.destroy(); 1417 this._internalFramebuffer = null; 1418 this._gl = null; 1419 }, 1420 1421 begin : function () { 1422 if (this._inBegin) return; 1423 this._resetContext(); 1424 this._inBegin = true; 1425 }, 1426 1427 end : function () { 1428 if (!this._inBegin) return; 1429 this._inBegin = false; 1430 var gl = this._gl; 1431 1432 var enabledArrays = this._enabledArrays; 1433 for (var i=0, n=enabledArrays.length; i<n; ++i) { 1434 gl.disableVertexAttribArray(enabledArrays[i]); 1435 } 1436 1437 var boundTextures = this._boundTextures; 1438 for (var i=0, n=boundTextures.length; i<n; ++i) { 1439 var tex = boundTextures[i]; 1440 if (!tex) continue; 1441 if (tex.target == gl.TEXTURE_2D) { 1442 SpiderGL.WebGL.Texture2D.unbind(gl, tex.unit); 1443 } 1444 else if (tex.target == gl.TEXTURE_CUBE_MAP) { 1445 SpiderGL.WebGL.TextureCubeMap.unbind(gl, tex.unit); 1446 } 1447 } 1448 1449 if (this._framebuffer) { 1450 SpiderGL.WebGL.Framebuffer.unbind(this._gl); 1451 } 1452 1453 this._internalFramebuffer.detachAll(); 1454 1455 this._reset(); 1456 this._resetContext(); 1457 }, 1458 1459 get isInBegin() { 1460 return this._inBegin; 1461 }, 1462 1463 setTechnique : function (t) { 1464 if (!this._inBegin) return; 1465 if (this._technique == t) return; 1466 this._technique = t; 1467 this._techniqueDirty = true; 1468 this._dirty = true; 1469 1470 if (!t) { 1471 SpiderGL.WebGL.Program.unbind(this._gl); 1472 } 1473 }, 1474 1475 get technique() { 1476 return this._technique; 1477 }, 1478 1479 setModel : function (m) { 1480 if (!this._inBegin) return; 1481 if (this._model == m) return; 1482 this._model = m; 1483 this._modelDirty = true; 1484 this._modelPartDirty = true; 1485 this._modelChunkDirty = true; 1486 this._dirty = true; 1487 }, 1488 1489 get model() { 1490 return this._model; 1491 }, 1492 1493 setPart : function (p) { 1494 if (!this._inBegin) return; 1495 if (this._part == p) return; 1496 this._partName = p; 1497 this._modelPartDirty = true; 1498 this._modelDirty = true; 1499 this._dirty = true; 1500 }, 1501 1502 get part() { 1503 return this._partName; 1504 }, 1505 1506 setChunk : function (c) { 1507 if (!this._inBegin) return; 1508 if (this._chunk == c) return; 1509 this._chunkName = c; 1510 this._modelDirty = true; 1511 this._modelChunkDirty = true; 1512 this._primModeDirty = true; 1513 this._dirty = true; 1514 }, 1515 1516 get chunk() { 1517 return this._chunkName; 1518 }, 1519 1520 setPrimitiveMode : function (m) { 1521 if (!this._inBegin) return; 1522 if (this._primMode == m) return; 1523 this._primMode = m; 1524 this._primModeDirty = true; 1525 this._modelDirty = true; 1526 this._dirty = true; 1527 }, 1528 1529 get primitiveMode() { 1530 return this._primMode; 1531 }, 1532 1533 setUniforms : function (u) { 1534 if (!this._inBegin) return; 1535 if (!this._technique) return; 1536 this._technique.program.setUniforms(u); 1537 }, 1538 1539 setDefaultGlobals : function () { 1540 if (!this._inBegin) return; 1541 1542 var technique = this._technique; 1543 if (!technique) return; 1544 1545 var globalsMap = technique.renderData.globalsMap; 1546 var uniforms = { }; 1547 for (var semantic in globalsMap) { 1548 var uniformName = globalsMap[semantic].name; 1549 var uniformValue = globalsMap[semantic].value; 1550 uniforms[uniformName] = uniformValue; 1551 } 1552 1553 technique.program.setUniforms(uniforms); 1554 }, 1555 1556 setGlobals : function (g) { 1557 if (!this._inBegin) return; 1558 if (!g) return; 1559 1560 var technique = this._technique; 1561 if (!technique) return; 1562 1563 var globalsMap = technique.renderData.globalsMap; 1564 var uniforms = { }; 1565 for (var semantic in g) { 1566 if (!globalsMap[semantic]) continue; 1567 var uniformName = globalsMap[semantic].name; 1568 var uniformValue = g[semantic]; 1569 uniforms[uniformName] = uniformValue; 1570 } 1571 1572 technique.program.setUniforms(uniforms); 1573 }, 1574 1575 setFramebuffer : function (fb) { 1576 if (!this._inBegin) return; 1577 1578 //this._internalFramebuffer.detachAll(); 1579 if (this._framebuffer == fb) return; 1580 1581 this._framebuffer = fb; 1582 this._framebufferDirty = true; 1583 this._viewportDirty = true; 1584 this._dirty = true; 1585 1586 if (fb) { 1587 fb.bind(); 1588 } 1589 else { 1590 SpiderGL.WebGL.Framebuffer.unbind(this._gl); 1591 } 1592 }, 1593 1594 activateOffScreenFramebuffer : function () { 1595 this.setFramebuffer(this._internalFramebuffer); 1596 }, 1597 1598 activateMainFramebuffer : function () { 1599 return this.setFramebuffer(null); 1600 }, 1601 1602 setFramebufferAttachments : function (attachments) { 1603 if (!this._inBegin) return; 1604 if (!this._framebuffer) return; 1605 this._framebuffer.setAttachments(attachments); 1606 this._framebufferDirty = true; 1607 this._viewportDirty = true; 1608 }, 1609 1610 setColorRenderTarget : function (rt) { 1611 if (!this._inBegin) return; 1612 if (!this._framebuffer) return; 1613 this._framebuffer.colorTarget = rt; 1614 this._viewportDirty = true; 1615 this._dirty = true; 1616 }, 1617 1618 setDepthRenderTarget : function (rt) { 1619 if (!this._inBegin) return; 1620 if (!this._framebuffer) return; 1621 this._framebuffer.depthTarget = rt; 1622 this._viewportDirty = true; 1623 this._dirty = true; 1624 }, 1625 1626 setStencilRenderTarget : function (rt) { 1627 if (!this._inBegin) return; 1628 if (!this._framebuffer) return; 1629 this._framebuffer.stencilTarget = rt; 1630 this._viewportDirty = true; 1631 this._dirty = true; 1632 }, 1633 1634 setDepthStencilRenderTarget : function (rt) { 1635 if (!this._inBegin) return; 1636 if (!this._framebuffer) return; 1637 this._framebuffer.depthStencilTarget = rt; 1638 this._viewportDirty = true; 1639 this._dirty = true; 1640 }, 1641 1642 clearFramebuffer : function (options) { 1643 if (!this._inBegin) return; 1644 if (!options) return; 1645 var gl = this._gl; 1646 var mask = 0; 1647 if (SpiderGL.Type.isNumber(options)) { 1648 mask = options; 1649 } 1650 else { 1651 if ("color" in options) { 1652 var color = options.color; 1653 if (color) { 1654 gl.clearColor(color[0], color[1], color[2], color[3]); 1655 } 1656 mask |= gl.COLOR_BUFFER_BIT; 1657 } 1658 if ("depth" in options) { 1659 var depth = options.depth; 1660 if (SpiderGL.Type.isNumber(depth)) { 1661 gl.clearDepth(depth); 1662 } 1663 mask |= gl.DEPTH_BUFFER_BIT; 1664 } 1665 if ("stencil" in options) { 1666 var stencil = options.stencil; 1667 if (SpiderGL.Type.isNumber(stencil)) { 1668 gl.clearStencil(stencil); 1669 } 1670 mask |= gl.Stencil_BUFFER_BIT; 1671 } 1672 } 1673 if (mask) { 1674 var fb = this._framebuffer; 1675 if (fb) { 1676 fb.clear(mask); 1677 } 1678 else { 1679 gl.clear(mask); 1680 } 1681 } 1682 }, 1683 1684 setViewport : function (x, y, width, height) { 1685 if (!this._inBegin) return; 1686 var gl = this._gl; 1687 gl.viewport(x, y, width, height); 1688 }, 1689 1690 setTexture : function (unit, texture) { 1691 if (texture) { 1692 texture.bind(unit); 1693 } 1694 else { 1695 var gl = this._gl; 1696 SpiderGL.WebGL.Texture2D.unbind(gl, unit); 1697 SpiderGL.WebGL.TextureCubeMap.unbind(gl, unit); 1698 } 1699 }, 1700 1701 get canRender() { 1702 return (!!this._inBegin && !!this._technique && !!this._model && !!this._partName && !!this._chunkName && !!this._primMode); 1703 }, 1704 1705 render : function () { 1706 if (!this.canRender) return; 1707 if (!this._update()) return; 1708 1709 var gl = this._gl; 1710 1711 var primitiveStreams = this._primitiveStreams; 1712 1713 var bufferedStreams = primitiveStreams.buffered; 1714 var arrayStreams = primitiveStreams.array; 1715 1716 // buffered 1717 ////////////// 1718 for (var i=0, n=bufferedStreams.length; i<n; ++i) { 1719 var data = bufferedStreams[i]; 1720 var buffer = data.buffer.glBuffer; 1721 buffer.bind(); 1722 1723 var infos = data.streams; 1724 for (var j=0, m=infos.length; j<m; ++j) { 1725 var stream = infos[j]; 1726 //gl.drawElements(stream.glMode, stream.count, stream.glType, stream.offset); 1727 buffer.drawElements(stream); 1728 } 1729 } 1730 ////////////// 1731 1732 // array 1733 ////////////// 1734 for (var j=0, n=arrayStreams.length; j<n; ++j) { 1735 var stream = arrayStreams[j]; 1736 gl.drawArrays(stream.glMode, stream.first, stream.count); 1737 } 1738 ////////////// 1739 }, 1740 1741 renderModelPart : function(partName) { 1742 var part = this.model.descriptor.logic.parts[partName]; 1743 this.setPart(partName); 1744 for (var c in part.chunks) { 1745 var chunkName = part.chunks[c]; 1746 this.setChunk(chunkName); 1747 this.render(); 1748 } 1749 }, 1750 1751 renderModel : function() { 1752 var parts = this.model.descriptor.logic.parts; 1753 for (var partName in parts) { 1754 var part = parts[partName]; 1755 this.setPart(partName); 1756 for (var c in part.chunks) { 1757 var chunkName = part.chunks[c]; 1758 this.setChunk(chunkName); 1759 this.render(); 1760 } 1761 } 1762 } 1763 }; 1764