David `Deltakosh` Catuhe 5 سال پیش
والد
کامیت
a377e34b22
2فایلهای تغییر یافته به همراه78 افزوده شده و 33 حذف شده
  1. 3 2
      src/Shaders/sprites.vertex.fx
  2. 75 31
      src/Sprites/spriteManager.ts

+ 3 - 2
src/Shaders/sprites.vertex.fx

@@ -1,6 +1,7 @@
 // Attributes
 attribute vec4 position;
-attribute vec4 options;
+attribute vec2 options;
+attribute vec2 offsets;
 attribute vec2 inverts;
 attribute vec4 cellInfo;
 attribute vec4 color;
@@ -21,7 +22,7 @@ void main(void) {
 	
 	float angle = position.w;
 	vec2 size = vec2(options.x, options.y);
-	vec2 offset = options.zw;
+	vec2 offset = offsets.xy;
 
 	cornerPos = vec2(offset.x - 0.5, offset.y  - 0.5) * size;
 

+ 75 - 31
src/Sprites/spriteManager.ts

@@ -128,6 +128,8 @@ export class SpriteManager implements ISpriteManager {
     private _packedAndReady: boolean = false;
 
     private _textureContent: Nullable<Uint8Array>;
+    
+    private _useInstancing = false;
 
     /**
     * An event triggered when the manager is disposed.
@@ -156,10 +158,13 @@ export class SpriteManager implements ISpriteManager {
     private _vertexData: Float32Array;
     private _buffer: Buffer;
     private _vertexBuffers: { [key: string]: VertexBuffer } = {};
+    private _spriteBuffer: Nullable<Buffer>;
     private _indexBuffer: DataBuffer;
     private _effectBase: Effect;
     private _effectFog: Effect;
 
+    private _vertexBufferSize: number;
+
     /**
      * Gets or sets the unique id of the sprite
      */
@@ -243,7 +248,7 @@ export class SpriteManager implements ISpriteManager {
         }
         this._capacity = capacity;
         this._fromPacked = fromPacked;
-
+        
         if (imgUrl) {
             this._spriteTexture = new Texture(imgUrl, scene, true, false, samplingMode);
             this._spriteTexture.wrapU = Texture.CLAMP_ADDRESSMODE;
@@ -261,49 +266,68 @@ export class SpriteManager implements ISpriteManager {
         }
 
         this._epsilon = epsilon;
-        this._scene = scene || Engine.LastCreatedScene;
+        this._scene = scene;
         this._scene.spriteManagers.push(this);
         this.uniqueId = this.scene.getUniqueId();
+        const engine = this._scene.getEngine();
+       // this._useInstancing = engine.getCaps().instancedArrays;
+
+        if (!this._useInstancing) {
+            var indices = [];
+            var index = 0;
+            for (var count = 0; count < capacity; count++) {
+                indices.push(index);
+                indices.push(index + 1);
+                indices.push(index + 2);
+                indices.push(index);
+                indices.push(index + 2);
+                indices.push(index + 3);
+                index += 4;
+            }
 
-        var indices = [];
-        var index = 0;
-        for (var count = 0; count < capacity; count++) {
-            indices.push(index);
-            indices.push(index + 1);
-            indices.push(index + 2);
-            indices.push(index);
-            indices.push(index + 2);
-            indices.push(index + 3);
-            index += 4;
+            this._indexBuffer = engine.createIndexBuffer(indices);
         }
 
-        this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
-
         // VBO
         // 18 floats per sprite (x, y, z, angle, sizeX, sizeY, offsetX, offsetY, invertU, invertV, cellLeft, cellTop, cellWidth, cellHeight, color r, color g, color b, color a)
-        this._vertexData = new Float32Array(capacity * 18 * 4);
-        this._buffer = new Buffer(scene.getEngine(), this._vertexData, true, 18);
+        this._vertexBufferSize = this._useInstancing ? 16 : 18;
+        this._vertexData = new Float32Array(capacity * this._vertexBufferSize * (this._useInstancing ? 1 : 4));
+        this._buffer = new Buffer(engine, this._vertexData, true, this._vertexBufferSize);
+
+        var positions = this._buffer.createVertexBuffer(VertexBuffer.PositionKind, 0, 4, this._vertexBufferSize, this._useInstancing);
+        var options = this._buffer.createVertexBuffer("options", 4, 2, this._vertexBufferSize, this._useInstancing);
+        
+        let offset = 6;
+        var offsets: VertexBuffer;
+        
+        if (this._useInstancing) {
+            var spriteData = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
+            this._spriteBuffer = new Buffer(engine, spriteData, false, 2);
+            offsets = this._spriteBuffer.createVertexBuffer("offsets", 0, 2);
+        } else {
+            offsets = this._buffer.createVertexBuffer("offsets", offset, 2, this._vertexBufferSize, this._useInstancing);
+            offset += 2;
+        }
 
-        var positions = this._buffer.createVertexBuffer(VertexBuffer.PositionKind, 0, 4);
-        var options = this._buffer.createVertexBuffer("options", 4, 4);
-        var inverts = this._buffer.createVertexBuffer("inverts", 8, 2);
-        var cellInfo = this._buffer.createVertexBuffer("cellInfo", 10, 4);
-        var colors = this._buffer.createVertexBuffer(VertexBuffer.ColorKind, 14, 4);
+        var inverts = this._buffer.createVertexBuffer("inverts", offset, 2, this._vertexBufferSize, this._useInstancing);
+        var cellInfo = this._buffer.createVertexBuffer("cellInfo", offset + 2, 4, this._vertexBufferSize, this._useInstancing);
+        var colors = this._buffer.createVertexBuffer(VertexBuffer.ColorKind, offset + 6, 4, this._vertexBufferSize, this._useInstancing);
 
         this._vertexBuffers[VertexBuffer.PositionKind] = positions;
         this._vertexBuffers["options"] = options;
+        this._vertexBuffers["offsets"] = offsets;
         this._vertexBuffers["inverts"] = inverts;
         this._vertexBuffers["cellInfo"] = cellInfo;
         this._vertexBuffers[VertexBuffer.ColorKind] = colors;
 
         // Effects
         this._effectBase = this._scene.getEngine().createEffect("sprites",
-            [VertexBuffer.PositionKind, "options", "inverts", "cellInfo", VertexBuffer.ColorKind],
+            [VertexBuffer.PositionKind, "options", "offsets", "inverts", "cellInfo", VertexBuffer.ColorKind],
             ["view", "projection", "textureInfos", "alphaTest"],
             ["diffuseSampler"], "");
 
         this._effectFog = this._scene.getEngine().createEffect("sprites",
-            [VertexBuffer.PositionKind, "options", "inverts", "cellInfo", VertexBuffer.ColorKind],
+            [VertexBuffer.PositionKind, "options", "offsets", "inverts", "cellInfo", VertexBuffer.ColorKind],
             ["view", "projection", "textureInfos", "alphaTest", "vFogInfos", "vFogColor"],
             ["diffuseSampler"], "#define FOG");
 
@@ -391,7 +415,7 @@ export class SpriteManager implements ISpriteManager {
     }
 
     private _appendSpriteVertex(index: number, sprite: Sprite, offsetX: number, offsetY: number, baseSize: any): void {
-        var arrayOffset = index * 18;
+        var arrayOffset = index * this._vertexBufferSize;
 
         if (offsetX === 0) {
             offsetX = this._epsilon;
@@ -415,8 +439,13 @@ export class SpriteManager implements ISpriteManager {
         // Options
         this._vertexData[arrayOffset + 4] = sprite.width;
         this._vertexData[arrayOffset + 5] = sprite.height;
-        this._vertexData[arrayOffset + 6] = offsetX;
-        this._vertexData[arrayOffset + 7] = offsetY;
+
+        if (!this._useInstancing) {
+            this._vertexData[arrayOffset + 6] = offsetX;
+            this._vertexData[arrayOffset + 7] = offsetY;
+        } else {
+            arrayOffset -= 2;
+        }
 
         // Inverts according to Right Handed
         if (this._scene.useRightHandedSystem) {
@@ -680,9 +709,11 @@ export class SpriteManager implements ISpriteManager {
             sprite._animate(deltaTime);
 
             this._appendSpriteVertex(offset++, sprite, 0, 0, baseSize);
-            this._appendSpriteVertex(offset++, sprite, 1, 0, baseSize);
-            this._appendSpriteVertex(offset++, sprite, 1, 1, baseSize);
-            this._appendSpriteVertex(offset++, sprite, 0, 1, baseSize);
+            if (!this._useInstancing) {
+                this._appendSpriteVertex(offset++, sprite, 1, 0, baseSize);
+                this._appendSpriteVertex(offset++, sprite, 1, 1, baseSize);
+                this._appendSpriteVertex(offset++, sprite, 0, 1, baseSize);
+            }
         }
 
         if (noSprite) {
@@ -726,13 +757,21 @@ export class SpriteManager implements ISpriteManager {
         if (!this.disableDepthWrite) {
             effect.setBool("alphaTest", true);
             engine.setColorWrite(false);
-            engine.drawElementsType(Material.TriangleFillMode, 0, (offset / 4) * 6);
+            if (this._useInstancing) {
+                engine.drawArraysType(Constants.MATERIAL_TriangleFanDrawMode, 0, 4, (offset / 4));
+            } else {
+                engine.drawElementsType(Material.TriangleFillMode, 0, (offset / 4) * 6);
+            }
             engine.setColorWrite(true);
             effect.setBool("alphaTest", false);
         }
 
         engine.setAlphaMode(this._blendMode);
-        engine.drawElementsType(Material.TriangleFillMode, 0, (offset / 4) * 6);
+        if (this._useInstancing) {
+            engine.drawArraysType(Constants.MATERIAL_TriangleFanDrawMode, 0, 4, (offset / 4));
+        } else {
+            engine.drawElementsType(Material.TriangleFillMode, 0, (offset / 4) * 6);
+        }
         engine.setAlphaMode(Constants.ALPHA_DISABLE);
 
         // Restore Right Handed
@@ -750,6 +789,11 @@ export class SpriteManager implements ISpriteManager {
             (<any>this._buffer) = null;
         }
 
+        if (this._spriteBuffer) {
+            this._spriteBuffer.dispose();
+            (<any>this._spriteBuffer) = null;
+        }
+
         if (this._indexBuffer) {
             this._scene.getEngine()._releaseBuffer(this._indexBuffer);
             (<any>this._indexBuffer) = null;