# Sorting sprites based on Z index

I am working on a 2D game engine in C# using OpenGL. I am trying to find a collection to satisfy my needs for sprite ordering, and I can't seem to find the combination of performance and functionality.

The following is the criteria I am after:

• The ability to be iterated over in order according to "Z" value, which may change for any sprite at any time
• Possible for many sprites to be added/removed within a single frame, so sorting each time a value was added/removed will have large performance impact without the correct implementation
• Insertion/removal speed is much lower priority than access speed during enumeration
• Have no need for indexing
• Only unique values, but with the correct collection, I can manage that manually if the base collection does not implement it, as I do in the example

Currently, this is the best I could come up with. (I removed all the interface implementations for clarity, leaving only the important stuff)

    public class SpriteBatch : ICollection<IRenderable>
{
private bool _needSort;

public SpriteBatch()
{
_dict = new Dictionary<uint, IRenderable>();
_keys = new List<uint>();
_needSort = false;
}

{
if (renderable == null)
throw new ArgumentNullException(nameof(renderable), "Item cannot be undefined.");
if (_dict.ContainsKey(renderable.Id))
return;
_needSort = true;
renderable.Disposed += (sender, args) => Remove(renderable);
renderable.ZChanged += (sender, args) => _needSort = true;
}

public bool Remove(IRenderable renderable)
{
if (renderable == null)
return false;
_dict.Remove(renderable.Id);
return _keys.Remove(renderable.Id);
}

public IEnumerator<IRenderable> GetEnumerator()
{
if (_needSort)
_keys.Sort((a, b) => _dict[a].Z.CompareTo(_dict[b].Z));
foreach (var key in _keys)
yield return _dict[key];
}
}


Was curious if anyone else had a better approach, or what the "standard" tried-and-true way of doing this is?

• Use Depth Buffer to do the sorting for you - for essentially free - it will be massively faster. Sorting sprites on CPU only makes sense for the sprites which have order-dependent blending going on – JBeurer Jun 18 '18 at 22:22
• As far as I am aware, this will largely complicate alpha blending, which nearly every sprite on each layer requires. Correct me if I am wrong, my first though was using the depth buffer for its obvious simplicity, but everything I have read indicates the hell it is going to play on blending and the frag shader, which each sprite may have individual settings, not just each layer. Currently each sprite has its individual shader settings, and each "layer" or "viewport" does as well, which is rendered to its own buffer. – ForeverZer0 Jun 19 '18 at 0:49