瀏覽代碼

Fixing big bug with instances

David Catuhe 11 年之前
父節點
當前提交
af1115eb93

+ 20 - 3
Babylon/Mesh/babylon.mesh.js

@@ -26,6 +26,7 @@ var BABYLON;
             this._visibleInstances = {};
             this._renderIdForInstances = -1;
             this._batchCache = new _InstancesBatch();
+            this._instancesBufferSize = 32 * 16 * 4;
         }
         Mesh.prototype.getTotalVertices = function () {
             if (!this._geometry) {
@@ -295,9 +296,19 @@ var BABYLON;
         };
 
         Mesh.prototype._renderWithInstances = function (subMesh, wireFrame, batch, effect, engine) {
-            if (!this._worldMatricesInstancesBuffer) {
-                var matricesCount = this.instances.length + 1;
-                this._worldMatricesInstancesBuffer = engine.createInstancesBuffer(matricesCount * 16 * 4);
+            var matricesCount = this.instances.length + 1;
+            var bufferSize = matricesCount * 16 * 4;
+
+            while (this._instancesBufferSize < bufferSize) {
+                this._instancesBufferSize *= 2;
+            }
+
+            if (!this._worldMatricesInstancesBuffer || this._worldMatricesInstancesBuffer.capacity < this._instancesBufferSize) {
+                if (this._worldMatricesInstancesBuffer) {
+                    engine.deleteInstancesBuffer(this._worldMatricesInstancesBuffer);
+                }
+
+                this._worldMatricesInstancesBuffer = engine.createInstancesBuffer(this._instancesBufferSize);
                 this._worldMatricesInstancesArray = new Float32Array(16 * matricesCount);
             }
 
@@ -602,6 +613,12 @@ var BABYLON;
                 this._geometry.releaseForMesh(this);
             }
 
+            // Instances
+            if (this._worldMatricesInstancesBuffer) {
+                this.getEngine().deleteInstancesBuffer(this._worldMatricesInstancesBuffer);
+                this._worldMatricesInstancesBuffer = null;
+            }
+
             while (this.instances.length) {
                 this.instances[0].dispose();
             }

+ 19 - 3
Babylon/Mesh/babylon.mesh.ts

@@ -21,6 +21,7 @@
         private _batchCache = new _InstancesBatch();
         private _worldMatricesInstancesBuffer: WebGLBuffer;
         private _worldMatricesInstancesArray: Float32Array;
+        private _instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
 
         constructor(name: string, scene: Scene) {
             super(name, scene);
@@ -299,9 +300,19 @@
         }
 
         public _renderWithInstances(subMesh: SubMesh, wireFrame: boolean, batch: _InstancesBatch, effect: Effect, engine: Engine): void {
-            if (!this._worldMatricesInstancesBuffer) {
-                var matricesCount = this.instances.length + 1;
-                this._worldMatricesInstancesBuffer = engine.createInstancesBuffer(matricesCount * 16 * 4);
+            var matricesCount = this.instances.length + 1;
+            var bufferSize = matricesCount * 16 * 4;
+
+            while (this._instancesBufferSize < bufferSize) {
+                this._instancesBufferSize *= 2;
+            }
+
+            if (!this._worldMatricesInstancesBuffer || this._worldMatricesInstancesBuffer.capacity < this._instancesBufferSize) {
+                if (this._worldMatricesInstancesBuffer) {
+                    engine.deleteInstancesBuffer(this._worldMatricesInstancesBuffer);
+                }
+
+                this._worldMatricesInstancesBuffer = engine.createInstancesBuffer(this._instancesBufferSize);
                 this._worldMatricesInstancesArray = new Float32Array(16 * matricesCount);
             }
 
@@ -609,6 +620,11 @@
             }
 
             // Instances
+            if (this._worldMatricesInstancesBuffer) {
+                this.getEngine().deleteInstancesBuffer(this._worldMatricesInstancesBuffer);
+                this._worldMatricesInstancesBuffer = null;
+            }
+
             while (this.instances.length) {
                 this.instances[0].dispose();
             }

+ 7 - 0
Babylon/babylon.engine.js

@@ -562,11 +562,18 @@
 
         Engine.prototype.createInstancesBuffer = function (capacity) {
             var buffer = this._gl.createBuffer();
+
+            buffer.capacity = capacity;
+
             this._gl.bindBuffer(this._gl.ARRAY_BUFFER, buffer);
             this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
             return buffer;
         };
 
+        Engine.prototype.deleteInstancesBuffer = function (buffer) {
+            this._gl.deleteBuffer(buffer);
+        };
+
         Engine.prototype.updateAndBindInstancesBuffer = function (instancesBuffer, data, offsetLocations) {
             this._gl.bindBuffer(this._gl.ARRAY_BUFFER, instancesBuffer);
             this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);

+ 7 - 0
Babylon/babylon.engine.ts

@@ -593,11 +593,18 @@
 
         public createInstancesBuffer(capacity: number): WebGLBuffer {
             var buffer = this._gl.createBuffer();
+
+            buffer.capacity = capacity;
+
             this._gl.bindBuffer(this._gl.ARRAY_BUFFER, buffer);
             this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
             return buffer;
         }
 
+        public deleteInstancesBuffer(buffer: WebGLBuffer): void {
+            this._gl.deleteBuffer(buffer);
+        }
+
 
         public updateAndBindInstancesBuffer(instancesBuffer: WebGLBuffer, data: Float32Array, offsetLocations: number[]): void {
             this._gl.bindBuffer(this._gl.ARRAY_BUFFER, instancesBuffer);

+ 1 - 0
Babylon/babylon.mixins.ts

@@ -52,6 +52,7 @@ interface WebGLTexture {
 
 interface WebGLBuffer {
     references: number;
+    capacity: number;
 }
 
 interface MouseEvent {

File diff suppressed because it is too large
+ 7 - 7
babylon.1.12-beta.js