diff --git a/OpenRa.Game/SheetBuilder.cs b/OpenRa.Game/SheetBuilder.cs index 06a1a76df7..08d5cb8110 100644 --- a/OpenRa.Game/SheetBuilder.cs +++ b/OpenRa.Game/SheetBuilder.cs @@ -87,7 +87,7 @@ namespace OpenRa.Game p = new Point(0,0); } - Sprite rect = new Sprite(current, p, imageSize, channel.Value); + Sprite rect = new Sprite(current, new Rectangle(p, imageSize), channel.Value); p.X += imageSize.Width; return rect; diff --git a/OpenRa.Game/Sprite.cs b/OpenRa.Game/Sprite.cs index cb277d3aa7..e58737d7af 100644 --- a/OpenRa.Game/Sprite.cs +++ b/OpenRa.Game/Sprite.cs @@ -7,18 +7,37 @@ namespace OpenRa.Game { class Sprite { - public readonly Point origin; - public readonly Size size; + public readonly Rectangle bounds; public readonly Sheet sheet; public readonly TextureChannel channel; - internal Sprite(Sheet sheet, Point origin, Size size, TextureChannel channel) + internal Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel) { - this.origin = origin; - this.size = size; + this.bounds = bounds; this.sheet = sheet; this.channel = channel; } + + RectangleF TextureCoords + { + get + { + return new RectangleF( + (float)(bounds.Left + 0.5f) / sheet.Size.Width, + (float)(bounds.Top + 0.5f) / sheet.Size.Height, + (float)(bounds.Width) / sheet.Size.Width, + (float)(bounds.Height) / sheet.Size.Height); + } + } + + public PointF MapTextureCoords(PointF p) + { + RectangleF uv = TextureCoords; + + return new PointF( + p.X > 0 ? uv.Right : uv.Left, + p.Y > 0 ? uv.Bottom : uv.Top); + } } public enum TextureChannel diff --git a/OpenRa.Game/Util.cs b/OpenRa.Game/Util.cs index 405010e404..429875b420 100644 --- a/OpenRa.Game/Util.cs +++ b/OpenRa.Game/Util.cs @@ -9,22 +9,6 @@ namespace OpenRa.Game { static class Util { - public static float U(Sprite s, float u) - { - float u0 = (float)(s.origin.X + 0.5f) / (float)s.sheet.bitmap.Width; - float u1 = (float)(s.origin.X + s.size.Width) / (float)s.sheet.bitmap.Width; - - return (u > 0) ? u1 : u0; - } - - public static float V(Sprite s, float v) - { - float v0 = (float)(s.origin.Y + 0.5f) / (float)s.sheet.bitmap.Height; - float v1 = (float)(s.origin.Y + s.size.Height) / (float)s.sheet.bitmap.Height; - - return (v > 0) ? v1 : v0; - } - public static float Constrain(float x, Range range) { return x < range.Start ? range.Start : x > range.End ? range.End : x; @@ -48,15 +32,14 @@ namespace OpenRa.Game return new PointF(paletteLine / 16.0f, channelEncoder(channel)); } - public static Vertex MakeVertex(PointF o, float u, float v, Sprite r, int palette) + public static Vertex MakeVertex(PointF o, PointF uv, Sprite r, int palette) { - float x2 = o.X + r.size.Width; - float y2 = o.Y + r.size.Height; + PointF farCorner = new PointF(o.X + r.bounds.Width, o.Y + r.bounds.Height); - PointF p = EncodeVertexAttributes(r.channel, palette); - - return new Vertex(Lerp(o.X, x2, u), Lerp(o.Y, y2, v), 0, U(r, u), V(r, v), - p.X, p.Y); + return new Vertex( + Lerp( o, farCorner, uv ), + r.MapTextureCoords(uv), + EncodeVertexAttributes(r.channel, palette)); } static float Lerp(float a, float b, float t) @@ -64,14 +47,27 @@ namespace OpenRa.Game return (1 - t) * a + t * b; } + static PointF Lerp(PointF a, PointF b, PointF t) + { + return new PointF( + Lerp(a.X, b.X, t.X), + Lerp(a.Y, b.Y, t.Y)); + } + + static PointF[] uv = + { + new PointF( 0,0 ), + new PointF( 1,0 ), + new PointF( 0,1 ), + new PointF( 1,1 ), + }; + public static void CreateQuad(List vertices, List indices, PointF o, Sprite r, int palette) { ushort offset = (ushort)vertices.Count; - vertices.Add(Util.MakeVertex(o, 0, 0, r, palette)); - vertices.Add(Util.MakeVertex(o, 1, 0, r, palette)); - vertices.Add(Util.MakeVertex(o, 0, 1, r, palette)); - vertices.Add(Util.MakeVertex(o, 1, 1, r, palette)); + foreach( PointF p in uv ) + vertices.Add(Util.MakeVertex(o, p, r, palette)); indices.Add(offset); indices.Add((ushort)(offset + 1)); @@ -84,11 +80,11 @@ namespace OpenRa.Game public static void CopyIntoChannel(Sprite dest, byte[] src) { - for (int i = 0; i < dest.size.Width; i++) - for (int j = 0; j < dest.size.Height; j++) + for (int i = 0; i < dest.bounds.Width; i++) + for (int j = 0; j < dest.bounds.Height; j++) { - Point p = new Point(dest.origin.X + i, dest.origin.Y + j); - byte b = src[i + dest.size.Width * j]; + Point p = new Point(dest.bounds.Left + i, dest.bounds.Top + j); + byte b = src[i + dest.bounds.Width * j]; Color original = dest.sheet.bitmap.GetPixel(p.X, p.Y); dest.sheet.bitmap.SetPixel(p.X, p.Y, ReplaceChannel(original, dest.channel, b)); } diff --git a/OpenRa.Game/Vertex.cs b/OpenRa.Game/Vertex.cs index d5061e22d1..c679fc7651 100644 --- a/OpenRa.Game/Vertex.cs +++ b/OpenRa.Game/Vertex.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using BluntDirectX.Direct3D; +using System.Drawing; namespace OpenRa.Game { @@ -12,14 +13,11 @@ namespace OpenRa.Game public float x, y, z, u, v; public float p, c; - public Vertex(float x, float y, float z, float u, float v, float p, float c) + public Vertex(PointF xy, PointF uv, PointF pc) { - this.x = x; this.y = y; this.z = z; - this.u = u; - this.v = v; - - this.p = p; - this.c = c; + this.x = xy.X; this.y = xy.Y; this.z = 0; + this.u = uv.X; this.v = uv.Y; + this.p = pc.X; this.c = pc.Y; } public const VertexFormat Format = VertexFormat.Position | VertexFormat.Texture2; diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index d8d9f627e4..a05b461682 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -30,10 +30,10 @@ namespace OpenRa.Game if (images == null) continue; - if (a.location.X > xr.End || a.location.X < xr.Start - images[0].size.Width) + if (a.location.X > xr.End || a.location.X < xr.Start - images[0].bounds.Width) continue; - if (a.location.Y > yr.End || a.location.Y < yr.Start - images[0].size.Height) + if (a.location.Y > yr.End || a.location.Y < yr.Start - images[0].bounds.Height) continue; foreach (Sprite image in images)