/// <summary> /// Draw a single texture from grid. /// </summary> /// <param name="batch">Spritebatch to draw on. Expected to be after 'Begin' was called.</param> /// <param name="texture">The grid texture itself.</param> /// <param name="offset">Optional drawing offset.</param> protected void DrawGridTexture(SpriteBatch batch, StaticBatchTexture texture, Point?offset) { // draw with offset if (offset.HasValue) { var dest = texture.DestRect; dest.Location += offset.Value; batch.Draw(texture.Texture, dest, Color.White); } // draw without offset else { batch.Draw(texture.Texture, texture.DestRect, Color.White); } // count draw calls LastDrawCallsCount++; }
/// <summary> /// Build the static batch from the list of sprites previously added to it. /// </summary> /// <param name="batch">Spritebatch to use for rendering.</param> /// <param name="clear">If true, will clear previous textures first. If false, will redraw on them.</param> /// <param name="releaseSpritesList">If true, will clear the current list of sprites after done building batch.</param> /// <param name="beginBatchHandler">If provided, this function will be called every time we need to begin a drawing batch. /// This provides the ability to choose how to begin the drawing batch, and add your own params and flags to it.</param> public void Build(SpriteBatch batch, bool clear = true, bool releaseSpritesList = true, BeginBatchHandler beginBatchHandler = null) { // clear previous textures if set to clear. if (clear) { Clear(); } // dictionary to sort static sprites into cells, before rendering them Dictionary <Point, List <StaticSprite> > sortedSprites = new Dictionary <Point, List <StaticSprite> >(); // used internally Point pointOne = new Point(1, 1); // arrange static sprites in grid foreach (var sprite in _spritesPending) { // calc the indexes this sprite is a part of Point startIndex = (sprite.BoundingRect.Location / _chunkSize); Point endIndex = startIndex + (sprite.BoundingRect.Size / _chunkSize) + pointOne; // add to sorted sprites dictionary Point currIndex = new Point(); for (currIndex.X = startIndex.X; currIndex.X <= endIndex.X; ++currIndex.X) { for (currIndex.Y = startIndex.Y; currIndex.Y <= endIndex.Y; ++currIndex.Y) { sortedSprites.GetOrCreate(currIndex).Add(sprite); } } } // now that we got sprites arranged into cells, draw them foreach (var indexAndSprite in sortedSprites) { // get current grid texture StaticBatchTexture currTexture; if (!_textures.TryGetValue(indexAndSprite.Key, out currTexture)) { _textures[indexAndSprite.Key] = currTexture = new StaticBatchTexture(_device, indexAndSprite.Key, _chunkSize); } // begin drawing batch if (beginBatchHandler != null) { beginBatchHandler(batch); } else { batch.Begin(DefaultSortMode, DefaultBlend, DefaultSamplerState); } // set rendering target _device.SetRenderTarget(currTexture.Texture); _device.Clear(Color.Transparent); // draw all sprites on it foreach (var sprite in indexAndSprite.Value) { // set relative dest rect var dest = sprite.DestRect; dest.Location -= currTexture.DestRect.Location; // draw sprite on texture batch.Draw(sprite.Texture, dest, sprite.SourceRect, sprite.Color, sprite.Rotation, sprite.Origin, sprite.SpriteEffect, sprite.ZIndex); } // end drawing current texture batch.End(); _device.SetRenderTarget(null); } // release previous list if (releaseSpritesList) { _spritesPending.Clear(); } }