private void RenderSpriteList(List <_2DSprite> sprites, Effect effect, EffectTechnique technique, List <_2DDrawGroup> cache)
{
if (sprites.Count == 0)
{
return;
}
/** Group by texture **/
var groupByTexture = GroupByTexture(sprites);
foreach (var group in groupByTexture)
{
var numSprites = group.Sprites.Count;
var texture = group.Pixel;
/** Build vertex data **/
var vertices = new _2DSpriteVertex[4 * numSprites];
var indices = new short[6 * numSprites];
var indexCount = 0;
var vertexCount = 0;
foreach (var sprite in group.Sprites)
{
//TODO: We want to pre-generate the sprite vertices, to reduce CPU usage.
//To do this they'll need to be scrolled by the gpu, all updates to sprite state
//will need to regenerate the _2DSpriteVertices, etc.
var srcRectangle = sprite.SrcRect;
var dstRectangle = sprite.AbsoluteDestRect;
indices[indexCount++] = (short)(vertexCount + 0);
indices[indexCount++] = (short)(vertexCount + 1);
indices[indexCount++] = (short)(vertexCount + 3);
indices[indexCount++] = (short)(vertexCount + 1);
indices[indexCount++] = (short)(vertexCount + 2);
indices[indexCount++] = (short)(vertexCount + 3);
// add the new vertices
var left = sprite.FlipHorizontally ? srcRectangle.Right : srcRectangle.Left;
var right = sprite.FlipHorizontally ? srcRectangle.Left : srcRectangle.Right;
var top = sprite.FlipVertically ? srcRectangle.Bottom : srcRectangle.Top;
var bot = sprite.FlipVertically ? srcRectangle.Top : srcRectangle.Bottom;
vertices[vertexCount++] = new _2DSpriteVertex(
new Vector3(dstRectangle.Left, dstRectangle.Top, 0)
, GetUV(texture, left, top), sprite.AbsoluteWorldPosition, (Single)sprite.ObjectID, sprite.Room);
vertices[vertexCount++] = new _2DSpriteVertex(
new Vector3(dstRectangle.Right, dstRectangle.Top, 0)
, GetUV(texture, right, top), sprite.AbsoluteWorldPosition, (Single)sprite.ObjectID, sprite.Room);
vertices[vertexCount++] = new _2DSpriteVertex(
new Vector3(dstRectangle.Right, dstRectangle.Bottom, 0)
, GetUV(texture, right, bot), sprite.AbsoluteWorldPosition, (Single)sprite.ObjectID, sprite.Room);
vertices[vertexCount++] = new _2DSpriteVertex(
new Vector3(dstRectangle.Left, dstRectangle.Bottom, 0)
, GetUV(texture, left, bot), sprite.AbsoluteWorldPosition, (Single)sprite.ObjectID, sprite.Room);
}
VertexBuffer vb = null;
IndexBuffer ib = null;
var count = indices.Length / 3;
if (count > 50) //completely arbitrary number, but seems to keep things fast. dont gen if it isn't "worth it".
{
vb = new VertexBuffer(Device, typeof(_2DSpriteVertex), vertices.Length, BufferUsage.WriteOnly);
vb.SetData(vertices);
ib = new IndexBuffer(Device, IndexElementSize.SixteenBits, indices.Length, BufferUsage.WriteOnly);
ib.SetData(indices);
vertices = null;
indices = null;
}
var dg = new _2DDrawGroup()
{
Pixel = group.Pixel,
Depth = group.Depth,
Mask = group.Mask,
VertBuf = vb,
IndexBuf = ib,
Vertices = vertices,
Indices = indices,
Primitives = count,
Technique = technique
};
if (cache != null)
{
cache.Add(dg);
}
else
{
RenderDrawGroup(dg);
dg.Dispose();
}
}
}