public void Draw(Texture2D texture, Vector2 position, Rectangle?sourceRectangle, Color color) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0.0f; item.TextureID = (int)texture.ID; Rectangle rect; if (sourceRectangle.HasValue) { rect = sourceRectangle.Value; } else { rect = new Rectangle(0, 0, texture.Image.ImageWidth, texture.Image.ImageHeight); } Vector2 texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y); Vector2 texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height); item.Set(position.X, position.Y, rect.Width, rect.Height, color, texCoordTL, texCoordBR); }
public SpriteBatchItem CreateBatchItem() { SpriteBatchItem spriteBatchItem = this._freeBatchItemQueue.Count <= 0 ? new SpriteBatchItem() : this._freeBatchItemQueue.Dequeue(); this._batchItemList.Add(spriteBatchItem); return(spriteBatchItem); }
public void Draw(Texture2D texture, Rectangle rectangle, Color color) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0; item.TextureID = (int)texture.ID; Vector2 texCoordTL = texture.Image.GetTextureCoord(0, 0); Vector2 texCoordBR = texture.Image.GetTextureCoord(texture.Image.ImageWidth, texture.Image.ImageHeight); item.Set ( rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, color, texCoordTL, texCoordBR ); }
public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle?sourceRectangle, Color color) { if (texture == null) { throw new ArgumentException("texture"); } // texture 0 is the texture beeing draw graphicsDevice.Textures[0] = texture; SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0.0f; item.TextureID = (int)texture.ID; if (sourceRectangle.HasValue) { tempRect = sourceRectangle.Value; } else { tempRect.X = 0; tempRect.Y = 0; tempRect.Width = texture.Width; tempRect.Height = texture.Height; } if (texture.Image == null) { float texWidthRatio = 1.0f / (float)texture.Width; float texHeightRatio = 1.0f / (float)texture.Height; // We are initially flipped vertically so we need to flip the corners so that // the image is bottom side up to display correctly texCoordTL.X = tempRect.X * texWidthRatio; //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio; texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio; texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio; //texCoordBR.Y = tempRect.Y * texHeightRatio; texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio; } else { texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X); texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y); texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width); texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height); } item.Set(destinationRectangle.X, destinationRectangle.Y, destinationRectangle.Width, destinationRectangle.Height, color, texCoordTL, texCoordBR); }
public SpriteBatchItem CreateBatchItem() { SpriteBatchItem item; if ( _freeBatchItemQueue.Count > 0 ) item = _freeBatchItemQueue.Dequeue(); else item = new SpriteBatchItem(); _batchItemList.Add(item); return item; }
public void Draw ( Texture2D texture, Vector2 position, Color color ) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0; item.TextureID = (int)texture.ID; tempRect.X = 0; tempRect.Y = 0; tempRect.Width = texture.Width; tempRect.Height = texture.Height; if (texture.Image == null) { float texWidthRatio = 1.0f / (float)texture.Width; float texHeightRatio = 1.0f / (float)texture.Height; // We are initially flipped vertically so we need to flip the corners so that // the image is bottom side up to display correctly texCoordTL.X = tempRect.X * texWidthRatio; //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio; texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio; texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio; //texCoordBR.Y = tempRect.Y * texHeightRatio; texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio; } else { texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X); texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y); texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width); texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height); } item.Set ( position.X, position.Y, tempRect.Width, tempRect.Height, color, texCoordTL, texCoordBR ); }
public void Draw(Texture2D imgTexture, Texture2D locTexture, Vector2 position, Nullable <Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) {//GG EDIT THIS IS NEW if (locTexture == null || imgTexture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.TextureID = (int)imgTexture.ID; Rectangle rect; if (sourceRectangle.HasValue) { rect = sourceRectangle.Value; } else { rect = new Rectangle(0, 0, locTexture.Image.ImageWidth, locTexture.Image.ImageHeight); } Vector2 texCoordTL = locTexture.Image.GetTextureCoord(rect.X, rect.Y); Vector2 texCoordBR = locTexture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height); if ((effect & SpriteEffects.FlipVertically) != 0) { float temp = texCoordBR.Y; texCoordBR.Y = texCoordTL.Y; texCoordTL.Y = temp; } if ((effect & SpriteEffects.FlipHorizontally) != 0) { float temp = texCoordBR.X; texCoordBR.X = texCoordTL.X; texCoordTL.X = temp; } item.Set ( position.X, position.Y, -origin.X * scale.X, -origin.Y * scale.Y, rect.Width * scale.X, rect.Height * scale.Y, (float)Math.Sin(rotation), (float)Math.Cos(rotation), color, texCoordTL, texCoordBR ); }
public void Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle?sourceRectangle, Color color) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0.0f; item.TextureID = (int)texture.ID; Rectangle rect; if (sourceRectangle.HasValue) { rect = sourceRectangle.Value; } else { rect = new Rectangle(0, 0, texture.Width, texture.Height); } Vector2 texCoordTL; // = texture.Image.GetTextureCoord ( rect.X, rect.Y ); Vector2 texCoordBR; // = texture.Image.GetTextureCoord ( rect.X+rect.Width, rect.Y+rect.Height ); if (texture.Image == null) { float texWidthRatio = 1.0f / (float)texture.Width; float texHeightRatio = 1.0f / (float)texture.Height; // We are initially flipped vertically so we need to flip the corners so that // the image is bottom side up to display correctly texCoordTL = new Vector2(rect.X * texWidthRatio, (rect.Y + rect.Height) * texHeightRatio); texCoordBR = new Vector2((rect.X + rect.Width) * texWidthRatio, rect.Y * texHeightRatio); } else { texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y); texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height); } item.Set ( destinationRectangle.X, destinationRectangle.Y, destinationRectangle.Width, destinationRectangle.Height, color, texCoordTL, texCoordBR); }
private SpriteBatchItem CreateBatchItem(Color Tint, int texId, float Depth) { // allocate 4 vertices for this quad, and set the batch pointer to the right offset. var bi = new SpriteBatchItem() { Tint = Tint, TextureID = texId, Depth = Depth, VertexBase = _vertexArray.Count }; _vertexArray.AddN(4); return(bi); }
public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable <Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.TextureID = (int)texture.ID; Rectangle rect; if (sourceRectangle.HasValue) { rect = sourceRectangle.Value; } else { rect = new Rectangle(0, 0, texture.Image.ImageWidth, texture.Image.ImageHeight); } Vector2 texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y); Vector2 texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height); if ((effect & SpriteEffects.FlipVertically) != 0) { float temp = texCoordBR.Y; texCoordBR.Y = texCoordTL.Y; texCoordTL.Y = temp; } if ((effect & SpriteEffects.FlipHorizontally) != 0) { float temp = texCoordBR.X; texCoordBR.X = texCoordTL.X; texCoordTL.X = temp; } item.Set ( destinationRectangle.X, destinationRectangle.Y, -origin.X, -origin.Y, destinationRectangle.Width, destinationRectangle.Height, (float)Math.Sin(rotation), (float)Math.Cos(rotation), color, texCoordTL, texCoordBR); }
public SpriteBatcher(GraphicsDevice device) { _device = device; _batchItemList = new SpriteBatchItem[InitialBatchSize]; _batchItemCount = 0; for (int i = 0; i < InitialBatchSize; i++) { _batchItemList[i] = new SpriteBatchItem(); } EnsureArrayCapacity(InitialBatchSize); }
public SpriteBatchItem CreateBatchItem() { SpriteBatchItem item; if (_freeBatchItemQueue.Count > 0) { item = _freeBatchItemQueue.Dequeue(); } else { item = new SpriteBatchItem(); } _batchItemList.Add(item); return(item); }
public void DrawString(SpriteFont spriteFont, string text, Vector2 position, Color color) { if (spriteFont == null) { throw new ArgumentException("spriteFont"); } Vector2 p = position; foreach (char c in text) { if (c == '\n') { p.Y += spriteFont.LineSpacing; p.X = position.X; continue; } if (spriteFont.characterData.ContainsKey(c) == false) { continue; } GlyphData g = spriteFont.characterData[c]; SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = 0.0f; item.TextureID = (int)spriteFont._texture.ID; texCoordTL.X = spriteFont._texture.Image.GetTextureCoordX(g.Glyph.X); texCoordTL.Y = spriteFont._texture.Image.GetTextureCoordY(g.Glyph.Y); texCoordBR.X = spriteFont._texture.Image.GetTextureCoordX(g.Glyph.X + g.Glyph.Width); texCoordBR.Y = spriteFont._texture.Image.GetTextureCoordY(g.Glyph.Y + g.Glyph.Height); item.Set ( p.X, p.Y + g.Cropping.Y, g.Glyph.Width, g.Glyph.Height, color, texCoordTL, texCoordBR ); p.X += (g.Kerning.Y + g.Kerning.Z + spriteFont.Spacing); } }
/// <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> /// <param name="effect">The custom effect to apply to the drawn geometry</param> public void DrawBatch(SpriteSortMode sortMode, Effect effect) { // nothing to do if (_batchItemList.Count == 0) { return; } // sort the batch items switch (sortMode) { case SpriteSortMode.Texture: // TODO: this is a quick inline sorting algorithm because the monogame sorting is broken // Not sure if this is the fastest way to do it but it has proven to be adequate for now. Texture2D current_tex = null; for (int point = 0; point < _batchItemList.Count; point++) { current_tex = _batchItemList[point].Texture; for (int i = point + 1; i < _batchItemList.Count; i++) { if (ReferenceEquals(current_tex, _batchItemList[i].Texture)) { SpriteBatchItem temp = _batchItemList[point]; _batchItemList[point] = _batchItemList[i]; _batchItemList[i] = temp; point++; } } } //_batchItemList.Sort(CompareTexture); break; case SpriteSortMode.FrontToBack: _batchItemList.Sort(CompareDepth); break; case SpriteSortMode.BackToFront: _batchItemList.Sort(CompareReverseDepth); break; } DrawList(_batchItemList); _freeBatchItemPool.RestoreAll(); }
/// <summary> /// Reuse a previously allocated SpriteBatchItem from the item pool. /// if there is none available grow the pool and initialize new items. /// </summary> /// <returns></returns> public SpriteBatchItem CreateBatchItem() { if (_batchItemCount >= _batchItemList.Length) { var oldSize = _batchItemList.Length; var newSize = oldSize + oldSize / 2; // grow by x1.5 newSize = (newSize + 63) & (~63); // grow in chunks of 64. Array.Resize(ref _batchItemList, newSize); for (int i = oldSize; i < newSize; i++) { _batchItemList[i] = new SpriteBatchItem(); } EnsureArrayCapacity(Math.Min(newSize, MaxBatchSize)); } var item = _batchItemList[_batchItemCount++]; return(item); }
/// <summary> /// Writes a string that is preprocessed as a vertex list (including rotation, scaling, flipping, etc). The /// characterVertices array must contain at least numVertices instances (each 4 representing a single sprite, /// which will be copied to the SpriteBatch's internal buffer. /// Vertices are expected in the order [TopLeft, TopRight, BottomLeft, BottomRight], repeated. /// /// The specified color is applied to the vertices in this function, the Red channel on each vertex is used as /// an index to the specified font texture array. /// </summary> public void DrawStringUnity(Texture2D[] fontTextures, int numVertices, VertexPositionColorTexture[] characterVertices, Color color) { // prepare texture instances for (int i = 0; i < numVertices;) { SpriteBatchItem item = _batcher.CreateBatchItem(); // use the vertex color R channel as index for the texture array (avoids an extra parameter) item.Texture = fontTextures[characterVertices[i].Color.R]; item.Depth = 0; item.vertexTL = characterVertices[i++]; item.vertexTR = characterVertices[i++]; item.vertexBL = characterVertices[i++]; item.vertexBR = characterVertices[i++]; item.vertexTL.Color = color; item.vertexTR.Color = color; item.vertexBL.Color = color; item.vertexBR.Color = color; } }
internal void DrawInternal(Texture2D texture, Vector4 destinationRectangle, Rectangle?sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth) { SpriteBatchItem batchItem = this._batcher.CreateBatchItem(); batchItem.Depth = depth; batchItem.Texture = texture; if (sourceRectangle.HasValue) { this._tempRect = sourceRectangle.Value; } else { this._tempRect.X = 0; this._tempRect.Y = 0; this._tempRect.Width = texture.Width; this._tempRect.Height = texture.Height; } this._texCoordTL.X = (float)this._tempRect.X / (float)texture.Width; this._texCoordTL.Y = (float)this._tempRect.Y / (float)texture.Height; this._texCoordBR.X = (float)(this._tempRect.X + this._tempRect.Width) / (float)texture.Width; this._texCoordBR.Y = (float)(this._tempRect.Y + this._tempRect.Height) / (float)texture.Height; if ((effect & SpriteEffects.FlipVertically) != SpriteEffects.None) { float num = this._texCoordBR.Y; this._texCoordBR.Y = this._texCoordTL.Y; this._texCoordTL.Y = num; } if ((effect & SpriteEffects.FlipHorizontally) != SpriteEffects.None) { float num = this._texCoordBR.X; this._texCoordBR.X = this._texCoordTL.X; this._texCoordTL.X = num; } 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 (this._sortMode != SpriteSortMode.Immediate) { return; } this._batcher.DrawBatch(this._sortMode); }
public SpriteBatcher(GraphicsDevice device, int capacity = 0) { _device = device; if (capacity <= 0) { capacity = InitialBatchSize; } else { capacity = (capacity + 63) & (~63); // ensure chunks of 64. } _batchItemList = new SpriteBatchItem[capacity]; _batchItemCount = 0; for (int i = 0; i < capacity; i++) { _batchItemList[i] = new SpriteBatchItem(); } EnsureArrayCapacity(capacity); }
internal void DrawInternal( Texture2D texture, Vector4 destinationRectangle, Rectangle?sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth, bool autoFlush ) { SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.Texture = texture; if (sourceRectangle.HasValue) { _tempRect = sourceRectangle.Value; } else { _tempRect.X = 0; _tempRect.Y = 0; _tempRect.Width = texture.Width; _tempRect.Height = texture.Height; } _texCoordTL.X = _tempRect.X / (float)texture.Width; _texCoordTL.Y = _tempRect.Y / (float)texture.Height; _texCoordBR.X = (_tempRect.X + _tempRect.Width) / (float)texture.Width; _texCoordBR.Y = (_tempRect.Y + _tempRect.Height) / (float)texture.Height; if ((effect & SpriteEffects.FlipVertically) != 0) { float temp = _texCoordBR.Y; _texCoordBR.Y = _texCoordTL.Y; _texCoordTL.Y = temp; } if ((effect & SpriteEffects.FlipHorizontally) != 0) { float temp = _texCoordBR.X; _texCoordBR.X = _texCoordTL.X; _texCoordTL.X = temp; } item.Set( destinationRectangle.X, destinationRectangle.Y, -origin.X, -origin.Y, destinationRectangle.Z, destinationRectangle.W, (float)Math.Sin(rotation), (float)Math.Cos(rotation), color, _texCoordTL, _texCoordBR ); if (autoFlush) { FlushIfNeeded(); } }
int CompareTexture( SpriteBatchItem a, SpriteBatchItem b ) { return a.TextureID.CompareTo(b.TextureID); }
/// <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) { // nothing to do if (_batchItemList.Count == 0) { return; } // sort the batch items switch (sortMode) { case SpriteSortMode.Texture: _batchItemList.Sort(CompareTexture); break; case SpriteSortMode.FrontToBack: _batchItemList.Sort(CompareDepth); break; case SpriteSortMode.BackToFront: _batchItemList.Sort(CompareReverseDepth); break; } // Determine how many iterations through the drawing code we need to make int batchIndex = 0; int batchCount = _batchItemList.Count; // Iterate through the batches, doing short.MaxValue sets of vertices only. while (batchCount > 0) { // setup the vertexArray array int startIndex = 0; int index = 0; Texture2D tex = null; int numBatchesToProcess = batchCount; if (numBatchesToProcess > MaxBatchSize) { numBatchesToProcess = MaxBatchSize; } EnsureArrayCapacity(numBatchesToProcess); // Draw the batches for (int i = 0; i < numBatchesToProcess; i += 1, batchIndex += 1) { SpriteBatchItem item = _batchItemList[batchIndex]; // if the texture changed, we need to flush and bind the new texture bool shouldFlush = !ReferenceEquals(item.Texture, tex); if (shouldFlush) { FlushVertexArray(startIndex, index); tex = item.Texture; startIndex = index = 0; _device.Textures[0] = tex; } // store the SpriteBatchItem data in our vertexArray _vertexArray[index++] = item.vertexTL; _vertexArray[index++] = item.vertexTR; _vertexArray[index++] = item.vertexBL; _vertexArray[index++] = item.vertexBR; // Release the texture and return the item to the queue. item.Texture = null; _freeBatchItemQueue.Enqueue(item); } // flush the remaining vertexArray data FlushVertexArray(startIndex, index); // Update our batch count to continue the process of culling down // large batches batchCount -= numBatchesToProcess; } _batchItemList.Clear(); }
private void DrawList(List <SpriteBatchItem> list) { // Determine how many iterations through the drawing code we need to make int batchIndex = 0; int batchCount = list.Count; // Iterate through the batches, doing short.MaxValue sets of vertices only. while (batchCount > 0) { // setup the vertexArray array var startIndex = 0; var index = 0; Texture2D tex = null; int numBatchesToProcess = batchCount; if (numBatchesToProcess > MaxBatchSize) { numBatchesToProcess = MaxBatchSize; } EnsureArrayCapacity(numBatchesToProcess); // Draw the batches for (int i = 0; i < numBatchesToProcess; i++, batchIndex++) { SpriteBatchItem item = list[batchIndex]; // if the texture changed, we need to flush and bind the new texture var shouldFlush = !ReferenceEquals(item.Texture, tex); if (shouldFlush) { FlushVertexArray(startIndex, index); tex = item.Texture; startIndex = index = 0; _device.Textures[0] = tex; } // store the SpriteBatchItem data in our vertexArray _vertexArray[index++] = item.vertexTL; _vertexArray[index++] = item.vertexTR; _vertexArray[index++] = item.vertexBL; _vertexArray[index++] = item.vertexBR; /*logCount++; * if (logCount > 300) * { * logCount = 0; * Console.WriteLine("Item vertex TL(x:" + item.vertexTL.Position.X + " y: " + item.vertexTL.Position.Y + ") --- " + * "vertex TR(x:" + item.vertexTR.Position.X + " y: " + item.vertexTR.Position.Y + ") --- " + * "vertex BL(x:" + item.vertexBL.Position.X + " y: " + item.vertexBL.Position.Y + ") --- " + * "vertex BR(x:" + item.vertexBR.Position.X + " y: " + item.vertexBR.Position.Y + ")"); * }*/ // Release the texture ( return the item to the queue later) item.Texture = null; } // flush the remaining vertexArray data FlushVertexArray(startIndex, index); // Update our batch count to continue the process of culling down // large batches batchCount -= numBatchesToProcess; } list.Clear(); }
int CompareTexture(SpriteBatchItem a, SpriteBatchItem b) { return(a.TextureID.CompareTo(b.TextureID)); }
int CompareReverseDepth(SpriteBatchItem a, SpriteBatchItem b) { return(b.Depth.CompareTo(a.Depth)); }
public SpriteBatcher (GraphicsDevice device) { _device = device; _batchItemList = new SpriteBatchItem[InitialBatchSize]; _batchItemCount = 0; for (int i = 0; i < InitialBatchSize; i++) _batchItemList[i] = new SpriteBatchItem(); EnsureArrayCapacity(InitialBatchSize); }
public void Draw(Texture2D texture, Rectangle destinationRectangle, Nullable <Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth) { if (texture == null) { throw new ArgumentException("texture"); } // texture 0 is the texture beeing draw graphicsDevice.Textures[0] = texture; SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.TextureID = (int)texture.ID; if (sourceRectangle.HasValue) { tempRect = sourceRectangle.Value; } else { tempRect.X = 0; tempRect.Y = 0; tempRect.Width = texture.Width; tempRect.Height = texture.Height; } if (texture.Image == null) { float texWidthRatio = 1.0f / (float)texture.Width; float texHeightRatio = 1.0f / (float)texture.Height; // We are initially flipped vertically so we need to flip the corners so that // the image is bottom side up to display correctly texCoordTL.X = tempRect.X * texWidthRatio; //texCoordTL.Y = (tempRect.Y + tempRect.Height) * texHeightRatio; texCoordTL.Y = 1.0f - tempRect.Y * texHeightRatio; texCoordBR.X = (tempRect.X + tempRect.Width) * texWidthRatio; //texCoordBR.Y = tempRect.Y * texHeightRatio; texCoordBR.Y = 1.0f - (tempRect.Y + tempRect.Height) * texHeightRatio; } else { texCoordTL.X = texture.Image.GetTextureCoordX(tempRect.X); texCoordTL.Y = texture.Image.GetTextureCoordY(tempRect.Y); texCoordBR.X = texture.Image.GetTextureCoordX(tempRect.X + tempRect.Width); texCoordBR.Y = texture.Image.GetTextureCoordY(tempRect.Y + tempRect.Height); } if ((effect & SpriteEffects.FlipVertically) != 0) { float temp = texCoordBR.Y; texCoordBR.Y = texCoordTL.Y; texCoordTL.Y = temp; } if ((effect & SpriteEffects.FlipHorizontally) != 0) { float temp = texCoordBR.X; texCoordBR.X = texCoordTL.X; texCoordTL.X = temp; } item.Set(destinationRectangle.X, destinationRectangle.Y, -origin.X, -origin.Y, destinationRectangle.Width, destinationRectangle.Height, (float)Math.Sin(rotation), (float)Math.Cos(rotation), color, texCoordTL, texCoordBR); }
/// <summary> /// Comparison of the underlying Texture objects for each given SpriteBatchitem. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>0 if they are equal, -1 or 1 if not.</returns> static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b) { return(a.Texture.SortingKey.CompareTo(b.Texture.SortingKey)); }
/// <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> /// <param name="effect">The custom effect to apply to the drawn geometry</param> public unsafe void DrawBatch(SpriteSortMode sortMode, Effect effect) { // nothing to do if (_batchItemCount == 0) { return; } // sort the batch items switch (sortMode) { case SpriteSortMode.Texture: case SpriteSortMode.FrontToBack: case SpriteSortMode.BackToFront: Array.Sort(_batchItemList, 0, _batchItemCount); break; } // Determine how many iterations through the drawing code we need to make int batchIndex = 0; int batchCount = _batchItemCount; unchecked { _device._graphicsMetrics._spriteCount += (ulong)batchCount; } // Iterate through the batches, doing short.MaxValue sets of vertices only. while (batchCount > 0) { // setup the vertexArray array var startIndex = 0; var index = 0; Texture2D tex = null; int numBatchesToProcess = batchCount; if (numBatchesToProcess > MaxBatchSize) { numBatchesToProcess = MaxBatchSize; } // Avoid the array checking overhead by using pointer indexing! fixed(VertexPositionColorTexture *vertexArrayFixedPtr = _vertexArray) { var vertexArrayPtr = vertexArrayFixedPtr; // Draw the batches for (int i = 0; i < numBatchesToProcess; i++, batchIndex++, index += 4, vertexArrayPtr += 4) { SpriteBatchItem item = _batchItemList[batchIndex]; // if the texture changed, we need to flush and bind the new texture var shouldFlush = !ReferenceEquals(item.Texture, tex); if (shouldFlush) { FlushVertexArray(startIndex, index, effect, tex); tex = item.Texture; startIndex = index = 0; vertexArrayPtr = vertexArrayFixedPtr; _device.Textures[0] = tex; } // store the SpriteBatchItem data in our vertexArray *(vertexArrayPtr + 0) = item.vertexTL; *(vertexArrayPtr + 1) = item.vertexTR; *(vertexArrayPtr + 2) = item.vertexBL; *(vertexArrayPtr + 3) = item.vertexBR; // Release the texture. item.Texture = null; } } // flush the remaining vertexArray data FlushVertexArray(startIndex, index, effect, tex); // Update our batch count to continue the process of culling down // large batches batchCount -= numBatchesToProcess; } // return items to the pool. _batchItemCount = 0; }
int CompareTexture(SpriteBatchItem a, SpriteBatchItem b) { return(ReferenceEquals(a.Texture, b.Texture) ? 0 : 1); }
private static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b) { return(!object.ReferenceEquals((object)a.Texture, (object)b.Texture) ? 1 : 0); }
int CompareTexture ( SpriteBatchItem a, SpriteBatchItem b ) { return ReferenceEquals( a.Texture, b.Texture ) ? 0 : 1; }
private static int CompareDepth(SpriteBatchItem a, SpriteBatchItem b) { return(a.Depth.CompareTo(b.Depth)); }
/// <summary> /// Comparison of the underlying Texture objects for each given SpriteBatchitem. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>0 if they are equal, -1 or 1 if not.</returns> static int CompareTexture ( SpriteBatchItem a, SpriteBatchItem b ) { return a.Texture.SortingKey.CompareTo(b.Texture.SortingKey); }
int CompareDepth( SpriteBatchItem a, SpriteBatchItem b ) { return a.Depth.CompareTo(b.Depth); }
private SpriteBatchItem CreateBatchItem(Color Tint, int texId, float Depth) { // allocate 4 vertices for this quad, and set the batch pointer to the right offset. var bi = new SpriteBatchItem() { Tint = Tint, TextureID = texId, Depth = Depth, VertexBase = _vertexArray.Count }; _vertexArray.AddN(4); return bi; }
int CompareReverseDepth( SpriteBatchItem a, SpriteBatchItem b ) { return b.Depth.CompareTo(a.Depth); }
public void DrawString ( SpriteFont spriteFont, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float depth ) { if (spriteFont == null) { throw new ArgumentException("spriteFont"); } Vector2 p = new Vector2(-origin.X, -origin.Y); float sin = (float)Math.Sin(rotation); float cos = (float)Math.Cos(rotation); foreach (char c in text) { if (c == '\n') { p.Y += spriteFont.LineSpacing; p.X = -origin.X; continue; } if (spriteFont.characterData.ContainsKey(c) == false) { continue; } GlyphData g = spriteFont.characterData[c]; SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.TextureID = (int)spriteFont._texture.ID; Vector2 texCoordTL = spriteFont._texture.Image.GetTextureCoord(g.Glyph.X, g.Glyph.Y); Vector2 texCoordBR = spriteFont._texture.Image.GetTextureCoord(g.Glyph.X + g.Glyph.Width, g.Glyph.Y + g.Glyph.Height); if (effects == SpriteEffects.FlipVertically) { float temp = texCoordBR.Y; texCoordBR.Y = texCoordTL.Y; texCoordTL.Y = temp; } else if (effects == SpriteEffects.FlipHorizontally) { float temp = texCoordBR.X; texCoordBR.X = texCoordTL.X; texCoordTL.X = temp; } item.Set ( position.X, position.Y, p.X * scale.X, (p.Y + g.Cropping.Y) * scale.Y, g.Glyph.Width * scale.X, g.Glyph.Height * scale.Y, sin, cos, color, texCoordTL, texCoordBR ); p.X += (g.Kerning.Y + g.Kerning.Z + spriteFont.Spacing); } }
private static int CompareTexture(SpriteBatchItem a, SpriteBatchItem b) { return object.ReferenceEquals((object) a.Texture, (object) b.Texture) ? 0 : 1; }
/// <summary> /// Reuse a previously allocated SpriteBatchItem from the item pool. /// if there is none available grow the pool and initialize new items. /// </summary> /// <returns></returns> public SpriteBatchItem CreateBatchItem() { if (_batchItemCount >= _batchItemList.Length) { var oldSize = _batchItemList.Length; var newSize = oldSize + oldSize/2; // grow by x1.5 newSize = (newSize + 63) & (~63); // grow in chunks of 64. Array.Resize(ref _batchItemList, newSize); for(int i=oldSize; i<newSize; i++) _batchItemList[i]=new SpriteBatchItem(); EnsureArrayCapacity(Math.Min(newSize, MaxBatchSize)); } var item = _batchItemList[_batchItemCount++]; return item; }
public void Draw( Texture2D texture, Rectangle destinationRectangle, Nullable <Rectangle> sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effect, float depth ) { if (texture == null) { throw new ArgumentException("texture"); } SpriteBatchItem item = _batcher.CreateBatchItem(); item.Depth = depth; item.TextureID = (int)texture.ID; Rectangle rect; if (sourceRectangle.HasValue) { rect = sourceRectangle.Value; } else { rect = new Rectangle(0, 0, texture.Width, texture.Height); } Vector2 texCoordTL; // = texture.Image.GetTextureCoord ( rect.X, rect.Y ); Vector2 texCoordBR; // = texture.Image.GetTextureCoord ( rect.X+rect.Width, rect.Y+rect.Height ); if (texture.Image == null) { float texWidthRatio = 1.0f / (float)texture.Width; float texHeightRatio = 1.0f / (float)texture.Height; // We are initially flipped vertically so we need to flip the corners so that // the image is bottom side up to display correctly texCoordTL = new Vector2(rect.X * texWidthRatio, (rect.Y + rect.Height) * texHeightRatio); texCoordBR = new Vector2((rect.X + rect.Width) * texWidthRatio, rect.Y * texHeightRatio); } else { texCoordTL = texture.Image.GetTextureCoord(rect.X, rect.Y); texCoordBR = texture.Image.GetTextureCoord(rect.X + rect.Width, rect.Y + rect.Height); } if (effect == SpriteEffects.FlipVertically) { float temp = texCoordBR.Y; texCoordBR.Y = texCoordTL.Y; texCoordTL.Y = temp; } else if (effect == SpriteEffects.FlipHorizontally) { float temp = texCoordBR.X; texCoordBR.X = texCoordTL.X; texCoordTL.X = temp; } item.Set ( destinationRectangle.X, destinationRectangle.Y, -origin.X, -origin.Y, destinationRectangle.Width, destinationRectangle.Height, (float)Math.Sin(rotation), (float)Math.Cos(rotation), color, texCoordTL, texCoordBR); }