/// <summary> /// Create an instance of MTSpriteBatchItem if there is none available in the free item queue. Otherwise, /// a previously allocated MTSpriteBatchItem is reused. /// </summary> /// <returns></returns> public MTSpriteBatchItem CreateBatchItem() { MTSpriteBatchItem mtSpriteBatchItem = this._freeBatchItemQueue.Count <= 0 ? new MTSpriteBatchItem() : this._freeBatchItemQueue.Dequeue(); this._batchItemList.Add(mtSpriteBatchItem); return(mtSpriteBatchItem); }
public MTSpriteBatchItem StealLastBatchItem() { MTSpriteBatchItem batchItem = this._batchItemList[this._batchItemList.Count - 1]; batchItem.inPool = false; return(batchItem); }
public void DrawExistingBatchItem(MTSpriteBatchItem item) { ++DuckGame.Graphics.currentDrawIndex; this._batcher.SqueezeInItem(item); if (Recorder.currentRecording != null) { Recorder.currentRecording.LogDraw(item.MetaData.texture.textureIndex, new Vec2(item.vertexTL.Position.X, item.vertexTL.Position.Y), new Vec2(item.vertexBR.Position.X, item.vertexBR.Position.Y), item.MetaData.rotation, item.MetaData.color, (short)item.MetaData.tempRect.x, (short)item.MetaData.tempRect.y, (short)((double)item.MetaData.tempRect.width * ((item.MetaData.effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None ? -1.0 : 1.0)), (short)((double)item.MetaData.tempRect.height * ((item.MetaData.effect & SpriteEffects.FlipVertically) != SpriteEffects.None ? -1.0 : 1.0)), item.MetaData.depth, item.MetaData.texture.currentObjectIndex, DuckGame.Graphics.currentObjectIndex, DuckGame.Graphics.currentDrawIndex); } if (Recorder.globalRecording == null) { return; } Recorder.globalRecording.LogDraw(item.MetaData.texture.textureIndex, new Vec2(item.vertexTL.Position.X, item.vertexTL.Position.Y), new Vec2(item.vertexBR.Position.X, item.vertexBR.Position.Y), item.MetaData.rotation, item.MetaData.color, (short)item.MetaData.tempRect.x, (short)item.MetaData.tempRect.y, (short)((double)item.MetaData.tempRect.width * ((item.MetaData.effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None ? -1.0 : 1.0)), (short)((double)item.MetaData.tempRect.height * ((item.MetaData.effect & SpriteEffects.FlipVertically) != SpriteEffects.None ? -1.0 : 1.0)), item.MetaData.depth, item.MetaData.texture.currentObjectIndex, DuckGame.Graphics.currentObjectIndex, DuckGame.Graphics.currentDrawIndex); }
public void DrawRecorderItem(ref RecorderFrameItem frame) { MTSpriteBatchItem batchItem = this._batcher.CreateBatchItem(); batchItem.Depth = frame.depth; if (frame.texture == (short)-1) { batchItem.Texture = DuckGame.Graphics.blankWhiteSquare.nativeObject as Texture2D; } else { Tex2D tex2DfromIndex = Content.GetTex2DFromIndex(frame.texture); if (tex2DfromIndex == null) { return; } batchItem.Texture = tex2DfromIndex.nativeObject as Texture2D; } if (batchItem.Texture == null) { return; } float num1 = (float)Math.Abs(frame.texW); float num2 = (float)Math.Abs(frame.texH); this._texCoordTL.x = (float)((double)frame.texX / (double)batchItem.Texture.Width + 9.99999974737875E-06); this._texCoordTL.y = (float)((double)frame.texY / (double)batchItem.Texture.Height + 9.99999974737875E-06); this._texCoordBR.x = (float)(((double)frame.texX + (double)num1) / (double)batchItem.Texture.Width - 9.99999974737875E-06); this._texCoordBR.y = (float)(((double)frame.texY + (double)num2) / (double)batchItem.Texture.Height - 9.99999974737875E-06); if (frame.texH < (short)0) { float y = this._texCoordBR.y; this._texCoordBR.y = this._texCoordTL.y; this._texCoordTL.y = y; } if (frame.texW < (short)0) { float x = this._texCoordBR.x; this._texCoordBR.x = this._texCoordTL.x; this._texCoordTL.x = x; } Vec2 vec2 = frame.bottomRight.Rotate(-frame.rotation, frame.topLeft); batchItem.Set(frame.topLeft.x, frame.topLeft.y, 0.0f, 0.0f, vec2.x - frame.topLeft.x, vec2.y - frame.topLeft.y, (float)Math.Sin((double)frame.rotation), (float)Math.Cos((double)frame.rotation), frame.color, this._texCoordTL, this._texCoordBR); }
public void DrawQuad( Vec2 p1, Vec2 p2, Vec2 p3, Vec2 p4, Vec2 t1, Vec2 t2, Vec2 t3, Vec2 t4, float depth, Tex2D tex, Color c) { ++DuckGame.Graphics.currentDrawIndex; MTSpriteBatchItem batchItem = this._batcher.CreateBatchItem(); batchItem.Depth = depth; batchItem.Texture = tex.nativeObject as Texture2D; batchItem.Material = (Material)null; batchItem.Set(p1, p2, p3, p4, t1, t2, t3, t4, c); }
internal void DoDrawInternalTex2D( Tex2D texture, Vec4 destinationRectangle, Rectangle?sourceRectangle, Color color, float rotation, Vec2 origin, SpriteEffects effect, float depth, bool autoFlush, Material fx) { ++DuckGame.Graphics.currentDrawIndex; MTSpriteBatchItem batchItem = this._batcher.CreateBatchItem(); batchItem.Depth = depth; batchItem.Texture = texture.nativeObject as Texture2D; batchItem.Material = fx; if (sourceRectangle.HasValue) { this._tempRect = sourceRectangle.Value; } else { this._tempRect.x = 0.0f; this._tempRect.y = 0.0f; this._tempRect.width = (float)texture.width; this._tempRect.height = (float)texture.height; } this._texCoordTL.x = (float)((double)this._tempRect.x / (double)texture.width + 9.99999974737875E-06); this._texCoordTL.y = (float)((double)this._tempRect.y / (double)texture.height + 9.99999974737875E-06); this._texCoordBR.x = (float)(((double)this._tempRect.x + (double)this._tempRect.width) / (double)texture.width - 9.99999974737875E-06); this._texCoordBR.y = (float)(((double)this._tempRect.y + (double)this._tempRect.height) / (double)texture.height - 9.99999974737875E-06); if ((effect & SpriteEffects.FlipVertically) != SpriteEffects.None) { float y = this._texCoordBR.y; this._texCoordBR.y = this._texCoordTL.y; this._texCoordTL.y = y; } if ((effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None) { float x = this._texCoordBR.x; this._texCoordBR.x = this._texCoordTL.x; this._texCoordTL.x = x; } batchItem.Set(destinationRectangle.x, destinationRectangle.y, -origin.x, -origin.y, destinationRectangle.z, destinationRectangle.w, (float)Math.Sin((double)rotation), (float)Math.Cos((double)rotation), color, this._texCoordTL, this._texCoordBR); if (Recorder.currentRecording != null) { if (DuckGame.Graphics.recordMetadata) { batchItem.MetaData = new MTSpriteBatchItemMetaData(); batchItem.MetaData.texture = texture; batchItem.MetaData.rotation = rotation; batchItem.MetaData.color = color; batchItem.MetaData.tempRect = this._tempRect; batchItem.MetaData.effect = effect; batchItem.MetaData.depth = depth; } Recorder.currentRecording.LogDraw(texture.textureIndex, new Vec2(batchItem.vertexTL.Position.X, batchItem.vertexTL.Position.Y), new Vec2(batchItem.vertexBR.Position.X, batchItem.vertexBR.Position.Y), rotation, color, (short)this._tempRect.x, (short)this._tempRect.y, (short)((double)this._tempRect.width * ((effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None ? -1.0 : 1.0)), (short)((double)this._tempRect.height * ((effect & SpriteEffects.FlipVertically) != SpriteEffects.None ? -1.0 : 1.0)), depth, texture.currentObjectIndex, DuckGame.Graphics.currentObjectIndex, DuckGame.Graphics.currentDrawIndex); } if (Recorder.globalRecording != null) { Recorder.globalRecording.LogDraw(texture.textureIndex, new Vec2(batchItem.vertexTL.Position.X, batchItem.vertexTL.Position.Y), new Vec2(batchItem.vertexBR.Position.X, batchItem.vertexBR.Position.Y), rotation, color, (short)this._tempRect.x, (short)this._tempRect.y, (short)((double)this._tempRect.width * ((effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None ? -1.0 : 1.0)), (short)((double)this._tempRect.height * ((effect & SpriteEffects.FlipVertically) != SpriteEffects.None ? -1.0 : 1.0)), depth, texture.currentObjectIndex, DuckGame.Graphics.currentObjectIndex, DuckGame.Graphics.currentDrawIndex); } if (!autoFlush) { return; } this.FlushIfNeeded(); }
/// <summary> /// Sorts the batch items and then groups batch drawing into maximal allowed batch sets that do not /// overflow the 16 bit array indices for vertices. /// </summary> /// <param name="sortMode">The type of depth sorting desired for the rendering.</param> public void DrawBatch(SpriteSortMode sortMode) { if (this._batchItemList.Count == 0) { return; } switch (sortMode) { case SpriteSortMode.Texture: this._batchItemList.Sort(new Comparison <MTSpriteBatchItem>(MTSpriteBatcher.CompareTexture)); break; case SpriteSortMode.BackToFront: this._batchItemList.Sort(new Comparison <MTSpriteBatchItem>(MTSpriteBatcher.CompareReverseDepth)); break; case SpriteSortMode.FrontToBack: this._batchItemList.Sort(new Comparison <MTSpriteBatchItem>(MTSpriteBatcher.CompareDepth)); break; } int index1 = 0; int numBatchItems; for (int count = this._batchItemList.Count; count > 0; count -= numBatchItems) { int start = 0; int end = 0; Texture2D texture2D = (Texture2D)null; Material material = (Material)null; numBatchItems = count; if (numBatchItems > 5461) { numBatchItems = 5461; } this.EnsureArrayCapacity(numBatchItems); int num1 = 0; while (num1 < numBatchItems) { MTSpriteBatchItem batchItem = this._batchItemList[index1]; if (!object.ReferenceEquals((object)batchItem.Texture, (object)texture2D) || !object.ReferenceEquals((object)batchItem.Material, (object)material)) { this.FlushVertexArray(start, end); if (material != null && batchItem.Material == null) { this._batch.ReapplyEffect(); } material = batchItem.Material; texture2D = batchItem.Texture; start = end = 0; this._device.Textures[0] = (Texture)texture2D; material?.Apply(); } VertexPositionColorTexture[] vertexArray1 = this._vertexArray; int index2 = end; int num2 = index2 + 1; vertexArray1[index2] = batchItem.vertexTL; VertexPositionColorTexture[] vertexArray2 = this._vertexArray; int index3 = num2; int num3 = index3 + 1; vertexArray2[index3] = batchItem.vertexTR; VertexPositionColorTexture[] vertexArray3 = this._vertexArray; int index4 = num3; int num4 = index4 + 1; vertexArray3[index4] = batchItem.vertexBL; VertexPositionColorTexture[] vertexArray4 = this._vertexArray; int index5 = num4; end = index5 + 1; vertexArray4[index5] = batchItem.vertexBR; if (batchItem.inPool) { batchItem.Texture = (Texture2D)null; batchItem.Material = (Material)null; this._freeBatchItemQueue.Enqueue(batchItem); } ++num1; ++index1; } this.FlushVertexArray(start, end); } this._batchItemList.Clear(); }
/// <summary> /// Implements the opposite of CompareDepth, where b is compared against a. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>-1 if b is less than a, 0 if equal, and 1 if b is greater than a</returns> private static int CompareReverseDepth(MTSpriteBatchItem a, MTSpriteBatchItem b) => b.Depth.CompareTo(a.Depth);
/// <summary> /// Compares the Depth of a against b returning -1 if a is less than b, /// 0 if equal, and 1 if a is greater than b. The test uses float.CompareTo(float) /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>-1 if a is less than b, 0 if equal, and 1 if a is greater than b</returns> private static int CompareDepth(MTSpriteBatchItem a, MTSpriteBatchItem b) => a.Depth.CompareTo(b.Depth);
/// <summary> /// Reference comparison of the underlying Texture objects for each given MTSpriteBatchitem. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>0 if they are not reference equal, and 1 if so.</returns> private static int CompareTexture(MTSpriteBatchItem a, MTSpriteBatchItem b) => !object.ReferenceEquals((object)a.Texture, (object)b.Texture) ? 1 : 0;
public void SqueezeInItem(MTSpriteBatchItem item) => this._batchItemList.Add(item);