Selaa lähdekoodia

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 8 vuotta sitten
vanhempi
commit
08ceb8da5a

BIN
assets/meshes/Dude/0.jpg


BIN
assets/meshes/Dude/1.jpg


BIN
assets/meshes/Dude/2.jpg


BIN
assets/meshes/Dude/3.jpg


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 0
assets/meshes/Dude/dude.babylon


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5 - 0
assets/meshes/skull.babylon


BIN
assets/textures/sun.png


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 23 - 23
dist/preview release/babylon.core.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5127 - 5112
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 32 - 32
dist/preview release/babylon.js


+ 170 - 56
dist/preview release/babylon.max.js

@@ -6553,6 +6553,8 @@ var BABYLON;
             this._currentBufferPointers = [];
             this._currentInstanceLocations = new Array();
             this._currentInstanceBuffers = new Array();
+            this._vaoRecordInProgress = false;
+            this._mustWipeVertexAttributes = false;
             // Hardware supported Compressed Textures
             this._texturesSupported = new Array();
             this._onVRFullScreenTriggered = function () {
@@ -6588,6 +6590,14 @@ var BABYLON;
             }
             // GL
             if (!options.disableWebGL2Support) {
+                try {
+                    this._gl = (canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
+                    if (this._gl) {
+                        this._webGLVersion = 2.0;
+                    }
+                }
+                catch (e) {
+                }
             }
             if (!this._gl) {
                 if (!canvas) {
@@ -6664,7 +6674,7 @@ var BABYLON;
             this._caps.textureHalfFloat = this._webGLVersion > 1 || (this._gl.getExtension('OES_texture_half_float') !== null);
             this._caps.textureHalfFloatLinearFiltering = this._webGLVersion > 1 || this._gl.getExtension('OES_texture_half_float_linear');
             this._caps.textureHalfFloatRender = renderToHalfFloat;
-            // Vertex array object
+            // Vertex array object 
             if (this._webGLVersion > 1) {
                 this._caps.vertexArrayObject = true;
             }
@@ -7448,6 +7458,7 @@ var BABYLON;
         Engine.prototype._resetVertexBufferBinding = function () {
             this.bindArrayBuffer(null);
             this._cachedVertexBuffers = null;
+            this._unBindVertexArrayObject();
         };
         Engine.prototype.createVertexBuffer = function (vertices) {
             var vbo = this._gl.createBuffer();
@@ -7533,7 +7544,7 @@ var BABYLON;
             this.bindBuffer(buffer, this._gl.ELEMENT_ARRAY_BUFFER);
         };
         Engine.prototype.bindBuffer = function (buffer, target) {
-            if (this._currentBoundBuffer[target] !== buffer) {
+            if (this._vaoRecordInProgress || this._currentBoundBuffer[target] !== buffer) {
                 this._gl.bindBuffer(target, buffer);
                 this._currentBoundBuffer[target] = buffer;
             }
@@ -7574,11 +7585,69 @@ var BABYLON;
                     changed = true;
                 }
             }
-            if (changed) {
+            if (changed || this._vaoRecordInProgress) {
                 this.bindArrayBuffer(buffer);
                 this._gl.vertexAttribPointer(indx, size, type, normalized, stride, offset);
             }
         };
+        Engine.prototype._bindIndexBufferWithCache = function (indexBuffer) {
+            if (this._cachedIndexBuffer !== indexBuffer) {
+                this._cachedIndexBuffer = indexBuffer;
+                this.bindIndexBuffer(indexBuffer);
+                this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
+                this._unBindVertexArrayObject();
+            }
+        };
+        Engine.prototype._bindVertexBuffersAttributes = function (vertexBuffers, effect) {
+            var attributes = effect.getAttributesNames();
+            if (!this._vaoRecordInProgress) {
+                this._unBindVertexArrayObject();
+            }
+            this.unbindAllAttributes();
+            for (var index = 0; index < attributes.length; index++) {
+                var order = effect.getAttributeLocation(index);
+                if (order >= 0) {
+                    var vertexBuffer = vertexBuffers[attributes[index]];
+                    if (!vertexBuffer) {
+                        continue;
+                    }
+                    this._gl.enableVertexAttribArray(order);
+                    if (!this._vaoRecordInProgress) {
+                        this._vertexAttribArraysEnabled[order] = true;
+                    }
+                    var buffer = vertexBuffer.getBuffer();
+                    this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
+                    if (vertexBuffer.getIsInstanced()) {
+                        this._gl.vertexAttribDivisor(order, 1);
+                        if (!this._vaoRecordInProgress) {
+                            this._currentInstanceLocations.push(order);
+                            this._currentInstanceBuffers.push(buffer);
+                        }
+                    }
+                }
+            }
+        };
+        Engine.prototype.recordVertexArrayObject = function (vertexBuffers, indexBuffer, effect) {
+            var vao = this._gl.createVertexArray();
+            this._vaoRecordInProgress = true;
+            this._gl.bindVertexArray(vao);
+            this._mustWipeVertexAttributes = true;
+            this._bindVertexBuffersAttributes(vertexBuffers, effect);
+            this.bindIndexBuffer(indexBuffer);
+            this._vaoRecordInProgress = false;
+            this._gl.bindVertexArray(null);
+            return vao;
+        };
+        Engine.prototype.bindVertexArrayObject = function (vertexArrayObject, indexBuffer) {
+            if (this._cachedVertexArrayObject !== vertexArrayObject) {
+                this._cachedVertexArrayObject = vertexArrayObject;
+                this._gl.bindVertexArray(vertexArrayObject);
+                this._cachedVertexBuffers = null;
+                this._cachedIndexBuffer = null;
+                this._uintIndicesCurrentlySet = indexBuffer != null && indexBuffer.is32Bits;
+                this._mustWipeVertexAttributes = true;
+            }
+        };
         Engine.prototype.bindBuffersDirectly = function (vertexBuffer, indexBuffer, vertexDeclaration, vertexStrideSize, effect) {
             if (this._cachedVertexBuffers !== vertexBuffer || this._cachedEffectForVertexBuffers !== effect) {
                 this._cachedVertexBuffers = vertexBuffer;
@@ -7598,42 +7667,22 @@ var BABYLON;
                     }
                 }
             }
-            if (this._cachedIndexBuffer !== indexBuffer) {
-                this._cachedIndexBuffer = indexBuffer;
-                this.bindIndexBuffer(indexBuffer);
-                this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
+            this._bindIndexBufferWithCache(indexBuffer);
+        };
+        Engine.prototype._unBindVertexArrayObject = function () {
+            if (!this._cachedVertexArrayObject) {
+                return;
             }
+            this._cachedVertexArrayObject = null;
+            this._gl.bindVertexArray(null);
         };
         Engine.prototype.bindBuffers = function (vertexBuffers, indexBuffer, effect) {
             if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {
                 this._cachedVertexBuffers = vertexBuffers;
                 this._cachedEffectForVertexBuffers = effect;
-                var attributes = effect.getAttributesNames();
-                this.unbindAllAttributes();
-                for (var index = 0; index < attributes.length; index++) {
-                    var order = effect.getAttributeLocation(index);
-                    if (order >= 0) {
-                        var vertexBuffer = vertexBuffers[attributes[index]];
-                        if (!vertexBuffer) {
-                            continue;
-                        }
-                        this._gl.enableVertexAttribArray(order);
-                        this._vertexAttribArraysEnabled[order] = true;
-                        var buffer = vertexBuffer.getBuffer();
-                        this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
-                        if (vertexBuffer.getIsInstanced()) {
-                            this._gl.vertexAttribDivisor(order, 1);
-                            this._currentInstanceLocations.push(order);
-                            this._currentInstanceBuffers.push(buffer);
-                        }
-                    }
-                }
-            }
-            if (indexBuffer != null && this._cachedIndexBuffer !== indexBuffer) {
-                this._cachedIndexBuffer = indexBuffer;
-                this.bindIndexBuffer(indexBuffer);
-                this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
+                this._bindVertexBuffersAttributes(vertexBuffers, effect);
             }
+            this._bindIndexBufferWithCache(indexBuffer);
         };
         Engine.prototype.unbindInstanceAttributes = function () {
             var boundBuffer;
@@ -7649,6 +7698,9 @@ var BABYLON;
             this._currentInstanceBuffers.length = 0;
             this._currentInstanceLocations.length = 0;
         };
+        Engine.prototype.releaseVertexArrayObject = function (vao) {
+            this._gl.deleteVertexArray(vao);
+        };
         Engine.prototype._releaseBuffer = function (buffer) {
             buffer.references--;
             if (buffer.references === 0) {
@@ -7812,12 +7864,6 @@ var BABYLON;
             return results;
         };
         Engine.prototype.enableEffect = function (effect) {
-            //if (!effect || !effect.getAttributesCount() || this._currentEffect === effect) {
-            //    if (effect && effect.onBind) {
-            //        effect.onBind(effect);
-            //    }
-            //    return;
-            //}
             // Use program
             this.setProgram(effect.getProgram());
             this._currentEffect = effect;
@@ -8035,6 +8081,7 @@ var BABYLON;
             this._cachedVertexBuffers = null;
             this._cachedIndexBuffer = null;
             this._cachedEffectForVertexBuffers = null;
+            this._unBindVertexArrayObject();
         };
         Engine.prototype.setSamplingMode = function (texture, samplingMode) {
             var gl = this._gl;
@@ -8966,14 +9013,20 @@ var BABYLON;
             }
         };
         Engine.prototype.unbindAllAttributes = function () {
+            if (this._mustWipeVertexAttributes) {
+                this._mustWipeVertexAttributes = false;
+                for (var i = 0; i < this._caps.maxVertexAttribs; i++) {
+                    this._gl.disableVertexAttribArray(i);
+                    this._vertexAttribArraysEnabled[i] = false;
+                }
+                return;
+            }
             for (var i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {
                 if (i >= this._caps.maxVertexAttribs || !this._vertexAttribArraysEnabled[i]) {
                     continue;
                 }
-                if (this._vertexAttribArraysEnabled[i]) {
-                    this._gl.disableVertexAttribArray(i);
-                    this._vertexAttribArraysEnabled[i] = false;
-                }
+                this._gl.disableVertexAttribArray(i);
+                this._vertexAttribArraysEnabled[i] = false;
             }
         };
         // Dispose
@@ -20685,7 +20738,7 @@ var BABYLON;
                 }
             }
             // VBOs
-            engine.bindBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
+            this._geometry._bind(effect, indexToBind);
         };
         Mesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
             if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
@@ -20813,7 +20866,7 @@ var BABYLON;
             else {
                 instancesBuffer.updateDirectly(this._instancesData, 0, instancesCount);
             }
-            engine.bindBuffers(this.geometry.getVertexBuffers(), this.geometry.getIndexBuffer(), effect);
+            this.geometry._bind(effect);
             this._draw(subMesh, fillMode, instancesCount);
             engine.unbindInstanceAttributes();
         };
@@ -25390,6 +25443,7 @@ var BABYLON;
     var Effect = (function () {
         function Effect(baseName, attributesNames, uniformsNames, samplers, engine, defines, fallbacks, onCompiled, onError, indexParameters) {
             var _this = this;
+            this.uniqueId = 0;
             this._isReady = false;
             this._compilationError = "";
             this._valueCache = {};
@@ -25402,6 +25456,7 @@ var BABYLON;
             this.onError = onError;
             this.onCompiled = onCompiled;
             this._indexParameters = indexParameters;
+            this.uniqueId = Effect._uniqueIdSeed++;
             var vertexSource;
             var fragmentSource;
             if (baseName.vertexElement) {
@@ -25436,6 +25491,13 @@ var BABYLON;
                 });
             });
         }
+        Object.defineProperty(Effect.prototype, "key", {
+            get: function () {
+                return this._key;
+            },
+            enumerable: true,
+            configurable: true
+        });
         // Properties
         Effect.prototype.isReady = function () {
             return this._isReady;
@@ -26048,6 +26110,7 @@ var BABYLON;
         };
         return Effect;
     }());
+    Effect._uniqueIdSeed = 0;
     // Statics
     Effect.ShadersStore = {};
     Effect.IncludesShadersStore = {};
@@ -29050,6 +29113,7 @@ var BABYLON;
             this.minAngularSpeed = 0;
             this.maxAngularSpeed = 0;
             this.layerMask = 0x0FFFFFFF;
+            this.customShader = null;
             /**
             * An event triggered when the system is disposed.
             * @type {BABYLON.Observable}
@@ -29358,8 +29422,16 @@ var BABYLON;
         };
         // Clone
         ParticleSystem.prototype.clone = function (name, newEmitter) {
-            var result = new ParticleSystem(name, this._capacity, this._scene);
-            BABYLON.Tools.DeepCopy(this, result, ["particles"]);
+            var custom = null;
+            var program = null;
+            if (this.customShader != null) {
+                program = this.customShader;
+                var defines = (program.shaderOptions.defines.length > 0) ? program.shaderOptions.defines.join("\n") : "";
+                custom = this._scene.getEngine().createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);
+            }
+            var result = new ParticleSystem(name, this._capacity, this._scene, custom);
+            result.customShader = program;
+            BABYLON.Tools.DeepCopy(this, result, ["particles", "customShader"]);
             if (newEmitter === undefined) {
                 newEmitter = this.emitter;
             }
@@ -29409,11 +29481,20 @@ var BABYLON;
             serializationObject.targetStopDuration = this.targetStopDuration;
             serializationObject.textureMask = this.textureMask.asArray();
             serializationObject.blendMode = this.blendMode;
+            serializationObject.customShader = this.customShader;
             return serializationObject;
         };
         ParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl) {
             var name = parsedParticleSystem.name;
-            var particleSystem = new ParticleSystem(name, parsedParticleSystem.capacity, scene);
+            var custom = null;
+            var program = null;
+            if (parsedParticleSystem.customShader) {
+                program = parsedParticleSystem.customShader;
+                var defines = (program.shaderOptions.defines.length > 0) ? program.shaderOptions.defines.join("\n") : "";
+                custom = scene.getEngine().createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);
+            }
+            var particleSystem = new ParticleSystem(name, parsedParticleSystem.capacity, scene, custom);
+            particleSystem.customShader = program;
             if (parsedParticleSystem.id) {
                 particleSystem.id = parsedParticleSystem.id;
             }
@@ -32438,14 +32519,22 @@ var BABYLON;
                     _this.object.rotationQuaternion.multiplyInPlace(_this._deltaRotation);
                 }
             };
+            /**
+             * Legacy collision detection event support
+             */
+            this.onCollideEvent = null;
             //event and body object due to cannon's event-based architecture.
             this.onCollide = function (e) {
-                if (!_this._onPhysicsCollideCallbacks.length)
+                if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent)
                     return;
                 var otherImpostor = _this._physicsEngine.getImpostorWithPhysicsBody(e.body);
                 if (otherImpostor) {
+                    // Legacy collision detection event support
+                    if (_this.onCollideEvent) {
+                        _this.onCollideEvent(_this, otherImpostor);
+                    }
                     _this._onPhysicsCollideCallbacks.filter(function (obj) {
-                        return (obj.otherImpostors.length === 0 || obj.otherImpostors.indexOf(otherImpostor) !== -1);
+                        return obj.otherImpostors.indexOf(otherImpostor) !== -1;
                     }).forEach(function (obj) {
                         obj.callback(_this, otherImpostor);
                     });
@@ -36709,6 +36798,9 @@ var BABYLON;
                 this._totalVertices = 0;
                 this._indices = [];
             }
+            if (this._engine.getCaps().vertexArrayObject) {
+                this._vertexArrayObjects = {};
+            }
             // applyToMesh
             if (mesh) {
                 if (mesh instanceof BABYLON.LinesMesh) {
@@ -36795,6 +36887,10 @@ var BABYLON;
                 }
             }
             this.notifyUpdate(kind);
+            if (this._vertexArrayObjects) {
+                this._disposeVertexArrayObjects();
+                this._vertexArrayObjects = {}; // Will trigger a rebuild of the VAO if supported
+            }
         };
         Geometry.prototype.updateVerticesDataDirectly = function (kind, data, offset) {
             var vertexBuffer = this.getVertexBuffer(kind);
@@ -36835,6 +36931,21 @@ var BABYLON;
                 }
             }
         };
+        Geometry.prototype._bind = function (effect, indexToBind) {
+            if (indexToBind === void 0) { indexToBind = undefined; }
+            if (indexToBind === undefined) {
+                indexToBind = this._indexBuffer;
+            }
+            if (indexToBind != this._indexBuffer || !this._vertexArrayObjects) {
+                this._engine.bindBuffers(this.getVertexBuffers(), indexToBind, effect);
+                return;
+            }
+            // Using VAO
+            if (!this._vertexArrayObjects[effect.key]) {
+                this._vertexArrayObjects[effect.key] = this._engine.recordVertexArrayObject(this.getVertexBuffers(), indexToBind, effect);
+            }
+            this._engine.bindVertexArrayObject(this._vertexArrayObjects[effect.key], indexToBind);
+        };
         Geometry.prototype.getTotalVertices = function () {
             if (!this.isReady()) {
                 return 0;
@@ -36948,12 +37059,6 @@ var BABYLON;
             if (index === -1) {
                 return;
             }
-            for (var kind in this._vertexBuffers) {
-                this._vertexBuffers[kind].dispose();
-            }
-            if (this._indexBuffer && this._engine._releaseBuffer(this._indexBuffer)) {
-                this._indexBuffer = null;
-            }
             meshes.splice(index, 1);
             mesh._geometry = null;
             if (meshes.length === 0 && shouldDispose) {
@@ -37084,6 +37189,14 @@ var BABYLON;
         Geometry.prototype.isDisposed = function () {
             return this._isDisposed;
         };
+        Geometry.prototype._disposeVertexArrayObjects = function () {
+            if (this._vertexArrayObjects) {
+                for (var kind in this._vertexArrayObjects) {
+                    this._engine.releaseVertexArrayObject(this._vertexArrayObjects[kind]);
+                }
+                this._vertexArrayObjects = {};
+            }
+        };
         Geometry.prototype.dispose = function () {
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
@@ -37092,6 +37205,7 @@ var BABYLON;
                 this.releaseForMesh(meshes[index]);
             }
             this._meshes = [];
+            this._disposeVertexArrayObjects();
             for (var kind in this._vertexBuffers) {
                 this._vertexBuffers[kind].dispose();
             }
@@ -52610,7 +52724,7 @@ var BABYLON;
     })(Internals = BABYLON.Internals || (BABYLON.Internals = {}));
 })(BABYLON || (BABYLON = {}));
 
-//# sourceMappingURL=babylon.tools.pmremgenerator.js.map
+//# sourceMappingURL=babylon.tools.pmremGenerator.js.map
 
 
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 32 - 32
dist/preview release/babylon.noworker.js


+ 8 - 0
src/Materials/babylon.effect.ts

@@ -63,7 +63,9 @@
         public onCompiled: (effect: Effect) => void;
         public onError: (effect: Effect, errors: string) => void;
         public onBind: (effect: Effect) => void;
+        public uniqueId = 0;
 
+        private static _uniqueIdSeed = 0;
         private _engine: Engine;
         private _uniformsNames: string[];
         private _samplers: string[];
@@ -91,6 +93,8 @@
 
             this._indexParameters = indexParameters;
 
+            this.uniqueId = Effect._uniqueIdSeed++;
+
             var vertexSource;
             var fragmentSource;
 
@@ -129,6 +133,10 @@
             });
         }
 
+        public get key(): string {
+            return this._key;
+        }
+
         // Properties
         public isReady(): boolean {
             return this._isReady;

+ 39 - 0
src/Mesh/babylon.geometry.ts

@@ -21,6 +21,7 @@
         public _boundingInfo: BoundingInfo;
         public _delayLoadingFunction: (any: any, geometry: Geometry) => void;
         public _softwareSkinningRenderId: number;
+        private _vertexArrayObjects: { [key: string]: WebGLVertexArrayObject; };
 
         /**
          *  The Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y 
@@ -58,6 +59,10 @@
                 this._indices = [];
             }
 
+            if (this._engine.getCaps().vertexArrayObject) {
+                this._vertexArrayObjects = {};
+            }
+
             // applyToMesh
             if (mesh) {
                 if (mesh instanceof LinesMesh) {
@@ -136,6 +141,11 @@
             }
 
             this.notifyUpdate(kind);
+
+            if (this._vertexArrayObjects) {
+                this._disposeVertexArrayObjects();
+                this._vertexArrayObjects = {}; // Will trigger a rebuild of the VAO if supported
+            }
         }
 
         public updateVerticesDataDirectly(kind: string, data: Float32Array, offset: number): void {
@@ -191,6 +201,24 @@
             }
         }
 
+        public _bind(effect: Effect, indexToBind: WebGLBuffer = undefined): void {  
+            if (indexToBind === undefined) {
+                indexToBind = this._indexBuffer;
+            }
+
+            if (indexToBind != this._indexBuffer || !this._vertexArrayObjects) {
+                this._engine.bindBuffers(this.getVertexBuffers(), indexToBind, effect);
+                return;
+            }
+
+            // Using VAO
+            if (!this._vertexArrayObjects[effect.key]) {
+                this._vertexArrayObjects[effect.key] = this._engine.recordVertexArrayObject(this.getVertexBuffers(), indexToBind, effect);
+            }
+
+            this._engine.bindVertexArrayObject(this._vertexArrayObjects[effect.key], indexToBind);
+        }
+
         public getTotalVertices(): number {
             if (!this.isReady()) {
                 return 0;
@@ -481,6 +509,15 @@
             return this._isDisposed;
         }
 
+        private _disposeVertexArrayObjects(): void {
+            if (this._vertexArrayObjects) {
+                for (var kind in this._vertexArrayObjects) {
+                    this._engine.releaseVertexArrayObject(this._vertexArrayObjects[kind]);
+                }
+                this._vertexArrayObjects = {};
+            }
+        }
+
         public dispose(): void {
             var meshes = this._meshes;
             var numOfMeshes = meshes.length;
@@ -490,6 +527,8 @@
             }
             this._meshes = [];
 
+            this._disposeVertexArrayObjects();
+
             for (var kind in this._vertexBuffers) {
                 this._vertexBuffers[kind].dispose();
             }

+ 3 - 2
src/Mesh/babylon.mesh.ts

@@ -825,7 +825,7 @@
             }
 
             // VBOs
-            engine.bindBuffers(this._geometry.getVertexBuffers(), indexToBind, effect);
+            this._geometry._bind(effect, indexToBind);
         }
 
         public _draw(subMesh: SubMesh, fillMode: number, instancesCount?: number): void {
@@ -976,7 +976,8 @@
             } else {
                 instancesBuffer.updateDirectly(this._instancesData, 0, instancesCount);
             }
-            engine.bindBuffers(this.geometry.getVertexBuffers(), this.geometry.getIndexBuffer(), effect);
+
+            this.geometry._bind(effect);
 
             this._draw(subMesh, fillMode, instancesCount);
 

+ 61 - 28
src/babylon.engine.ts

@@ -497,6 +497,9 @@
 
         private _externalData: StringDictionary<Object>;
         private _bindedRenderFunction: any;
+
+        private _vaoRecordInProgress = false;
+        private _mustWipeVertexAttributes = false;
         
         // Hardware supported Compressed Textures
         private _texturesSupported = new Array<string>();
@@ -534,10 +537,10 @@
             // GL
             if (!options.disableWebGL2Support) {
                 try {
-                this._gl = <WebGLRenderingContext>(canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
-                if (this._gl) {
-                    this._webGLVersion = 2.0;
-                }
+                    this._gl = <WebGLRenderingContext>(canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
+                    if (this._gl) {
+                        this._webGLVersion = 2.0;
+                    }
                 } catch (e) {
                 // Do nothing
                 }  
@@ -1253,7 +1256,7 @@
         private _resetVertexBufferBinding(): void {
             this.bindArrayBuffer(null);
             this._cachedVertexBuffers = null;
-            this._cachedVertexArrayObject = null;
+            this._unBindVertexArrayObject();
         }
 
         public createVertexBuffer(vertices: number[] | Float32Array): WebGLBuffer {
@@ -1352,10 +1355,10 @@
         }
 
         private bindBuffer(buffer: WebGLBuffer, target: number): void {
-            if (this._currentBoundBuffer[target] !== buffer) {
+            if (this._vaoRecordInProgress || this._currentBoundBuffer[target] !== buffer) {
                 this._gl.bindBuffer(target, buffer);
                 this._currentBoundBuffer[target] = buffer;
-            }
+           }
         }
 
         public updateArrayBuffer(data: Float32Array): void {
@@ -1378,7 +1381,7 @@
                 if (pointer.offset !== offset) { pointer.offset = offset; changed = true; }
             }
 
-            if (changed) {
+            if (changed || this._vaoRecordInProgress) {
                 this.bindArrayBuffer(buffer);
                 this._gl.vertexAttribPointer(indx, size, type, normalized, stride, offset);
             }
@@ -1389,12 +1392,18 @@
                 this._cachedIndexBuffer = indexBuffer;
                 this.bindIndexBuffer(indexBuffer);
                 this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
+
+                this._unBindVertexArrayObject();
             }
         }
 
-        private _bindVertexBuffersAttributes(vertexBuffers: { [key: string]: VertexBuffer; }, effect: Effect, storeInstanceLocationsAndBuffers = false) {
+        private _bindVertexBuffersAttributes(vertexBuffers: { [key: string]: VertexBuffer; }, effect: Effect) {
             var attributes = effect.getAttributesNames();
 
+            if (!this._vaoRecordInProgress) {
+                this._unBindVertexArrayObject();
+            }
+
             this.unbindAllAttributes();
 
             for (var index = 0; index < attributes.length; index++) {
@@ -1408,14 +1417,16 @@
                     }
 
                     this._gl.enableVertexAttribArray(order);
-                    this._vertexAttribArraysEnabled[order] = true;
+                    if (!this._vaoRecordInProgress) {
+                        this._vertexAttribArraysEnabled[order] = true;
+                    }
 
                     var buffer = vertexBuffer.getBuffer();
                     this.vertexAttribPointer(buffer, order, vertexBuffer.getSize(), this._gl.FLOAT, false, vertexBuffer.getStrideSize() * 4, vertexBuffer.getOffset() * 4);
 
                     if (vertexBuffer.getIsInstanced()) {
                         this._gl.vertexAttribDivisor(order, 1);
-                        if (storeInstanceLocationsAndBuffers) {
+                        if (!this._vaoRecordInProgress) {
                             this._currentInstanceLocations.push(order);
                             this._currentInstanceBuffers.push(buffer);
                         }
@@ -1427,10 +1438,15 @@
         public recordVertexArrayObject(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: WebGLBuffer, effect: Effect): WebGLVertexArrayObject {
             var vao = this._gl.createVertexArray();
 
+            this._vaoRecordInProgress = true;
             this._gl.bindVertexArray(vao);
+            
+            this._mustWipeVertexAttributes = true;
+            this._bindVertexBuffersAttributes(vertexBuffers, effect);
 
-            this._bindVertexBuffersAttributes(vertexBuffers, effect, false);
+            this.bindIndexBuffer(indexBuffer);
 
+            this._vaoRecordInProgress = false;
             this._gl.bindVertexArray(null);
 
             return vao;
@@ -1441,9 +1457,12 @@
                 this._cachedVertexArrayObject = vertexArrayObject;
 
                 this._gl.bindVertexArray(vertexArrayObject);
-            }
+                this._cachedVertexBuffers = null;
+                this._cachedIndexBuffer = null;
 
-            this._bindIndexBufferWithCache(indexBuffer);
+                this._uintIndicesCurrentlySet = indexBuffer != null && indexBuffer.is32Bits; 
+                this._mustWipeVertexAttributes = true;
+            }
         }
 
         public bindBuffersDirectly(vertexBuffer: WebGLBuffer, indexBuffer: WebGLBuffer, vertexDeclaration: number[], vertexStrideSize: number, effect: Effect): void {
@@ -1476,12 +1495,21 @@
             this._bindIndexBufferWithCache(indexBuffer);
         }
 
+        private _unBindVertexArrayObject(): void {
+            if (!this._cachedVertexArrayObject) {
+                return;
+            }
+
+            this._cachedVertexArrayObject = null;
+            this._gl.bindVertexArray(null);
+        }
+
         public bindBuffers(vertexBuffers: { [key: string]: VertexBuffer; }, indexBuffer: WebGLBuffer, effect: Effect): void {
             if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {
                 this._cachedVertexBuffers = vertexBuffers;
                 this._cachedEffectForVertexBuffers = effect;
-
-                this._bindVertexBuffersAttributes(vertexBuffers, effect, true);
+                
+                this._bindVertexBuffersAttributes(vertexBuffers, effect);
             }
 
             this._bindIndexBufferWithCache(indexBuffer);
@@ -1502,6 +1530,10 @@
             this._currentInstanceLocations.length = 0;
         }
 
+        public releaseVertexArrayObject(vao: WebGLVertexArrayObject) {
+            this._gl.deleteVertexArray(vao);
+        }
+
         public _releaseBuffer(buffer: WebGLBuffer): boolean {
             buffer.references--;
 
@@ -1710,14 +1742,6 @@
         }
 
         public enableEffect(effect: Effect): void {
-            //if (!effect || !effect.getAttributesCount() || this._currentEffect === effect) {
-
-            //    if (effect && effect.onBind) {
-            //        effect.onBind(effect);
-            //    }
-            //    return;
-            //}
-
             // Use program
             this.setProgram(effect.getProgram());
 
@@ -1994,6 +2018,7 @@
             this._cachedVertexBuffers = null;
             this._cachedIndexBuffer = null;
             this._cachedEffectForVertexBuffers = null;
+            this._unBindVertexArrayObject();
         }
 
         public setSamplingMode(texture: WebGLTexture, samplingMode: number): void {
@@ -3111,15 +3136,23 @@
         }
 
         public unbindAllAttributes() {
+            if (this._mustWipeVertexAttributes) {
+                this._mustWipeVertexAttributes = false;
+
+                for (var i = 0; i < this._caps.maxVertexAttribs; i++) {
+                    this._gl.disableVertexAttribArray(i);
+                    this._vertexAttribArraysEnabled[i] = false;
+                }
+                return;
+            }
+
             for (var i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {
                 if (i >= this._caps.maxVertexAttribs || !this._vertexAttribArraysEnabled[i]) {
                     continue;
                 }
 
-                if (this._vertexAttribArraysEnabled[i]) {
-                    this._gl.disableVertexAttribArray(i);
-                    this._vertexAttribArraysEnabled[i] = false;
-                }
+                this._gl.disableVertexAttribArray(i);
+                this._vertexAttribArraysEnabled[i] = false;
             }
         }