Pārlūkot izejas kodu

init uniformBuffer.ts

Benjamin Guignabert 8 gadi atpakaļ
vecāks
revīzija
c2528ad616

+ 1 - 0
Tools/Gulp/config.json

@@ -89,6 +89,7 @@
             "../../src/Materials/babylon.material.js",
             "../../src/Materials/babylon.standardMaterial.js",
             "../../src/Materials/babylon.multiMaterial.js",
+            "../../src/Materials/babylon.uniformBuffer.js",
             "../../src/Loading/babylon.sceneLoader.js",
             "../../src/Loading/Plugins/babylon.babylonFileLoader.js",
             "../../src/Sprites/babylon.spriteManager.js",

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 763 - 734
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 763 - 734
dist/preview release/babylon.module.d.ts


+ 172 - 0
src/Materials/babylon.uniformBuffer.ts

@@ -0,0 +1,172 @@
+module BABYLON {
+    export class UniformBuffer {
+        private _engine: Engine;
+        private _buffer: WebGLBuffer;
+        private _data: number[];
+        private _dynamic: boolean;
+        private _uniformNames: string[];
+        private _uniformLocations: number[];
+        private _uniformSizes: number[];
+        private _uniformLocationPointer: number;
+        private _needSync: boolean;
+
+        constructor(engine: Engine, data?: number[], dynamic?: boolean) {
+            this._engine = engine;
+
+            this._dynamic = dynamic;
+
+            this._data = data || [];
+
+            this._uniformNames = [];
+            this._uniformLocations = [];
+            this._uniformSizes = [];
+            this._uniformLocationPointer = 0;
+            this._needSync = false;
+        }
+
+        // Properties
+        public isDynamic(): boolean {
+            return this._dynamic;
+        }
+
+        public getData(): number[] {
+            return this._data;
+        }
+
+        public getBuffer(): WebGLBuffer {
+            return this._buffer;
+        }
+
+        // Methods
+        private _adaptSizeToLayout(size: number): number {
+            return Math.ceil(size / 4) * 4;
+        }
+
+        public addUniform(name: string, size: number | number[]) {
+            // This function must be called in the order of the shader layout !
+
+            // size can be the size of the uniform, or data directly
+            var data;
+            if (size instanceof Array) {
+                data = size;
+                size = this._adaptSizeToLayout(data.length);
+            } else {
+                // In std140 layout, uniform size must be multiple of 4 floats
+                size = this._adaptSizeToLayout(<number>size);
+                data = [];
+
+                // Fill with zeros
+                for (var i = 0; i < size; i++) {
+                    data.push(0);
+                }
+            }
+
+            if (this._uniformNames.indexOf(name) !== -1) {
+                // Already existing uniform
+                return;
+            }
+
+            this._uniformNames.push(name);
+            this._uniformSizes.push(size);
+            this._uniformLocations.push(this._uniformLocationPointer);
+            this._uniformLocationPointer += size;
+
+            for (var i = 0; i < size; i++) {
+                this._data.push(data[i]);
+            }
+
+            this._needSync = true;
+        }
+
+        public addColor3(name: string, color: Color3) {
+            var temp = []
+            color.toArray(temp);
+            this.addUniform(name, temp);
+        }
+
+        public addColor4(name: string, color: Color3, alpha: number) {
+            var temp = []
+            color.toArray(temp);
+            temp.push(alpha);
+            this.addUniform(name, temp);
+        }
+
+        public addVector3(name: string, vector: Vector3) {
+            var temp = []
+            vector.toArray(temp);
+            this.addUniform(name, temp);
+        }
+
+        public create(): void {
+            if (this._buffer) {
+                return; // nothing to do
+            }
+
+            var data = this._data;
+
+            if (this._dynamic) {
+                this._buffer = this._engine.createDynamicUniformBuffer(data);
+            } else {
+                this._buffer = this._engine.createUniformBuffer(data);
+            }
+
+            this._needSync = false;
+        }
+
+        public update(): void {
+            if (!this._buffer) {
+                this.create();
+                return;
+            }
+
+            this._engine.updateUniformBuffer(this._buffer, this._data);
+
+            this._needSync = false;
+        }
+
+        public updateUniform(uniformName: string, data: number[]) {
+            var index = this._uniformNames.indexOf(uniformName);
+
+            if (index === -1) {
+                return;
+            }
+
+            if (!this._buffer) {
+                this.create();
+            }
+
+            var location = this._uniformLocations[index];
+            var size = this._adaptSizeToLayout(data.length);
+
+            if (size != this._uniformSizes[index]) {
+                Tools.Error("Wrong uniform size.");
+                return;
+            }
+
+            var changed = false;
+            for (var i = 0; i < data.length; i++) {
+                if (this._data[location + i] !== data[i]) {
+                    changed = true;
+                    this._data[location + i] = data[i];
+                }
+            }
+
+            this._needSync = this._needSync || changed;
+        }
+
+        public updateUniformDirectly(uniformName: string, data: number[]) {
+            this.updateUniform(uniformName, data);
+
+            this.update();
+        }
+
+        public dispose(): void {
+            if (!this._buffer) {
+                return;
+            }
+            if (this._engine._releaseBuffer(this._buffer)) {
+                this._buffer = null;
+            }
+        }
+    }
+} 

+ 48 - 8
src/babylon.engine.ts

@@ -1300,17 +1300,63 @@
         }
 
         // UBOs
-        public createUniformBuffer(size: number): WebGLBuffer {
+        public createUniformBuffer(elements: number[] | Float32Array): WebGLBuffer {
             var ubo = this._gl.createBuffer();
             this.bindUniformBuffer(ubo);
 
-            this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(size), this._gl.STATIC_DRAW);
+            if (elements instanceof Float32Array) {
+                this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.STATIC_DRAW);
+            } else {
+                this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(<number[]>elements), this._gl.STATIC_DRAW);
+            }
+
+            this.bindUniformBuffer(null);
+
+            ubo.references = 1;
+            return ubo;
+        }
+
+        public createDynamicUniformBuffer(elements: number[] | Float32Array): WebGLBuffer {
+            var ubo = this._gl.createBuffer();
+            this.bindUniformBuffer(ubo);
+
+            if (elements instanceof Float32Array) {
+                this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.DYNAMIC_DRAW);
+            } else {
+                this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(<number[]>elements), this._gl.DYNAMIC_DRAW);
+            }
 
             this.bindUniformBuffer(null);
+
             ubo.references = 1;
             return ubo;
         }
 
+        public updateUniformBuffer(uniformBuffer: WebGLBuffer, elements: number[] | Float32Array, offset?: number, count?: number): void {
+            this.bindUniformBuffer(uniformBuffer);
+
+            if (offset === undefined) {
+                offset = 0;
+            }
+
+            if (count === undefined) {
+                if (elements instanceof Float32Array) {
+                    this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, <Float32Array>elements);
+                } else {
+                    this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, new Float32Array(<number[]>elements));
+                }
+            } else {
+                if (elements instanceof Float32Array) {
+                    this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, <Float32Array>elements.subarray(offset, offset + count));
+                } else {
+                    this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, new Float32Array(<number[]>elements).subarray(offset, offset + count));
+                }
+            }
+
+            this.bindUniformBuffer(null);
+        }
+
+
         // VBOs
         private _resetVertexBufferBinding(): void {
             this.bindArrayBuffer(null);
@@ -1844,12 +1890,6 @@
             }
         }
 
-        public updateUniformBuffer(ubo: WebGLBuffer, array: Float32Array): void {
-            this.bindUniformBuffer(ubo);
-            this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, array);
-            this.bindUniformBuffer(null);
-        }
-
         public setIntArray(uniform: WebGLUniformLocation, array: Int32Array): void {
             if (!uniform)
                 return;