Files
OpenRA/OpenRA.Game/Graphics/SpriteRenderer.cs
RoosterDragon 53f06ba093 Implement dynamic hardware palette sizing.
The HardwarePalette will now grow its palette buffer and texture in power-of-2 increments. This avoids it having to allocate memory for a full 256x256 texture up front. In practice the default mods use 22 or 23 palettes so a 32x256 texture is used. This means both the buffer and texture save neatly on memory. Additionally, HardwarePalette.ApplyModifiers sees a nice speedup as it has to transfer a much smaller amount of memory from the buffer to the texture.

To facilitate this change, the MaxPalettes constant is no more. Instead the PaletteReference deals with the calculation of the index and this is passed into the appropriate methods.
2015-01-07 22:41:51 +00:00

132 lines
3.3 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
* see COPYING.
*/
#endregion
using System.Drawing;
namespace OpenRA.Graphics
{
public class SpriteRenderer : Renderer.IBatchRenderer
{
readonly Renderer renderer;
readonly IShader shader;
readonly Vertex[] vertices;
Sheet currentSheet;
BlendMode currentBlend = BlendMode.Alpha;
int nv = 0;
public SpriteRenderer(Renderer renderer, IShader shader)
{
this.renderer = renderer;
this.shader = shader;
vertices = new Vertex[renderer.TempBufferSize];
}
public void Flush()
{
if (nv > 0)
{
shader.SetTexture("DiffuseTexture", currentSheet.GetTexture());
renderer.Device.SetBlendMode(currentBlend);
shader.Render(() =>
{
var vb = renderer.GetTempVertexBuffer();
vb.SetData(vertices, nv);
renderer.DrawBatch(vb, 0, nv, PrimitiveType.QuadList);
});
renderer.Device.SetBlendMode(BlendMode.None);
nv = 0;
currentSheet = null;
}
}
public void DrawSprite(Sprite s, float2 location, PaletteReference pal)
{
DrawSprite(s, location, pal.TextureIndex, s.Size);
}
public void DrawSprite(Sprite s, float2 location, PaletteReference pal, float2 size)
{
DrawSprite(s, location, pal.TextureIndex, size);
}
void DrawSprite(Sprite s, float2 location, float paletteTextureIndex, float2 size)
{
renderer.CurrentBatchRenderer = this;
if (s.Sheet != currentSheet)
Flush();
if (s.BlendMode != currentBlend)
Flush();
if (nv + 4 > renderer.TempBufferSize)
Flush();
currentBlend = s.BlendMode;
currentSheet = s.Sheet;
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteTextureIndex, nv, size);
nv += 4;
}
// For RGBASpriteRenderer, which doesn't use palettes
public void DrawSprite(Sprite s, float2 location)
{
DrawSprite(s, location, 0, s.Size);
}
public void DrawSprite(Sprite s, float2 location, float2 size)
{
DrawSprite(s, location, 0, size);
}
public void DrawSprite(Sprite s, float2 a, float2 b, float2 c, float2 d)
{
renderer.CurrentBatchRenderer = this;
if (s.Sheet != currentSheet)
Flush();
if (s.BlendMode != currentBlend)
Flush();
if (nv + 4 > renderer.TempBufferSize)
Flush();
currentSheet = s.Sheet;
currentBlend = s.BlendMode;
Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv);
nv += 4;
}
public void DrawVertexBuffer(IVertexBuffer<Vertex> buffer, int start, int length, PrimitiveType type, Sheet sheet)
{
shader.SetTexture("DiffuseTexture", sheet.GetTexture());
renderer.Device.SetBlendMode(BlendMode.Alpha);
shader.Render(() => renderer.DrawBatch(buffer, start, length, type));
renderer.Device.SetBlendMode(BlendMode.None);
}
public void SetPalette(ITexture palette)
{
shader.SetTexture("Palette", palette);
}
public void SetViewportParams(Size screen, float zoom, int2 scroll)
{
shader.SetVec("Scroll", scroll.X, scroll.Y);
shader.SetVec("r1", zoom * 2f / screen.Width, -zoom * 2f / screen.Height);
shader.SetVec("r2", -1, 1);
}
}
}