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 WebGL 31 */ 32 33 /** 34 * The SpiderGL.WebGL namespace. 35 * 36 * @namespace The SpiderGL.WebGL namespace. 37 * 38 * The SpiderGL.WebGL namespace gives access to WebGL functionalities in terms of context creation and enhancement, and object wrappers. 39 * The main purpose of the module is to provide a robust and intuitive way of dealing with all native WebGL objects (e.g., textures, framebuffers, etc.). 40 * Each specialized wrapper handles creation/destruction, edit operations (i.e. parameter settings), and binding of the underlying native WebGL object (the GL handle). 41 * To allow low level access and integration with existing code, the native handle is exposed. On the other side, wrappers can be created for already existing native objects, 42 * ensuring that the same wrapper will be used for multiple wraps of the same object. 43 * To create a robust interoperability between wrapper usage and native WebGL calls on handles, wrappers must be informed whenever any single native call operates on the wrapped handle. 44 * SpiderGL handles this task by hijacking the WebGLRenderingContext object, and installing on it a set of extensions that use callback mechanisms to report changes to wrappers. 45 * Moreover, to overcome the bind-to-edit/bind-to-use paradigm typical of the OpenGL API family, SpiderGL injects an extension that is insired by GL_EXT_direct_state_access extension. 46 */ 47 SpiderGL.WebGL = { }; 48 49 /** 50 * The SpiderGL.WebGL.Context namespace. 51 * 52 * @namespace The SpiderGL.WebGL.Context namespace. 53 */ 54 SpiderGL.WebGL.Context = { }; 55 56 /** 57 * The string for obtaining a WebGLRenderingContext from a canvas. 58 * 59 * @constant 60 * 61 * @see SpiderGL.WebGL.Context.get 62 */ 63 SpiderGL.WebGL.Context.WEBGL_STRING = "experimental-webgl"; 64 65 /** 66 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL. 67 * 68 * @default true 69 * 70 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 71 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION 72 * @see SpiderGL.WebGL.Context.setStandardGLUnpack 73 */ 74 SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y = true; 75 76 /** 77 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL. 78 * 79 * @default true 80 * 81 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y 82 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION 83 * @see SpiderGL.WebGL.Context.setStandardGLUnpack 84 */ 85 SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA = false; 86 87 /** 88 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_COLORSPACE_CONVERSION_WEBGL. 89 * 90 * @default WebGLRenderingContext.NONE 91 * 92 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y 93 * @see SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 94 * @see SpiderGL.WebGL.Context.setStandardGLUnpack 95 */ 96 SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION = WebGLRenderingContext.NONE; 97 98 /** 99 * Retrieves the WebGLRenderingContext from a canvas. 100 * 101 * The WebGLRenderingContext is obtained by calling the getContext() method of the canvas object. 102 * 103 * @param {HTMLCanvasElement} canvas The HTMLCanvasElement from which retrieve the WebGL context. 104 * @param {object} args The optional WebGL context arguments. 105 * 106 * @returns {WebGLRenderingContext} The canvas WebGL rendering context. 107 * 108 * @see SpiderGL.WebGL.Context.hijack 109 * @see SpiderGL.WebGL.Context.getHijacked 110 */ 111 SpiderGL.WebGL.Context.get = function (canvas, args) { 112 var c = canvas; 113 if (SpiderGL.Type.isString(c)) { c = SpiderGL.DOM.getElementById(c); } 114 if (!SpiderGL.Type.instanceOf(c, HTMLCanvasElement)) { return null; } 115 var ctx = c.getContext(SpiderGL.WebGL.Context.WEBGL_STRING, args); 116 return ctx; 117 } 118 119 SpiderGL.WebGL.Context._prepareContex = function (gl) { 120 if (!gl) return; 121 122 var sgl = gl._spidergl; 123 if (sgl) return; 124 125 sgl = { }; 126 gl._spidergl = sgl; 127 sgl.TAG = 0; 128 sgl.gl = gl; 129 130 var glFunctions = { }; 131 sgl.glFunctions = glFunctions; 132 for (var f in gl) { 133 var fn = gl[fn]; 134 if (typeof fn == "function") { 135 glFunctions[f] = fn; 136 } 137 } 138 }; 139 140 SpiderGL.WebGL.Context._addExtension = function (gl, extName, propName, setupFunc) { 141 if (!gl) return; 142 143 var getExtension = gl.getExtension; 144 gl.getExtension = function (name) { 145 if (name == extName) { 146 var sgl = this._spidergl; 147 if (!sgl) return null; 148 var pubExt = sgl[propName]; 149 if (!pubExt) { 150 pubExt = { }; 151 152 pubExt.TAG = 0; 153 154 var ext = { }; 155 pubExt._ext = ext; 156 157 ext[propName] = pubExt; 158 ext.sgl = sgl; 159 ext.gl = gl; 160 161 var glFunctions = { }; 162 ext.glFunctions = glFunctions; 163 164 if (!setupFunc(gl, pubExt)) return null; 165 166 sgl[propName] = pubExt; 167 } 168 return pubExt; 169 } 170 return getExtension.call(this, name); 171 }; 172 }; 173 174 SpiderGL.WebGL.Context._setup_SGL_current_binding = function (gl, pubExt) { 175 if (!gl) return false; 176 if (!pubExt) return false; 177 if (!gl._spidergl) return false; 178 if (gl._spidergl.cb) return false; 179 180 var cb = pubExt; 181 var ext = cb._ext; 182 var glFunctions = ext.glFunctions; 183 184 185 186 // buffer 187 ////////////////////////////////////////////////////////////////////////////////////////// 188 ext.currentBuffer = { }; 189 ext.currentBuffer[gl.ARRAY_BUFFER ] = gl.getParameter(gl.ARRAY_BUFFER_BINDING); 190 ext.currentBuffer[gl.ELEMENT_ARRAY_BUFFER] = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING); 191 192 ext.bufferStack = { }; 193 ext.bufferStack[gl.ARRAY_BUFFER ] = [ ]; 194 ext.bufferStack[gl.ELEMENT_ARRAY_BUFFER] = [ ]; 195 196 glFunctions.bindBuffer = gl.bindBuffer; 197 gl.bindBuffer = function (target, buffer) { 198 var ext = this._spidergl.cb._ext; 199 var current = ext.currentBuffer[target]; 200 if (current == buffer) return; 201 ext.currentBuffer[target] = buffer; 202 ext.glFunctions.bindBuffer.call(this, target, buffer); 203 }; 204 205 cb.getCurrentBuffer = function (target) { 206 return this._ext.currentBuffer[target]; 207 }; 208 209 cb.pushBuffer = function (target) { 210 var ext = this._ext; 211 var stack = ext.bufferStack[target]; 212 var buffer = ext.currentBuffer[target]; 213 stack.push(buffer); 214 }; 215 216 cb.popBuffer = function (target) { 217 var ext = this._ext; 218 var stack = ext.bufferStack[target]; 219 if (stack.length <= 0) return; 220 var buffer = stack.pop(); 221 ext.gl.bindBuffer(target, buffer); 222 }; 223 ////////////////////////////////////////////////////////////////////////////////////////// 224 225 226 227 // framebuffer 228 ////////////////////////////////////////////////////////////////////////////////////////// 229 ext.currentFramebuffer = { }; 230 ext.currentFramebuffer[gl.FRAMEBUFFER] = gl.getParameter(gl.FRAMEBUFFER_BINDING); 231 232 ext.framebufferStack = { }; 233 ext.framebufferStack[gl.FRAMEBUFFER] = [ ]; 234 235 glFunctions.bindFramebuffer = gl.bindFramebuffer; 236 gl.bindFramebuffer = function (target, framebuffer) { 237 var ext = this._spidergl.cb._ext; 238 var current = ext.currentFramebuffer[target]; 239 if (current == framebuffer) return; 240 ext.currentFramebuffer[target] = framebuffer; 241 ext.glFunctions.bindFramebuffer.call(this, target, framebuffer); 242 }; 243 244 cb.getCurrentFramebuffer = function (target) { 245 return this._ext.currentFramebuffer[target]; 246 }; 247 248 cb.pushFramebuffer = function (target) { 249 var ext = this._ext; 250 var stack = ext.framebufferStack[target]; 251 var framebuffer = ext.currentFramebuffer[target]; 252 stack.push(framebuffer); 253 }; 254 255 cb.popFramebuffer = function (target) { 256 var ext = this._ext; 257 var stack = ext.framebufferStack[target]; 258 if (stack.length <= 0) return; 259 var framebuffer = stack.pop(); 260 ext.gl.bindFramebuffer(target, framebuffer); 261 }; 262 ////////////////////////////////////////////////////////////////////////////////////////// 263 264 265 266 // program 267 ////////////////////////////////////////////////////////////////////////////////////////// 268 ext.currentProgram = gl.getParameter(gl.CURRENT_PROGRAM); 269 270 ext.programStack = [ ]; 271 272 glFunctions.useProgram = gl.useProgram; 273 gl.useProgram = function (program) { 274 var ext = this._spidergl.cb._ext; 275 var current = ext.currentProgram; 276 if (current == program) return; 277 ext.currentProgram = program; 278 ext.glFunctions.useProgram.call(this, program); 279 }; 280 281 cb.getCurrentProgram = function () { 282 return this._ext.currentProgram; 283 }; 284 285 cb.pushProgram = function () { 286 var ext = this._ext; 287 var stack = ext.programStack; 288 var program = ext.currentProgram; 289 stack.push(program); 290 }; 291 292 cb.popProgram = function () { 293 var ext = this._ext; 294 var stack = ext.programStack; 295 if (stack.length <= 0) return; 296 var program = stack.pop(); 297 ext.gl.useProgram(program); 298 }; 299 ////////////////////////////////////////////////////////////////////////////////////////// 300 301 302 303 // renderbuffer 304 ////////////////////////////////////////////////////////////////////////////////////////// 305 ext.currentRenderbuffer = { }; 306 ext.currentRenderbuffer[gl.RENDERBUFFER] = gl.getParameter(gl.RENDERBUFFER_BINDING); 307 308 ext.renderbufferStack = { }; 309 ext.renderbufferStack[gl.RENDERBUFFER] = [ ]; 310 311 glFunctions.bindRenderbuffer = gl.bindRenderbuffer; 312 gl.bindRenderbuffer = function (target, renderbuffer) { 313 var ext = this._spidergl.cb._ext; 314 var current = ext.currentRenderbuffer[target]; 315 if (current == renderbuffer) return; 316 ext.currentRenderbuffer[target] = renderbuffer; 317 ext.glFunctions.bindRenderbuffer.call(this, target, renderbuffer); 318 }; 319 320 cb.getCurrentRenderbuffer = function (target) { 321 return this._ext.currentRenderbuffer[target]; 322 }; 323 324 cb.pushRenderbuffer = function (target) { 325 var ext = this._ext; 326 var stack = ext.renderbufferStack[target]; 327 var renderbuffer = ext.currentRenderbuffer[target]; 328 stack.push(renderbuffer); 329 }; 330 331 cb.popRenderbuffer = function (target) { 332 var ext = this._ext; 333 var stack = ext.renderbufferStack[target]; 334 if (stack.length <= 0) return; 335 var renderbuffer = stack.pop(); 336 ext.gl.bindRenderbuffer(target, renderbuffer); 337 }; 338 ////////////////////////////////////////////////////////////////////////////////////////// 339 340 341 342 // shader 343 ////////////////////////////////////////////////////////////////////////////////////////// 344 ext.currentShader = { }; 345 ext.currentShader[gl.VERTEX_SHADER ] = null; 346 ext.currentShader[gl.FRAGMENT_SHADER] = null; 347 348 ext.shaderStack = { }; 349 ext.shaderStack[gl.VERTEX_SHADER ] = [ ]; 350 ext.shaderStack[gl.FRAGMENT_SHADER] = [ ]; 351 352 ext.glFunctions.bindShader = function (target, shader) { }; 353 cb.bindShader = function (target, shader) { 354 var ext = this._ext; 355 var current = ext.currentShader[target]; 356 if (current == shader) return; 357 ext.currentShader[target] = shader; 358 ext.glFunctions.bindShader.call(ext.gl, target, shader); 359 }; 360 361 cb.getCurrentShader = function (target) { 362 return this._ext.currentShader[target]; 363 }; 364 365 cb.pushShader = function (target) { 366 var ext = this._ext; 367 var stack = ext.shaderStack[target]; 368 var shader = ext.currentShader[target]; 369 stack.push(shader); 370 }; 371 372 cb.popShader = function (target) { 373 var ext = this._ext; 374 var stack = ext.shaderStack[target]; 375 if (stack.length <= 0) return; 376 var shader = stack.pop(); 377 ext.gl.bindShader(target, shader); 378 }; 379 ////////////////////////////////////////////////////////////////////////////////////////// 380 381 382 383 // texture 384 ////////////////////////////////////////////////////////////////////////////////////////// 385 ext.currentTexture = { }; 386 387 var currentTextureUnit = gl.getParameter(gl.ACTIVE_TEXTURE); 388 var textureUnitsCount = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); 389 ext.currentTexture = { }; 390 ext.textureStack = { }; 391 ext.textureUnitStack = [ ]; 392 for (var i=0; i<textureUnitsCount; ++i) { 393 var textureUnit = gl.TEXTURE0 + i; 394 gl.activeTexture(textureUnit); 395 396 var textureBindings = { } 397 textureBindings[gl.TEXTURE_2D ] = gl.getParameter(gl.TEXTURE_BINDING_2D); 398 textureBindings[gl.TEXTURE_CUBE_MAP] = gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP); 399 ext.currentTexture[textureUnit] = textureBindings; 400 401 var textureStacks = { } 402 textureStacks[gl.TEXTURE_2D ] = [ ]; 403 textureStacks[gl.TEXTURE_CUBE_MAP] = [ ]; 404 ext.textureStack[textureUnit] = textureStacks; 405 } 406 gl.activeTexture(currentTextureUnit); 407 ext.currentTextureUnit = currentTextureUnit; 408 409 glFunctions.activeTexture = gl.activeTexture; 410 gl.activeTexture = function (texture) { 411 var ext = this._spidergl.cb._ext; 412 var current = ext.currentTextureUnit; 413 if (current == texture) return; 414 ext.currentTextureUnit = texture; 415 ext.glFunctions.activeTexture.call(this, texture); 416 }; 417 418 cb.getCurrentTextureUnit = function () { 419 return this._ext.currentTextureUnit; 420 }; 421 422 cb.pushTextureUnit = function () { 423 var ext = this._ext; 424 var stack = ext.textureUnitStack; 425 var unit = ext.currentTextureUnit; 426 stack.push(unit); 427 }; 428 429 cb.popTextureUnit = function () { 430 var ext = this._ext; 431 var stack = ext.textureUnitStack; 432 if (stack.length <= 0) return; 433 var unit = stack.pop(); 434 ext.gl.activeTexture(unit); 435 }; 436 437 glFunctions.bindTexture = gl.bindTexture; 438 gl.bindTexture = function (target, texture) { 439 var ext = this._spidergl.cb._ext; 440 var unit = ext.currentTextureUnit; 441 var current = ext.currentTexture[unit][target]; 442 if (current == texture) return; 443 ext.currentTexture[unit][target] = texture; 444 ext.glFunctions.bindTexture.call(this, target, texture); 445 }; 446 447 cb.getCurrentTexture = function (target) { 448 var ext = this._ext; 449 var unit = ext.currentTextureUnit; 450 return ext.currentTexture[unit][target]; 451 }; 452 453 cb.pushTexture = function (target) { 454 var ext = this._ext; 455 var unit = ext.currentTextureUnit; 456 var stack = ext.textureStack[unit][target]; 457 var texture = ext.currentTexture[unit][target]; 458 stack.push(texture); 459 }; 460 461 cb.popTexture = function (target) { 462 var ext = this._ext; 463 var unit = ext.currentTextureUnit; 464 var stack = ext.textureStack[unit][target]; 465 if (stack.length <= 0) return; 466 var texture = stack.pop(); 467 ext.gl.bindTexture(target, texture); 468 }; 469 ////////////////////////////////////////////////////////////////////////////////////////// 470 471 return true; 472 }; 473 474 SpiderGL.WebGL.Context._setup_SGL_wrapper_notify = function (gl, pubExt) { 475 if (!gl) return false; 476 if (!pubExt) return false; 477 if (!gl._spidergl) return false; 478 if (gl._spidergl.wn) return false; 479 480 var wn = pubExt; 481 var ext = wn._ext; 482 var glFunctions = ext.glFunctions; 483 484 ext.cb = gl.getExtension("SGL_current_binding"); 485 if (!ext.cb) return false; 486 487 488 489 // buffer 490 ////////////////////////////////////////////////////////////////////////////////////////// 491 glFunctions.deleteBuffer = gl.deleteBuffer; 492 gl.deleteBuffer = function (buffer) { 493 var ext = this._spidergl.wn._ext; 494 ext.glFunctions.deleteBuffer.apply(this, arguments); 495 var current = buffer; 496 (current && current._spidergl && current._spidergl._gl_deleteBuffer.apply(current._spidergl, arguments)); 497 }; 498 499 glFunctions.isBuffer = gl.isBuffer; 500 gl.isBuffer = function (buffer) { 501 var ext = this._spidergl.wn._ext; 502 var r = ext.glFunctions.isBuffer.apply(this, arguments); 503 var current = buffer; 504 (current && current._spidergl && current._spidergl._gl_isBuffer.apply(current._spidergl, arguments)); 505 return r; 506 }; 507 508 glFunctions.bindBuffer = gl.bindBuffer; 509 gl.bindBuffer = function (target) { 510 var ext = this._spidergl.wn._ext; 511 ext.glFunctions.bindBuffer.apply(this, arguments); 512 var current = ext.cb.getCurrentBuffer(target); 513 (current && current._spidergl && current._spidergl._gl_bindBuffer.apply(current._spidergl, arguments)); 514 }; 515 516 glFunctions.getBufferParameter = gl.getBufferParameter; 517 gl.getBufferParameter = function (target) { 518 var ext = this._spidergl.wn._ext; 519 var r = ext.glFunctions.getBufferParameter.apply(this, arguments); 520 var current = ext.cb.getCurrentBuffer(target); 521 (current && current._spidergl && current._spidergl._gl_getBufferParameter.apply(current._spidergl, arguments)); 522 return r; 523 }; 524 525 glFunctions.bufferData = gl.bufferData; 526 gl.bufferData = function (target) { 527 var ext = this._spidergl.wn._ext; 528 ext.glFunctions.bufferData.apply(this, arguments); 529 var current = ext.cb.getCurrentBuffer(target); 530 (current && current._spidergl && current._spidergl._gl_bufferData.apply(current._spidergl, arguments)); 531 } 532 533 glFunctions.bufferSubData = gl.bufferSubData; 534 gl.bufferSubData = function (target) { 535 var ext = this._spidergl.wn._ext; 536 ext.glFunctions.bufferSubData.apply(this, arguments); 537 var current = ext.cb.getCurrentBuffer(target); 538 (current && current._spidergl && current._spidergl._gl_bufferSubData.apply(current._spidergl, arguments)); 539 } 540 541 glFunctions.vertexAttribPointer = gl.vertexAttribPointer; 542 gl.vertexAttribPointer = function () { 543 var ext = this._spidergl.wn._ext; 544 ext.glFunctions.vertexAttribPointer.apply(this, arguments); 545 var target = this.ARRAY_BUFFER; 546 var current = ext.cb.getCurrentBuffer(target); 547 (current && current._spidergl && current._spidergl._gl_vertexAttribPointer.apply(current._spidergl, arguments)); 548 }; 549 550 glFunctions.drawElements = gl.drawElements; 551 gl.drawElements = function (buffer, mode, count, type, offset) { 552 var ext = this._spidergl.wn._ext; 553 ext.glFunctions.drawElements.apply(this, arguments); 554 var target = this.ELEMENT_ARRAY_BUFFER; 555 var current = ext.cb.getCurrentBuffer(target); 556 (current && current._spidergl && current._spidergl._gl_drawElements.apply(current._spidergl, arguments)); 557 }; 558 ////////////////////////////////////////////////////////////////////////////////////////// 559 560 561 562 // framebuffer 563 ////////////////////////////////////////////////////////////////////////////////////////// 564 glFunctions.deleteFramebuffer = gl.deleteFramebuffer; 565 gl.deleteFramebuffer = function (framebuffer) { 566 var ext = this._spidergl.wn._ext; 567 ext.glFunctions.deleteFramebuffer.apply(this, arguments); 568 var current = framebuffer; 569 (current && current._spidergl && current._spidergl._gl_deleteFramebuffer.apply(current._spidergl, arguments)); 570 }; 571 572 glFunctions.isFramebuffer = gl.isFramebuffer; 573 gl.isFramebuffer = function (framebuffer) { 574 var ext = this._spidergl.wn._ext; 575 var r = ext.glFunctions.isFramebuffer.apply(this, arguments); 576 var current = framebuffer; 577 (current && current._spidergl && current._spidergl._gl_isFramebuffer.apply(current._spidergl, arguments)); 578 return r; 579 }; 580 581 glFunctions.bindFramebuffer = gl.bindFramebuffer; 582 gl.bindFramebuffer = function (target) { 583 var ext = this._spidergl.wn._ext; 584 ext.glFunctions.bindFramebuffer.apply(this, arguments); 585 var current = ext.cb.getCurrentFramebuffer(target); 586 (current && current._spidergl && current._spidergl._gl_bindFramebuffer.apply(current._spidergl, arguments)); 587 }; 588 589 glFunctions.checkFramebufferStatus = gl.checkFramebufferStatus; 590 gl.checkFramebufferStatus = function (target) { 591 var ext = this._spidergl.wn._ext; 592 var r = ext.glFunctions.checkFramebufferStatus.apply(this, arguments); 593 var current = ext.cb.getCurrentFramebuffer(target); 594 (current && current._spidergl && current._spidergl._gl_checkFramebufferStatus.apply(current._spidergl, arguments)); 595 return r; 596 }; 597 598 glFunctions.getFramebufferAttachmentParameter = gl.getFramebufferAttachmentParameter; 599 gl.getFramebufferAttachmentParameter = function (target) { 600 var ext = this._spidergl.wn._ext; 601 var r = ext.glFunctions.getFramebufferAttachmentParameter.apply(this, arguments); 602 var current = ext.cb.getCurrentFramebuffer(target); 603 (current && current._spidergl && current._spidergl._gl_getFramebufferAttachmentParameter.apply(current._spidergl, arguments)); 604 return r; 605 }; 606 607 glFunctions.framebufferRenderbuffer = gl.framebufferRenderbuffer; 608 gl.framebufferRenderbuffer = function (target) { 609 var ext = this._spidergl.wn._ext; 610 ext.glFunctions.framebufferRenderbuffer.apply(this, arguments); 611 var current = ext.cb.getCurrentFramebuffer(target); 612 (current && current._spidergl && current._spidergl._gl_framebufferRenderbuffer.apply(current._spidergl, arguments)); 613 } 614 615 glFunctions.framebufferTexture2D = gl.framebufferTexture2D; 616 gl.framebufferTexture2D = function (target) { 617 var ext = this._spidergl.wn._ext; 618 ext.glFunctions.framebufferTexture2D.apply(this, arguments); 619 var current = ext.cb.getCurrentFramebuffer(target); 620 (current && current._spidergl && current._spidergl._gl_framebufferTexture2D.apply(current._spidergl, arguments)); 621 }; 622 623 glFunctions.clear = gl.clear; 624 gl.clear = function () { 625 var ext = this._spidergl.wn._ext; 626 ext.glFunctions.clear.apply(this, arguments); 627 var target = this.FRAMEBUFFER; 628 var current = ext.cb.getCurrentFramebuffer(target); 629 (current && current._spidergl && current._spidergl._gl_clear.apply(current._spidergl, arguments)); 630 }; 631 632 glFunctions.readPixels = gl.readPixels; 633 gl.readPixels = function () { 634 var ext = this._spidergl.wn._ext; 635 ext.glFunctions.readPixels.apply(this, arguments); 636 var target = this.FRAMEBUFFER; 637 var current = ext.cb.getCurrentFramebuffer(target); 638 (current && current._spidergl && current._spidergl._gl_readPixels.apply(current._spidergl, arguments)); 639 }; 640 ////////////////////////////////////////////////////////////////////////////////////////// 641 642 643 644 // program 645 ////////////////////////////////////////////////////////////////////////////////////////// 646 glFunctions.deleteProgram = gl.deleteProgram; 647 gl.deleteProgram = function (program) { 648 var ext = this._spidergl.wn._ext; 649 ext.glFunctions.deleteProgram.apply(this, arguments); 650 var current = program; 651 (current && current._spidergl && current._spidergl._gl_deleteProgram.apply(current._spidergl, arguments)); 652 }; 653 654 glFunctions.isProgram = gl.isProgram; 655 gl.isProgram = function (program) { 656 var ext = this._spidergl.wn._ext; 657 var r = ext.glFunctions.isProgram.apply(this, arguments); 658 var current = program; 659 (current && current._spidergl && current._spidergl._gl_isProgram.apply(current._spidergl, arguments)); 660 return r; 661 }; 662 663 glFunctions.useProgram = gl.useProgram; 664 gl.useProgram = function () { 665 var ext = this._spidergl.wn._ext; 666 ext.glFunctions.useProgram.apply(this, arguments); 667 var current = ext.cb.getCurrentProgram(); 668 (current && current._spidergl && current._spidergl._gl_useProgram.apply(current._spidergl, arguments)); 669 }; 670 671 glFunctions.getActiveAttrib = gl.getActiveAttrib; 672 gl.getActiveAttrib = function (program) { 673 var ext = this._spidergl.wn._ext; 674 var r = ext.glFunctions.getActiveAttrib.apply(this, arguments); 675 var current = program; 676 (current && current._spidergl && current._spidergl._gl_getActiveAttrib.apply(current._spidergl, arguments)); 677 return r; 678 }; 679 680 glFunctions.getActiveUniform = gl.getActiveUniform; 681 gl.getActiveUniform = function (program) { 682 var ext = this._spidergl.wn._ext; 683 var r = ext.glFunctions.getActiveUniform.apply(this, arguments); 684 var current = program; 685 (current && current._spidergl && current._spidergl._gl_getActiveUniform.apply(current._spidergl, arguments)); 686 return r; 687 }; 688 689 glFunctions.getAttachedShaders = gl.getAttachedShaders; 690 gl.getAttachedShaders = function (program) { 691 var ext = this._spidergl.wn._ext; 692 var r = ext.glFunctions.getAttachedShaders.apply(this, arguments); 693 var current = program; 694 (current && current._spidergl && current._spidergl._gl_getAttachedShaders.apply(current._spidergl, arguments)); 695 return r; 696 }; 697 698 glFunctions.getAttribLocation = gl.getAttribLocation; 699 gl.getAttribLocation = function (program) { 700 var ext = this._spidergl.wn._ext; 701 var r = ext.glFunctions.getAttribLocation.apply(this, arguments); 702 var current = program; 703 (current && current._spidergl && current._spidergl._gl_getAttribLocation.apply(current._spidergl, arguments)); 704 return r; 705 }; 706 707 glFunctions.getProgramParameter = gl.getProgramParameter; 708 gl.getProgramParameter = function (program) { 709 var ext = this._spidergl.wn._ext; 710 var r = ext.glFunctions.getProgramParameter.apply(this, arguments); 711 var current = program; 712 (current && current._spidergl && current._spidergl._gl_getProgramParameter.apply(current._spidergl, arguments)); 713 return r; 714 }; 715 716 glFunctions.getProgramInfoLog = gl.getProgramInfoLog; 717 gl.getProgramInfoLog = function (program) { 718 var ext = this._spidergl.wn._ext; 719 var r = ext.glFunctions.getProgramInfoLog.apply(this, arguments); 720 var current = program; 721 (current && current._spidergl && current._spidergl._gl_getProgramInfoLog.apply(current._spidergl, arguments)); 722 return r; 723 }; 724 725 glFunctions.getUniform = gl.getUniform; 726 gl.getUniform = function (program) { 727 var ext = this._spidergl.wn._ext; 728 var r = ext.glFunctions.getUniform.apply(this, arguments); 729 var current = program; 730 (current && current._spidergl && current._spidergl._gl_getUniform.apply(current._spidergl, arguments)); 731 return r; 732 }; 733 734 glFunctions.getUniformLocation = gl.getUniformLocation; 735 gl.getUniformLocation = function (program) { 736 var ext = this._spidergl.wn._ext; 737 var r = ext.glFunctions.getUniformLocation.apply(this, arguments); 738 var current = program; 739 (current && current._spidergl && current._spidergl._gl_getUniformLocation.apply(current._spidergl, arguments)); 740 return r; 741 }; 742 743 glFunctions.attachShader = gl.attachShader; 744 gl.attachShader = function (program) { 745 var ext = this._spidergl.wn._ext; 746 ext.glFunctions.attachShader.apply(this, arguments); 747 var current = program; 748 (current && current._spidergl && current._spidergl._gl_attachShader.apply(current._spidergl, arguments)); 749 }; 750 751 glFunctions.bindAttribLocation = gl.bindAttribLocation; 752 gl.bindAttribLocation = function (program) { 753 var ext = this._spidergl.wn._ext; 754 ext.glFunctions.bindAttribLocation.apply(this, arguments); 755 var current = program; 756 (current && current._spidergl && current._spidergl._gl_bindAttribLocation.apply(current._spidergl, arguments)); 757 }; 758 759 glFunctions.detachShader = gl.detachShader; 760 gl.detachShader = function (program) { 761 var ext = this._spidergl.wn._ext; 762 ext.glFunctions.detachShader.apply(this, arguments); 763 var current = program; 764 (current && current._spidergl && current._spidergl._gl_detachShader.apply(current._spidergl, arguments)); 765 }; 766 767 glFunctions.linkProgram = gl.linkProgram; 768 gl.linkProgram = function (program) { 769 var ext = this._spidergl.wn._ext; 770 ext.glFunctions.linkProgram.apply(this, arguments); 771 var current = program; 772 (current && current._spidergl && current._spidergl._gl_linkProgram.apply(current._spidergl, arguments)); 773 }; 774 775 glFunctions.uniform1f = gl.uniform1f; 776 gl.uniform1f = function () { 777 var ext = this._spidergl.wn._ext; 778 ext.glFunctions.uniform1f.apply(this, arguments); 779 var current = ext.cb.getCurrentProgram(); 780 (current && current._spidergl && current._spidergl._gl_uniform1f.apply(current._spidergl, arguments)); 781 }; 782 783 glFunctions.uniform1fv = gl.uniform1fv; 784 gl.uniform1fv = function () { 785 var ext = this._spidergl.wn._ext; 786 ext.glFunctions.uniform1fv.apply(this, arguments); 787 var current = ext.cb.getCurrentProgram(); 788 (current && current._spidergl && current._spidergl._gl_uniform1fv.apply(current._spidergl, arguments)); 789 }; 790 791 glFunctions.uniform1i = gl.uniform1i; 792 gl.uniform1i = function () { 793 var ext = this._spidergl.wn._ext; 794 ext.glFunctions.uniform1i.apply(this, arguments); 795 var current = ext.cb.getCurrentProgram(); 796 (current && current._spidergl && current._spidergl._gl_uniform1i.apply(current._spidergl, arguments)); 797 }; 798 799 glFunctions.uniform1iv = gl.uniform1iv; 800 gl.uniform1iv = function () { 801 var ext = this._spidergl.wn._ext; 802 ext.glFunctions.uniform1iv.apply(this, arguments); 803 var current = ext.cb.getCurrentProgram(); 804 (current && current._spidergl && current._spidergl._gl_uniform1iv.apply(current._spidergl, arguments)); 805 }; 806 807 glFunctions.uniform2f = gl.uniform2f; 808 gl.uniform2f = function () { 809 var ext = this._spidergl.wn._ext; 810 ext.glFunctions.uniform2f.apply(this, arguments); 811 var current = ext.cb.getCurrentProgram(); 812 (current && current._spidergl && current._spidergl._gl_uniform2f.apply(current._spidergl, arguments)); 813 }; 814 815 glFunctions.uniform2fv = gl.uniform2fv; 816 gl.uniform2fv = function () { 817 var ext = this._spidergl.wn._ext; 818 ext.glFunctions.uniform2fv.apply(this, arguments); 819 var current = ext.cb.getCurrentProgram(); 820 (current && current._spidergl && current._spidergl._gl_uniform2fv.apply(current._spidergl, arguments)); 821 }; 822 823 glFunctions.uniform2i = gl.uniform2i; 824 gl.uniform2i = function () { 825 var ext = this._spidergl.wn._ext; 826 ext.glFunctions.uniform2i.apply(this, arguments); 827 var current = ext.cb.getCurrentProgram(); 828 (current && current._spidergl && current._spidergl._gl_uniform2i.apply(current._spidergl, arguments)); 829 }; 830 831 glFunctions.uniform2iv = gl.uniform2iv; 832 gl.uniform2iv = function () { 833 var ext = this._spidergl.wn._ext; 834 ext.glFunctions.uniform2iv.apply(this, arguments); 835 var current = ext.cb.getCurrentProgram(); 836 (current && current._spidergl && current._spidergl._gl_uniform2iv.apply(current._spidergl, arguments)); 837 }; 838 839 glFunctions.uniform3f = gl.uniform3f; 840 gl.uniform3f = function () { 841 var ext = this._spidergl.wn._ext; 842 ext.glFunctions.uniform3f.apply(this, arguments); 843 var current = ext.cb.getCurrentProgram(); 844 (current && current._spidergl && current._spidergl._gl_uniform3f.apply(current._spidergl, arguments)); 845 }; 846 847 glFunctions.uniform3fv = gl.uniform3fv; 848 gl.uniform3fv = function () { 849 var ext = this._spidergl.wn._ext; 850 ext.glFunctions.uniform3fv.apply(this, arguments); 851 var current = ext.cb.getCurrentProgram(); 852 (current && current._spidergl && current._spidergl._gl_uniform3fv.apply(current._spidergl, arguments)); 853 }; 854 855 glFunctions.uniform3i = gl.uniform3i; 856 gl.uniform3i = function () { 857 var ext = this._spidergl.wn._ext; 858 ext.glFunctions.uniform3i.apply(this, arguments); 859 var current = ext.cb.getCurrentProgram(); 860 (current && current._spidergl && current._spidergl._gl_uniform3i.apply(current._spidergl, arguments)); 861 }; 862 863 glFunctions.uniform3iv = gl.uniform3iv; 864 gl.uniform3iv = function () { 865 var ext = this._spidergl.wn._ext; 866 ext.glFunctions.uniform3iv.apply(this, arguments); 867 var current = ext.cb.getCurrentProgram(); 868 (current && current._spidergl && current._spidergl._gl_uniform3iv.apply(current._spidergl, arguments)); 869 }; 870 871 glFunctions.uniform4f = gl.uniform4f; 872 gl.uniform4f = function () { 873 var ext = this._spidergl.wn._ext; 874 ext.glFunctions.uniform4f.apply(this, arguments); 875 var current = ext.cb.getCurrentProgram(); 876 (current && current._spidergl && current._spidergl._gl_uniform4f.apply(current._spidergl, arguments)); 877 }; 878 879 glFunctions.uniform4fv = gl.uniform4fv; 880 gl.uniform4fv = function () { 881 var ext = this._spidergl.wn._ext; 882 ext.glFunctions.uniform4fv.apply(this, arguments); 883 var current = ext.cb.getCurrentProgram(); 884 (current && current._spidergl && current._spidergl._gl_uniform4fv.apply(current._spidergl, arguments)); 885 }; 886 887 glFunctions.uniform4i = gl.uniform4i; 888 gl.uniform4i = function () { 889 var ext = this._spidergl.wn._ext; 890 ext.glFunctions.uniform4i.apply(this, arguments); 891 var current = ext.cb.getCurrentProgram(); 892 (current && current._spidergl && current._spidergl._gl_uniform4i.apply(current._spidergl, arguments)); 893 }; 894 895 glFunctions.uniform4iv = gl.uniform4iv; 896 gl.uniform4iv = function () { 897 var ext = this._spidergl.wn._ext; 898 ext.glFunctions.uniform4iv.apply(this, arguments); 899 var current = ext.cb.getCurrentProgram(); 900 (current && current._spidergl && current._spidergl._gl_uniform4iv.apply(current._spidergl, arguments)); 901 }; 902 903 glFunctions.uniformMatrix2fv = gl.uniformMatrix2fv; 904 gl.uniformMatrix2fv = function () { 905 var ext = this._spidergl.wn._ext; 906 ext.glFunctions.uniformMatrix2fv.apply(this, arguments); 907 var current = ext.cb.getCurrentProgram(); 908 (current && current._spidergl && current._spidergl._gl_uniformMatrix2fv.apply(current._spidergl, arguments)); 909 }; 910 911 glFunctions.uniformMatrix3fv = gl.uniformMatrix3fv; 912 gl.uniformMatrix3fv = function () { 913 var ext = this._spidergl.wn._ext; 914 ext.glFunctions.uniformMatrix3fv.apply(this, arguments); 915 var current = ext.cb.getCurrentProgram(); 916 (current && current._spidergl && current._spidergl._gl_uniformMatrix3fv.apply(current._spidergl, arguments)); 917 }; 918 919 glFunctions.uniformMatrix4fv = gl.uniformMatrix4fv; 920 gl.uniformMatrix4fv = function () { 921 var ext = this._spidergl.wn._ext; 922 ext.glFunctions.uniformMatrix4fv.apply(this, arguments); 923 var current = ext.cb.getCurrentProgram(); 924 (current && current._spidergl && current._spidergl._gl_uniformMatrix4fv.apply(current._spidergl, arguments)); 925 }; 926 927 glFunctions.validateProgram = gl.validateProgram; 928 gl.validateProgram = function (program) { 929 var ext = this._spidergl.wn._ext; 930 ext.glFunctions.validateProgram.apply(this, arguments); 931 var current = program; 932 (current && current._spidergl && current._spidergl._gl_validateProgram.apply(current._spidergl, arguments)); 933 }; 934 ////////////////////////////////////////////////////////////////////////////////////////// 935 936 937 938 // renderbuffer 939 ////////////////////////////////////////////////////////////////////////////////////////// 940 glFunctions.deleteRenderbuffer = gl.deleteRenderbuffer; 941 gl.deleteRenderbuffer = function (renderbuffer) { 942 var ext = this._spidergl.wn._ext; 943 ext.glFunctions.deleteRenderbuffer.apply(this, arguments); 944 var current = renderbuffer; 945 (current && current._spidergl && current._spidergl._gl_deleteRenderbuffer.apply(current._spidergl, arguments)); 946 }; 947 948 glFunctions.isRenderbuffer = gl.isRenderbuffer; 949 gl.isRenderbuffer = function (renderbuffer) { 950 var ext = this._spidergl.wn._ext; 951 var r = ext.glFunctions.isRenderbuffer.apply(this, arguments); 952 var current = renderbuffer; 953 (current && current._spidergl && current._spidergl._gl_isRenderbuffer.apply(current._spidergl, arguments)); 954 return r; 955 }; 956 957 glFunctions.bindRenderbuffer = gl.bindRenderbuffer; 958 gl.bindRenderbuffer = function (target) { 959 var ext = this._spidergl.wn._ext; 960 ext.glFunctions.bindRenderbuffer.apply(this, arguments); 961 var current = ext.cb.getCurrentRenderbuffer(target); 962 (current && current._spidergl && current._spidergl._gl_bindRenderbuffer.apply(current._spidergl, arguments)); 963 }; 964 965 glFunctions.getRenderbufferParameter = gl.getRenderbufferParameter; 966 gl.getRenderbufferParameter = function (target) { 967 var ext = this._spidergl.wn._ext; 968 var r = ext.glFunctions.getRenderbufferParameter.apply(this, arguments); 969 var current = ext.cb.getCurrentRenderbuffer(target); 970 (current && current._spidergl && current._spidergl._gl_getRenderbufferParameter.apply(current._spidergl, arguments)); 971 return r; 972 }; 973 974 glFunctions.renderbufferStorage = gl.renderbufferStorage; 975 gl.renderbufferStorage = function (target) { 976 var ext = this._spidergl.wn._ext; 977 ext.glFunctions.renderbufferStorage.apply(this, arguments); 978 var current = ext.cb.getCurrentRenderbuffer(target); 979 (current && current._spidergl && current._spidergl._gl_renderbufferStorage.apply(current._spidergl, arguments)); 980 } 981 ////////////////////////////////////////////////////////////////////////////////////////// 982 983 984 985 // shader 986 ////////////////////////////////////////////////////////////////////////////////////////// 987 glFunctions.deleteShader = gl.deleteShader; 988 gl.deleteShader = function (shader) { 989 var ext = this._spidergl.wn._ext; 990 ext.glFunctions.deleteShader.apply(this, arguments); 991 var current = shader; 992 (current && current._spidergl && current._spidergl._gl_deleteShader.apply(current._spidergl, arguments)); 993 }; 994 995 glFunctions.isShader = gl.isShader; 996 gl.isShader = function (shader) { 997 var ext = this._spidergl.wn._ext; 998 var r = ext.glFunctions.isShader.apply(this, arguments); 999 var current = shader; 1000 (current && current._spidergl && current._spidergl._gl_isShader.apply(current._spidergl, arguments)); 1001 return r; 1002 }; 1003 1004 glFunctions.getShaderParameter = gl.getShaderParameter; 1005 gl.getShaderParameter = function (shader) { 1006 var ext = this._spidergl.wn._ext; 1007 var r = ext.glFunctions.getShaderParameter.apply(this, arguments); 1008 var current = shader; 1009 (current && current._spidergl && current._spidergl._gl_getShaderParameter.apply(current._spidergl, arguments)); 1010 return r; 1011 }; 1012 1013 glFunctions.getShaderInfoLog = gl.getShaderInfoLog; 1014 gl.getShaderInfoLog = function (shader) { 1015 var ext = this._spidergl.wn._ext; 1016 var r = ext.glFunctions.getShaderInfoLog.apply(this, arguments); 1017 var current = shader; 1018 (current && current._spidergl && current._spidergl._gl_getShaderInfoLog.apply(current._spidergl, arguments)); 1019 return r; 1020 }; 1021 1022 glFunctions.getShaderSource = gl.getShaderSource; 1023 gl.getShaderSource = function (shader) { 1024 var ext = this._spidergl.wn._ext; 1025 var r = ext.glFunctions.getShaderSource.apply(this, arguments); 1026 var current = shader; 1027 (current && current._spidergl && current._spidergl._gl_getShaderSource.apply(current._spidergl, arguments)); 1028 return r; 1029 }; 1030 1031 glFunctions.compileShader = gl.compileShader; 1032 gl.compileShader = function (shader) { 1033 var ext = this._spidergl.wn._ext; 1034 ext.glFunctions.compileShader.apply(this, arguments); 1035 var current = shader; 1036 (current && current._spidergl && current._spidergl._gl_compileShader.apply(current._spidergl, arguments)); 1037 } 1038 1039 glFunctions.shaderSource = gl.shaderSource; 1040 gl.shaderSource = function (shader) { 1041 var ext = this._spidergl.wn._ext; 1042 ext.glFunctions.shaderSource.apply(this, arguments); 1043 var current = shader; 1044 (current && current._spidergl && current._spidergl._gl_shaderSource.apply(current._spidergl, arguments)); 1045 } 1046 ////////////////////////////////////////////////////////////////////////////////////////// 1047 1048 1049 1050 // texture 1051 ////////////////////////////////////////////////////////////////////////////////////////// 1052 ext.textureTargetMap = { }; 1053 ext.textureTargetMap[gl.TEXTURE_2D ] = gl.TEXTURE_2D; 1054 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP ] = gl.TEXTURE_CUBE_MAP; 1055 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_X] = gl.TEXTURE_CUBE_MAP; 1056 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_X] = gl.TEXTURE_CUBE_MAP; 1057 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_Y] = gl.TEXTURE_CUBE_MAP; 1058 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_Y] = gl.TEXTURE_CUBE_MAP; 1059 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_Z] = gl.TEXTURE_CUBE_MAP; 1060 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] = gl.TEXTURE_CUBE_MAP; 1061 1062 glFunctions.deleteTexture = gl.deleteTexture; 1063 gl.deleteTexture = function (texture) { 1064 var ext = this._spidergl.wn._ext; 1065 ext.glFunctions.deleteTexture.apply(this, arguments); 1066 var current = texture; 1067 (current && current._spidergl && current._spidergl._gl_deleteTexture.apply(current._spidergl, arguments)); 1068 }; 1069 1070 glFunctions.isTexture = gl.isTexture; 1071 gl.isTexture = function (texture) { 1072 var ext = this._spidergl.wn._ext; 1073 var r = ext.glFunctions.isTexture.apply(this, arguments); 1074 var current = texture; 1075 (current && current._spidergl && current._spidergl._gl_isTexture.apply(current._spidergl, arguments)); 1076 return r; 1077 }; 1078 1079 glFunctions.bindTexture = gl.bindTexture; 1080 gl.bindTexture = function (target) { 1081 var ext = this._spidergl.wn._ext; 1082 ext.glFunctions.bindTexture.apply(this, arguments); 1083 var current = ext.cb.getCurrentTexture(target); 1084 (current && current._spidergl && current._spidergl._gl_bindTexture.apply(current._spidergl, arguments)); 1085 }; 1086 1087 glFunctions.getTexParameter = gl.getTexParameter; 1088 gl.getTexParameter = function (target) { 1089 var ext = this._spidergl.wn._ext; 1090 var r = ext.glFunctions.getTexParameter.apply(this, arguments); 1091 var current = ext.cb.getCurrentTexture(target); 1092 (current && current._spidergl && current._spidergl._gl_getTexParameter.apply(current._spidergl, arguments)); 1093 return r; 1094 }; 1095 1096 glFunctions.copyTexImage2D = gl.copyTexImage2D; 1097 gl.copyTexImage2D = function (target) { 1098 var ext = this._spidergl.wn._ext; 1099 ext.glFunctions.copyTexImage2D.apply(this, arguments); 1100 var texTarget = ext.textureTargetMap[target]; 1101 var current = ext.cb.getCurrentTexture(texTarget); 1102 (current && current._spidergl && current._spidergl._gl_copyTexImage2D.apply(current._spidergl, arguments)); 1103 } 1104 1105 glFunctions.copyTexSubImage2D = gl.copyTexSubImage2D; 1106 gl.copyTexSubImage2D = function (target) { 1107 var ext = this._spidergl.wn._ext; 1108 ext.glFunctions.copyTexSubImage2D.apply(this, arguments); 1109 var texTarget = ext.textureTargetMap[target]; 1110 var current = ext.cb.getCurrentTexture(texTarget); 1111 (current && current._spidergl && current._spidergl._gl_copyTexSubImage2D.apply(current._spidergl, arguments)); 1112 } 1113 1114 glFunctions.generateMipmap = gl.generateMipmap; 1115 gl.generateMipmap = function (target) { 1116 var ext = this._spidergl.wn._ext; 1117 ext.glFunctions.generateMipmap.apply(this, arguments); 1118 var current = ext.cb.getCurrentTexture(target); 1119 (current && current._spidergl && current._spidergl._gl_generateMipmap.apply(current._spidergl, arguments)); 1120 } 1121 1122 glFunctions.texImage2D = gl.texImage2D; 1123 gl.texImage2D = function (target) { 1124 var ext = this._spidergl.wn._ext; 1125 ext.glFunctions.texImage2D.apply(this, arguments); 1126 var texTarget = ext.textureTargetMap[target]; 1127 var current = ext.cb.getCurrentTexture(texTarget); 1128 (current && current._spidergl && current._spidergl._gl_texImage2D.apply(current._spidergl, arguments)); 1129 } 1130 1131 glFunctions.texParameterf = gl.texParameterf; 1132 gl.texParameterf = function (target) { 1133 var ext = this._spidergl.wn._ext; 1134 ext.glFunctions.texParameterf.apply(this, arguments); 1135 var current = ext.cb.getCurrentTexture(target); 1136 (current && current._spidergl && current._spidergl._gl_texParameterf.apply(current._spidergl, arguments)); 1137 } 1138 1139 glFunctions.texParameteri = gl.texParameteri; 1140 gl.texParameteri = function (target) { 1141 var ext = this._spidergl.wn._ext; 1142 ext.glFunctions.texParameteri.apply(this, arguments); 1143 var current = ext.cb.getCurrentTexture(target); 1144 (current && current._spidergl && current._spidergl._gl_texParameteri.apply(current._spidergl, arguments)); 1145 } 1146 1147 glFunctions.texSubImage2D = gl.texSubImage2D; 1148 gl.texSubImage2D = function (target) { 1149 var ext = this._spidergl.wn._ext; 1150 ext.glFunctions.texSubImage2D.apply(this, arguments); 1151 var texTarget = ext.textureTargetMap[target]; 1152 var current = ext.cb.getCurrentTexture(texTarget); 1153 (current && current._spidergl && current._spidergl._gl_texSubImage2D.apply(current._spidergl, arguments)); 1154 } 1155 ////////////////////////////////////////////////////////////////////////////////////////// 1156 1157 return true; 1158 }; 1159 1160 SpiderGL.WebGL.Context._setup_SGL_direct_state_access = function (gl, pubExt) { 1161 if (!gl) return false; 1162 if (!pubExt) return false; 1163 if (!gl._spidergl) return false; 1164 if (gl._spidergl.dsa) return false; 1165 1166 var dsa = pubExt; 1167 var ext = dsa._ext; 1168 var glFunctions = ext.glFunctions; 1169 1170 ext.cb = gl.getExtension("SGL_current_binding"); 1171 if (!ext.cb) return false; 1172 1173 // buffer 1174 ////////////////////////////////////////////////////////////////////////////////////////// 1175 dsa.getBufferParameter = function (buffer, target, pname) { 1176 var ext = this._ext; 1177 var gl = ext.gl; 1178 var current = ext.cb.getCurrentBuffer(target); 1179 (current != buffer) && gl.bindBuffer(target, buffer); 1180 var r = gl.getBufferParameter(target, pname); 1181 (current != buffer) && gl.bindBuffer(target, current); 1182 return r; 1183 }; 1184 1185 dsa.bufferData = function (buffer, target, dataOrSize, usage) { 1186 var ext = this._ext; 1187 var gl = ext.gl; 1188 var current = ext.cb.getCurrentBuffer(target); 1189 (current != buffer) && gl.bindBuffer(target, buffer); 1190 gl.bufferData(target, dataOrSize, usage); 1191 (current != buffer) && gl.bindBuffer(target, current); 1192 } 1193 1194 dsa.bufferSubData = function (buffer, target, offset, data) { 1195 var ext = this._ext; 1196 var gl = ext.gl; 1197 var current = ext.cb.getCurrentBuffer(target); 1198 (current != buffer) && gl.bindBuffer(target, buffer); 1199 gl.bufferSubData(target, offset, data); 1200 (current != buffer) && gl.bindBuffer(target, current); 1201 } 1202 1203 dsa.vertexAttribPointer = function (buffer, indx, size, type, normalized, stride, offset) { 1204 var ext = this._ext; 1205 var gl = ext.gl; 1206 var target = gl.ARRAY_BUFFER; 1207 var current = ext.cb.getCurrentBuffer(target); 1208 (current != buffer) && gl.bindBuffer(target, buffer); 1209 gl.vertexAttribPointer(indx, size, type, normalized, stride, offset); 1210 (current != buffer) && gl.bindBuffer(target, current); 1211 }; 1212 1213 dsa.drawElements = function (buffer, mode, count, type, offset) { 1214 var ext = this._ext; 1215 var gl = ext.gl; 1216 var target = gl.ELEMENT_ARRAY_BUFFER; 1217 var current = ext.cb.getCurrentBuffer(target); 1218 (current != buffer) && gl.bindBuffer(target, buffer); 1219 gl.drawElements(mode, count, type, offset); 1220 (current != buffer) && gl.bindBuffer(target, current); 1221 }; 1222 ////////////////////////////////////////////////////////////////////////////////////////// 1223 1224 1225 1226 // framebuffer 1227 ////////////////////////////////////////////////////////////////////////////////////////// 1228 dsa.checkFramebufferStatus = function (framebuffer, target) { 1229 var ext = this._ext; 1230 var gl = ext.gl; 1231 var current = ext.cb.getCurrentFramebuffer(target); 1232 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1233 var r = gl.checkFramebufferStatus(target); 1234 (current != framebuffer) && gl.bindFramebuffer(target, current); 1235 return r; 1236 }; 1237 1238 dsa.getFramebufferAttachmentParameter = function (framebuffer, target, attachment, pname) { 1239 var ext = this._ext; 1240 var gl = ext.gl; 1241 var current = ext.cb.getCurrentFramebuffer(target); 1242 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1243 var r = gl.getFramebufferAttachmentParameter(target, attachment, pname); 1244 (current != framebuffer) && gl.bindFramebuffer(target, current); 1245 return r; 1246 }; 1247 1248 dsa.framebufferRenderbuffer = function (framebuffer, target, attachment, renderbuffertarget, renderbuffer) { 1249 var ext = this._ext; 1250 var gl = ext.gl; 1251 var current = ext.cb.getCurrentFramebuffer(target); 1252 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1253 gl.framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); 1254 (current != framebuffer) && gl.bindFramebuffer(target, current); 1255 }; 1256 1257 dsa.framebufferTexture2D = function (framebuffer, target, attachment, textarget, texture, level) { 1258 var ext = this._ext; 1259 var gl = ext.gl; 1260 var current = ext.cb.getCurrentFramebuffer(target); 1261 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1262 gl.framebufferTexture2D(target, attachment, textarget, texture, level); 1263 (current != framebuffer) && gl.bindFramebuffer(target, current); 1264 }; 1265 1266 dsa.clear = function (framebuffer, mask) { 1267 var ext = this._ext; 1268 var gl = ext.gl; 1269 var target = gl.FRAMEBUFFER 1270 var current = ext.cb.getCurrentFramebuffer(target); 1271 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1272 gl.clear(mask); 1273 (current != framebuffer) && gl.bindFramebuffer(target, current); 1274 }; 1275 1276 dsa.readPixels = function (framebuffer, x, y, width, height, format, type, pixels) { 1277 var ext = this._ext; 1278 var gl = ext.gl; 1279 var target = gl.FRAMEBUFFER 1280 var current = ext.cb.getCurrentFramebuffer(target); 1281 (current != framebuffer) && gl.bindFramebuffer(target, framebuffer); 1282 gl.readPixels(x, y, width, height, format, type, pixels); 1283 (current != framebuffer) && gl.bindFramebuffer(target, current); 1284 }; 1285 ////////////////////////////////////////////////////////////////////////////////////////// 1286 1287 1288 1289 // program 1290 ////////////////////////////////////////////////////////////////////////////////////////// 1291 dsa.uniform1f = function (program, location, x) { 1292 var ext = this._ext; 1293 var gl = ext.gl; 1294 var current = ext.cb.getCurrentProgram(); 1295 (current != program) && gl.useProgram(program); 1296 gl.uniform1f(location, x); 1297 (current != program) && gl.useProgram(current); 1298 }; 1299 1300 dsa.uniform1fv = function (program, location, v) { 1301 var ext = this._ext; 1302 var gl = ext.gl; 1303 var current = ext.cb.getCurrentProgram(); 1304 (current != program) && gl.useProgram(program); 1305 gl.uniform1fv(location, v); 1306 (current != program) && gl.useProgram(current); 1307 }; 1308 1309 dsa.uniform1i = function (program, location, x) { 1310 var ext = this._ext; 1311 var gl = ext.gl; 1312 var current = ext.cb.getCurrentProgram(); 1313 (current != program) && gl.useProgram(program); 1314 gl.uniform1i(location, x); 1315 (current != program) && gl.useProgram(current); 1316 }; 1317 1318 dsa.uniform1iv = function (program, location, v) { 1319 var ext = this._ext; 1320 var gl = ext.gl; 1321 var current = ext.cb.getCurrentProgram(); 1322 (current != program) && gl.useProgram(program); 1323 gl.uniform1iv(location, v); 1324 (current != program) && gl.useProgram(current); 1325 }; 1326 1327 dsa.uniform2f = function (program, location, x, y) { 1328 var ext = this._ext; 1329 var gl = ext.gl; 1330 var current = ext.cb.getCurrentProgram(); 1331 (current != program) && gl.useProgram(program); 1332 gl.uniform2f(location, x, y); 1333 (current != program) && gl.useProgram(current); 1334 }; 1335 1336 dsa.uniform2fv = function (program, location, v) { 1337 var ext = this._ext; 1338 var gl = ext.gl; 1339 var current = ext.cb.getCurrentProgram(); 1340 (current != program) && gl.useProgram(program); 1341 gl.uniform2fv(location, v); 1342 (current != program) && gl.useProgram(current); 1343 }; 1344 1345 dsa.uniform2i = function (program, location, x, y) { 1346 var ext = this._ext; 1347 var gl = ext.gl; 1348 var current = ext.cb.getCurrentProgram(); 1349 (current != program) && gl.useProgram(program); 1350 gl.uniform2i(location, x, y); 1351 (current != program) && gl.useProgram(current); 1352 }; 1353 1354 dsa.uniform2iv = function (program, location, v) { 1355 var ext = this._ext; 1356 var gl = ext.gl; 1357 var current = ext.cb.getCurrentProgram(); 1358 (current != program) && gl.useProgram(program); 1359 gl.uniform2iv(location, v); 1360 (current != program) && gl.useProgram(current); 1361 }; 1362 1363 dsa.uniform3f = function (program, location, x, y, z) { 1364 var ext = this._ext; 1365 var gl = ext.gl; 1366 var current = ext.cb.getCurrentProgram(); 1367 (current != program) && gl.useProgram(program); 1368 gl.uniform3f(location, x, y, z); 1369 (current != program) && gl.useProgram(current); 1370 }; 1371 1372 dsa.uniform3fv = function (program, location, v) { 1373 var ext = this._ext; 1374 var gl = ext.gl; 1375 var current = ext.cb.getCurrentProgram(); 1376 (current != program) && gl.useProgram(program); 1377 gl.uniform3fv(location, v); 1378 (current != program) && gl.useProgram(current); 1379 }; 1380 1381 dsa.uniform3i = function (program, location, x, y, z) { 1382 var ext = this._ext; 1383 var gl = ext.gl; 1384 var current = ext.cb.getCurrentProgram(); 1385 (current != program) && gl.useProgram(program); 1386 gl.uniform3i(location, x, y, z); 1387 (current != program) && gl.useProgram(current); 1388 }; 1389 1390 dsa.uniform3iv = function (program, location, v) { 1391 var ext = this._ext; 1392 var gl = ext.gl; 1393 var current = ext.cb.getCurrentProgram(); 1394 (current != program) && gl.useProgram(program); 1395 gl.uniform3iv(location, v); 1396 (current != program) && gl.useProgram(current); 1397 }; 1398 1399 dsa.uniform4f = function (program, location, x, y, z, w) { 1400 var ext = this._ext; 1401 var gl = ext.gl; 1402 var current = ext.cb.getCurrentProgram(); 1403 (current != program) && gl.useProgram(program); 1404 gl.uniform4f(location, x, y, z, w); 1405 (current != program) && gl.useProgram(current); 1406 }; 1407 1408 dsa.uniform4fv = function (program, location, v) { 1409 var ext = this._ext; 1410 var gl = ext.gl; 1411 var current = ext.cb.getCurrentProgram(); 1412 (current != program) && gl.useProgram(program); 1413 gl.uniform4fv(location, v); 1414 (current != program) && gl.useProgram(current); 1415 }; 1416 1417 dsa.uniform4i = function (program, location, x, y, z, w) { 1418 var ext = this._ext; 1419 var gl = ext.gl; 1420 var current = ext.cb.getCurrentProgram(); 1421 (current != program) && gl.useProgram(program); 1422 gl.uniform4i(location, x, y, z, w); 1423 (current != program) && gl.useProgram(current); 1424 }; 1425 1426 dsa.uniform4iv = function (program, location, v) { 1427 var ext = this._ext; 1428 var gl = ext.gl; 1429 var current = ext.cb.getCurrentProgram(); 1430 (current != program) && gl.useProgram(program); 1431 gl.uniform4iv(location, v); 1432 (current != program) && gl.useProgram(current); 1433 }; 1434 1435 dsa.uniformMatrix2fv = function (program, location, transpose, value) { 1436 var ext = this._ext; 1437 var gl = ext.gl; 1438 var current = ext.cb.getCurrentProgram(); 1439 (current != program) && gl.useProgram(program); 1440 gl.uniformMatrix2fv(location, transpose, value); 1441 (current != program) && gl.useProgram(current); 1442 }; 1443 1444 dsa.uniformMatrix3fv = function (program, location, transpose, value) { 1445 var ext = this._ext; 1446 var gl = ext.gl; 1447 var current = ext.cb.getCurrentProgram(); 1448 (current != program) && gl.useProgram(program); 1449 gl.uniformMatrix3fv(location, transpose, value); 1450 (current != program) && gl.useProgram(current); 1451 }; 1452 1453 dsa.uniformMatrix4fv = function (program, location, transpose, value) { 1454 var ext = this._ext; 1455 var gl = ext.gl; 1456 var current = ext.cb.getCurrentProgram(); 1457 (current != program) && gl.useProgram(program); 1458 gl.uniformMatrix4fv(location, transpose, value); 1459 (current != program) && gl.useProgram(current); 1460 }; 1461 ////////////////////////////////////////////////////////////////////////////////////////// 1462 1463 1464 1465 // renderbuffer 1466 ////////////////////////////////////////////////////////////////////////////////////////// 1467 dsa.getRenderbufferParameter = function (renderbuffer, target, pname) { 1468 var ext = this._ext; 1469 var gl = ext.gl; 1470 var current = ext.cb.getCurrentRenderbuffer(target); 1471 (current != renderbuffer) && gl.bindRenderbuffer(target, renderbuffer); 1472 var r = gl.getRenderbufferParameter.call(gl, target, pname); 1473 (current != renderbuffer) && gl.bindRenderbuffer(target, current); 1474 return r; 1475 }; 1476 1477 dsa.renderbufferStorage = function (renderbuffer, target, internalformat, width, height) { 1478 var ext = this._ext; 1479 var gl = ext.gl; 1480 var current = ext.cb.getCurrentRenderbuffer(target); 1481 (current != renderbuffer) && gl.bindRenderbuffer(target, renderbuffer); 1482 gl.renderbufferStorage(target, internalformat, width, height); 1483 (current != renderbuffer) && gl.bindRenderbuffer(target, current); 1484 }; 1485 ////////////////////////////////////////////////////////////////////////////////////////// 1486 1487 1488 1489 // shader 1490 ////////////////////////////////////////////////////////////////////////////////////////// 1491 // NO DSA FUNCTIONS 1492 dsa.shaderIsNull = function (shader) { 1493 return (shader == null); 1494 }; 1495 ////////////////////////////////////////////////////////////////////////////////////////// 1496 1497 1498 1499 // texture 1500 ////////////////////////////////////////////////////////////////////////////////////////// 1501 ext.textureTargetMap = { }; 1502 ext.textureTargetMap[gl.TEXTURE_2D ] = gl.TEXTURE_2D; 1503 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP ] = gl.TEXTURE_CUBE_MAP; 1504 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_X] = gl.TEXTURE_CUBE_MAP; 1505 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_X] = gl.TEXTURE_CUBE_MAP; 1506 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_Y] = gl.TEXTURE_CUBE_MAP; 1507 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_Y] = gl.TEXTURE_CUBE_MAP; 1508 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_POSITIVE_Z] = gl.TEXTURE_CUBE_MAP; 1509 ext.textureTargetMap[gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] = gl.TEXTURE_CUBE_MAP; 1510 1511 dsa.getTexParameter = function (texture, target, pname) { 1512 var ext = this._ext; 1513 var gl = ext.gl; 1514 var current = ext.cb.getCurrentTexture(target); 1515 (current != texture) && gl.bindTexture(target, texture); 1516 var r = gl.getTexParameter(target, pname); 1517 (current != texture) && gl.bindTexture(target, current); 1518 return r; 1519 }; 1520 1521 dsa.copyTexImage2D = function (texture, target, level, internalformat, x, y, width, height, border) { 1522 var ext = this._ext; 1523 var gl = ext.gl; 1524 var texTarget = ext.textureTargetMap[target]; 1525 var current = ext.cb.getCurrentTexture(texTarget); 1526 (current != texture) && gl.bindTexture(texTarget, texture); 1527 gl.copyTexImage2D(target, level, internalformat, x, y, width, height, border); 1528 (current != texture) && gl.bindTexture(texTarget, current); 1529 }; 1530 1531 dsa.copyTexSubImage2D = function (texture, target, level, xoffset, yoffset, x, y, width, height, border) { 1532 var ext = this._ext; 1533 var gl = ext.gl; 1534 var texTarget = ext.textureTargetMap[target]; 1535 var current = ext.cb.getCurrentTexture(texTarget); 1536 (current != texture) && gl.bindTexture(texTarget, texture); 1537 gl.copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, border); 1538 (current != texture) && gl.bindTexture(texTarget, current); 1539 }; 1540 1541 dsa.generateMipmap = function (texture, target) { 1542 var ext = this._ext; 1543 var gl = ext.gl; 1544 var current = ext.cb.getCurrentTexture(target); 1545 (current != texture) && gl.bindTexture(target, texture); 1546 gl.generateMipmap(target); 1547 (current != texture) && gl.bindTexture(target, current); 1548 }; 1549 1550 dsa.texImage2D = function (texture, target) { 1551 var ext = this._ext; 1552 var gl = ext.gl; 1553 var texTarget = ext.textureTargetMap[target]; 1554 var current = ext.cb.getCurrentTexture(texTarget); 1555 (current != texture) && gl.bindTexture(texTarget, texture); 1556 var args = Array.prototype.slice.call(arguments, 1); 1557 gl.texImage2D.apply(gl, args); 1558 (current != texture) && gl.bindTexture(texTarget, current); 1559 }; 1560 1561 dsa.texParameterf = function (texture, target, pname, param) { 1562 var ext = this._ext; 1563 var gl = ext.gl; 1564 var current = ext.cb.getCurrentTexture(target); 1565 (current != texture) && gl.bindTexture(target, texture); 1566 gl.texParameterf(target, pname, param); 1567 (current != texture) && gl.bindTexture(target, current); 1568 }; 1569 1570 dsa.texParameteri = function (texture, target, pname, param) { 1571 var ext = this._ext; 1572 var gl = ext.gl; 1573 var current = ext.cb.getCurrentTexture(target); 1574 (current != texture) && gl.bindTexture(target, texture); 1575 gl.texParameteri(target, pname, param); 1576 (current != texture) && gl.bindTexture(target, current); 1577 }; 1578 1579 dsa.texSubImage2D = function (texture, target) { 1580 var ext = this._ext; 1581 var gl = ext.gl; 1582 var texTarget = ext.textureTargetMap[target]; 1583 var current = ext.cb.getCurrentTexture(texTarget); 1584 (current != texture) && gl.bindTexture(texTarget, texture); 1585 var args = Array.prototype.slice.call(arguments, 1); 1586 gl.texSubImage2D.apply(gl, args); 1587 (current != texture) && gl.bindTexture(texTarget, current); 1588 }; 1589 1590 dsa.bindTexture = function (unit, target, texture) { 1591 var ext = this._ext; 1592 var gl = ext.gl; 1593 var cb = ext.cb; 1594 var currentUnit = cb.getCurrentTextureUnit(); 1595 (currentUnit != unit) && gl.activeTexture(unit); 1596 gl.bindTexture(target, texture); 1597 (currentUnit != unit) && gl.activeTexture(currentUnit); 1598 }; 1599 ////////////////////////////////////////////////////////////////////////////////////////// 1600 1601 return true; 1602 }; 1603 1604 /** 1605 * Hijacks a WebGLRenderingContext for SpiderGL.WebGL.ObjectGL wrappers. 1606 * 1607 * The WebGLRenderingContext is modified to allow SpiderGL.WebGL.ObjectGL wrappers to be edited without explicit bind and without affecting the WebGL object bindings. 1608 * Most WebGL objects follow the "bind to edit" / "bind to use" paradigm. 1609 * This means that the object must be bound to the WebGL context to modify some parameter or its resource data. 1610 * As a side effect, binding the object just to modify it has the same result of binding it to be used during rendering. 1611 * To prevent this side effect, all the WebGLRenderingContext functions that bind and modify object parameters or data, as long as the rendering functions, are wrapped. 1612 * This allows SpiderGL wrappers (derived from {@link SpiderGL.WebGL.ObjectGL}) to be edited without affecting the binding state of the WebGLRenderingContext. 1613 * The following example clarifies how bindings are handled. 1614 * 1615 * @example 1616 * var textureA = gl.createTexture(); 1617 * gl.bindTexture(gl.TEXTURE_2D, textureA); 1618 * gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 1619 * // other texture calls 1620 * var textureB = new SpiderGL.WebGL.Texture2D(gl, parameters); 1621 * textureB.minFilter = gl.LINEAR; // textureB is hiddenly bound to modify the minification filter 1622 * gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); // textureA is automatically re-bound to keep WebGL semantic 1623 * textureB.magFilter = gl.LINEAR; // textureB is hiddenly bound to modify another parameter 1624 * gl.drawArrays(gl.TRIANGLES, 0, 3); // textureA is automatically re-bound to keep WebGL semantic 1625 * textureB.bind(); // bind textureB to WebGL, breaking the binding with textureA 1626 * gl.drawArrays(gl.TRIANGLES, 0, 3); // textureA is used 1627 * 1628 * @param {WebGLRenderingContext} gl The WebGLRenderingContext to modify. 1629 * 1630 * @returns {bool} True on success, false if the gl argument is not valid or has already been modified. 1631 * 1632 * @see SpiderGL.WebGL.Context.isHijacked 1633 * @see SpiderGL.WebGL.Context.getHijacked 1634 * @see SpiderGL.WebGL.Context.get 1635 * @see SpiderGL.WebGL.ObjectGL 1636 */ 1637 SpiderGL.WebGL.Context.hijack = function (gl) { 1638 if (!SpiderGL.Type.instanceOf(gl, WebGLRenderingContext)) { return false; } 1639 if (gl._spidergl) { return false; } 1640 1641 SpiderGL.WebGL.Context._prepareContex(gl); 1642 1643 SpiderGL.WebGL.Context._addExtension(gl, "SGL_current_binding", "cb", SpiderGL.WebGL.Context._setup_SGL_current_binding); 1644 SpiderGL.WebGL.Context._addExtension(gl, "SGL_wrapper_notify", "wn", SpiderGL.WebGL.Context._setup_SGL_wrapper_notify); 1645 SpiderGL.WebGL.Context._addExtension(gl, "SGL_direct_state_access", "dsa", SpiderGL.WebGL.Context._setup_SGL_direct_state_access); 1646 1647 var cb = gl.getExtension("SGL_current_binding" ); 1648 var wn = gl.getExtension("SGL_wrapper_notify" ); 1649 var dsa = gl.getExtension("SGL_direct_state_access"); 1650 1651 var hijacked = (!!cb && !!wn && !!dsa); 1652 1653 return hijacked; 1654 } 1655 1656 /** 1657 * Tests whether a WebGLRenderingContext is hijacked. 1658 * 1659 * The WebGLRenderingContext is hijacked after a successful call to {@link SpiderGL.WebGL.Context.hijack}. 1660 * 1661 * @param {WebGLRenderingContext} gl The WebGLRenderingContext to test. 1662 * 1663 * @returns {bool} True on success, false if the gl argument is not valid or has already been modified. 1664 * 1665 * @see SpiderGL.WebGL.Context.hijack 1666 * @see SpiderGL.WebGL.Context.getHijacked 1667 * @see SpiderGL.WebGL.Context.get 1668 */ 1669 SpiderGL.WebGL.Context.isHijacked = function (gl) { 1670 return (SpiderGL.Type.instanceOf(gl, WebGLRenderingContext) && gl._spidergl); 1671 } 1672 1673 /** 1674 * Creates a WebGLRenderingContext and hijacks it. 1675 * 1676 * The WebGLRenderingContext obtained from the canvas parameter with optional arguments is hijacked. 1677 * 1678 * @param {HTMLCanvasElement} canvas The HTMLCanvasElement from which retrieve the WebGL context. 1679 * @param {object} args The optional WebGL context arguments. 1680 * 1681 * @returns {WebGLRenderingContext} The hijacked canvas WebGL rendering context. 1682 * 1683 * @see SpiderGL.WebGL.Context.get 1684 * @see SpiderGL.WebGL.Context.getHijacked 1685 * @see SpiderGL.WebGL.Context.isHijacked 1686 */ 1687 SpiderGL.WebGL.Context.getHijacked = function (canvas, args) { 1688 var gl = SpiderGL.WebGL.Context.get(canvas, args); 1689 SpiderGL.WebGL.Context.hijack(gl); 1690 return gl; 1691 } 1692 1693 /** 1694 * Sets pixel store unpack parameters to standard OpenGL SpiderGL values. 1695 * The parameters to be set are UNPACK_FLIP_Y_WEBGL (true), UNPACK_PREMULTIPLY_ALPHA_WEBGL (false) and UNPACK_COLORSPACE_CONVERSION_WEBGL (WebGLRenderingContext.NONE). 1696 * 1697 * @param {WebGLRenderingContext} gl The target WebGLRenderingContext. 1698 */ 1699 SpiderGL.WebGL.Context.setStandardGLUnpack = function (gl) { 1700 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 1701 gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); 1702 gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, WebGLRenderingContext.NONE); 1703 } 1704 1705 /** 1706 * Creates a SpiderGL.WebGL.ObjectGL. 1707 * 1708 * SpiderGL.WebGL.ObjectGL is the base class for every WebObjectGL wrapper and must not be directly used. 1709 * In general, every SpiderGL.WebGL.ObjectGL-derived constructor takes two arguments: a hijacked WebGLRenderingContext ("gl") 1710 * and an optional object argument ("options") that is used to wrap an existing native WebObjectGL and to set object-specific parameters or data. 1711 * If the options parameter has a propery named "handle" referencing a WebObjectGL, the constructed SpiderGL.WebGL.ObjectGL will use the provided WebObjectGL as the underlying resource. 1712 * Otherwise, a new WebObjectGL is created. In both cases, the internal WebObjectGL can be accessed with the {@link handle} read-only property and directly used in WebGLRenderingContext calls. 1713 * With a notification mechanism built into the hijacked WebGLRenderingContext, every direct access is communicated to the wrapper to keep up-to-date the internal state of the wrapper. 1714 * 1715 * @example 1716 * // create a native vertex WebGLBuffer 1717 * var vbo = gl.createBuffer(); 1718 * gl.bindBuffer(gl.ARRAY_BUFFER, vbo); 1719 * // ... use buffer ... 1720 * // create a SpiderGL wrapper from an existing object; 1721 * // the native object can be accessed through the "handle" property. 1722 * var wrappedVBO = new SpiderGL.WebGL.VertexBuffer(gl, {handle: vbo}); 1723 * // it is not mandatory to bind the object before setting parameters or data 1724 * as the hijacked WebGLRendering context takes care of it and does not break previous bindings 1725 * wrappedVBO.setSize(sizeInBytes, gl.STATIC_DRAW); 1726 * wrappedVBO.bind(); // equivalent to gl.bindBuffer(gl.ARRAY_BUFFER, wrappedVBO.handle) 1727 * // create another SpiderGL.WebGL.VertexBuffer without specifying an existing object, 1728 * // thus letting the wrapper to create one 1729 * var anotherVBO = new SpiderGL.WebGL.VertexBuffer(gl, {size: someSizeInBytes}); 1730 * 1731 * @class The SpiderGL.WebGL.ObjectGL is the base class for all WebGL object wrappers. 1732 * 1733 * @augments SpiderGL.Core.ObjectBase 1734 * 1735 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 1736 * @param {number} target The WebObjectGL default target. 1737 * @param {object} [options] Object-specific parameters. 1738 */ 1739 SpiderGL.WebGL.ObjectGL = function (gl, target, options) { 1740 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 1741 1742 options = SpiderGL.Utility.getDefaultObject({ 1743 handle : null 1744 }, options); 1745 1746 SpiderGL.Core.ObjectBase.call(this); 1747 1748 var wn = gl.getExtension("SGL_wrapper_notify"); 1749 1750 this._gl = gl; 1751 this._cb = gl.getExtension("SGL_current_binding"); 1752 this._dsa = gl.getExtension("SGL_direct_state_access"); 1753 1754 this._h = options.handle; 1755 this._t = target; 1756 } 1757 1758 /** 1759 * Default WebObjectGL target. 1760 * 1761 * @type number 1762 * 1763 * @default WebGLRenderingContext.NONE 1764 */ 1765 SpiderGL.WebGL.ObjectGL.TARGET = WebGLRenderingContext.NONE; 1766 1767 /** 1768 * Generic null WebObjectGL binding. 1769 * 1770 * This function is empty and provided only for completeness. 1771 * 1772 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 1773 */ 1774 SpiderGL.WebGL.ObjectGL.unbind = function (gl) { }; 1775 1776 SpiderGL.WebGL.ObjectGL.prototype = { 1777 /** 1778 * The WebGLRenderingContext used at costruction. 1779 * 1780 * @type WebGLRenderingContext 1781 * 1782 * @readonly 1783 * 1784 * @see #handle 1785 */ 1786 get gl() { 1787 return this._gl; 1788 }, 1789 1790 /** 1791 * The native WebObjectGL. 1792 * 1793 * The native handle can be used with WebGLRenderingContext methods. 1794 * 1795 * @type WebObjectGL 1796 * 1797 * @readonly 1798 * 1799 * @see #gl 1800 */ 1801 get handle() { 1802 return this._h; 1803 }, 1804 1805 /** 1806 * The WebObjectGL default target. 1807 * 1808 * @type number 1809 * 1810 * @readonly 1811 */ 1812 get target() { 1813 return this._t; 1814 }, 1815 1816 /** 1817 * Tests for non-null handle. 1818 * 1819 * @type bool 1820 * 1821 * @readonly 1822 */ 1823 get isValid() { 1824 return (this._h != null); 1825 }, 1826 1827 /* * 1828 * Tests for empty object. 1829 * It is reimplemented on each derived classes with object-specific semantic. 1830 * 1831 * @type bool 1832 * 1833 * @readonly 1834 */ 1835 /* 1836 get isEmpty () { 1837 return true; 1838 }, 1839 */ 1840 1841 /** 1842 * Tests if the object is ready to use. 1843 * It is reimplemented on each derived classes with object-specific semantic. 1844 * 1845 * @type bool 1846 * 1847 * @readonly 1848 */ 1849 get isReady () { 1850 return false; 1851 }, 1852 1853 /** 1854 * Destroys the wrapped WebObjectGL. 1855 * 1856 * After calling this method, the object must not be accessed anymore. 1857 */ 1858 destroy : function () { 1859 }, 1860 1861 /** 1862 * Binds the object to the rendering pipeline. 1863 * 1864 * The wrapped WebObjectGL is bound to its default target in the WebGLRenderingContext. 1865 */ 1866 bind : function () { 1867 }, 1868 1869 /** 1870 * Binds the null object to the rendering pipeline. 1871 * 1872 * This method is provided for symmetry with {@link SpiderGL.WebGL.ObjectGL#bind}. It binds the null object to the per-object webGL target. 1873 */ 1874 unbind : function () { 1875 } 1876 }; 1877 1878 SpiderGL.Type.extend(SpiderGL.WebGL.ObjectGL, SpiderGL.Core.ObjectBase); 1879 1880 /** 1881 * Creates a SpiderGL.WebGL.Buffer. 1882 * 1883 * SpiderGL.WebGL.Buffer is the base class for WebGLBuffer object wrappers ({@link SpiderGL.WebGL.VertexBuffer} and {@link SpiderGL.WebGL.IndexBuffer}) and must not be directly used. 1884 * When passing data or size with the options parameter, the data field will have precedence on the size field, which will be ignored. 1885 * 1886 * @class The SpiderGL.WebGL.Buffer is the base class for all WebGLBuffer object wrappers, i.e. {@link SpiderGL.WebGL.VertexBuffer} and {@link SpiderGL.WebGL.IndexBuffer}. 1887 * 1888 * @augments SpiderGL.WebGL.ObjectGL 1889 * 1890 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 1891 * @param {number} target The WebGLBuffer target. It must be either WebGLRenderingContext.ARRAY_BUFFER or WebGLRenderingContext.ELEMENT_ARRAY_BUFFER. 1892 * @param {object} [options] Optional parameters. 1893 * @param {WebGLBuffer} [options.handle] If defined, the provided buffer will be wrapped and its size and usage attributes will be queried to the rendering context. Otherwise an internal buffer will be created. 1894 * @param {ArrayBuffer|ArrayBufferView} [options.data] Buffer content to be set with WebGLRenderingContext.bufferData (see {@link setData}). If present, the data will be set both if a handle is provided or internally created. 1895 * @param {number} [options.size] Buffer size to be set with WebGLRenderingContext.bufferData (see {@link setData}). If present, it will be set both if a handle is provided or internally created. If data parameter is present, the size field is ignored. 1896 * @param {number} [options.usage=SpiderGL.WebGL.Buffer.DEFAULT_USAGE] WebGL buffer usage hint parameter for WebGLRenderingContext.bufferData. 1897 * 1898 * @example 1899 * // create a vertex buffer with a specified size 1900 * var vbuff = new SpiderGL.WebGL.VertexBuffer(gl, { 1901 * size : 2 * 1024 * 1024, // 2 MB 1902 * usage : gl.STATIC_DRAW // if omitted, defaults to SpiderGL.WebGL.Buffer.DEFAULT_USAGE 1903 * }); 1904 * 1905 * // create an index buffer with content 1906 * var ibuff = new SpiderGL.WebGL.IndexBuffer(gl, { 1907 * data : new Uint16Array(...) // use a typed array for setting buffer data 1908 * }); 1909 * 1910 * @see SpiderGL.WebGL.ObjectGL 1911 * @see SpiderGL.WebGL.VertexBuffer 1912 * @see SpiderGL.WebGL.IndexBuffer 1913 */ 1914 SpiderGL.WebGL.Buffer = function (gl, target, options) { 1915 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 1916 1917 if (SpiderGL.Type.instanceOf(options, WebGLBuffer)) { 1918 options = { handle : options }; 1919 } 1920 else if (SpiderGL.Type.instanceOf(options, ArrayBuffer) || SpiderGL.Type.isTypedArray(options)) { 1921 options = { data : options }; 1922 } 1923 else if (SpiderGL.Type.isNumber(options)) { 1924 options = { size : options }; 1925 } 1926 1927 options = SpiderGL.Utility.getDefaultObject({ 1928 handle : null, 1929 data : null, 1930 size : 0, 1931 usage : SpiderGL.WebGL.Buffer.DEFAULT_USAGE 1932 }, options); 1933 1934 SpiderGL.WebGL.ObjectGL.call(this, gl, target, options); 1935 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 1936 1937 var gl = this._gl; 1938 var cb = this._cb; 1939 var dsa = this._dsa; 1940 1941 var t = this._t; 1942 var h = this._h; 1943 1944 cb.pushBuffer(t); 1945 if (h) { 1946 gl.bindBuffer(t, h); 1947 options.size = gl.getBufferParameter(t, gl.BUFFER_SIZE); 1948 options.usage = gl.getBufferParameter(t, gl.BUFFER_USAGE); 1949 } 1950 else { 1951 h = gl.createBuffer(); 1952 gl.bindBuffer(t, h); 1953 this._h = h; 1954 } 1955 cb.popBuffer(t); 1956 h._spidergl = this; 1957 1958 this._size = options.size; 1959 this._usage = options.usage; 1960 1961 if (options.data) { 1962 this.setData(options.data, options.usage); 1963 } 1964 else if (options.size) { 1965 this.setSize(options.size, options.usage); 1966 } 1967 } 1968 1969 /** 1970 * Default WebGLBuffer target. 1971 * 1972 * @type number 1973 * 1974 * @default WebGLRenderingContext.NONE 1975 */ 1976 SpiderGL.WebGL.Buffer.TARGET = WebGLRenderingContext.NONE; 1977 1978 /** 1979 * Default usage hint when specifying buffer size or data. 1980 * 1981 * @type number 1982 * 1983 * @default WebGLRenderingContext.STATIC_DRAW 1984 */ 1985 SpiderGL.WebGL.Buffer.DEFAULT_USAGE = WebGLRenderingContext.STATIC_DRAW; 1986 1987 /** 1988 * Default buffer offset when specifying buffer subdata. 1989 * 1990 * @type number 1991 * 1992 * @default 0 1993 */ 1994 SpiderGL.WebGL.Buffer.DEFAULT_SUB_DATA_OFFSET = 0; 1995 1996 /** 1997 * Generic WebGLBuffer unbinding. 1998 * 1999 * This function is empty and it is provided only for completeness. 2000 * 2001 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 2002 */ 2003 SpiderGL.WebGL.Buffer.unbind = function (gl) { }; 2004 2005 SpiderGL.WebGL.Buffer.prototype = { 2006 _gl_deleteBuffer : function () { 2007 this._h = null; 2008 }, 2009 2010 _gl_isBuffer : function () { 2011 }, 2012 2013 _gl_bindBuffer : function () { 2014 }, 2015 2016 _gl_getBufferParameter : function () { 2017 }, 2018 2019 _gl_bufferData : function () { 2020 var sizeOrData = arguments[1]; 2021 var usage = arguments[2]; 2022 this._size = (SpiderGL.Type.isNumber(sizeOrData)) ? (sizeOrData) : (sizeOrData.byteLength); 2023 this._usage = usage; 2024 }, 2025 2026 _gl_bufferSubData : function () { 2027 }, 2028 2029 _gl_vertexAttribPointer : function () { 2030 }, 2031 2032 _gl_drawElements : function () { 2033 }, 2034 2035 /* * 2036 * Tests for empty buffer. 2037 * It is true if the buffer size is greather than zero, false otherwise. 2038 * 2039 * @type bool 2040 * 2041 * @readonly 2042 */ 2043 /* 2044 get isEmpty() { return (this._size <= 0); }, 2045 */ 2046 2047 /** 2048 * Tests if the buffer is ready to use. 2049 * A buffer is considered ready if its size is greater than zero. 2050 * 2051 * @type bool 2052 * 2053 * @readonly 2054 */ 2055 get isReady () { 2056 return (this._size > 0); 2057 }, 2058 2059 /** 2060 * The size in bytes of the buffer. 2061 * 2062 * @type number 2063 * 2064 * @readonly 2065 */ 2066 get size() { 2067 return this._size; 2068 }, 2069 2070 /** 2071 * The usage hint of the WebGLBuffer. 2072 * It refers to the usage hint as specified in WebGLRenderingContext.bufferData(). 2073 * 2074 * @type number 2075 * 2076 * @readonly 2077 */ 2078 get usage() { 2079 return this._usage; 2080 }, 2081 2082 /** 2083 * Sets the buffer size and usage. 2084 * The buffer is set up with specified size and usage. 2085 * 2086 * @param {number} size The buffer size. 2087 * @param {number} [usage=SpiderGL.WebGL.Buffer.DEFAULT_USAGE] WebGL buffer usage hint. 2088 * 2089 * @see setData 2090 */ 2091 setSize : function (size, usage) { 2092 usage = SpiderGL.Utility.getDefaultValue(usage, SpiderGL.WebGL.Buffer.DEFAULT_USAGE); 2093 this._dsa.bufferData(this._h, this._t, size, usage); 2094 }, 2095 2096 /** 2097 * Sets the buffer data and usage. 2098 * The buffer is set up with specified data and usage. 2099 * 2100 * @param {ArrayBuffer|ArrayBufferView} data The buffer data. 2101 * @param {number} [usage=SpiderGL.WebGL.Buffer.DEFAULT_USAGE] WebGL buffer usage hint. 2102 * 2103 * @see setSubData 2104 * @see setSize 2105 */ 2106 setData : function (data, usage) { 2107 usage = SpiderGL.Utility.getDefaultValue(usage, SpiderGL.WebGL.Buffer.DEFAULT_USAGE); 2108 this._dsa.bufferData(this._h, this._t, data, usage); 2109 }, 2110 2111 /** 2112 * Sets a range of the buffer data. 2113 * A range of buffer content can be set by specifying the starting offset and the typed array of values. 2114 * 2115 * @param {ArrayBuffer|ArrayBufferView} data The buffer sub data. 2116 * @param {number} [offset=SpiderGL.WebGL.Buffer.DEFAULT_SUB_DATA_OFFSET] The range starting offset, in bytes. 2117 * 2118 * @see setData 2119 */ 2120 setSubData : function (data, offset) { 2121 offset = SpiderGL.Utility.getDefaultValue(offset, SpiderGL.WebGL.Buffer.DEFAULT_SUB_DATA_OFFSET); 2122 this._dsa.bufferSubData(this._h, this._t, offset, data); 2123 }, 2124 2125 /** 2126 * Destroys the WebGLBuffer. 2127 * After destruction, the handle is set to null and this object should not be used anymore. 2128 * 2129 * @see SpiderGL.WebGL.ObjectGL#destroy 2130 */ 2131 destroy : function () { 2132 this._gl.deleteBuffer(this._h); 2133 }, 2134 2135 /** 2136 * Binds the wrapped WebGLBuffer to the appropriate target. 2137 * The used target is set by the derived objects {@link SpiderGL.WebGL.VertexBuffer} and {@link SpiderGL.WebGL.IndexBuffer}. 2138 * 2139 * @see unbind 2140 */ 2141 bind : function () { 2142 this._gl.bindBuffer(this._t, this._h); 2143 }, 2144 2145 /** 2146 * Binds "null" to the appropriate target. 2147 * This method is provided only for simmetry with {@link bind} and is not relative to the object state. 2148 * 2149 * @see bind 2150 */ 2151 unbind : function () { 2152 this._gl.bindBuffer(this._t, null); 2153 } 2154 }; 2155 2156 SpiderGL.Type.extend(SpiderGL.WebGL.Buffer, SpiderGL.WebGL.ObjectGL); 2157 2158 /** 2159 * Creates a SpiderGL.WebGL.VertexBuffer. 2160 * 2161 * SpiderGL.WebGL.VertexBuffer represents a wrapper for a WebGLBuffer to be bound to the WebGLRenderingContext.ARRAY_BUFFER target. 2162 * 2163 * @class The SpiderGL.WebGL.VertexBuffer is WebGLBuffer wrapper for vertex buffers. 2164 * 2165 * @augments SpiderGL.WebGL.Buffer 2166 * 2167 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 2168 * @param {object} [options] See {@link SpiderGL.WebGL.Buffer}. 2169 * 2170 * @see SpiderGL.WebGL.Buffer 2171 * @see SpiderGL.WebGL.IndexBuffer 2172 * @see SpiderGL.WebGL.ObjectGL 2173 */ 2174 SpiderGL.WebGL.VertexBuffer = function (gl, options) { 2175 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 2176 SpiderGL.WebGL.Buffer.call(this, gl, SpiderGL.WebGL.VertexBuffer.TARGET, options); 2177 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 2178 } 2179 2180 /** 2181 * WebGL target for vertex buffers. 2182 * 2183 * @type number 2184 * 2185 * @default WebGLRenderingContext.ARRAY_BUFFER 2186 */ 2187 SpiderGL.WebGL.VertexBuffer.TARGET = WebGLRenderingContext.ARRAY_BUFFER; 2188 2189 /** 2190 * Default vertex attribute index when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2191 * 2192 * @type number 2193 * 2194 * @default 0 2195 */ 2196 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX = 0; 2197 2198 /** 2199 * Default vertex attribute size when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2200 * 2201 * @type number 2202 * 2203 * @default 3 2204 */ 2205 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE = 3; 2206 2207 /** 2208 * Default vertex attribute type when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2209 * 2210 * @type number 2211 * 2212 * @default WebGLRenderingContext.FLOAT 2213 */ 2214 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE = WebGLRenderingContext.FLOAT; 2215 2216 /** 2217 * Default vertex attribute normalized flag when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2218 * 2219 * @type bool 2220 * 2221 * @default false 2222 */ 2223 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED = false; 2224 2225 /** 2226 * Default vertex attribute stride when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2227 * 2228 * @type number 2229 * 2230 * @default 0 2231 */ 2232 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE = 0; 2233 2234 /** 2235 * Default vertex attribute offset when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2236 * 2237 * @type number 2238 * 2239 * @default 0 2240 */ 2241 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET = 0; 2242 2243 /** 2244 * Default enable flag for vertex attribute when using SpiderGL.WebGL.VertexBuffer#vertexAttribPointer. 2245 * 2246 * @type bool 2247 * 2248 * @default true 2249 */ 2250 SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE = true; 2251 2252 /** 2253 * WebGLBuffer unbinding for vertex buffers. 2254 * 2255 * This function binds the null buffer to the WebGLRenderingContext.ARRAY_BUFFER target. 2256 * 2257 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 2258 */ 2259 SpiderGL.WebGL.VertexBuffer.unbind = function (gl) { gl.bindBuffer(SpiderGL.WebGL.VertexBuffer.TARGET, null); }; 2260 2261 SpiderGL.WebGL.VertexBuffer.prototype = { 2262 /** 2263 * Latches the WebGL vertex attribute pointer with the internal buffer. 2264 * The effect of this method is to bind the SpiderGL.WebGL.VertexBuffer and call WebGLRenderingContext.vertexAttribPointer() with the provided parameters. 2265 * 2266 * @param {object} [options] Vertex attribute pointer parameters. 2267 * @param {number} [options.index=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX] Attribute index. 2268 * @param {number} [options.size=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE] Attribute size. 2269 * @param {number} [options.type=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE] Attribute base type. 2270 * @param {number} [options.normalized=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED] True if the attribute has an integer type and must be normalized. 2271 * @param {number} [options.stride=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE] Bytes from the beginning of an element and the beginning of the next one. 2272 * @param {number} [options.offset=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET] Offset (in bytes) from the start of the buffer. 2273 * @param {bool} [options.enable=SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE] If true, the index-th vertex attribute array will be enabled with WebGLRenderingContext.enableVertexAttribArray(index). 2274 * 2275 * @example 2276 * var vb = new SpiderGL.WebGL.VertexBuffer(...); // create a vertex buffer 2277 * // [... set vb data ...] 2278 * // calling vb.vertexAttribPointer has the same effect of: 2279 * // vb.bind(); 2280 * // gl.vertexAttribPointer(positionAttributeIndex, 3, gl.FLOAT, false, 0, 0); 2281 * // gl.enableVertexAttribArray(positionAttributeIndex); 2282 * vb.vertexAttribPointer({ 2283 * index : positionAttributeIndex, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX 2284 * size : 3, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE 2285 * glType : gl.FLOAT, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE 2286 * normalized : false, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED 2287 * stride : 0, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE 2288 * offset : 0, // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET 2289 * enable : true // if omitted, defaults to SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE 2290 * }); 2291 */ 2292 vertexAttribPointer : function (options) { 2293 options = SpiderGL.Utility.getDefaultObject({ 2294 index : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX, 2295 size : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE, 2296 glType : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE, 2297 normalized : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED, 2298 stride : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE, 2299 offset : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET, 2300 enable : SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE 2301 }, options); 2302 2303 this._dsa.vertexAttribPointer(this._h, options.index, options.size, options.glType, options.normalized, options.stride, options.offset); 2304 if (options.enable) { 2305 this._gl.enableVertexAttribArray(options.index); 2306 } 2307 } 2308 }; 2309 2310 SpiderGL.Type.extend(SpiderGL.WebGL.VertexBuffer, SpiderGL.WebGL.Buffer); 2311 2312 2313 /** 2314 * Creates a SpiderGL.WebGL.IndexBuffer. 2315 * 2316 * SpiderGL.WebGL.IndexBuffer represents a wrapper for a WebGLBuffer to be bound to the WebGLRenderingContext.ELEMENT_ARRAY_BUFFER target. 2317 * 2318 * @class The SpiderGL.WebGL.IndexBuffer is WebGLBuffer wrapper for index buffers. 2319 * 2320 * @augments SpiderGL.WebGL.Buffer 2321 * 2322 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 2323 * @param {object} [options] See {@link SpiderGL.WebGL.Buffer}. 2324 * 2325 * @see SpiderGL.WebGL.Buffer 2326 * @see SpiderGL.WebGL.VertexBuffer 2327 * @see SpiderGL.WebGL.ObjectGL 2328 */ 2329 SpiderGL.WebGL.IndexBuffer = function (gl, options) { 2330 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 2331 SpiderGL.WebGL.Buffer.call(this, gl, SpiderGL.WebGL.IndexBuffer.TARGET, options); 2332 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 2333 } 2334 2335 /** 2336 * WebGL target for index buffers. 2337 * 2338 * @type number 2339 * 2340 * @default WebGLRenderingContext.ELEMENT_ARRAY_BUFFER 2341 */ 2342 SpiderGL.WebGL.IndexBuffer.TARGET = WebGLRenderingContext.ELEMENT_ARRAY_BUFFER; 2343 2344 /** 2345 * Default elements draw mode when using SpiderGL.WebGL.IndexBuffer#drawElements. 2346 * 2347 * @type number 2348 * 2349 * @default WebGLRenderingContext.TRIANGLES 2350 */ 2351 SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE = WebGLRenderingContext.TRIANGLES; 2352 2353 /** 2354 * Default elements count when using SpiderGL.WebGL.IndexBuffer#drawElements. 2355 * A negative value causes the calculation of the maximum number of elements given the buffer size, offset and index type. 2356 * 2357 * @type number 2358 * 2359 * @default -1 2360 */ 2361 SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT = -1; 2362 2363 /** 2364 * Default index type when using SpiderGL.WebGL.IndexBuffer#drawElements. 2365 * 2366 * @type number 2367 * 2368 * @default WebGLRenderingContext.UNSIGNED_SHORT 2369 */ 2370 SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE = WebGLRenderingContext.UNSIGNED_SHORT; 2371 2372 /** 2373 * Default index buffer offset when using SpiderGL.WebGL.IndexBuffer#drawElements. 2374 * 2375 * @type number 2376 * 2377 * @default 0 2378 */ 2379 SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET = 0; 2380 2381 /** 2382 * WebGLBuffer unbinding for index buffers. 2383 * 2384 * This function binds the null buffer to the WebGLRenderingContext.ELEMENT_ARRAY_BUFFER target. 2385 * 2386 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 2387 */ 2388 SpiderGL.WebGL.IndexBuffer.unbind = function (gl) { gl.bindBuffer(SpiderGL.WebGL.IndexBuffer.TARGET, null); }; 2389 2390 SpiderGL.WebGL.IndexBuffer.prototype = { 2391 /** 2392 * Binds the index buffers and calls WebGLRenderingContext.drawElements with the provided parameters. 2393 * 2394 * @param {object} [options] Draw parameters. 2395 * @param {number} [options.glMode=SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE] The WebGL primitive type. 2396 * @param {number} [options.count=SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT] Number of elements to draw. If less than or equal to zero, its value will be calculated as the maximum number of stored indices, based on offset, buffer size and index type. 2397 * @param {number} [options.glType=SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE] Index type. 2398 * @param {number} [options.offset=SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET] Offset (in bytes) from the start of the buffer. 2399 * 2400 * @example 2401 * var ib = new SpiderGL.WebGL.IndexBuffer(...); // create an index buffer 2402 * // [... set ib data ...] 2403 * // calling ib.drawElements has the same effect of: 2404 * // ib.bind(); 2405 * // gl.drawElements(gl.TRIANGLES, (ib.size - offset) / SpiderGL.Type.SIZEOF_UINT16, gl.UNSIGNED_SHORT, offset); 2406 * ib.drawElements({ 2407 * glMode : gl.TRIANGLES, // if omitted, defaults to SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE 2408 * count : 0, // if omitted, defaults to SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT 2409 * glType : gl.UNSIGNED_SHORT, // if omitted, defaults to SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE 2410 * offset : offset // if omitted, defaults to SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET 2411 * }); 2412 */ 2413 drawElements : function (options) { 2414 options = SpiderGL.Utility.getDefaultObject({ 2415 glMode : SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE, 2416 count : SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT, 2417 glType : SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE, 2418 offset : SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET 2419 }, options); 2420 2421 if (options.count < 1) { 2422 var bytesPerElem = SpiderGL.Type.typeSizeFromGL(options.glType); 2423 options.count = (this._size - options.offset) / bytesPerElem; 2424 } 2425 2426 this._dsa.drawElements(this._h, options.glMode, options.count, options.glType, options.offset); 2427 } 2428 }; 2429 2430 SpiderGL.Type.extend(SpiderGL.WebGL.IndexBuffer, SpiderGL.WebGL.Buffer); 2431 2432 /** 2433 * Creates a SpiderGL.WebGL.Framebuffer. 2434 * 2435 * SpiderGL.WebGL.Framebuffer wraps a WebGLFramebuffer object. 2436 * 2437 * @class The SpiderGL.WebGL.Framebuffer is a wrapper for WebGLFramebuffer. 2438 * 2439 * @augments SpiderGL.WebGL.ObjectGL 2440 * 2441 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 2442 * @param {object} [options] Optional parameters. 2443 * @param {WebGLFramebuffer} [options.handle] A WebGLFramebuffer. If present, this object will be used as the wrapped WebGLFramebuffer. Otherwise a new one will be created. 2444 * @param {bool} [options.autoViewport=SpiderGL.WebGL.Framebuffer.DEFAULT_AUTO_VIEWPORT] The value of the {@link autoViewport} property. 2445 * @param {object} [options.color] Color attachment target (see {@link setAttachments}). 2446 * @param {object} [options.depth] Depth attachment target (see {@link setAttachments}). 2447 * @param {object} [options.stencil] Stencil attachment target (see {@link setAttachments}). 2448 * @param {object} [options.depthStencil] Depth-Stencil attachment target (see {@link setAttachments}). 2449 * 2450 * @see setAttachments 2451 * @see SpiderGL.WebGL.Texture2D 2452 * @see SpiderGL.WebGL.TextureCubeMap 2453 * @see SpiderGL.WebGL.Renderbuffer 2454 * @see SpiderGL.WebGL.ObjectGL 2455 */ 2456 SpiderGL.WebGL.Framebuffer = function (gl, options) { 2457 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 2458 2459 if (SpiderGL.Type.instanceOf(options, WebGLFramebuffer)) { 2460 options = { handle : options }; 2461 } 2462 2463 options = SpiderGL.Utility.getDefaultObject({ 2464 handle : null, 2465 autoViewport : SpiderGL.WebGL.Framebuffer.DEFAULT_AUTO_VIEWPORT 2466 }, options); 2467 2468 var that = SpiderGL.WebGL.ObjectGL.call(this, gl, SpiderGL.WebGL.Framebuffer.TARGET, options); 2469 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 2470 2471 var gl = this._gl; 2472 var cb = this._cb; 2473 var dsa = this._dsa; 2474 2475 var t = this._t; 2476 var h = this._h; 2477 2478 var imported = false; 2479 if (h) { 2480 imported = true; 2481 } 2482 else { 2483 h = gl.createFramebuffer(); 2484 this._h = h; 2485 } 2486 h._spidergl = this; 2487 2488 this._attachments = { }; 2489 this._status = 0; 2490 this._autoViewport = options.autoViewport; 2491 this._viewport = [ 0, 0, 1, 1 ]; 2492 2493 cb.pushFramebuffer(t); 2494 gl.bindFramebuffer(t, h); 2495 2496 if (imported) { 2497 var resource = null; 2498 var type = 0; 2499 var level = 0; 2500 var target = 0; 2501 2502 for (var attachment in SpiderGL.WebGL.Framebuffer._attachmentName) { 2503 resource = gl.getFramebufferAttachmentParameter(t, att, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); 2504 type = gl.getFramebufferAttachmentParameter(t, att, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); 2505 switch (type) { 2506 case gl.RENDERBUFFER: 2507 target = gl.RENDERBUFFER; 2508 this._importRenderbuffer(t, attachment, target, resource); 2509 break; 2510 case gl.TEXTURE: 2511 level = gl.getFramebufferAttachmentParameter(t, att, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL); 2512 target = gl.getFramebufferAttachmentParameter(t, att, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE); 2513 if (target == 0) target = gl.TEXTURE_2D; 2514 this._importTexture(t, attachment, target, resource, level); 2515 break; 2516 default: break; 2517 } 2518 } 2519 } 2520 2521 this._status = gl.checkFramebufferStatus(t); 2522 2523 cb.popFramebuffer(t); 2524 2525 this.setAttachments(options); 2526 } 2527 2528 /** 2529 * WebGL target for framebuffers. 2530 * 2531 * @type number 2532 * 2533 * @default WebGLRenderingContext.FRAMEBUFFER 2534 */ 2535 SpiderGL.WebGL.Framebuffer.TARGET = WebGLRenderingContext.FRAMEBUFFER; 2536 2537 /** 2538 * Default value for SpiderGL.WebGL.Framebuffer#autoViewport. 2539 * 2540 * @type bool 2541 * 2542 * @default true 2543 */ 2544 SpiderGL.WebGL.Framebuffer.DEFAULT_AUTO_VIEWPORT = true; 2545 2546 /** 2547 * Default texture level to attach when using SpiderGL.WebGL.Framebuffer#setAttachments. 2548 * 2549 * @type number 2550 * 2551 * @default 0 2552 */ 2553 SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL = 0; 2554 2555 /** 2556 * Default texture cube map face to attach when using SpiderGL.WebGL.Framebuffer#setAttachments. 2557 * 2558 * @type number 2559 * 2560 * @default WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X 2561 */ 2562 SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE = WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X; 2563 2564 /** 2565 * Default read rectangle left coordinate (in pixels). 2566 * 2567 * @type number 2568 * 2569 * @default 0 2570 * 2571 * @see SpiderGL.WebGL.Framebuffer#readPixels 2572 */ 2573 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X = 0; 2574 2575 /** 2576 * Default read rectangle bottom coordinate (in pixels). 2577 * 2578 * @type number 2579 * 2580 * @default 0 2581 * 2582 * @see SpiderGL.WebGL.Framebuffer#readPixels 2583 */ 2584 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_Y = 0; 2585 2586 /** 2587 * Default read rectangle width (in pixels). 2588 * If less than zero, the width will be set to span the whole render target (starting from read rectangle x coordinate). 2589 * 2590 * @type number 2591 * 2592 * @default -1 2593 * 2594 * @see SpiderGL.WebGL.Framebuffer#readPixels 2595 */ 2596 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_WIDTH = -1; 2597 2598 /** 2599 * Default read rectangle height (in pixels). 2600 * If less than zero, the height will be set to span the whole render target (starting from read rectangle y coordinate). 2601 * 2602 * @type number 2603 * 2604 * @default -1 2605 * 2606 * @see SpiderGL.WebGL.Framebuffer#readPixels 2607 */ 2608 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_HEIGHT = -1; 2609 2610 /** 2611 * The WebGL pixel format for reading framebuffer pixels. 2612 * 2613 * @type number 2614 * 2615 * @default WebGLRenderingContext.RGBA 2616 * 2617 * @see SpiderGL.WebGL.Framebuffer#readPixels 2618 */ 2619 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_FORMAT = WebGLRenderingContext.RGBA; 2620 2621 /** 2622 * The WebGL birfield mask used for clearing the framebuffer. 2623 * 2624 * @type number 2625 * 2626 * @default (WebGLRenderingContext.COLOR_BUFFER_BIT | WebGLRenderingContext.DEPTH_BUFFER_BIT | WebGLRenderingContext.STENCIL_BUFFER_BIT) 2627 * 2628 * @see SpiderGL.WebGL.Framebuffer#clear 2629 */ 2630 SpiderGL.WebGL.Framebuffer.DEFAULT_CLEAR_MASK = (WebGLRenderingContext.COLOR_BUFFER_BIT | WebGLRenderingContext.DEPTH_BUFFER_BIT | WebGLRenderingContext.STENCIL_BUFFER_BIT); 2631 2632 /** 2633 * The WebGL pixel type for reading framebuffer pixels. 2634 * 2635 * @type number 2636 * 2637 * @default WebGLRenderingContext.UNSIGNED_BYTE 2638 * 2639 * @see SpiderGL.WebGL.Framebuffer#readPixels 2640 */ 2641 SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_TYPE = WebGLRenderingContext.UNSIGNED_BYTE; 2642 2643 /** 2644 * WebGLFramebuffer unbinding. 2645 * 2646 * This function binds the null framebuffer to the WebGLRenderingContext.FRAMEBUFFER target. 2647 * 2648 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 2649 */ 2650 SpiderGL.WebGL.Framebuffer.unbind = function (gl) { gl.bindFramebuffer(SpiderGL.WebGL.Framebuffer.TARGET, null); }; 2651 2652 SpiderGL.WebGL.Framebuffer._attachmentName = { }; 2653 SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.COLOR_ATTACHMENT0] = "color"; 2654 SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.DEPTH_ATTACHMENT] = "depth"; 2655 SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.STENCIL_ATTACHMENT] = "stencil"; 2656 SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.DEPTH_STENCIL_ATTACHMENT] = "depthStencil"; 2657 2658 SpiderGL.WebGL.Framebuffer.prototype = { 2659 _gl_deleteFramebuffer : function (framebuffer) { 2660 this._h = null; 2661 }, 2662 2663 _gl_isFramebuffer : function (framebuffer) { 2664 }, 2665 2666 _gl_bindFramebuffer : function (target, framebuffer) { 2667 }, 2668 2669 _gl_checkFramebufferStatus : function (target) { 2670 }, 2671 2672 _gl_getFramebufferAttachmentParameter : function (target, attachment, pname) { 2673 }, 2674 2675 _gl_framebufferRenderbuffer : function (target, attachment, renderbuffertarget, renderbuffer) { 2676 this._importRenderbuffer.apply(this, arguments); 2677 this._status = this._gl.checkFramebufferStatus(this._t); 2678 }, 2679 2680 _gl_framebufferTexture2D : function (target, attachment, textarget, texture, level) { 2681 this._importTexture.apply(this, arguments); 2682 this._status = this._gl.checkFramebufferStatus(this._t); 2683 }, 2684 2685 _gl_clear : function (mask) { 2686 }, 2687 2688 _gl_readPixels : function (x, y, width, height, format, type, pixels) { 2689 }, 2690 2691 _importTexture : function (target, attachment, textarget, texture, level) { 2692 var name = SpiderGL.WebGL.Framebuffer._attachmentName[attachment]; 2693 if (!name) return; 2694 2695 if (!texture) { 2696 delete this._attachments[name]; 2697 return; 2698 } 2699 2700 var gl = this._gl; 2701 2702 var att = { 2703 attachment : attachment, 2704 resource : null, 2705 target : textarget, 2706 level : level, 2707 face : gl.NONE 2708 }; 2709 2710 this._attachments[name] = att; 2711 2712 if (textarget == gl.TEXTURE_2D) { 2713 att.resource = new SpiderGL.WebGL.Texture2D(gl, { handle : texture }); 2714 } 2715 else { 2716 att.resource = new SpiderGL.WebGL.TextureCubeMap(gl, { handle : texture }); 2717 att.face = textarget; 2718 } 2719 2720 this._viewport = [ 0, 0, SpiderGL.Math.max(att.resource.width, 1), SpiderGL.Math.max(att.resource.height, 1) ]; 2721 }, 2722 2723 _importRenderbuffer : function (target, attachment, renderbuffertarget, renderbuffer) { 2724 var name = SpiderGL.WebGL.Framebuffer._attachmentName[attachment]; 2725 if (!name) return; 2726 2727 if (!renderbuffer) { 2728 delete this._attachments[name]; 2729 return; 2730 } 2731 2732 var gl = this._gl; 2733 2734 var att = { 2735 attachment : attachment, 2736 resource : null, 2737 target : renderbuffertarget, 2738 level : 0, 2739 face : gl.NONE 2740 }; 2741 2742 this._attachments[name] = att; 2743 2744 att.resource = new SpiderGL.WebGL.Renderbuffer(gl, { handle : renderbuffer }); 2745 2746 this._viewport = [ 0, 0, SpiderGL.Math.max(att.resource.width, 1), SpiderGL.Math.max(att.resource.height, 1) ]; 2747 }, 2748 2749 _setAttachment : function (attachment, nfo) { 2750 var name = SpiderGL.WebGL.Framebuffer._attachmentName[attachment]; 2751 if (!name) return false; 2752 2753 var gl = this._gl; 2754 2755 var isNullResource = (!nfo || (("resource" in nfo) && !nfo.resource)); 2756 if (isNullResource) { 2757 var att = this._attachments[name]; 2758 if (att) { 2759 if (att.target === gl.RENDERBUFFER) { 2760 gl.framebufferRenderbuffer(t, att.attachment, gl.RENDERBUFFER, null); 2761 } 2762 else { 2763 gl.framebufferTexture2D(t, att.attachment, gl.TEXTURE_2D, null, 0); 2764 } 2765 } 2766 return; 2767 } 2768 2769 var resourceType = gl.NONE; 2770 2771 if (SpiderGL.Type.instanceOf(nfo, WebGLTexture)) { 2772 nfo = { resource : nfo }; 2773 resourceType = gl.TEXTURE; 2774 } 2775 else if (SpiderGL.Type.instanceOf(nfo, WebGLRenderbuffer)) { 2776 nfo = { resource : nfo }; 2777 resourceType = gl.RENDERBUFFER; 2778 } 2779 else if (SpiderGL.Type.instanceOf(nfo, SpiderGL.WebGL.Texture)) { 2780 nfo = { resource : nfo.handle }; 2781 resourceType = gl.TEXTURE; 2782 } 2783 else if (SpiderGL.Type.instanceOf(nfo, SpiderGL.WebGL.Renderbuffer)) { 2784 nfo = { resource : nfo.handle }; 2785 resourceType = gl.RENDERBUFFER; 2786 } 2787 2788 var cubeFaceSpecified = !!nfo && (typeof (nfo.face) != "undefined"); 2789 2790 nfo = SpiderGL.Utility.getDefaultObject({ 2791 resource : null, 2792 level : SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL, 2793 face : SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE 2794 }, nfo); 2795 2796 var t = this._t; 2797 2798 switch (resourceType) { 2799 case gl.TEXTURE: 2800 var isCubemap = SpiderGL.Type.instanceOf(nfo, SpiderGL.WebGL.TextureCubeMap) || cubeFaceSpecified; 2801 var target = (isCubemap) ? (nfo.face) : (gl.TEXTURE_2D); 2802 gl.framebufferTexture2D(t, attachment, target, nfo.resource, nfo.level); 2803 break; 2804 case gl.RENDERBUFFER: 2805 gl.framebufferRenderbuffer(t, attachment, gl.RENDERBUFFER, nfo.resource); 2806 break; 2807 default: break; 2808 } 2809 2810 return true; 2811 }, 2812 2813 /* 2814 get isEmpty () { 2815 return ( 2816 !this._attachments.color && 2817 !this._attachments.depth && 2818 !this._attachments.stencil && 2819 !this._attachments.depthStencil 2820 ); 2821 }, 2822 */ 2823 2824 /** 2825 * Tests if the framebuffer is ready to use. 2826 * A framebuffer is considered ready if its status is WebGLRenderingContext.FRAMEBUFFER_COMPLETE. 2827 * 2828 * @type bool 2829 * 2830 * @readonly 2831 * 2832 * @see isComplete 2833 */ 2834 get isReady () { 2835 return this.isComplete; 2836 }, 2837 2838 /** 2839 * The WebGL status of the framebuffer. 2840 * 2841 * @type number 2842 * 2843 * @readonly 2844 * 2845 * @see isComplete 2846 */ 2847 get status() { 2848 return this._status; 2849 }, 2850 2851 /** 2852 * Indicates if the the status of the framebuffer is WebGLRenderingContext.FRAMEBUFFER_COMPLETE. 2853 * 2854 * @type number 2855 * 2856 * @readonly 2857 */ 2858 get isComplete() { 2859 return (this._status === this._gl.FRAMEBUFFER_COMPLETE); 2860 }, 2861 2862 /** 2863 * Gets a 4-component array with the viewport parameters. 2864 * 2865 * Viewport parameters are stored as [0, 0, width, height] and will be set using WebGLRenderingContext.viewport() during a {@link bind} call if {@link autoViewport} is true. 2866 * The width and height parameters corresponds to the width and height of the last resource attached with {@link setAttachments}. 2867 * 2868 * @type array 2869 * 2870 * @readonly 2871 * 2872 * @see autoViewport 2873 * @see setAttachments 2874 */ 2875 get viewport() { 2876 return this._viewport.slice(); 2877 }, 2878 2879 /** 2880 * Gets the width of the attached resources. 2881 * 2882 * The value represents the width of the attached resources. 2883 * It is equal to viewport[2]. 2884 * 2885 * @type number 2886 * 2887 * @readonly 2888 * 2889 * @see height 2890 * @see viewport 2891 */ 2892 get width() { 2893 return this._viewport[2]; 2894 }, 2895 2896 /** 2897 * Gets the height of the attached resources. 2898 * 2899 * The value represents the height of the attached resources. 2900 * It is equal to viewport[3]. 2901 * 2902 * @type number 2903 * 2904 * @readonly 2905 * 2906 * @see width 2907 * @see viewport 2908 */ 2909 get height() { 2910 return this._viewport[3]; 2911 }, 2912 2913 /** 2914 * Automatic viewport settings in a call to {@link bind}. 2915 * 2916 * If true, when calling {@link bind} the viewport will be set with a call to WebGLRenderingContext.viewport(). 2917 * 2918 * @type bool 2919 */ 2920 get autoViewport() { 2921 return this._autoViewport; 2922 }, 2923 2924 set autoViewport(on) { 2925 this._autoViewport = !!on; 2926 }, 2927 2928 /** 2929 * Sets the framebuffer attachments. 2930 * It is used to attach resources (SpiderGL.WebGL.Texture2D, SpiderGL.WebGL.TextureCubeMap or SpiderGL.WebGL.Renderbuffer) as render targets. 2931 * 2932 * @param {object} attachments The resources to attach to the WebGLFramebuffer. 2933 * @param {object|SpiderGL.WebGL.Texture2D|SpiderGL.WebGL.TextureCubeMap|SpiderGL.WebGL.Renderbuffer} [attachments.color] The color attachment for target WebGLRenderingContext.COLOR_ATTACHMENT0; if omitted, the current color attachment is kept; if null, the current color attachment is detached. 2934 * @param {SpiderGL.WebGL.Texture2D|SpiderGL.WebGL.TextureCubeMap|SpiderGL.WebGL.Renderbuffer} [attachments.color.resource] The resource to use as a render target for color attachment. 2935 * @param {number} [attachments.color.level=SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL] If resource is SpiderGL.WebGL.Texture2D or SpiderGL.WebGL.TextureCubeMap, specifies the texture level to attach. As per WebGL specifications, level must be zero. 2936 * @param {number} [attachments.color.face=SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE] If resource is SpiderGL.WebGL.TextureCubeMap, specifies the texture cube map face to attach. 2937 * @param {object|SpiderGL.WebGL.Renderbuffer} [attachments.depth] Same as attachments.color but for WebGLRenderingContext.DEPTH_ATTACHMENT. To ensure the restrictions of the WebGL specifications, stencil and depthStencil attachments are detached. 2938 * @param {object|SpiderGL.WebGL.Renderbuffer} [attachments.stencil] Same as attachments.color but for WebGLRenderingContext.STENCIL_ATTACHMENT. To ensure the restrictions of the WebGL specifications, depth and depthStencil attachments are detached. 2939 * @param {object|SpiderGL.WebGL.Renderbuffer} [attachments.depthStencil] Same as attachments.color but for WebGLRenderingContext.DEPTH_STENCIL_ATTACHMENT. To ensure the restrictions of the WebGL specifications, depth and stencil attachments are detached. 2940 * 2941 * @returns {bool} True if the framebuffer is complete, false otherwise. 2942 * 2943 * @example 2944 * var t2D = new SpiderGL.WebGL.Texture2D(...); 2945 * var tCM = new SpiderGL.WebGL.TextureCubeMap(...); 2946 * var rb = new SpiderGL.WebGL.Renderbuffer(...); 2947 * 2948 * var fb = new SpiderGL.WebGL.Framebuffer(gl, { 2949 * color : {resource: t2D, level: 0 }, // alternatively: color: t2D; in this case level would default to SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL 2950 * depth : rb // alternatively: depth: {resource: rb}; renderbuffers do not have mipmap levels 2951 * }; 2952 * // use fb 2953 * // ... 2954 * 2955 * // change attachment 2956 * fb.setAttachments({ 2957 * color: {resource: tCM, face: gl.TEXTURE_CUBE_MAP_NEGATIVE_Z} // if face is omitted, defaults to SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE 2958 * }) 2959 * 2960 * @see getAttachments 2961 */ 2962 setAttachments : function (attachments) { 2963 attachments = attachments || { }; 2964 2965 var gl = this._gl; 2966 var cb = this._cb; 2967 2968 var t = this._t; 2969 var h = this._h; 2970 2971 cb.pushFramebuffer(t); 2972 gl.bindFramebuffer(t, h); 2973 2974 if ("color" in attachments) { 2975 this._setAttachment(gl.COLOR_ATTACHMENT0, attachments.color); 2976 } 2977 2978 if ("depthStencil" in attachments) { 2979 this._setAttachment(gl.DEPTH_ATTACHMENT, null ); 2980 this._setAttachment(gl.STENCIL_ATTACHMENT, null ); 2981 this._setAttachment(gl.DEPTH_STENCIL_ATTACHMENT, attachments.depthStencil); 2982 } 2983 else if ("depth" in attachments) { 2984 this._setAttachment(gl.DEPTH_STENCIL_ATTACHMENT, null ); 2985 this._setAttachment(gl.STENCIL_ATTACHMENT, null ); 2986 this._setAttachment(gl.DEPTH_ATTACHMENT, attachments.depth ); 2987 } 2988 else if ("stencil" in attachments) { 2989 this._setAttachment(gl.DEPTH_STENCIL_ATTACHMENT, null ); 2990 this._setAttachment(gl.DEPTH_ATTACHMENT, null ); 2991 this._setAttachment(gl.STENCIL_ATTACHMENT, attachments.stencil ); 2992 } 2993 2994 this._status = gl.checkFramebufferStatus(t); 2995 2996 cb.popFramebuffer(t); 2997 2998 return this.isComplete; 2999 }, 3000 3001 /** 3002 * Retrieves the attached resources. 3003 * This method returns a new object containing the attachments information. 3004 * 3005 * @returns {object} The attachments data. The object fields may be: color, depth, stencil and depthStencil. 3006 * 3007 * @see setAttachments 3008 */ 3009 getAttachments : function () { 3010 var rAtts = { }; 3011 var att = null; 3012 for (var a in this._attachments) { 3013 att = this._attachments[a]; 3014 rAtts[a] = { 3015 attachment : att.attachment, 3016 resource : att.resource, 3017 target : att.target, 3018 level : att.level 3019 }; 3020 } 3021 return rAtts; 3022 }, 3023 3024 /** 3025 * Detaches all attached resources. 3026 * 3027 * @see setAttachments 3028 */ 3029 detachAll : function () { 3030 this.setAttachments({ 3031 color : null, 3032 depthStencil : null 3033 }); 3034 }, 3035 3036 /** 3037 * Gets/Sets the resource attached to the color attachment. 3038 * If no resource is attached the result is null. 3039 * When setting, default attaching parameters are used. 3040 * 3041 * @type SpiderGL.WebGL.Texture|SpiderGL.WebGL.Renderbuffer 3042 * 3043 * @readonly 3044 * 3045 * @see depthTarget 3046 * @see stencilTarget 3047 * @see depthStencilTarget 3048 */ 3049 get colorTarget() { 3050 var att = this._attachments.color; 3051 if (!att) return null 3052 return att.resource; 3053 }, 3054 3055 set colorTarget(rt) { 3056 this.setAttachments({ color : rt }); 3057 }, 3058 3059 /** 3060 * Gets/Sets the resource attached to the depth attachment. 3061 * If no resource is attached the result is null. 3062 * When setting, default attaching parameters are used. 3063 * 3064 * @type SpiderGL.WebGL.Texture|SpiderGL.WebGL.Renderbuffer 3065 * 3066 * @readonly 3067 * 3068 * @see colorTarget 3069 * @see stencilTarget 3070 * @see depthStencilTarget 3071 */ 3072 get depthTarget() { 3073 var att = this._attachments.depth; 3074 if (!att) return null 3075 return att.resource; 3076 }, 3077 3078 set depthTarget(rt) { 3079 this.setAttachments({ depth : rt }); 3080 }, 3081 3082 /** 3083 * Gets/Sets the resource attached to the stencil attachment. 3084 * If no resource is attached the result is null. 3085 * When setting, default attaching parameters are used. 3086 * 3087 * @type SpiderGL.WebGL.Texture|SpiderGL.WebGL.Renderbuffer 3088 * 3089 * @readonly 3090 * 3091 * @see colorTarget 3092 * @see depthTarget 3093 * @see depthStencilTarget 3094 */ 3095 get stencilTarget() { 3096 var att = this._attachments.stencil; 3097 if (!att) return null 3098 return att.resource; 3099 }, 3100 3101 set stencilTarget(rt) { 3102 this.setAttachments({ stencil : rt }); 3103 }, 3104 3105 /** 3106 * Gets/Sets the resource attached to the depthStencil attachment. 3107 * If no resource is attached the result is null. 3108 * When setting, default attaching parameters are used. 3109 * 3110 * @type SpiderGL.WebGL.Texture|SpiderGL.WebGL.Renderbuffer 3111 * 3112 * @readonly 3113 * 3114 * @see colorTarget 3115 * @see depthTarget 3116 * @see stencilTarget 3117 */ 3118 get depthStencilTarget() { 3119 var att = this._attachments.depthStencil; 3120 if (!att) return null 3121 return att.resource; 3122 }, 3123 3124 set depthStencilTarget(rt) { 3125 this.setAttachments({ depthStencil : rt }); 3126 }, 3127 3128 /** 3129 * Clears the framebuffer using current clear values. 3130 * 3131 * @param {number} mask The clear mask as for WebGLRenderingContext.clear. 3132 */ 3133 clear : function (mask) { 3134 mask = SpiderGL.Utility.getDefaultValue(mask, SpiderGL.WebGL.Framebuffer.DEFAULT_CLEAR_MASK); 3135 this._dsa.clear(this._h, mask); 3136 }, 3137 3138 /** 3139 * Reads the pixels from a rectangular region of the framebuffer. 3140 * 3141 * @param {ArrayBufferView} buffer The destination buffer in which pixels will be written. 3142 * @param {object} [options] Optional parameters. 3143 * @param {number} [options.x=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X] The rectangle left coordinate (in pixels). 3144 * @param {number} [options.y=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X] The rectangle bottom coordinate (in pixels). 3145 * @param {number} [options.width=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_WIDTH] The rectangle width (in pixels). If less than zero, the width will be set to span the whole render target (starting from rectangle x coordinate). 3146 * @param {number} [options.height=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_HEIGHT] The rectangle height (in pixels). If less than zero, the height will be set to span the whole render target (starting from rectangle y coordinate). 3147 * @param {number} [options.format=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_FORMAT] The WebGL pixel format. 3148 * @param {number} [options.type=SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_TYPE] The WebGL pixel type. 3149 */ 3150 readPixels : function (buffer, options) { 3151 options = SpiderGL.Utility.getDefaultObject({ 3152 x : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X, 3153 y : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_Y, 3154 width : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_WIDTH, 3155 height : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_HEIGHT, 3156 format : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_FORMAT, 3157 type : SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_TYPE 3158 }, options); 3159 3160 if (options.width < 0) { options.width = this._viewport[2]; } 3161 if (options.height < 0) { options.height = this._viewport[3]; } 3162 3163 this._dsa.readPixels(this._h, options.x, options.y, options.width, options.height, options.format, options.type, buffer); 3164 }, 3165 3166 /** 3167 * Sets the WebGL viewport to the framebuffer viewport rectangle. 3168 * 3169 * @see viewport 3170 * @see autoViewport 3171 * @see setAttachments 3172 */ 3173 applyViewport : function () { 3174 var gl = this._gl; 3175 var vp = this._viewport; 3176 gl.viewport(vp[0], vp[1], vp[2], vp[3]); 3177 }, 3178 3179 /** 3180 * Destroys the WebGLFramebuffer. 3181 * After destruction, the handle is set to null and this object should not be used anymore. 3182 * 3183 * @see SpiderGL.WebGL.ObjectGL#destroy 3184 */ 3185 destroy : function () { 3186 this._gl.deleteFramebuffer(this._h); 3187 }, 3188 3189 /** 3190 * Binds the wrapped WebGLFramebuffer to the WebGLRenderingContex.FRAMEBUFFER target. 3191 * If setViewport is not specified and autoViewport is true, the stored viewport is set with WebGLRenderingContext.viewport(). 3192 * 3193 * @param {bool} [setViewport] If specified, overrides the value of autoViewport. 3194 * 3195 * @see unbind 3196 * @see autoViewport 3197 */ 3198 bind : function (setViewport) { 3199 var gl = this._gl; 3200 gl.bindFramebuffer(this._t, this._h); 3201 var svp = SpiderGL.Utility.getDefaultValue(setViewport, this._autoViewport); 3202 if (svp) { 3203 var vp = this._viewport; 3204 gl.viewport(vp[0], vp[1], vp[2], vp[3]); 3205 } 3206 }, 3207 3208 /** 3209 * Binds "null" to the WebGLRenderingContex.FRAMEBUFFER target. 3210 * This method is provided only for simmetry with {@link bind} and is not relative to the object state. 3211 * 3212 * @see bind 3213 */ 3214 unbind : function () { 3215 this._gl.bindFramebuffer(this._t, null); 3216 } 3217 }; 3218 3219 SpiderGL.Type.extend(SpiderGL.WebGL.Framebuffer, SpiderGL.WebGL.ObjectGL); 3220 3221 /** 3222 * Creates a SpiderGL.WebGL.Program. 3223 * 3224 * SpiderGL.WebGL.Program is a wrapper for WebGLProgram objects. 3225 * 3226 * @class The SpiderGL.WebGL.Program is a wrapper for WebGLProgram objects. 3227 * 3228 * @augments SpiderGL.WebGL.ObjectGL 3229 * 3230 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 3231 * @param {object} [options] Optional parameters. 3232 * @param {WebGLProgram} [options.handle] A WebGLProgram. If present, this object will be used as the wrapped WebGLProgram and the attached shaders will be queried. Otherwise a new one will be created. 3233 * @param {bool} [options.autoLink=SpiderGL.WebGL.Program.DEFAULT_AUTO_LINK] If true, the program will be linked automatically whenever shaders are added or removed, or vertex attribute indices change. 3234 * @param {array} [options.shaders] An array of SpiderGL.WebGL.Shader objects to attach to the program. 3235 * @param {object} [options.attributes] An object where each property has the name of a vertex shader attribute and whose value is the attribute index to wich the vertex attribute will be bound. 3236 * @param {object} [options.uniforms] An object where each property has the name of a program uniform and whose value is the uniform value. 3237 * 3238 * @example 3239 * var vertexShader = new SpiderGL.WebGL.VertexShader (gl, {source: vertexShaderSrc }); 3240 * var fragmentShader = new SpiderGL.WebGL.FragmentShader (gl, {source: fragmentShaderSrc}); 3241 * 3242 * var program = new SpiderGL.WebGL.Program(gl, { 3243 * autoLink : true, // if true, the program is automatically linked whenever shaders are added or removed, or whenever attribute indices are changed. 3244 * shaders : [vertexShader, fragmentShader], 3245 * attributes : { 3246 * aPosition : 0, // the vertex shader aPosition attribute will be bound to the vertex attribute at index 0 3247 * aNormal : 1 // the vertex shader aNormal attribute will be bound to the vertex attribute at index 1 3248 * }, 3249 * uniforms : { 3250 * uDiffuseMap : 0, // index of the texture unit for diffuse color textures 3251 * uScaleFactor : 2.0 3252 * } 3253 * }; 3254 * 3255 * // uniforms can also be set when the program is not bound 3256 * program.setUniforms({ 3257 * uModelViewProjection : getMVP(), 3258 * uShininess : getShininess() 3259 * }); 3260 * 3261 * program.bind(); 3262 * // render 3263 * 3264 * @see setShaders 3265 * @see setAttributes 3266 * @see setUniforms 3267 * @see autoLink 3268 * @see SpiderGL.WebGL.Shader 3269 * @see SpiderGL.WebGL.ObjectGL 3270 */ 3271 SpiderGL.WebGL.Program = function (gl, options) { 3272 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 3273 3274 if (SpiderGL.Type.instanceOf(options, WebGLProgram)) { 3275 options = { handle : options }; 3276 } 3277 3278 options = SpiderGL.Utility.getDefaultObject({ 3279 handle : null, 3280 autoLink : SpiderGL.WebGL.Program.DEFAULT_AUTO_LINK 3281 }, options); 3282 3283 SpiderGL.WebGL.ObjectGL.call(this, gl, SpiderGL.WebGL.Program.TARGET, options); 3284 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 3285 3286 var gl = this._gl; 3287 var cb = this._cb; 3288 var dsa = this._dsa; 3289 3290 var h = this._h; 3291 3292 var linked = false; 3293 var log = ""; 3294 3295 var imported = false; 3296 if (h) { 3297 imported = true; 3298 linked = !!gl.getProgramParameter(h, gl.LINK_STATUS); 3299 log = gl.getProgramInfoLog(h); 3300 if (!log) { log = ""; } 3301 } 3302 else { 3303 h = gl.createProgram(); 3304 this._h = h; 3305 } 3306 h._spidergl = this; 3307 3308 this._shaders = [ ]; 3309 this._linked = linked; 3310 this._log = log; 3311 this._autoLink = options.autoLink; 3312 this._attributes = { }; 3313 this._uniforms = { }; 3314 3315 if (imported) { 3316 var shaders = gl.getAttachedShaders(h); 3317 for (var i=0,n=shaders.length; i<n; ++i) { 3318 this._importShader(shaders[i]); 3319 } 3320 } 3321 3322 var mustLink = false; 3323 if (this._addShaders(options.shaders)) { mustLink = true; } 3324 if (this._setAttributes(options.attributes)) { mustLink = true; } 3325 3326 if (mustLink && this._autoLink) { this.link(); } 3327 else if (imported) { this._postLink(); } 3328 3329 this.setUniforms(options.uniforms); 3330 } 3331 3332 /** 3333 * Dummy WebGL target for programs. 3334 * It is equal to WebGLRenderingContext.NONE and is provided only for completeness with other WebGL wrappers. 3335 * 3336 * @type number 3337 * 3338 * @default WebGLRenderingContext.NONE 3339 */ 3340 SpiderGL.WebGL.Program.TARGET = WebGLRenderingContext.NONE; 3341 3342 /** 3343 * Default value for SpiderGL.WebGL.Program#autoLink. 3344 * 3345 * @type bool 3346 * 3347 * @default true 3348 */ 3349 SpiderGL.WebGL.Program.DEFAULT_AUTO_LINK = true; 3350 3351 /** 3352 * WebGLProgram unbinding. 3353 * 3354 * This function binds the null program with WebGLRenderingContext.useProgram(null). 3355 * 3356 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 3357 */ 3358 SpiderGL.WebGL.Program.unbind = function (gl) { gl.useProgram(null); }; 3359 3360 SpiderGL.WebGL.Program._uniformSetFunctions = { }; 3361 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.BOOL ] = function (dsa, h, v) { dsa.uniform1i (h, this.location, v); }; 3362 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.BOOL_VEC2 ] = function (dsa, h, v) { dsa.uniform2iv (h, this.location, v); }; 3363 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.BOOL_VEC3 ] = function (dsa, h, v) { dsa.uniform3iv (h, this.location, v); }; 3364 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.BOOL_VEC4 ] = function (dsa, h, v) { dsa.uniform4iv (h, this.location, v); }; 3365 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.INT ] = function (dsa, h, v) { dsa.uniform1i (h, this.location, v); }; 3366 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.INT_VEC2 ] = function (dsa, h, v) { dsa.uniform2iv (h, this.location, v); }; 3367 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.INT_VEC3 ] = function (dsa, h, v) { dsa.uniform3iv (h, this.location, v); }; 3368 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.INT_VEC4 ] = function (dsa, h, v) { dsa.uniform4iv (h, this.location, v); }; 3369 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT ] = function (dsa, h, v) { dsa.uniform1f (h, this.location, v); }; 3370 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_VEC2 ] = function (dsa, h, v) { dsa.uniform2fv (h, this.location, v); }; 3371 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_VEC3 ] = function (dsa, h, v) { dsa.uniform3fv (h, this.location, v); }; 3372 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_VEC4 ] = function (dsa, h, v) { dsa.uniform4fv (h, this.location, v); }; 3373 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_MAT2 ] = function (dsa, h, v) { dsa.uniformMatrix2fv (h, this.location, false, v); }; 3374 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_MAT3 ] = function (dsa, h, v) { dsa.uniformMatrix3fv (h, this.location, false, v); }; 3375 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.FLOAT_MAT4 ] = function (dsa, h, v) { dsa.uniformMatrix4fv (h, this.location, false, v); }; 3376 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.SAMPLER_2D ] = function (dsa, h, v) { dsa.uniform1i (h, this.location, v); }; 3377 SpiderGL.WebGL.Program._uniformSetFunctions[WebGLRenderingContext.SAMPLER_CUBE] = function (dsa, h, v) { dsa.uniform1i (h, this.location, v); }; 3378 3379 SpiderGL.WebGL.Program.prototype = { 3380 _gl_deleteProgram : function (program) { 3381 this._h = null; 3382 }, 3383 3384 _gl_isProgram : function (program) { 3385 }, 3386 3387 _gl_useProgram : function (program) { 3388 }, 3389 3390 _gl_getActiveAttrib : function (program, index) { 3391 }, 3392 3393 _gl_getActiveUniform : function (program, index) { 3394 }, 3395 3396 _gl_getAttachedShaders : function (program) { 3397 }, 3398 3399 _gl_getAttribLocation : function (program, name) { 3400 }, 3401 3402 _gl_getProgramParameter : function (program, pname) { 3403 }, 3404 3405 _gl_getProgramInfoLog : function (program) { 3406 }, 3407 3408 _gl_getUniform : function (program, location) { 3409 }, 3410 3411 _gl_getUniformLocation : function (program, name) { 3412 }, 3413 3414 _gl_attachShader : function (program, shader) { 3415 this._importShader(shader); 3416 }, 3417 3418 _gl_bindAttribLocation : function (program, index, name) { 3419 }, 3420 3421 _gl_detachShader : function (program, shader) { 3422 if (!shader) { return; } 3423 var idx = this._shaderHandleIndex(shader); 3424 if (idx < 0) { return; } 3425 this._shaders.splice(idx, 1); 3426 }, 3427 3428 _gl_linkProgram : function (program) { 3429 this._postLink(); 3430 }, 3431 3432 _gl_uniform1f : function (location, x) { 3433 }, 3434 3435 _gl_uniform1fv : function (location, v) { 3436 }, 3437 3438 _gl_uniform1i : function (location, x) { 3439 }, 3440 3441 _gl_uniform1iv : function (location, v) { 3442 }, 3443 3444 _gl_uniform2f : function (location, x, y) { 3445 }, 3446 3447 _gl_uniform2fv : function (location, v) { 3448 }, 3449 3450 _gl_uniform2i : function (location, x, y) { 3451 }, 3452 3453 _gl_uniform2iv : function (location, v) { 3454 }, 3455 3456 _gl_uniform3f : function (location, x, y, z) { 3457 }, 3458 3459 _gl_uniform3fv : function (location, v) { 3460 }, 3461 3462 _gl_uniform3i : function (location, x, y, z) { 3463 }, 3464 3465 _gl_uniform3iv : function (location, v) { 3466 }, 3467 3468 _gl_uniform4f : function (location, x, y, z, w) { 3469 }, 3470 3471 _gl_uniform4fv : function (location, v) { 3472 }, 3473 3474 _gl_uniform4i : function (location, x, y, z, w) { 3475 }, 3476 3477 _gl_uniform4iv : function (location, v) { 3478 }, 3479 3480 _gl_uniformMatrix2fv : function (location, transpose, value) { 3481 }, 3482 3483 _gl_uniformMatrix3fv : function (location, transpose, value) { 3484 }, 3485 3486 _gl_uniformMatrix4fv : function (location, transpose, value) { 3487 }, 3488 3489 _gl_validateProgram : function (program) { 3490 }, 3491 3492 _shaderHandleIndex : function (shader) { 3493 for (var i=0,n=this._shaders.length; i<n; ++i) { 3494 if (this._shaders[i].handle === shader) { 3495 return i; 3496 } 3497 } 3498 return -1; 3499 }, 3500 3501 _shaderIndex : function (shader) { 3502 if (this._shaders.indexOf) { return this._shaders.indexOf(shader); } 3503 else { 3504 for (var i=0,n=this._shaders.length; i<n; ++i) { 3505 if (this._shaders[i] === shader) { 3506 return i; 3507 } 3508 } 3509 return -1; 3510 } 3511 }, 3512 3513 _importShader : function (shader) { 3514 if (!shader) { return; } 3515 if (this._shaderHandleIndex(shader) >= 0) { return; } 3516 3517 var gl = this._gl; 3518 var shd = shader._spidergl; 3519 if (!shd) { 3520 var type = gl.getShaderParameter(shader, gl.SHADER_TYPE); 3521 switch (type) { 3522 case gl.VERTEX_SHADER : shd = new SpiderGL.WebGL.VertexShader (gl, { handle : shader }); break; 3523 case gl.FRAGMENT_SHADER : shd = new SpiderGL.WebGL.FragmentShader (gl, { handle : shader }); break; 3524 default : return; break; 3525 } 3526 } 3527 this._shaders.push(shd); 3528 }, 3529 3530 _updateActiveInfo : function () { 3531 var gl = this._gl; 3532 var h = this._h; 3533 3534 var n = 0; 3535 var nfo = null; 3536 var name = null; 3537 var loc = null; 3538 3539 var attributes = { }; 3540 n = gl.getProgramParameter(h, gl.ACTIVE_ATTRIBUTES); 3541 for (var i=0; i<n; ++i) { 3542 nfo = gl.getActiveAttrib(h, i); 3543 name = nfo.name; 3544 loc = gl.getAttribLocation(h, name); 3545 attributes[name] = { 3546 index : i, 3547 name : name, 3548 size : nfo.size, 3549 type : nfo.type, 3550 location : loc 3551 }; 3552 } 3553 3554 var uniforms = { }; 3555 n = gl.getProgramParameter(h, gl.ACTIVE_UNIFORMS); 3556 for (var i=0; i<n; ++i) { 3557 nfo = gl.getActiveUniform(h, i); 3558 name = nfo.name; 3559 loc = gl.getUniformLocation(h, name); 3560 uniforms[name] = { 3561 index : i, 3562 name : name, 3563 size : nfo.size, 3564 type : nfo.type, 3565 location : loc, 3566 setValue : SpiderGL.WebGL.Program._uniformSetFunctions[nfo.type] 3567 }; 3568 } 3569 3570 this._attributes = attributes; 3571 this._uniforms = uniforms; 3572 }, 3573 3574 _postLink : function () { 3575 var gl = this._gl; 3576 var h = this._h; 3577 this._linked = !!gl.getProgramParameter(h, gl.LINK_STATUS); 3578 this._log = gl.getProgramInfoLog(h); 3579 if (!this._log) { this._log = ""; } 3580 this._updateActiveInfo(); 3581 }, 3582 3583 _addShaders : function (shaders) { 3584 if (!shaders) { return false; } 3585 3586 var gl = this._gl; 3587 var h = this._h; 3588 var shd = null; 3589 var hshd = null; 3590 3591 for (var i=0,n=shaders.length; i<n; ++i) { 3592 shd = shaders[i]; 3593 hshd = null; 3594 if (SpiderGL.Type.instanceOf(shd, SpiderGL.WebGL.Shader)) { 3595 hshd = shd.handle; 3596 } 3597 if (SpiderGL.Type.instanceOf(shd, WebGLShader)) { 3598 hshd = shd; 3599 } 3600 if (hshd) { 3601 gl.attachShader(h, hshd); 3602 } 3603 } 3604 3605 return true; 3606 }, 3607 3608 _removeShaders : function (shaders) { 3609 if (!shaders) { return false; } 3610 3611 var gl = this._gl; 3612 var h = this._h; 3613 var shd = null; 3614 var hshd = null; 3615 3616 for (var i=0,n=shaders.length; i<n; ++i) { 3617 shd = shaders[i]; 3618 hshd = null; 3619 if (SpiderGL.Type.instanceOf(shd, SpiderGL.WebGL.Shader)) { 3620 hshd = shd.handle; 3621 } 3622 if (SpiderGL.Type.instanceOf(shd, SpiderGL.WebGL.Shader)) { 3623 hshd = shd; 3624 } 3625 if (hshd) { 3626 gl.detachShader(h, hshd); 3627 } 3628 } 3629 3630 return true; 3631 }, 3632 3633 _setAttributes : function (attributes) { 3634 if (!attributes) { return false; } 3635 var gl = this._gl; 3636 var h = this._h; 3637 for (var a in attributes) { 3638 gl.bindAttribLocation(h, attributes[a], a); 3639 } 3640 return true; 3641 }, 3642 3643 /* 3644 get isEmpty () { return (this._shaders.length <= 0); }, 3645 */ 3646 3647 /** 3648 * Tests if the program is ready to use. 3649 * A program is considered ready if it is succesfully linked. 3650 * 3651 * @type bool 3652 * 3653 * @readonly 3654 * 3655 * @see isLinked 3656 */ 3657 get isReady() { 3658 return this.isLinked; 3659 }, 3660 3661 /** 3662 * Tests if the program is linked. 3663 * 3664 * @type bool 3665 * 3666 * @readonly 3667 * 3668 * @see isReady 3669 */ 3670 get isLinked() { 3671 return this._linked; 3672 }, 3673 3674 /* 3675 get isValidated() { 3676 return this._validated; 3677 }, 3678 */ 3679 3680 /** 3681 * Gets the program info log. 3682 * 3683 * @type bool 3684 * 3685 * @readonly 3686 */ 3687 get log() { 3688 return this._log; 3689 }, 3690 3691 /** 3692 * Gets/Sets if the program will be linked automatically whenever shaders are added or removed, or vertex attribute indices change. 3693 * 3694 * @type bool 3695 * 3696 * @see link 3697 */ 3698 get autoLink() { 3699 return this._autoLink; 3700 }, 3701 3702 set autoLink(on) { 3703 this._autoLink = !!on; 3704 }, 3705 3706 /** 3707 * Attaches the provided shaders to the program. 3708 * If link is not specified and autoLink is true, the program is automatically linked. 3709 * 3710 * @param {array|SpiderGL.WebGL.Shader} shaders An array of SpiderGL.WebGL.Shader or a single SpiderGL.WebGL.Shader to attach. 3711 * @param {bool} [link] If specified, overrides the value of autoLink. 3712 * 3713 * @returns {bool} If the program has been linked, returns whether the program is linked, otherwise always returns true. 3714 * 3715 * @see isLinked 3716 */ 3717 addShaders : function (shaders, link) { 3718 var mustLink = this._addShaders(shaders); 3719 if (!mustLink) { return true; }; 3720 mustLink = SpiderGL.Utility.getDefaultValue(link, this._autoLink); 3721 if (!mustLink) { return true; } 3722 return this.link() 3723 }, 3724 3725 /** 3726 * Detaches the provided shaders to the program. 3727 * If link is not specified and autoLink is true, the program is automatically linked. 3728 * 3729 * @param {array|SpiderGL.WebGL.Shader} shaders An array of SpiderGL.WebGL.Shader or a single SpiderGL.WebGL.Shader to detach. 3730 * @param {bool} [link] If specified, overrides the value of autoLink. 3731 * 3732 * @returns {bool} If the program has been linked, returns whether the program is linked, otherwise always returns true. 3733 */ 3734 removeShaders : function (shaders, link) { 3735 var mustLink = this._removeShaders(shaders); 3736 if (!mustLink) { return true; }; 3737 mustLink = SpiderGL.Utility.getDefaultValue(link, this._autoLink); 3738 if (!mustLink) { return true; } 3739 return this.link() 3740 }, 3741 3742 /** 3743 * Tests whether the passed shader is attached to the program. 3744 * 3745 * @param {SpiderGL.WebGL.Shader} shader The shader to test for attachment. 3746 * 3747 * @returns {bool} If the shader is attached, false otherwise. 3748 */ 3749 hasShader : function (shader) { 3750 return (this._shaderIndex(shader) >= 0); 3751 }, 3752 3753 /** 3754 * Gets the attached shaders. 3755 * 3756 * @returns {array} An array with the attached SpiderGL.WebGL.Shader objects. 3757 */ 3758 getShaders : function () { 3759 return this._shaders.slice(); 3760 }, 3761 3762 /** 3763 * Links the program. 3764 * 3765 * @returns {bool} True if the program has been succesfully linked, false otherwise. 3766 */ 3767 link : function () { 3768 this._gl.linkProgram(this._h); 3769 return this._linked; 3770 }, 3771 3772 /** 3773 * Validates the program with the current attribute indices, uniforms and WebGLRenderingContext state 3774 * It is performed using WebGLRenderingContext.validateProgram(). 3775 * 3776 * @returns {bool} True if the program has been succesfully validated, false otherwise. 3777 */ 3778 validate : function () { 3779 var gl = this._gl; 3780 var h = this._h; 3781 gl.validateProgram(h); 3782 var validated = !!gl.getProgramParameter(h, gl.VALIDATE_STATUS); 3783 return validated; 3784 }, 3785 3786 /** 3787 * Sets the indices of vertex shader attributes. 3788 * Only the recognized attributes (i.e. the active attributes in vertex shaders) will be set. 3789 * The attribute binding indices will take effect only when the program is linked again. 3790 * If autoLink is true, the program is automatically linked. 3791 * 3792 * @param {object} attributes The attributes to set. For each attribute index to set, the object must contain a property whose name is the name of the vertex attribute and whose value is a non-negative integer specifying the attribute bind index. 3793 * 3794 * @example 3795 * var vertexShaderSrc = "" + 3796 * "..." + 3797 * "attribute vec3 aPosition; \n" + 3798 * "attribute vec3 aNormal; \n" + 3799 * "..."; 3800 * 3801 * // setup the program (attribute indices can also be set at construction) 3802 * // ... 3803 * 3804 * // set attributes indices; 3805 * // if autoLink is true, the program will be automatically linked; 3806 * // otherwise it must be explicitly linked with program.link() 3807 * program.setAttributes({ 3808 * aPosition : 3, // bind attribute aPosition to vertex attribute 3 3809 * aNormal : 1 // bind attribute aNormal to vertex attribute 1 3810 * aColor : 2 // this attribute is not set because it is not an active attribute 3811 * }); 3812 * 3813 * @returns {bool} True if the attributes have been set, false otherwise. 3814 * 3815 * @see getAttributesIndices 3816 * @see getAttributesInfo 3817 * @see setUniforms 3818 * @see link 3819 * @see autoLink 3820 */ 3821 setAttributes : function (attributes) { 3822 if (!this._setAttributes(attributes)) return false; 3823 if (this._autoLink) return this.link(); 3824 return true; 3825 }, 3826 3827 /** 3828 * Gets vertex attributes names. 3829 * 3830 * @returns {array} An array containing the names of all active vertex shader attributes. 3831 * 3832 * @see getAttributesIndices 3833 * @see getAttributesInfo 3834 */ 3835 getAttributesNames : function () { 3836 var attributes = this._attributes; 3837 var rAttributes = [ ]; 3838 for (var a in attributes) { 3839 rAttributes.push(attributes[a].name); 3840 } 3841 return rAttributes; 3842 }, 3843 3844 /** 3845 * Gets the vertex attributes binding indices. 3846 * 3847 * @returns {object} An object with one property for each active vertex attribute. The name of the property is the name of the attribute in the vertex shader and its value is a non-negative integer representing the attribute bind index. 3848 * 3849 * @see getAttributesInfo 3850 * @see setAttributes 3851 */ 3852 getAttributesIndices : function () { 3853 var attributes = this._attributes; 3854 var rAttributes = { }; 3855 for (var a in attributes) { 3856 rAttributes[a] = attributes[a].location; 3857 } 3858 return rAttributes; 3859 }, 3860 3861 /** 3862 * Gets the vertex attributes informations. 3863 * 3864 * @returns {object} An object where each property has the name of a vertex shader attribute and whose value is an object containing attribute information. The attribute index is in the "location" property. 3865 * 3866 * @see getAttributesIndices 3867 * @see setAttributes 3868 */ 3869 getAttributesInfo : function () { 3870 var attributes = this._attributes; 3871 var attribute = null; 3872 var rAttributes = { }; 3873 for (var a in attributes) { 3874 attribute = attributes[a]; 3875 rAttributes[a] = { 3876 index : attribute.index, 3877 name : attribute.name, 3878 size : attribute.size, 3879 type : attribute.type, 3880 location : attribute.location 3881 }; 3882 } 3883 return rAttributes; 3884 }, 3885 3886 /** 3887 * Sets the program uniforms. 3888 * Only the recognized uniforms are set. 3889 * 3890 * @param {object} uniforms An object where each property has the name of the uniform to set and whose value is the uniform value. 3891 * 3892 * @example 3893 * var vertexShaderSrc = "" + 3894 * "..." + 3895 * "uniform mat4 uMVP; \n" + 3896 * "uniform float uScale; \n" + 3897 * "uniform vec3 uLightPos; \n" + 3898 * "..."; 3899 * 3900 * // setup the program (uniforms can also be set at construction) 3901 * // ... 3902 * 3903 * // set uniform values; 3904 * program.setUniforms({ 3905 * uMVP : getModelViewProjection(), 3906 * uScale : 2.3, 3907 * uLightPos : [0, 0.5, 4.7], // can be a typed array: new Float32Array([0, 0.5, 4.7]) 3908 * uOther : 1.0 // this uniform is not set because it is not an active uniform 3909 * }); 3910 * 3911 * @returns {bool} True if the uniforms have been set succesfully, false otherwise. 3912 */ 3913 setUniforms : function (uniforms) { 3914 if (!uniforms) { return false; } 3915 3916 var gl = this._gl; 3917 var cb = this._cb; 3918 var dsa = this._dsa; 3919 3920 var h = this._h; 3921 3922 cb.pushProgram(); 3923 gl.useProgram(h); 3924 3925 var _uniforms = this._uniforms; 3926 var uniform = null; 3927 var value = null; 3928 for (var u in uniforms) { 3929 uniform = _uniforms[u]; 3930 if (uniform) { 3931 uniform.setValue(dsa, h, uniforms[u]); 3932 } 3933 } 3934 3935 cb.popProgram(); 3936 3937 return true; 3938 }, 3939 3940 /** 3941 * Gets uniforms names. 3942 * 3943 * @returns {array} An array containing the names of all active uniforms. 3944 * 3945 * @see getUniformsValues 3946 * @see getUniformsInfo 3947 */ 3948 getUniformsNames : function () { 3949 var uniforms = this._uniforms; 3950 var rUniforms = [ ]; 3951 for (var u in uniforms) { 3952 rUniforms.push(uniforms[u].name); 3953 } 3954 return rUniforms; 3955 }, 3956 3957 /** 3958 * Gets the values of the program uniforms. 3959 * 3960 * @returns {object} An object with one property for each active uniform. The name of the property is the name of the uniform and its value is the uniform value, which can be a number, an array or a typed array. 3961 */ 3962 getUniformsValues : function () { 3963 var gl = this._gl; 3964 var h = this._h; 3965 var uniforms = this._uniforms; 3966 var rUniforms = { }; 3967 for (var u in uniforms) { 3968 rUniforms[u] = gl.getUniform(h, uniforms[u].location); 3969 } 3970 return rUniforms; 3971 }, 3972 3973 /** 3974 * Gets the program uniforms informations. 3975 * 3976 * @returns {object} An object where each property has the name of a program uniform and whose value is an object containing uinformation. 3977 */ 3978 getUniformsInfo : function () { 3979 var uniforms = this._uniforms; 3980 var uniform = null; 3981 var value = null; 3982 var rUniforms = { }; 3983 for (var u in uniforms) { 3984 uniform = uniforms[u]; 3985 rUniforms[u] = { 3986 index : uniform.index, 3987 name : uniform.name, 3988 size : uniform.size, 3989 type : uniform.type, 3990 location : uniform.location 3991 }; 3992 } 3993 return rUniforms; 3994 }, 3995 3996 /** 3997 * Destroys the WebGLProgram. 3998 * After destruction, the handle is set to null and this object should not be used anymore. 3999 * 4000 * @see SpiderGL.WebGL.ObjectGL#destroy 4001 */ 4002 destroy : function () { 4003 this._gl.deleteProgram(this._h); 4004 }, 4005 4006 /** 4007 * Binds the wrapped WebGLProgram with WebGLRenderingContext.useProgram(). 4008 * 4009 * @see unbind 4010 */ 4011 bind : function () { 4012 this._gl.useProgram(this._h); 4013 }, 4014 4015 /** 4016 * Binds the "null" program with WebGLRenderingContext.useProgram(null). 4017 * This method is provided only for simmetry with {@link bind} and is not relative to the object state. 4018 * 4019 * @see bind 4020 */ 4021 unbind : function () { 4022 this._gl.useProgram(null); 4023 } 4024 }; 4025 4026 SpiderGL.Type.extend(SpiderGL.WebGL.Program, SpiderGL.WebGL.ObjectGL); 4027 4028 /** 4029 * Creates a SpiderGL.WebGL.Renderbuffer. 4030 * 4031 * SpiderGL.WebGL.Renderbuffer is a wrapper for WebGLRenderbuffer. 4032 * 4033 * @class The SpiderGL.WebGL.Renderbuffer is a wrapper for WebGLRenderbuffer. 4034 * 4035 * @augments SpiderGL.WebGL.ObjectGL 4036 * 4037 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 4038 * @param {object} [options] Optional parameters. 4039 * @param {WebGLRenderbuffer} [options.handle] A WebGLRenderbuffer. If present, this object will be used as the wrapped WebGLRenderbuffer. Otherwise a new one will be created. 4040 * @param {number} [options.internalFormat] The WebGL enumeration specifying the renderbuffer internal format. 4041 * @param {object} [options.width] The width of the renderbuffer. 4042 * @param {object} [options.height] The height of the renderbuffer. 4043 * 4044 * @example 4045 * var rb = new SpiderGL.WebGL.Renderbuffer(gl, { 4046 * internalFormat : gl.RGBA, 4047 * width : 800, 4048 * height : 600 4049 * }); 4050 * 4051 * @see setStorage 4052 * @see SpiderGL.WebGL.Framebuffer 4053 * @see SpiderGL.WebGL.ObjectGL 4054 */ 4055 SpiderGL.WebGL.Renderbuffer = function (gl, options) { 4056 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 4057 4058 if (SpiderGL.Type.instanceOf(h, WebGLRenderbuffer)) { 4059 options = { handle : options }; 4060 } 4061 4062 options = SpiderGL.Utility.getDefaultObject({ 4063 handle : null, 4064 }, options); 4065 4066 SpiderGL.WebGL.ObjectGL.call(this, gl, SpiderGL.WebGL.Renderbuffer.TARGET, options); 4067 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 4068 4069 var gl = this._gl; 4070 var cb = this._cb; 4071 var dsa = this._dsa; 4072 4073 var t = this._t; 4074 var h = this._h; 4075 4076 var format = gl.NONE; 4077 var width = 0; 4078 var height = 0; 4079 4080 if (h) { 4081 cb.pushRenderbuffer(t); 4082 gl.bindRenderbuffer(t, h); 4083 format = gl.getRenderbufferParameter(t, gl.RENDERBUFFER_INTERNAL_FORMAT); 4084 width = gl.getRenderbufferParameter(t, gl.RENDERBUFFER_WIDTH); 4085 height = gl.getRenderbufferParameter(t, gl.RENDERBUFFER_HEIGHT); 4086 cb.popRenderbuffer(t); 4087 } 4088 else { 4089 h = gl.createRenderbuffer(); 4090 this._h = h; 4091 } 4092 h._spidergl = this; 4093 4094 this._width = width; 4095 this._height = height; 4096 this._format = format; 4097 4098 if (SpiderGL.Type.isNumber(options.internalFormat) && SpiderGL.Type.isNumber(options.width) && SpiderGL.Type.isNumber(options.height)) { 4099 this.setStorage(options.internalFormat, options.width, options.height, options.format); 4100 } 4101 } 4102 4103 /** 4104 * WebGL target for renderbuffers. 4105 * 4106 * @type number 4107 * 4108 * @default WebGLRenderingContext.RENDERBUFFER 4109 */ 4110 SpiderGL.WebGL.Renderbuffer.TARGET = WebGLRenderingContext.RENDERBUFFER; 4111 4112 /** 4113 * WebGLRenderbuffer unbinding. 4114 * 4115 * This function binds the null renderbuffer to the WebGLRenderingContext.RENDERBUFFER target. 4116 * 4117 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 4118 */ 4119 SpiderGL.WebGL.Renderbuffer.unbind = function (gl) { gl.bindRenderbuffer(SpiderGL.WebGL.Renderbuffer.TARGET, null); }; 4120 4121 SpiderGL.WebGL.Renderbuffer.prototype = { 4122 _gl_deleteRenderbuffer : function (renderbuffer) { 4123 this._h = null; 4124 }, 4125 4126 _gl_isRenderbuffer : function (renderbuffer) { 4127 }, 4128 4129 _gl_bindRenderbuffer : function (target, renderbuffer) { 4130 }, 4131 4132 _gl_getRenderbufferParameter : function (target, pname) { 4133 }, 4134 4135 _gl_renderbufferStorage : function (target, internalformat, width, height) { 4136 this._format = internalformat; 4137 this._width = width; 4138 this._height = height; 4139 }, 4140 4141 /* 4142 get isEmpty () { return ((this._width <= 0) || (this._height <= 0)); }, 4143 */ 4144 4145 /** 4146 * Tests if the renderbuffer is ready to use. 4147 * A renderbuffer is considered ready if its width and height are greater than zero. 4148 * 4149 * @type bool 4150 * 4151 * @readonly 4152 */ 4153 get isReady() { 4154 return ((this._width > 0) && (this._height > 0)); 4155 }, 4156 4157 /** 4158 * Gets the WebGL internal format of the renderbuffer. 4159 * 4160 * @type number 4161 * 4162 * @readonly 4163 */ 4164 get format() { 4165 return this._format; 4166 }, 4167 4168 /** 4169 * Gets the width in pixels of the renderbuffer. 4170 * 4171 * @type number 4172 * 4173 * @readonly 4174 */ 4175 get width() { 4176 return this._width; 4177 }, 4178 4179 /** 4180 * Gets the height in pixels of the renderbuffer. 4181 * 4182 * @type number 4183 * 4184 * @readonly 4185 */ 4186 get height() { 4187 return this._height; 4188 }, 4189 4190 /** 4191 * Setups the renderbuffer storage configuration. 4192 * 4193 * @param {number} internalFormat The WebGL enumeration for the internal pixel format. 4194 * @param {number} width The width in pixels of the renderbuffer. 4195 * @param {number} height The height in pixels of the renderbuffer. 4196 */ 4197 setStorage : function (internalFormat, width, height) { 4198 this._dsa.renderbufferStorage(this._h, this._t, internalFormat, width, height); 4199 }, 4200 4201 /** 4202 * Destroys the WebGLRenderbuffer. 4203 * After destruction, the handle is set to null and this object should not be used anymore. 4204 * 4205 * @see SpiderGL.WebGL.ObjectGL#destroy 4206 */ 4207 destroy : function () { 4208 this._gl.deleteRenderbuffer(this._h); 4209 }, 4210 4211 /** 4212 * Binds the wrapped WebGLRenderbuffer to the WebGLRenderingContex.RENDERBUFFER target. 4213 * 4214 * @see unbind 4215 */ 4216 bind : function () { 4217 this._gl.bindRenderbuffer(this._t, this._h); 4218 }, 4219 4220 /** 4221 * Binds "null" to the WebGLRenderingContex.RENDERBUFFER target. 4222 * This method is provided only for simmetry with {@link bind} and is not relative to the object state. 4223 * 4224 * @see bind 4225 */ 4226 unbind : function () { 4227 this._gl.bindRenderbuffer(this._t, null); 4228 } 4229 }; 4230 4231 SpiderGL.Type.extend(SpiderGL.WebGL.Renderbuffer, SpiderGL.WebGL.ObjectGL); 4232 4233 /** 4234 * Creates a SpiderGL.WebGL.Shader. 4235 * 4236 * SpiderGL.WebGL.Shader is the base class for WebGLShader object wrappers and must not be directly used. 4237 * 4238 * @class The SpiderGL.WebGL.Shader is the base class for all WebGLShader object wrappers, i.e. {@link SpiderGL.WebGL.Shader} and {@link SpiderGL.WebGL.FragmentShader}. 4239 * 4240 * @augments SpiderGL.WebGL.ObjectGL 4241 * 4242 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 4243 * @param {number} target Not used. 4244 * @param {number} type WebGL shader type. 4245 * @param {object} [options] Optional parameters. 4246 * @param {WebGLShader} [options.handle] If defined, the provided shader will be wrapped and its source code will be queried to the rendering context. Otherwise an internal shader will be created. 4247 * @param {bool} [options.autoCompile=SpiderGL.WebGL.Shader.DEFAULT_AUTO_COMPILE] If true, the shader is automatically compiled whenever its source code changes. 4248 * @param {string} [options.source] Shader source code. If autoCompile is true, the shader will be automatically compiled. 4249 * 4250 * @see autoCompile 4251 * @see source 4252 * @see compile 4253 * @see SpiderGL.WebGL.VertexShader 4254 * @see SpiderGL.WebGL.FragmentShader 4255 * @see SpiderGL.WebGL.Program 4256 * @see SpiderGL.WebGL.ObjectGL 4257 */ 4258 SpiderGL.WebGL.Shader = function (gl, target, type, options) { 4259 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 4260 4261 if (SpiderGL.Type.instanceOf(options, WebGLShader)) { 4262 options = { handle : options }; 4263 } 4264 else if (SpiderGL.Type.isString(options)) { 4265 options = { source : options }; 4266 } 4267 4268 options = SpiderGL.Utility.getDefaultObject({ 4269 handle : null, 4270 source : null, 4271 autoCompile : SpiderGL.WebGL.Shader.DEFAULT_AUTO_COMPILE 4272 }, options); 4273 4274 SpiderGL.WebGL.ObjectGL.call(this, gl, target, options); 4275 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 4276 4277 var gl = this._gl; 4278 var cb = this._cb; 4279 var dsa = this._dsa; 4280 4281 var source = ""; 4282 var compiled = false; 4283 var deleted = false; 4284 var log = ""; 4285 4286 var h = this._h; 4287 if (h) { 4288 source = gl.getShaderSource(h); 4289 if (!source) { source = ""; } 4290 compiled = !!gl.getShaderParameter(h, gl.COMPILE_STATUS); 4291 deleted = !!gl.getShaderParameter(h, gl.DELETE_STATUS); 4292 log = gl.getShaderInfoLog(h); 4293 if (!log) { log = ""; } 4294 } 4295 else { 4296 h = gl.createShader(type); 4297 this._h = h; 4298 } 4299 h._spidergl = this; 4300 4301 this._source = source; 4302 this._compiled = compiled; 4303 this._log = log; 4304 this._autoCompile = options.autoCompile; 4305 4306 if (options.source) { this.setSource(options.source); } 4307 } 4308 4309 /** 4310 * Dummy WebGL target for shaders. 4311 * 4312 * It is equal to WebGLRenderingContext.NONE and is provided only for completeness with other WebGL wrappers. 4313 * 4314 * @type number 4315 * 4316 * @default WebGLRenderingContext.NONE 4317 */ 4318 SpiderGL.WebGL.Shader.TARGET = WebGLRenderingContext.NONE; 4319 4320 /** 4321 * Default value for SpiderGL.WebGL.Shader#autoCompile. 4322 * 4323 * @type bool 4324 * 4325 * @default true 4326 */ 4327 SpiderGL.WebGL.Shader.DEFAULT_AUTO_COMPILE = true; 4328 4329 /** 4330 * Dummy shader unbinding. 4331 * 4332 * This function does nothing and it is provided only for simmetry with other wrappers. 4333 * 4334 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 4335 */ 4336 SpiderGL.WebGL.Shader.unbind = function (gl) { }; 4337 4338 SpiderGL.WebGL.Shader.prototype = { 4339 _gl_deleteShader : function (shader) { 4340 this._h = null; 4341 }, 4342 4343 _gl_isShader : function (shader) { 4344 }, 4345 4346 _gl_getShaderParameter : function (shader, pname) { 4347 }, 4348 4349 _gl_getShaderInfoLog : function (shader) { 4350 }, 4351 4352 _gl_getShaderSource : function (shader) { 4353 }, 4354 4355 _gl_compileShader : function (shader) { 4356 this._postCompile(); 4357 }, 4358 4359 _gl_shaderSource : function (shader, source) { 4360 this._source = source; 4361 if (!this._source) { this._source = ""; } 4362 }, 4363 4364 _postCompile : function () { 4365 var gl = this._gl; 4366 var h = this._h; 4367 this._compiled = !!gl.getShaderParameter(h, gl.COMPILE_STATUS); 4368 this._log = gl.getShaderInfoLog(h); 4369 if (!this._log) { this._log = ""; } 4370 }, 4371 4372 /* 4373 get isEmpty () { return (this._source.length <= 0); }, 4374 */ 4375 4376 /** 4377 * Tests if the shader is ready to use. 4378 * A shader is considered ready if it is successfully compiled. 4379 * 4380 * @type bool 4381 * 4382 * @readonly 4383 * 4384 * @see isCompiled 4385 */ 4386 get isReady() { 4387 return this.isCompiled; 4388 }, 4389 4390 /** 4391 * Tests if the shader is successfully compiled. 4392 * 4393 * @type bool 4394 * 4395 * @readonly 4396 * 4397 * @see isReady 4398 */ 4399 get isCompiled() { 4400 return this._compiled; 4401 }, 4402 4403 /** 4404 * Gets the log output generated by the shader compiler. 4405 * 4406 * @type string 4407 * 4408 * @readonly 4409 * 4410 * @see compile 4411 */ 4412 get log() { 4413 return this._log; 4414 }, 4415 4416 /** 4417 * Gets/Sets if the shader will be compiled automatically whenever the source code is changed. 4418 * 4419 * @type bool 4420 * 4421 * @see source 4422 * @see compile 4423 */ 4424 get autoCompile() { 4425 return this._autoCompile; 4426 }, 4427 4428 set autoCompile(on) { 4429 this._autoCompile = !!on; 4430 }, 4431 4432 /** 4433 * Sets the shader source code. 4434 * If compile is not specified and autoCompile is true, the shader is automatically compiled. 4435 * 4436 * @param {string} src The shader source code. 4437 * @param {bool} [compile] If specified, overrides the value of autoCompile. 4438 * 4439 * @see compile 4440 * @see autoCompile 4441 */ 4442 setSource : function (src, compile) { 4443 var gl = this._gl; 4444 var h = this._h; 4445 4446 gl.shaderSource(h, src); 4447 4448 var c = SpiderGL.Utility.getDefaultValue(compile, this._autoCompile); 4449 if (!c) { true; } 4450 return this.compile(); 4451 }, 4452 4453 /** 4454 * Gets/Sets the shader source code. 4455 * If autoCompile is true, the shader is automatically compiled when the source code string is changed. 4456 * 4457 * @type string 4458 * 4459 * @see setSource 4460 * @see compile 4461 * @see autoCompile 4462 */ 4463 get source() { 4464 return this._source; 4465 }, 4466 4467 set source(src) { 4468 this.setSource(src); 4469 }, 4470 4471 /** 4472 * Compiles the shader. 4473 * 4474 * @returns {bool} True if the shader has been successfully compiled, false otherwise. 4475 * 4476 * @see source 4477 * @see autoCompile 4478 * @see log 4479 */ 4480 compile : function () { 4481 this._gl.compileShader(this._h); 4482 return this._compiled; 4483 }, 4484 4485 /** 4486 * Destroys the WebGLShader. 4487 * After destruction, the handle is set to null and this object should not be used anymore. 4488 * 4489 * @see SpiderGL.WebGL.ObjectGL#destroy 4490 */ 4491 destroy : function () { 4492 this._gl.deleteShader(this._h); 4493 }, 4494 4495 /** 4496 * Dummy bind method. 4497 * It is provided for simmetry with other WebGL object wrappers. 4498 * 4499 * @see unbind 4500 */ 4501 bind : function () { 4502 }, 4503 4504 /** 4505 * Dummy unbind method. 4506 * It is provided for simmetry with other WebGL object wrappers. 4507 * 4508 * @see bind 4509 */ 4510 unbind : function () { 4511 } 4512 }; 4513 4514 SpiderGL.Type.extend(SpiderGL.WebGL.Shader, SpiderGL.WebGL.ObjectGL); 4515 4516 /** 4517 * Creates a SpiderGL.WebGL.VertexShader. 4518 * 4519 * SpiderGL.WebGL.VertexShader represents a wrapper for a WebGLShader whose type is type WebGLRenderingContext.VERTEX_SHADER. 4520 * 4521 * @class The SpiderGL.WebGL.VertexShader is a WebGLShader wrapper for vertex shaders. 4522 * 4523 * @augments SpiderGL.WebGL.Shader 4524 * 4525 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 4526 * @param {object} [options] See {@link SpiderGL.WebGL.Shader}. 4527 * 4528 * @see SpiderGL.WebGL.Shader 4529 * @see SpiderGL.WebGL.FragmentShader 4530 * @see SpiderGL.WebGL.Program 4531 * @see SpiderGL.WebGL.ObjectGL 4532 */ 4533 SpiderGL.WebGL.VertexShader = function (gl, options) { 4534 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 4535 SpiderGL.WebGL.Shader.call(this, gl, SpiderGL.WebGL.VertexShader.TARGET, gl.VERTEX_SHADER, options); 4536 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 4537 } 4538 4539 /** 4540 * Dummy WebGL target for vertex shaders. 4541 * 4542 * It is equal to WebGLRenderingContext.NONE and is provided only for completeness with other WebGL wrappers. 4543 * 4544 * @type number 4545 * 4546 * @default WebGLRenderingContext.NONE 4547 */ 4548 SpiderGL.WebGL.VertexShader.TARGET = WebGLRenderingContext.NONE; 4549 4550 /** 4551 * Dummy vertex shader unbinding. 4552 * 4553 * This function does nothing and it is provided only for simmetry with other wrappers. 4554 * 4555 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 4556 */ 4557 SpiderGL.WebGL.VertexShader.unbind = function (gl) { }; 4558 4559 SpiderGL.WebGL.VertexShader.prototype = { }; 4560 4561 SpiderGL.Type.extend(SpiderGL.WebGL.VertexShader, SpiderGL.WebGL.Shader); 4562 4563 /** 4564 * Creates a SpiderGL.WebGL.FragmentShader. 4565 * 4566 * SpiderGL.WebGL.FragmentShader represents a wrapper for a WebGLShader whose type is type WebGLRenderingContext.FRAGMENT_SHADER. 4567 * 4568 * @class The SpiderGL.WebGL.FragmentShader is a WebGLShader wrapper for fragment shaders. 4569 * 4570 * @augments SpiderGL.WebGL.Shader 4571 * 4572 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 4573 * @param {object} [options] See {@link SpiderGL.WebGL.Shader}. 4574 * 4575 * @see SpiderGL.WebGL.Shader 4576 * @see SpiderGL.WebGL.VertexShader 4577 * @see SpiderGL.WebGL.Program 4578 * @see SpiderGL.WebGL.ObjectGL 4579 */ 4580 SpiderGL.WebGL.FragmentShader = function (gl, options) { 4581 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 4582 SpiderGL.WebGL.Shader.call(this, gl, SpiderGL.WebGL.FragmentShader.TARGET, gl.FRAGMENT_SHADER, options); 4583 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 4584 } 4585 4586 /** 4587 * Dummy WebGL target for fragment shaders. 4588 * 4589 * It is equal to WebGLRenderingContext.NONE and is provided only for completeness with other WebGL wrappers. 4590 * 4591 * @type number 4592 * 4593 * @default WebGLRenderingContext.NONE 4594 */ 4595 SpiderGL.WebGL.FragmentShader.TARGET = WebGLRenderingContext.NONE; 4596 4597 /** 4598 * Dummy fragment shader unbinding. 4599 * 4600 * This function does nothing and it is provided only for simmetry with other wrappers. 4601 * 4602 * @param {WebGLRenderingContext} gl A WebGLRenderingContext. 4603 */ 4604 SpiderGL.WebGL.FragmentShader.unbind = function (gl) { }; 4605 4606 SpiderGL.WebGL.FragmentShader.prototype = { }; 4607 4608 SpiderGL.Type.extend(SpiderGL.WebGL.FragmentShader, SpiderGL.WebGL.Shader); 4609 4610 /** 4611 * Creates a SpiderGL.WebGL.Texture. 4612 * 4613 * SpiderGL.WebGL.Texture is the base class for WebGLTexture object wrappers ({@link SpiderGL.WebGL.Texture2D} and {@link SpiderGL.WebGL.TextureCubeMap}) and must not be directly used. 4614 * 4615 * @class The SpiderGL.WebGL.Texture is the base class for all WebGLTexture object wrappers, i.e. {@link SpiderGL.WebGL.Texture2D} and {@link SpiderGL.WebGL.TextureCubeMap}. 4616 * 4617 * @augments SpiderGL.WebGL.ObjectGL 4618 * 4619 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 4620 * @param {number} target Texture-specific target. 4621 * @param {object} [options] Optional parameters. 4622 * @param {WebGLTexture} [options.handle] If defined, the provided texture will be wrapped and its sampling parameters will be queried to the rendering context; as texture image base level width and height can not be retrieved, they should be specified with the width and height optional parameters. If handle is not specified, an internal texture will be created. 4623 * @param {string|array} [options.url] The url of the texture image to load. It has precedence over the data optional parameter. For SpiderGL.Texture.Texture2D, url is a string. For SpiderGL.Texture.TextureCubeMap, url is an array of six strings, one for each cube map face, in the order [+X, -X, +Y, -Y, +Z, -Z]. 4624 * @param {ArrayBuffer|ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.data] The texture image pixel data. 4625 * @param {number} [options.internalFormat=SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT] The texture internal format. 4626 * @param {number} [options.width] If data is null or a typed array, specifies the texture image width. If handle is provided, the width parameter will supply the width information, not querable to the WebGLRenderingContext. 4627 * @param {number} [options.height] If data is null or a typed array, specifies the texture image height. If handle is provided, the width parameter will supply the height information, not querable to the WebGLRenderingContext. 4628 * @param {number} [options.border=SpiderGL.WebGL.Texture.DEFAULT_BORDER] Texture border. 4629 * @param {number} [options.format=SpiderGL.WebGL.Texture.DEFAULT_FORMAT] The format parameter used for WebGLRenderingContext.texImage2D. 4630 * @param {number} [options.type=SpiderGL.WebGL.Texture.DEFAULT_TYPE] The type parameter used for WebGLRenderingContext.texImage2D. 4631 * @param {number} [options.magFilter=SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER] Texture magnification filter (see {@link SpiderGL.WebGL.Texture#magFilter}). 4632 * @param {number} [options.minFilter=SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER] Texture minnification filter (see {@link SpiderGL.WebGL.Texture#minFilter}). 4633 * @param {number} [options.wrapS=SpiderGL.WebGL.Texture.DEFAULT_WRAP_S] Texture horizontal wrap mode (see {@link SpiderGL.WebGL.Texture#wrapS}). 4634 * @param {number} [options.wrapT=SpiderGL.WebGL.Texture.DEFAULT_WRAP_T] Texture vertical wrap mode (see {@link SpiderGL.WebGL.Texture#wrapT}). 4635 * @param {bool} [options.autoMipmap=SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP] If true, mipmaps are automatically generated when calling setImage or setSubImage (see {@link SpiderGL.WebGL.Texture#autoMipmap}). 4636 * @param {bool} [options.generateMipmap] If specified, overrides autoMipmap for this call. 4637 * @param {bool} [options.flipYPolicy=SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y] WebGL unpack flip Y policy (see SpiderGL.WebGL.Texture#flipYPolicy). 4638 * @param {bool} [options.flipY] If specified, overrides flipYPolicy for this call. 4639 * @param {bool} [options.premultiplyAlphaPolicy=SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA] WebGL unpack premultiply alpha policy (see SpiderGL.WebGL.Texture#premultiplyAlphaPolicy). 4640 * @param {bool} [options.premultiplyAlpha] If specified, overrides premultiplyAlphaPolicy for this call. 4641 * @param {number} [options.colorspaceConversionPolicy=SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION] WebGL unpack colorspace conversion policy (see SpiderGL.WebGL.Texture#colorspaceConversionPolicy). 4642 * @param {number} [options.colorspaceConversion] If specified, overrides colorspaceConversionPolicy for this call. 4643 * @param {function} [options.onCancel] If url is specified, this function will be called if image data loading is cancelled. 4644 * @param {function} [options.onError] If url is specified, this function will be called if an error occurs when loading image data. 4645 * @param {function} [options.onProgress] If url is specified, this function will be called during the image loading progress. 4646 * @param {function} [options.onSuccess] If url is specified, this function will be called when image data has been successfully loaded. 4647 * 4648 * @example 4649 * var tex1 = new SpiderGL.WebGL.Texture2D(gl, { 4650 * internalFormat : gl.RGBA, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT 4651 * width : 256, 4652 * height : 128, 4653 * border : 0, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_BORDER 4654 * format : gl.RGBA, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_FORMAT 4655 * type : gl.UNSIGNED_BYTE, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_TYPE 4656 * data : new Uint8Array(...), // if omitted or null, the texture is initialized to zero by the WebGLRenderingContext 4657 * magFilter : gl.LINEAR, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER 4658 * minFilter : gl.LINEAR, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER 4659 * wrapS : gl.CLAMP_TO_EDGE, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_WRAP_S 4660 * wrapT : gl.CLAMP_TO_EDGE, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_WRAP_T 4661 * autoMipmap : true, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP 4662 * generateMipmap : false, // if specified, overrides autoMipmap for this implicit call to setImage 4663 * flipYPolicy : true, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y 4664 * flipY : false, // if specified, overrides flipYPolicy for this implicit call to setImage 4665 * premultiplyAlphaPolicy : true, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 4666 * premultiplyAlpha : false, // if specified, overrides premultiplyAlphaPolicy for this implicit call to setImage 4667 * colorspaceConversionPolicy : true, // if omitted, defaults to SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION 4668 * colorspaceConversion : false // if specified, overrides colorspaceConversionPolicy for this implicit call to setImage 4669 * }); 4670 * 4671 * var tex2 = new SpiderGL.WebGL.TextureCubeMap(gl, { 4672 * url : [ 4673 * http://someurl.org/cubemap_pos_x.png, 4674 * http://someurl.org/cubemap_neg_x.png, 4675 * http://someurl.org/cubemap_pos_y.png, 4676 * http://someurl.org/cubemap_neg_y.png, 4677 * http://someurl.org/cubemap_pos_z.png, 4678 * http://someurl.org/cubemap_neg_z.png 4679 * ], 4680 * onCancel : function () { ... }, 4681 * onError : function () { ... }, 4682 * onProgress : function () { ... }, 4683 * onLoad : function () { ... }, 4684 * wrapS : gl.REPEAT, 4685 * magFilter : gl.NEAREST 4686 * }); 4687 * 4688 * @see SpiderGL.WebGL.Texture2D 4689 * @see SpiderGL.WebGL.TextureCubeMap 4690 * @see SpiderGL.WebGL.Framebuffer 4691 * @see SpiderGL.WebGL.ObjectGL 4692 */ 4693 SpiderGL.WebGL.Texture = function (gl, target, options) { 4694 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 4695 4696 if (SpiderGL.Type.instanceOf(options, WebGLTexture)) { 4697 options = { handle : options }; 4698 } 4699 else if (SpiderGL.Type.isString(options)) { 4700 options = { url : options }; 4701 } 4702 4703 options = SpiderGL.Utility.getDefaultObject({ 4704 handle : null, 4705 magFilter : SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER, 4706 minFilter : SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER, 4707 wrapS : SpiderGL.WebGL.Texture.DEFAULT_WRAP_S, 4708 wrapT : SpiderGL.WebGL.Texture.DEFAULT_WRAP_T, 4709 flipYPolicy : SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y, 4710 premultiplyAlphaPolicy : SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA, 4711 colorspaceConversionPolicy : SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION, 4712 autoMipmap : SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP, 4713 format : gl.NONE, 4714 width : 0, 4715 height : 0 4716 }, options); 4717 4718 SpiderGL.WebGL.ObjectGL.call(this, gl, target, options); 4719 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 4720 4721 var gl = this._gl; 4722 var cb = this._cb; 4723 var dsa = this._dsa; 4724 4725 var t = this._t; 4726 var h = this._h; 4727 4728 if (!h) { 4729 h = gl.createTexture(); 4730 this._h = h; 4731 } 4732 4733 cb.pushTexture(t); 4734 gl.bindTexture(t, h); 4735 this._magFilter = gl.getTexParameter(t, gl.TEXTURE_MAG_FILTER); 4736 this._minFilter = gl.getTexParameter(t, gl.TEXTURE_MIN_FILTER); 4737 this._wrapS = gl.getTexParameter(t, gl.TEXTURE_WRAP_S); 4738 this._wrapT = gl.getTexParameter(t, gl.TEXTURE_WRAP_T); 4739 cb.popTexture(t); 4740 h._spidergl = this; 4741 4742 this._format = options.format; 4743 this._width = options.width; 4744 this._height = options.height; 4745 this._flipY = options.flipYPolicy; 4746 this._premultiplyAlpha = options.premultiplyAlphaPolicy; 4747 this._colorspaceConversion = options.colorspaceConversionPolicy; 4748 this._autoMipmap = options.autoMipmap; 4749 4750 this._missingFaces = SpiderGL.WebGL.Texture._FACE_ALL_BITS; 4751 4752 this.setSampler(options); 4753 } 4754 4755 SpiderGL.WebGL.Texture.TARGET = WebGLRenderingContext.NONE; 4756 4757 /** 4758 * Default texture border when calling setImage 4759 * 4760 * @type number 4761 * 4762 * @default 0 4763 */ 4764 SpiderGL.WebGL.Texture.DEFAULT_BORDER = 0; 4765 4766 /** 4767 * Default texture input data format when calling setImage or setSubImage. 4768 * 4769 * @type number 4770 * 4771 * @default WebGLRenderingContext.RGBA 4772 */ 4773 SpiderGL.WebGL.Texture.DEFAULT_FORMAT = WebGLRenderingContext.RGBA; 4774 4775 /** 4776 * Default value for SpiderGL.WebGL.Texture#autoMipmap 4777 * 4778 * @type bool 4779 * 4780 * @default false 4781 */ 4782 SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP = false; 4783 4784 /** 4785 * Default texture internal format when calling setImage. 4786 * 4787 * @type number 4788 * 4789 * @default WebGLRenderingContext.RGBA 4790 */ 4791 SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT = WebGLRenderingContext.RGBA; 4792 4793 /** 4794 * Default texture level when calling setImage. 4795 * 4796 * @type number 4797 * 4798 * @default 0 4799 */ 4800 SpiderGL.WebGL.Texture.DEFAULT_LEVEL = 0; 4801 4802 /** 4803 * Default texture magnification filter. 4804 * 4805 * @type number 4806 * 4807 * @default WebGLRenderingContext.LINEAR 4808 */ 4809 SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER = WebGLRenderingContext.LINEAR; 4810 4811 /** 4812 * Default texture minification filter. 4813 * 4814 * @type number 4815 * 4816 * @default WebGLRenderingContext.LINEAR 4817 */ 4818 SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER = WebGLRenderingContext.LINEAR; 4819 4820 /** 4821 * Default texture input data type when calling setImage or setSubImage. 4822 * 4823 * @type number 4824 * 4825 * @default WebGLRenderingContext.UNSIGNED_BYTE 4826 */ 4827 SpiderGL.WebGL.Texture.DEFAULT_TYPE = WebGLRenderingContext.UNSIGNED_BYTE; 4828 4829 /** 4830 * Default texture wrap mode in horizontal direction. 4831 * 4832 * @type number 4833 * 4834 * @default WebGLRenderingContext.REPEAT 4835 */ 4836 SpiderGL.WebGL.Texture.DEFAULT_WRAP_S = WebGLRenderingContext.REPEAT; 4837 4838 /** 4839 * Default texture wrap mode in vertical direction. 4840 * 4841 * @type number 4842 * 4843 * @default WebGLRenderingContext.REPEAT 4844 */ 4845 SpiderGL.WebGL.Texture.DEFAULT_WRAP_T = WebGLRenderingContext.REPEAT; 4846 4847 /** 4848 * Default texture sub-image x offset when calling setSubImage. 4849 * 4850 * @type number 4851 * 4852 * @default 0 4853 */ 4854 SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET = 0; 4855 4856 /** 4857 * Default texture sub-image y offset when calling setSubImage. 4858 * 4859 * @type number 4860 * 4861 * @default 0 4862 */ 4863 SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET = 0; 4864 4865 /** 4866 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_FLIP_Y_WEBGL when calling setImage or setSubImage. 4867 * 4868 * @default true 4869 * 4870 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 4871 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION 4872 */ 4873 SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y = true; 4874 4875 /** 4876 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL when calling setImage or setSubImage. 4877 * 4878 * @default true 4879 * 4880 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y 4881 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION 4882 */ 4883 SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA = false; 4884 4885 /** 4886 * Default value for pixel unpack parameter WebGLRenderingContext.UNPACK_COLORSPACE_CONVERSION_WEBGL when calling setImage or setSubImage. 4887 * 4888 * @default WebGLRenderingContext.NONE 4889 * 4890 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y 4891 * @see SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 4892 */ 4893 SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION = WebGLRenderingContext.NONE; 4894 4895 SpiderGL.WebGL.Texture.unbind = function (gl) { }; 4896 4897 SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT = (1 << 0); 4898 SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT = (1 << 1); 4899 SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT = (1 << 2); 4900 SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT = (1 << 3); 4901 SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT = (1 << 4); 4902 SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT = (1 << 5); 4903 SpiderGL.WebGL.Texture._FACE_ALL_BITS = (SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT | SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT | SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT | SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT | SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT | SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT); 4904 4905 SpiderGL.WebGL.Texture._faceBits = { }; 4906 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_2D ] = SpiderGL.WebGL.Texture._FACE_ALL_BITS; 4907 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP ] = SpiderGL.WebGL.Texture._FACE_ALL_BITS; 4908 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X] = SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT; 4909 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_X] = SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT; 4910 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Y] = SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT; 4911 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Y] = SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT; 4912 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Z] = SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT; 4913 SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Z] = SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT; 4914 4915 SpiderGL.WebGL.Texture.prototype = { 4916 _gl_deleteTexture : function (texture) { 4917 this._h = null; 4918 }, 4919 4920 _gl_isTexture : function (texture) { 4921 }, 4922 4923 _gl_bindTexture : function (target, texture) { 4924 }, 4925 4926 _gl_getTexParameter : function (target, pname) { 4927 }, 4928 4929 _gl_copyTexImage2D : function (target, level, internalformat, x, y, width, height, border) { 4930 if (level == 0) { 4931 this._format = internalformat; 4932 this._width = width; 4933 this._height = height; 4934 } 4935 }, 4936 4937 _gl_copyTexSubImage2D : function (target, level, xoffset, yoffset, x, y, width, height, border) { 4938 }, 4939 4940 _gl_generateMipmap : function (target) { 4941 }, 4942 4943 _gl_texImage2D : function (target) { 4944 var n = arguments.length; 4945 if (n === 6) { 4946 if (arguments[1] === 0) { 4947 this._format = arguments[2]; 4948 this._width = arguments[5].width; 4949 this._height = arguments[5].height; 4950 } 4951 } 4952 else if (n === 9) { 4953 if (arguments[1] === 0) { 4954 this._format = arguments[2]; 4955 this._width = arguments[3]; 4956 this._height = arguments[4]; 4957 } 4958 } 4959 }, 4960 4961 _gl_texParameterf : function (target, pname, param) { 4962 this._setTexParameter(pname, param); 4963 }, 4964 4965 _gl_texParameteri : function (target, pname, param) { 4966 this._setTexParameter(pname, param); 4967 }, 4968 4969 _gl_texSubImage2D : function (target) { 4970 }, 4971 4972 _setTexParameter : function (pname, param) { 4973 var gl = this._gl; 4974 4975 switch (pname) { 4976 case gl.TEXTURE_MAG_FILTER : this._magFilter = param; break; 4977 case gl.TEXTURE_MIN_FILTER : this._minFilter = param; break; 4978 case gl.TEXTURE_WRAP_S : this._wrapS = param; break; 4979 case gl.TEXTURE_WRAP_T : this._wrapT = param; break; 4980 default : break; 4981 } 4982 }, 4983 4984 _setImageData : function (fullImage, target, options) { 4985 options = SpiderGL.Utility.getDefaultObject({ 4986 internalFormat : SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT, 4987 border : SpiderGL.WebGL.Texture.DEFAULT_BORDER, 4988 xoffset : SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET, 4989 yoffset : SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET, 4990 level : SpiderGL.WebGL.Texture.DEFAULT_LEVEL, 4991 format : SpiderGL.WebGL.Texture.DEFAULT_FORMAT, 4992 type : SpiderGL.WebGL.Texture.DEFAULT_TYPE, 4993 width : 0, 4994 height : 0, 4995 generateMipmap : this._autoMipmap, 4996 flipY : this._flipY, 4997 premultiplyAlpha : this._premultiplyAlpha, 4998 colorspaceConversion : this._colorspaceConversion, 4999 data : null, 5000 url : null, 5001 onCancel : null, 5002 onError : null, 5003 onProgress : null, 5004 onSuccess : null 5005 }, options); 5006 5007 var isURL = !!options.url; 5008 var isData = false; 5009 if (!isURL) { isData = (!options.data || SpiderGL.Type.isTypedArray(options.data)); /* (!options.data || SpiderGL.Type.instanceOf(options.data, ArrayBufferView)) */ } 5010 var isElement = false; 5011 if (!isURL && !isData) { 5012 // [WORKAROUND] 5013 // Firefox does not define ImageData 5014 // /* correct */ isElement = (SpiderGL.Type.instanceOf(data, ImageData) || SpiderGL.Type.instanceOf(data, HTMLImageElement) || SpiderGL.Type.instanceOf(data, HTMLCanvasElement) || SpiderGL.Type.instanceOf(data, HTMLVideoElement)); 5015 isElement = (SpiderGL.Type.instanceOf(options.data, HTMLImageElement) || SpiderGL.Type.instanceOf(options.data, HTMLCanvasElement) || SpiderGL.Type.instanceOf(options.data, HTMLVideoElement)); 5016 if (!isElement) { 5017 if (typeof ImageData != "undefined") { 5018 isElement = SpiderGL.Type.instanceOf(options.data, ImageData); 5019 } 5020 } 5021 } 5022 5023 var gl = this._gl; 5024 var cb = this._cb; 5025 var dsa = this._dsa; 5026 5027 var t = target; 5028 var h = this._h; 5029 5030 var userFlipY = -1; 5031 var flipY = -1; 5032 var userPremultiplyAlpha = -1; 5033 var premultiplyAlpha = -1; 5034 var userColorspaceConversion = -1; 5035 var colorspaceConversion = -1; 5036 5037 if (isData || isElement) { 5038 userFlipY = options.flipY; 5039 if (userFlipY != SpiderGL.Core.DONT_CARE) { 5040 flipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL); 5041 if (userFlipY == flipY) { flipY = -1; } 5042 else { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, userFlipY); } 5043 } 5044 5045 userPremultiplyAlpha = options.premultiplyAlpha; 5046 if (userPremultiplyAlpha != SpiderGL.Core.DONT_CARE) { 5047 premultiplyAlpha = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL); 5048 if (userPremultiplyAlpha == premultiplyAlpha) { premultiplyAlpha = -1; } 5049 else { gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, userPremultiplyAlpha); } 5050 } 5051 5052 userColorspaceConversion = options.colorspaceConversion; 5053 if (userColorspaceConversion != SpiderGL.Core.DONT_CARE) { 5054 colorspaceConversion = gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL); 5055 if (userColorspaceConversion == colorspaceConversion) { colorspaceConversion = -1; } 5056 else { gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, userColorspaceConversion); } 5057 } 5058 } 5059 5060 var imageUpdated = false; 5061 5062 if (isURL) { 5063 var opts = { 5064 internalFormat : options.internalFormat, 5065 border : options.border, 5066 xoffset : options.xoffset, 5067 yoffset : options.yoffset, 5068 level : options.level, 5069 format : options.format, 5070 type : options.type, 5071 generateMipmap : options.generateMipmap, 5072 flipY : options.flipY, 5073 premultiplyAlpha : options.premultiplyAlpha, 5074 colorspaceConversion : options.colorspaceConversion, 5075 data : null 5076 }; 5077 5078 var that = this; 5079 var onSuccess = options.onSuccess; 5080 5081 var req = new SpiderGL.IO.ImageRequest(options.url, { 5082 onCancel : options.onCancel, 5083 onError : options.onError, 5084 onProgress : options.onProgress, 5085 onSuccess : function () { 5086 opts.data = req.image; 5087 if (fullImage) { 5088 that._setImage(target, opts); 5089 } 5090 else { 5091 that._setSubImage(target, opts); 5092 } 5093 if (onSuccess) { onSuccess(); } 5094 }, 5095 send : true 5096 }); 5097 5098 return true; 5099 } 5100 else if (isData) { 5101 if ((options.width <= 0) || (options.height <= 0)) { return false; } 5102 if (fullImage) { 5103 dsa.texImage2D(h, t, options.level, options.internalFormat, options.width, options.height, options.border, options.format, options.type, options.data); 5104 imageUpdated = true; 5105 } 5106 else { 5107 dsa.texSubImage2D(h, t, options.level, options.xoffset, options.yoffset, options.width, options.height, options.format, options.type, options.data); 5108 } 5109 } 5110 else if (isElement) { 5111 if (fullImage) { 5112 dsa.texImage2D(h, t, options.level, options.internalFormat, options.format, options.type, options.data); 5113 imageUpdated = true; 5114 } 5115 else { 5116 dsa.texSubImage2D(h, t, options.level, options.xoffset, options.yoffset, options.format, options.type, options.data); 5117 } 5118 } 5119 else { 5120 return false; 5121 } 5122 5123 if (imageUpdated) { 5124 this._missingFaces &= ~(SpiderGL.WebGL.Texture._faceBits[t]); 5125 } 5126 5127 if (isData || isElement) { 5128 if (flipY != -1) { gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY); } 5129 if (premultiplyAlpha != -1) { gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); } 5130 if (colorspaceConversion != -1) { gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); } 5131 } 5132 5133 if (options.generateMipmap) { 5134 this.generateMipmap(); 5135 } 5136 5137 return true; 5138 }, 5139 5140 _setImage : function (target, options) { 5141 return this._setImageData(true, target, options); 5142 }, 5143 5144 _setSubImage : function (target, options) { 5145 return this._setImageData(false, target, options); 5146 }, 5147 5148 /* 5149 get isEmpty () { return ((this._width <= 0) || (this._height <= 0)); }, 5150 */ 5151 5152 /** 5153 * Tests if the texture is ready to use. 5154 * A texture is considered ready if all its associated images (one for 2D textures, six for cube maps) have width and height greater than zero. 5155 * 5156 * @type bool 5157 * 5158 * @readonly 5159 */ 5160 get isReady() { 5161 return ((this._missingFaces == 0) && (this._width > 0) && (this._height > 0)); 5162 }, 5163 5164 /** 5165 * Gets/Sets the flip Y policy. 5166 * It specifies the image data vertical flipping policy when unpacking pixel data in setData or setSubData. 5167 * If set to true, the WebGL pixel unpack parameter WebGLRenderingContext.UNPACK_FLIP_Y will be set to true 5168 * If set to false, the WebGL pixel unpack parameter WebGLRenderingContext.UNPACK_FLIP_Y will be set to false 5169 * In either case, the unpack parameter will be restored. 5170 * If set to SpiderGL.Core.DONT_CARE, the current WebGLRenderingContext setting will be used (i.e. nothing will be changed). 5171 * 5172 * @type bool 5173 * 5174 * @default SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y 5175 */ 5176 get flipYPolicy() { 5177 return this._flipY; 5178 }, 5179 5180 set flipYPolicy(x) { 5181 this._flipY = SpiderGL.Utility.getDefaultValue(x, SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y); 5182 }, 5183 5184 /** 5185 * Gets/Sets the premultiply alpha policy. 5186 * It specifies the image data premultiply alpha policy when unpacking pixel data in setData or setSubData. 5187 * If set to true, the WebGL pixel unpack parameter WebGLRenderingContext.UNPACK_PREMULTIPLY_ALPHA will be set to true 5188 * If set to false, the WebGL pixel unpack parameter WebGLRenderingContext.UNPACK_PREMULTIPLY_ALPHA will be set to false 5189 * In either case, the unpack parameter will be restored after image data has been set 5190 * If set to SpiderGL.Core.DONT_CARE, the current WebGLRenderingContext setting will be used (i.e. nothing will be changed). 5191 * 5192 * @type bool 5193 * 5194 * @default SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA 5195 */ 5196 get premultuplyAlphaPolicy() { 5197 return this._premultuplyAlpha; 5198 }, 5199 5200 set premultuplyAlphaPolicy(x) { 5201 this._premultuplyAlpha = SpiderGL.Utility.getDefaultValue(x, SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA); 5202 }, 5203 5204 /** 5205 * Gets/Sets the colorspace conversionpolicy. 5206 * It specifies the image data colorpsce conversion policy when unpacking pixel data in setData or setSubData. 5207 * If set to SpiderGL.Core.DONT_CARE, the current WebGLRenderingContext setting will be used (i.e. nothing will be changed). 5208 * Otherwise, the specified value will be used and then restored after image data has been set. 5209 * 5210 * @type number 5211 * 5212 * @default SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION 5213 */ 5214 get colorspaceConversionPolicy() { 5215 return this._colorspaceConversion; 5216 }, 5217 5218 set colorspaceConversionPolicy(x) { 5219 this._colorspaceConversion = SpiderGL.Utility.getDefaultValue(x, SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION); 5220 }, 5221 5222 /** 5223 * Gets/Sets the automatic mipmap generation. 5224 * 5225 * @type bool 5226 * 5227 * @default SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP 5228 */ 5229 get autoMipmap() { 5230 return this._autoMipmap; 5231 }, 5232 5233 set autoMipmap(on) { 5234 this._autoMipmap = on; 5235 }, 5236 5237 /** 5238 * Gets the texture image internal format. 5239 * 5240 * @type number 5241 * 5242 * @readonly 5243 */ 5244 get format() { 5245 return this._format; 5246 }, 5247 5248 /** 5249 * Gets the texture image width. 5250 * 5251 * @type number 5252 * 5253 * @readonly 5254 */ 5255 get width() { 5256 return this._width; 5257 }, 5258 5259 /** 5260 * Gets the texture image height. 5261 * 5262 * @type number 5263 * 5264 * @readonly 5265 */ 5266 get height() { 5267 return this._height; 5268 }, 5269 5270 /** 5271 * Gets/Sets the texture magnification filter. 5272 * 5273 * @type number 5274 */ 5275 get magFilter() { 5276 return this._magFilter; 5277 }, 5278 5279 set magFilter(f) { 5280 f = SpiderGL.Utility.getDefaultValue(w, SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER); 5281 this._dsa.texParameteri(this._h, this._t, gl.TEXTURE_MAG_FILTER, f); 5282 }, 5283 5284 /** 5285 * Gets/Sets the texture minification filter. 5286 * 5287 * @type number 5288 */ 5289 get minFilter() { 5290 return this._minFilter; 5291 }, 5292 5293 set minFilter (f) { 5294 f = SpiderGL.Utility.getDefaultValue(w, SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER); 5295 this._dsa.texParameteri(this._h, this._t, gl.TEXTURE_MIN_FILTER, f); 5296 }, 5297 5298 /** 5299 * Gets/Sets the texture horizontal wrap mode. 5300 * 5301 * @type number 5302 */ 5303 get wrapS() { 5304 return this._wrapS; 5305 }, 5306 5307 set wrapS(w) { 5308 w = SpiderGL.Utility.getDefaultValue(w, SpiderGL.WebGL.Texture.DEFAULT_WRAP_S); 5309 this._dsa.texParameteri(this._h, this._t, gl.TEXTURE_WRAP_S, w); 5310 }, 5311 5312 /** 5313 * Gets/Sets the texture vertical wrap mode. 5314 * 5315 * @type number 5316 */ 5317 get wrapT() { 5318 return this._wrapT; 5319 }, 5320 5321 set wrapT(w) { 5322 w = SpiderGL.Utility.getDefaultValue(w, SpiderGL.WebGL.Texture.DEFAULT_WRAP_T); 5323 this._dsa.texParameteri(this._h, this._t, gl.TEXTURE_WRAP_T, w); 5324 }, 5325 5326 /** 5327 * Sets the texture sampling (filtering and addressing) mode. 5328 * It is a utility function to specify the addressing and filtering parameters at once. 5329 * Only the specified properties will be changed. 5330 * To restore the default value, specify the property with value SpiderGL.Core.DEFAULT. 5331 * 5332 * @param {object} sampler The sampling options. 5333 * @param {number} [sampler.magFilter] Texture magnification filter (see {@link SpiderGL.WebGL.Texture#magFilter}). 5334 * @param {number} [sampler.minFilter] Texture minnification filter (see {@link SpiderGL.WebGL.Texture#minFilter}). 5335 * @param {number} [sampler.wrapS] Texture horizontal wrap mode (see {@link SpiderGL.WebGL.Texture#wrapS}). 5336 * @param {number} [sampler.wrapT] Texture vertical wrap mode (see {@link SpiderGL.WebGL.Texture#wrapT}). 5337 */ 5338 setSampler : function (sampler) { 5339 if (!sampler) return false; 5340 5341 var gl = this._gl; 5342 var cb = this._cb; 5343 var dsa = this._dsa; 5344 5345 var t = this._t; 5346 var h = this._h; 5347 5348 cb.pushTexture(t); 5349 gl.bindTexture(t, h); 5350 5351 var p = 0; 5352 5353 if ("magFilter" in sampler) { 5354 p = SpiderGL.Utility.getDefaultValue(sampler.magFilter, SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER); 5355 gl.texParameteri(t, gl.TEXTURE_MAG_FILTER, p); 5356 } 5357 5358 if ("minFilter" in sampler) { 5359 p = SpiderGL.Utility.getDefaultValue(sampler.minFilter, SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER); 5360 gl.texParameteri(t, gl.TEXTURE_MIN_FILTER, p); 5361 } 5362 5363 if ("wrapS" in sampler) { 5364 p = SpiderGL.Utility.getDefaultValue(sampler.wrapS, SpiderGL.WebGL.Texture.DEFAULT_WRAP_S); 5365 gl.texParameteri(t, gl.TEXTURE_WRAP_S, p); 5366 } 5367 5368 if ("wrapT" in sampler) { 5369 p = SpiderGL.Utility.getDefaultValue(sampler.wrapT, SpiderGL.WebGL.Texture.DEFAULT_WRAP_T); 5370 gl.texParameteri(t, gl.TEXTURE_WRAP_T, p); 5371 } 5372 5373 cb.popTexture(t); 5374 5375 return true; 5376 }, 5377 5378 /** 5379 * Gets the texture sampling (filtering and addressing) mode. 5380 * 5381 * @returns {object} The sampling options. The returned object will have the following properties: magFilter, minFilter, wrapS, wrapT. 5382 */ 5383 getSampler : function () { 5384 return { 5385 magFilter : this._magFilter, 5386 minFilter : this._minFilter, 5387 wrapS : this._wrapS, 5388 wrapT : this._wrapT 5389 }; 5390 }, 5391 5392 /** 5393 * Generates the mipmap pyramid. 5394 */ 5395 generateMipmap : function () { 5396 if (this._missingFaces != 0) return; 5397 this._dsa.generateMipmap(this._h, this._t); 5398 }, 5399 5400 /** 5401 * Destroys the WebGLTexture. 5402 * After destruction, the handle is set to null and this object should not be used anymore. 5403 * 5404 * @see SpiderGL.WebGL.ObjectGL#destroy 5405 */ 5406 destroy : function () { 5407 this._gl.deleteTexture(this._h); 5408 }, 5409 5410 /** 5411 * Binds the texture to the appropriate target for SpiderGL.WebGL.Texture2D and SpiderGL.WebGL.TextureCubeMap. 5412 * 5413 * @param {number} unit The unit (zero-based index) to which bind the texture. If not specified, the current texture unit is used. 5414 * 5415 * @see unbind 5416 */ 5417 bind : function (unit) { 5418 var gl = this._gl; 5419 var cb = this._cb; 5420 var dsa = this._dsa; 5421 if (typeof unit == "undefined") { 5422 gl.bindTexture(this._t, this._h); 5423 } 5424 else { 5425 dsa.bindTexture(gl.TEXTURE0 + unit, this._t, this._h); 5426 } 5427 }, 5428 5429 /** 5430 * Binds "null" to the appropriate texture target for SpiderGL.WebGL.Texture2D and SpiderGL.WebGL.TextureCubeMap. 5431 * This method is provided only for simmetry with {@link bind} and is not relative to the object state. 5432 * 5433 * @param {number} unit The unit (zero-based index) to which bind the null texture. If not specified, the current texture unit is used. 5434 * 5435 * @see bind 5436 */ 5437 unbind : function (unit) { 5438 var gl = this._gl; 5439 var cb = this._cb; 5440 var dsa = this._dsa; 5441 if (typeof unit == "undefined") { 5442 gl.bindTexture(this._t, null); 5443 } 5444 else { 5445 dsa.bindTexture(gl.TEXTURE0 + unit, this._t, null); 5446 } 5447 } 5448 }; 5449 5450 SpiderGL.Type.extend(SpiderGL.WebGL.Texture, SpiderGL.WebGL.ObjectGL); 5451 5452 /** 5453 * Creates a SpiderGL.WebGL.Texture2D. 5454 * 5455 * SpiderGL.WebGL.Texture2D is a wrapper for 2D WebGLTexture objects. 5456 * 5457 * @class The SpiderGL.WebGL.Texture2D is a wrapper for 2D WebGLTexture objects 5458 * 5459 * @augments SpiderGL.WebGL.Texture 5460 * 5461 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 5462 * @param {object} [options] Optional parameters (see SpiderGL.WebGL.Texture constructor). 5463 * 5464 * @see SpiderGL.WebGL.Texture 5465 * @see SpiderGL.WebGL.TextureCubeMap 5466 * @see SpiderGL.WebGL.Framebuffer 5467 * @see SpiderGL.WebGL.ObjectGL 5468 */ 5469 SpiderGL.WebGL.Texture2D = function (gl, options) { 5470 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 5471 SpiderGL.WebGL.Texture.call(this, gl, SpiderGL.WebGL.Texture2D.TARGET, options); 5472 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 5473 5474 options = options || { }; 5475 if (SpiderGL.Type.instanceOf(options, WebGLTexture)) { 5476 options = { handle : options }; 5477 } 5478 else if (SpiderGL.Type.isString(options)) { 5479 options = { url : options }; 5480 } 5481 5482 if (("url" in options) || ("data" in options) || (("width" in options) && ("height" in options))) { this.setImage(options); } 5483 } 5484 5485 SpiderGL.WebGL.Texture2D.TARGET = WebGLRenderingContext.TEXTURE_2D; 5486 5487 SpiderGL.WebGL.Texture2D.unbind = function (gl, unit) { 5488 var cb = gl.getExtension("SGL_current_binding"); 5489 var dsa = gl.getExtension("SGL_direct_state_access"); 5490 if (typeof unit == "undefined") { 5491 gl.bindTexture(SpiderGL.WebGL.Texture2D.TARGET, null); 5492 } 5493 else { 5494 dsa.bindTexture(gl.TEXTURE0 + unit, SpiderGL.WebGL.Texture2D.TARGET, null); 5495 } 5496 }; 5497 5498 SpiderGL.WebGL.Texture2D.prototype = { 5499 /** 5500 * Sets the texture image. 5501 * 5502 * @param {object} options The image data and type parameters (see SpiderGL.WebGL.Texture constructor). 5503 * @param {ArrayBuffer|ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.data] The texture image pixel data. 5504 * @param {number} [options.internalFormat=SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT] The texture internal format. 5505 * @param {number} [options.level=SpiderGL.WebGL.Texture.DEFAULT_LEVEL] The texture image mip level. 5506 * @param {number} [options.width] If data is null or a typed array, specifies the texture image width. If handle is provided, the width parameter will supply the width information, not querable to the WebGLRenderingContext. 5507 * @param {number} [options.height] If data is null or a typed array, specifies the texture image height. If handle is provided, the width parameter will supply the height information, not querable to the WebGLRenderingContext. 5508 * @param {number} [options.border=SpiderGL.WebGL.Texture.DEFAULT_BORDER] Texture border. 5509 * @param {number} [options.format=SpiderGL.WebGL.Texture.DEFAULT_FORMAT] The format parameter used for WebGLRenderingContext.texImage2D. 5510 * @param {number} [options.type=SpiderGL.WebGL.Texture.DEFAULT_TYPE] The type parameter used for WebGLRenderingContext.texImage2D. 5511 * @param {bool} [options.generateMipmap] If specified, overrides autoMipmap. 5512 * @param {bool} [options.flipY] If specified, overrides flipYPolicy. 5513 * @param {bool} [options.premultiplyAlpha] If specified, overrides premultiplyAlphaPolicy. 5514 * @param {number} [options.colorspaceConversion] If specified, overrides colorspaceConversionPolicy. 5515 * @param {function} [options.onAbort] If url is specified, this function will be called if image data loading is aborted. 5516 * @param {function} [options.onError] If url is specified, this function will be called if an error occurs when loading image data. 5517 * @param {function} [options.onLoad] If url is specified, this function will be called when image data has been loaded. 5518 * 5519 * @see setSubImage 5520 * @see SpiderGL.WebGL.Texture 5521 */ 5522 setImage : function (options) { 5523 return this._setImage(this._t, options); 5524 }, 5525 5526 /** 5527 * Sets a region of the texture image. 5528 * 5529 * @param {object} options The image data and type parameters (see SpiderGL.WebGL.Texture constructor). 5530 * @param {ArrayBuffer|ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.data] The texture sub-image pixel data. 5531 * @param {number} [options.xoffset=SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET] The sub-image x offset. 5532 * @param {number} [options.yoffset=SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET] The sub-image y offset. 5533 * @param {number} [options.width] If data is null or a typed array, specifies the texture image width. If handle is provided, the width parameter will supply the width information, not querable to the WebGLRenderingContext. 5534 * @param {number} [options.height] If data is null or a typed array, specifies the texture image height. If handle is provided, the width parameter will supply the height information, not querable to the WebGLRenderingContext. 5535 * @param {number} [options.border=SpiderGL.WebGL.Texture.DEFAULT_BORDER] Texture border. 5536 * @param {number} [options.format=SpiderGL.WebGL.Texture.DEFAULT_FORMAT] The format parameter used for WebGLRenderingContext.texSubImage2D. 5537 * @param {number} [options.type=SpiderGL.WebGL.Texture.DEFAULT_TYPE] The type parameter used for WebGLRenderingContext.texSubImage2D. 5538 * @param {bool} [options.generateMipmap] If specified, overrides autoMipmap. 5539 * @param {bool} [options.flipY] If specified, overrides flipYPolicy. 5540 * @param {bool} [options.premultiplyAlpha] If specified, overrides premultiplyAlphaPolicy. 5541 * @param {number} [options.colorspaceConversion] If specified, overrides colorspaceConversionPolicy. 5542 * @param {function} [options.onAbort] If url is specified, this function will be called if image data loading is aborted. 5543 * @param {function} [options.onError] If url is specified, this function will be called if an error occurs when loading image data. 5544 * @param {function} [options.onLoad] If url is specified, this function will be called when image data has been loaded. 5545 * 5546 * @see setImage 5547 * @see SpiderGL.WebGL.Texture 5548 */ 5549 setSubImage : function (options) { 5550 return this._setSubImage(this._t, options); 5551 } 5552 }; 5553 5554 SpiderGL.Type.extend(SpiderGL.WebGL.Texture2D, SpiderGL.WebGL.Texture); 5555 5556 /** 5557 * Creates a SpiderGL.WebGL.TextureCubeMap. 5558 * 5559 * SpiderGL.WebGL.TextureCubeMap is a wrapper for cube map WebGLTexture objects. 5560 * 5561 * @class The SpiderGL.WebGL.TextureCubeMap is a wrapper for cube map WebGLTexture objects 5562 * 5563 * @augments SpiderGL.WebGL.Texture 5564 * 5565 * @param {WebGLRenderingContext} gl A WebGLRenderingContext hijacked with {@link SpiderGL.WebGL.Context.hijack}. 5566 * @param {object} [options] Optional parameters (see SpiderGL.WebGL.Texture constructor). This constructor accepts only the url options as an array of six strings, or internalFormat, width, height, format and type, ignoring the data property. 5567 * 5568 * @see SpiderGL.WebGL.Texture 5569 * @see SpiderGL.WebGL.Texture2D 5570 * @see SpiderGL.WebGL.Framebuffer 5571 * @see SpiderGL.WebGL.ObjectGL 5572 */ 5573 SpiderGL.WebGL.TextureCubeMap = function (gl, options) { 5574 if (!SpiderGL.WebGL.Context.isHijacked(gl)) { return null; } 5575 SpiderGL.WebGL.Texture.call(this, gl, SpiderGL.WebGL.TextureCubeMap.TARGET, options); 5576 if (!!this._h && !!this._h._spidergl && (this._h._spidergl != this)) return this._h._spidergl; 5577 5578 options = options || { }; 5579 if (SpiderGL.Type.instanceOf(options, WebGLTexture)) { 5580 options = { handle : options }; 5581 } 5582 else if (SpiderGL.Type.isString(options)) { 5583 options = { url : options }; 5584 } 5585 5586 var faceTargets = SpiderGL.WebGL.TextureCubeMap._faceTargets; 5587 5588 if (options.url) { 5589 var urls = options.url; 5590 for (var i=0; i<6; ++i) { 5591 options.url = urls[i]; 5592 this.setImage(faceTargets[i], options); 5593 } 5594 } 5595 else if (options.data) { 5596 var datas = options.data; 5597 for (var i=0; i<6; ++i) { 5598 options.data = datas[i]; 5599 this.setImage(faceTargets[i], options); 5600 } 5601 } 5602 else if ((options.width > 0) && (options.height > 0)) { 5603 for (var i=0; i<6; ++i) { 5604 this.setImage(faceTargets[i], options); 5605 } 5606 } 5607 } 5608 5609 SpiderGL.WebGL.TextureCubeMap.TARGET = WebGLRenderingContext.TEXTURE_CUBE_MAP; 5610 5611 SpiderGL.WebGL.TextureCubeMap.unbind = function (gl, unit) { 5612 var cb = gl.getExtension("SGL_current_binding"); 5613 var dsa = gl.getExtension("SGL_direct_state_access"); 5614 if (typeof unit == "undefined") { 5615 gl.bindTexture(SpiderGL.WebGL.TextureCubeMap.TARGET, null); 5616 } 5617 else { 5618 dsa.bindTexture(gl.TEXTURE0 + unit, SpiderGL.WebGL.TextureCubeMap.TARGET, null); 5619 } 5620 }; 5621 5622 SpiderGL.WebGL.TextureCubeMap._faceTargets = [ 5623 WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_X, 5624 WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_X, 5625 WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Y, 5626 WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Y, 5627 WebGLRenderingContext.TEXTURE_CUBE_MAP_POSITIVE_Z, 5628 WebGLRenderingContext.TEXTURE_CUBE_MAP_NEGATIVE_Z 5629 ]; 5630 5631 SpiderGL.WebGL.TextureCubeMap.prototype = { 5632 /** 5633 * Sets the texture image for a cube face. 5634 * 5635 * @param {number} face The cube map face to set. 5636 * @param {object} options The image data and type parameters (see SpiderGL.WebGL.Texture constructor). 5637 * @param {ArrayBuffer|ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.data] The texture image pixel data. 5638 * @param {number} [options.internalFormat=SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT] The texture internal format. 5639 * @param {number} [options.width] If data is null or a typed array, specifies the texture image width. If handle is provided, the width parameter will supply the width information, not querable to the WebGLRenderingContext. 5640 * @param {number} [options.height] If data is null or a typed array, specifies the texture image height. If handle is provided, the width parameter will supply the height information, not querable to the WebGLRenderingContext. 5641 * @param {number} [options.border=SpiderGL.WebGL.Texture.DEFAULT_BORDER] Texture border. 5642 * @param {number} [options.format=SpiderGL.WebGL.Texture.DEFAULT_FORMAT] The format parameter used for WebGLRenderingContext.texImage2D. 5643 * @param {number} [options.type=SpiderGL.WebGL.Texture.DEFAULT_TYPE] The type parameter used for WebGLRenderingContext.texImage2D. 5644 * @param {bool} [options.generateMipmap] If specified, overrides autoMipmap. 5645 * @param {bool} [options.flipY] If specified, overrides flipYPolicy. 5646 * @param {bool} [options.premultiplyAlpha] If specified, overrides premultiplyAlphaPolicy. 5647 * @param {number} [options.colorspaceConversion] If specified, overrides colorspaceConversionPolicy. 5648 * @param {function} [options.onAbort] If url is specified, this function will be called if image data loading is aborted. 5649 * @param {function} [options.onError] If url is specified, this function will be called if an error occurs when loading image data. 5650 * @param {function} [options.onLoad] If url is specified, this function will be called when image data has been loaded. 5651 * 5652 * @see setSubImage 5653 * @see SpiderGL.WebGL.Texture 5654 */ 5655 setImage : function (face, options) { 5656 /* 5657 var b = SpiderGL.WebGL.TextureCubeMap._faceBits[face]; 5658 if (!b) return false; 5659 var r = this._setImage(face, options); 5660 if (r) { this._missingFaces &= ~b; } 5661 return r; 5662 */ 5663 return this._setImage(face, options); 5664 }, 5665 5666 /** 5667 * Sets a region of the texture image for a cube face. 5668 * 5669 * @param {number} face The cube map face to set. 5670 * @param {object} options The image data and type parameters (see SpiderGL.WebGL.Texture constructor). 5671 * @param {ArrayBuffer|ArrayBufferView|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} [options.data] The texture sub-image pixel data. 5672 * @param {number} [options.xoffset=SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET] The sub-image x offset. 5673 * @param {number} [options.yoffset=SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET] The sub-image y offset. 5674 * @param {number} [options.width] If data is null or a typed array, specifies the texture image width. If handle is provided, the width parameter will supply the width information, not querable to the WebGLRenderingContext. 5675 * @param {number} [options.height] If data is null or a typed array, specifies the texture image height. If handle is provided, the width parameter will supply the height information, not querable to the WebGLRenderingContext. 5676 * @param {number} [options.border=SpiderGL.WebGL.Texture.DEFAULT_BORDER] Texture border. 5677 * @param {number} [options.format=SpiderGL.WebGL.Texture.DEFAULT_FORMAT] The format parameter used for WebGLRenderingContext.texSubImage2D. 5678 * @param {number} [options.type=SpiderGL.WebGL.Texture.DEFAULT_TYPE] The type parameter used for WebGLRenderingContext.texSubImage2D. 5679 * @param {bool} [options.generateMipmap] If specified, overrides autoMipmap. 5680 * @param {bool} [options.flipY] If specified, overrides flipYPolicy. 5681 * @param {bool} [options.premultiplyAlpha] If specified, overrides premultiplyAlphaPolicy. 5682 * @param {number} [options.colorspaceConversion] If specified, overrides colorspaceConversionPolicy. 5683 * @param {function} [options.onAbort] If url is specified, this function will be called if image data loading is aborted. 5684 * @param {function} [options.onError] If url is specified, this function will be called if an error occurs when loading image data. 5685 * @param {function} [options.onLoad] If url is specified, this function will be called when image data has been loaded. 5686 * 5687 * @see setImage 5688 * @see SpiderGL.WebGL.Texture 5689 */ 5690 setSubImage : function (face, options) { 5691 return this._setSubImage(face, options); 5692 } 5693 }; 5694 5695 SpiderGL.Type.extend(SpiderGL.WebGL.TextureCubeMap, SpiderGL.WebGL.Texture); 5696 5697