Merge pull request #11098 from pchote/vertex-secondary-texcoords

Replace SheetType.DualIndexed with secondary texture coordinates on Vertex.
This commit is contained in:
Matthias Mailänder
2016-04-17 10:22:57 +02:00
16 changed files with 132 additions and 87 deletions

View File

@@ -69,12 +69,12 @@ namespace OpenRA.Graphics
var eb = endColor.B / 255.0f;
var ea = endColor.A / 255.0f;
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa);
vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea);
vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea);
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa);
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea, 0, 0);
vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa, 0, 0);
}
public void DrawLine(float2 start, float2 end, float width, Color color)
@@ -93,12 +93,12 @@ namespace OpenRA.Graphics
var b = color.B / 255.0f;
var a = color.A / 255.0f;
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a);
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a, 0, 0);
}
/// <summary>
@@ -186,12 +186,12 @@ namespace OpenRA.Graphics
if (nv + 6 > renderer.TempBufferSize)
Flush();
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a);
vertices[nv++] = new Vertex(cb + Offset, r, g, b, a);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a);
vertices[nv++] = new Vertex(cd + Offset, r, g, b, a);
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a);
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cb + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cc + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(cd + Offset, r, g, b, a, 0, 0);
vertices[nv++] = new Vertex(ca + Offset, r, g, b, a, 0, 0);
// Advance line segment
end = next;
@@ -243,12 +243,12 @@ namespace OpenRA.Graphics
var cb = color.B / 255.0f;
var ca = color.A / 255.0f;
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca);
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca, 0, 0);
vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca, 0, 0);
}
public void FillEllipse(RectangleF r, Color color, int vertices = 32)

View File

@@ -25,8 +25,7 @@ namespace OpenRA.Graphics
public enum SheetType
{
Indexed = 1,
DualIndexed = 2,
BGRA = 4,
BGRA = 2,
}
public sealed class SheetBuilder : IDisposable

View File

@@ -48,6 +48,24 @@ namespace OpenRA.Graphics
}
}
public class SpriteWithSecondaryData : Sprite
{
public readonly Rectangle SecondaryBounds;
public readonly TextureChannel SecondaryChannel;
public readonly float SecondaryTop, SecondaryLeft, SecondaryBottom, SecondaryRight;
public SpriteWithSecondaryData(Sprite s, Rectangle secondaryBounds, TextureChannel secondaryChannel)
: base(s.Sheet, s.Bounds, s.ZRamp, s.Offset, s.Channel, s.BlendMode)
{
SecondaryBounds = secondaryBounds;
SecondaryChannel = secondaryChannel;
SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width;
SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height;
SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width;
SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height;
}
}
public enum TextureChannel : byte
{
Red = 0,

View File

@@ -59,7 +59,7 @@ namespace OpenRA.Graphics
for (var i = 0; i < vertices.Length; i++)
{
var v = vertices[i];
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.U, v.V, palette.TextureIndex, v.C);
vertices[i] = new Vertex(v.X, v.Y, v.Z, v.S, v.T, v.U, v.V, palette.TextureIndex, v.C);
}
for (var row = 0; row < map.MapSize.Y; row++)

View File

@@ -43,7 +43,6 @@ namespace OpenRA.Graphics
{
this.tileset = tileset;
var allocated = false;
var type = tileset.EnableDepth ? SheetType.DualIndexed : SheetType.Indexed;
Func<Sheet> allocate = () =>
{
@@ -51,10 +50,10 @@ namespace OpenRA.Graphics
throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
allocated = true;
return new Sheet(type, new Size(tileset.SheetSize, tileset.SheetSize));
return new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize));
};
sheetBuilder = new SheetBuilder(type, allocate);
sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
random = new MersenneTwister();
var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);
@@ -71,10 +70,17 @@ namespace OpenRA.Graphics
{
var f = allFrames[j];
var s = sheetBuilder.Allocate(f.Size, f.Offset);
Util.FastCopyIntoChannel(s, 0, f.Data);
Util.FastCopyIntoChannel(s, f.Data);
if (tileset.EnableDepth)
Util.FastCopyIntoChannel(s, 1, allFrames[j + frameCount].Data);
{
var ss = sheetBuilder.Allocate(f.Size, f.Offset);
Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);
// s and ss are guaranteed to use the same sheet
// because of the custom terrain sheet allocation
s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel);
}
return s;
}).ToArray());

View File

@@ -31,25 +31,36 @@ namespace OpenRA.Graphics
public static void FastCreateQuad(Vertex[] vertices, float3 a, float3 b, float3 c, float3 d, Sprite r, float paletteTextureIndex, int nv)
{
float sl = 0;
float st = 0;
float sr = 0;
float sb = 0;
var attribC = ChannelSelect[(int)r.Channel];
if (r.Sheet.Type == SheetType.DualIndexed)
attribC *= -1;
vertices[nv] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, paletteTextureIndex, attribC);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, paletteTextureIndex, attribC);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC);
var ss = r as SpriteWithSecondaryData;
if (ss != null)
{
sl = ss.SecondaryLeft;
st = ss.SecondaryTop;
sr = ss.SecondaryRight;
sb = ss.SecondaryBottom;
attribC = -(attribC + ChannelSelect[(int)ss.Channel] / 10);
}
vertices[nv] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC);
vertices[nv + 1] = new Vertex(b, r.Right, r.Top, sr, st, paletteTextureIndex, attribC);
vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC);
vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, sr, sb, paletteTextureIndex, attribC);
vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, sl, sb, paletteTextureIndex, attribC);
vertices[nv + 5] = new Vertex(a, r.Left, r.Top, sl, st, paletteTextureIndex, attribC);
}
public static void FastCopyIntoChannel(Sprite dest, byte[] src) { FastCopyIntoChannel(dest, 0, src); }
public static void FastCopyIntoChannel(Sprite dest, int channelOffset, byte[] src)
public static void FastCopyIntoChannel(Sprite dest, byte[] src)
{
var data = dest.Sheet.GetData();
var srcStride = dest.Bounds.Width;
var destStride = dest.Sheet.Size.Width * 4;
var destOffset = destStride * dest.Bounds.Top + dest.Bounds.Left * 4 + ChannelMasks[(int)dest.Channel + channelOffset];
var destOffset = destStride * dest.Bounds.Top + dest.Bounds.Left * 4 + ChannelMasks[(int)dest.Channel];
var destSkip = destStride - 4 * srcStride;
var height = dest.Bounds.Height;

View File

@@ -16,14 +16,15 @@ namespace OpenRA.Graphics
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public readonly float X, Y, Z, U, V, P, C;
public readonly float X, Y, Z, S, T, U, V, P, C;
public Vertex(float3 xyz, float u, float v, float p, float c)
: this(xyz.X, xyz.Y, xyz.Z, u, v, p, c) { }
public Vertex(float3 xyz, float s, float t, float u, float v, float p, float c)
: this(xyz.X, xyz.Y, xyz.Z, s, t, u, v, p, c) { }
public Vertex(float x, float y, float z, float u, float v, float p, float c)
public Vertex(float x, float y, float z, float s, float t, float u, float v, float p, float c)
{
X = x; Y = y; Z = z;
S = s; T = t;
U = u; V = v;
P = p; C = c;
}

View File

@@ -54,10 +54,10 @@ namespace OpenRA.Graphics
if (allocated)
throw new SheetOverflowException("");
allocated = true;
return SheetBuilder.AllocateSheet(SheetType.DualIndexed, Game.Settings.Graphics.SheetSize);
return SheetBuilder.AllocateSheet(SheetType.Indexed, Game.Settings.Graphics.SheetSize);
};
return new SheetBuilder(SheetType.DualIndexed, allocate);
return new SheetBuilder(SheetType.Indexed, allocate);
}
public VoxelLoader(IReadOnlyFileSystem fileSystem)
@@ -78,6 +78,7 @@ namespace OpenRA.Graphics
var c = 0;
for (var v = 0; v < sv; v++)
{
for (var u = 0; u < su; u++)
{
var voxel = first(u, v) ?? second(u, v);
@@ -85,22 +86,28 @@ namespace OpenRA.Graphics
normals[c] = voxel == null ? (byte)0 : voxel.Normal;
c++;
}
}
var s = sheetBuilder.Allocate(new Size(su, sv));
Util.FastCopyIntoChannel(s, 0, colors);
Util.FastCopyIntoChannel(s, 1, normals);
var size = new Size(su, sv);
var s = sheetBuilder.Allocate(size);
var t = sheetBuilder.Allocate(size);
Util.FastCopyIntoChannel(s, colors);
Util.FastCopyIntoChannel(t, normals);
// s and t are guaranteed to use the same sheet because
// of the custom voxel sheet allocation implementation
s.Sheet.CommitBufferedData();
var channelP = ChannelSelect[(int)s.Channel];
var channelC = ChannelSelect[(int)s.Channel + 1];
var channelC = ChannelSelect[(int)t.Channel];
return new Vertex[6]
{
new Vertex(coord(0, 0), s.Left, s.Top, channelP, channelC),
new Vertex(coord(su, 0), s.Right, s.Top, channelP, channelC),
new Vertex(coord(su, sv), s.Right, s.Bottom, channelP, channelC),
new Vertex(coord(su, sv), s.Right, s.Bottom, channelP, channelC),
new Vertex(coord(0, sv), s.Left, s.Bottom, channelP, channelC),
new Vertex(coord(0, 0), s.Left, s.Top, channelP, channelC)
new Vertex(coord(0, 0), s.Left, s.Top, t.Left, t.Top, channelP, channelC),
new Vertex(coord(su, 0), s.Right, s.Top, t.Right, t.Top, channelP, channelC),
new Vertex(coord(su, sv), s.Right, s.Bottom, t.Right, t.Bottom, channelP, channelC),
new Vertex(coord(su, sv), s.Right, s.Bottom, t.Right, t.Bottom, channelP, channelC),
new Vertex(coord(0, sv), s.Left, s.Bottom, t.Left, t.Bottom, channelP, channelC),
new Vertex(coord(0, 0), s.Left, s.Top, t.Left, t.Top, channelP, channelC)
};
}

View File

@@ -332,7 +332,7 @@ namespace OpenRA.Graphics
var size = new Size(renderer.SheetSize, renderer.SheetSize);
var framebuffer = renderer.Device.CreateFrameBuffer(size);
var sheet = new Sheet(SheetType.DualIndexed, framebuffer.Texture);
var sheet = new Sheet(SheetType.BGRA, framebuffer.Texture);
mappedBuffers.Add(sheet, framebuffer);
return sheet;