Rework multi-resolution sprite handling:
- Sprite.Bounds now refers to rectangles in the source image. Use this when copying pixels, etc. - Sprite.Size now refers to sizes in effective pixel coordinates. Use this when rendering. - Sheet.DPIScale has been removed. - "Density" term is introduced to refer to the number of artwork pixels per effective pixel.
This commit is contained in:
@@ -54,10 +54,10 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public static IReadOnlyDictionary<string, Collection> Collections { get; private set; }
|
public static IReadOnlyDictionary<string, Collection> Collections { get; private set; }
|
||||||
static Dictionary<string, Collection> collections;
|
static Dictionary<string, Collection> collections;
|
||||||
static Dictionary<string, Sheet> cachedSheets;
|
static Dictionary<string, Pair<Sheet, int>> cachedSheets;
|
||||||
static Dictionary<string, Dictionary<string, Sprite>> cachedSprites;
|
static Dictionary<string, Dictionary<string, Sprite>> cachedSprites;
|
||||||
static Dictionary<string, Sprite[]> cachedPanelSprites;
|
static Dictionary<string, Sprite[]> cachedPanelSprites;
|
||||||
static Dictionary<Collection, Sheet> cachedCollectionSheets;
|
static Dictionary<Collection, Pair<Sheet, int>> cachedCollectionSheets;
|
||||||
|
|
||||||
static IReadOnlyFileSystem fileSystem;
|
static IReadOnlyFileSystem fileSystem;
|
||||||
static float dpiScale = 1;
|
static float dpiScale = 1;
|
||||||
@@ -72,10 +72,10 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
fileSystem = modData.DefaultFileSystem;
|
fileSystem = modData.DefaultFileSystem;
|
||||||
collections = new Dictionary<string, Collection>();
|
collections = new Dictionary<string, Collection>();
|
||||||
cachedSheets = new Dictionary<string, Sheet>();
|
cachedSheets = new Dictionary<string, Pair<Sheet, int>>();
|
||||||
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
|
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
|
||||||
cachedPanelSprites = new Dictionary<string, Sprite[]>();
|
cachedPanelSprites = new Dictionary<string, Sprite[]>();
|
||||||
cachedCollectionSheets = new Dictionary<Collection, Sheet>();
|
cachedCollectionSheets = new Dictionary<Collection, Pair<Sheet, int>>();
|
||||||
|
|
||||||
Collections = new ReadOnlyDictionary<string, Collection>(collections);
|
Collections = new ReadOnlyDictionary<string, Collection>(collections);
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
if (cachedSheets != null)
|
if (cachedSheets != null)
|
||||||
foreach (var sheet in cachedSheets.Values)
|
foreach (var sheet in cachedSheets.Values)
|
||||||
sheet.Dispose();
|
sheet.First.Dispose();
|
||||||
|
|
||||||
collections = null;
|
collections = null;
|
||||||
cachedSheets = null;
|
cachedSheets = null;
|
||||||
@@ -108,47 +108,43 @@ namespace OpenRA.Graphics
|
|||||||
collections.Add(name, FieldLoader.Load<Collection>(yaml));
|
collections.Add(name, FieldLoader.Load<Collection>(yaml));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Sheet SheetForCollection(Collection c)
|
static Pair<Sheet, int> SheetForCollection(Collection c)
|
||||||
{
|
{
|
||||||
Sheet sheet;
|
Pair<Sheet, int> sheetDensity;
|
||||||
|
|
||||||
// Outer cache avoids recalculating image names
|
// Outer cache avoids recalculating image names
|
||||||
if (!cachedCollectionSheets.TryGetValue(c, out sheet))
|
if (!cachedCollectionSheets.TryGetValue(c, out sheetDensity))
|
||||||
{
|
{
|
||||||
string sheetImage;
|
var image = c.Image;
|
||||||
float sheetScale;
|
var density = 1;
|
||||||
if (dpiScale > 2 && !string.IsNullOrEmpty(c.Image3x))
|
if (dpiScale > 2 && !string.IsNullOrEmpty(c.Image3x))
|
||||||
{
|
{
|
||||||
sheetImage = c.Image3x;
|
image = c.Image3x;
|
||||||
sheetScale = 3;
|
density = 3;
|
||||||
}
|
}
|
||||||
else if (dpiScale > 1 && !string.IsNullOrEmpty(c.Image2x))
|
else if (dpiScale > 1 && !string.IsNullOrEmpty(c.Image2x))
|
||||||
{
|
{
|
||||||
sheetImage = c.Image2x;
|
image = c.Image2x;
|
||||||
sheetScale = 2;
|
density = 2;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sheetImage = c.Image;
|
|
||||||
sheetScale = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inner cache makes sure we share sheets between collections
|
// Inner cache makes sure we share sheets between collections
|
||||||
if (!cachedSheets.TryGetValue(sheetImage, out sheet))
|
if (!cachedSheets.TryGetValue(image, out sheetDensity))
|
||||||
{
|
{
|
||||||
using (var stream = fileSystem.Open(sheetImage))
|
Sheet sheet;
|
||||||
|
using (var stream = fileSystem.Open(image))
|
||||||
sheet = new Sheet(SheetType.BGRA, stream);
|
sheet = new Sheet(SheetType.BGRA, stream);
|
||||||
|
|
||||||
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
|
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
|
||||||
sheet.DPIScale = sheetScale;
|
|
||||||
|
|
||||||
cachedSheets.Add(sheetImage, sheet);
|
sheetDensity = Pair.New(sheet, density);
|
||||||
|
cachedSheets.Add(image, sheetDensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedCollectionSheets.Add(c, sheet);
|
cachedCollectionSheets.Add(c, sheetDensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sheet;
|
return sheetDensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Sprite GetImage(string collectionName, string imageName)
|
public static Sprite GetImage(string collectionName, string imageName)
|
||||||
@@ -174,14 +170,14 @@ namespace OpenRA.Graphics
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Cache the sprite
|
// Cache the sprite
|
||||||
var sheet = SheetForCollection(collection);
|
var sheetDensity = SheetForCollection(collection);
|
||||||
if (cachedCollection == null)
|
if (cachedCollection == null)
|
||||||
{
|
{
|
||||||
cachedCollection = new Dictionary<string, Sprite>();
|
cachedCollection = new Dictionary<string, Sprite>();
|
||||||
cachedSprites.Add(collectionName, cachedCollection);
|
cachedSprites.Add(collectionName, cachedCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
var image = new Sprite(sheet, mi, TextureChannel.RGBA);
|
var image = new Sprite(sheetDensity.First, sheetDensity.Second * mi, TextureChannel.RGBA, 1f / sheetDensity.Second);
|
||||||
cachedCollection.Add(imageName, image);
|
cachedCollection.Add(imageName, image);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
@@ -214,7 +210,7 @@ namespace OpenRA.Graphics
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache the sprites
|
// Cache the sprites
|
||||||
var sheet = SheetForCollection(collection);
|
var sheetDensity = SheetForCollection(collection);
|
||||||
var pr = collection.PanelRegion;
|
var pr = collection.PanelRegion;
|
||||||
var ps = collection.PanelSides;
|
var ps = collection.PanelSides;
|
||||||
|
|
||||||
@@ -231,7 +227,7 @@ namespace OpenRA.Graphics
|
|||||||
Pair.New(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
|
Pair.New(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7]))
|
||||||
};
|
};
|
||||||
|
|
||||||
sprites = sides.Select(x => ps.HasSide(x.First) ? new Sprite(sheet, x.Second, TextureChannel.RGBA) : null)
|
sprites = sides.Select(x => ps.HasSide(x.First) ? new Sprite(sheetDensity.First, sheetDensity.Second * x.Second, TextureChannel.RGBA, 1f / sheetDensity.Second) : null)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace OpenRA.Graphics
|
|||||||
|
|
||||||
public readonly Size Size;
|
public readonly Size Size;
|
||||||
public readonly SheetType Type;
|
public readonly SheetType Type;
|
||||||
public float DPIScale = 1f;
|
|
||||||
|
|
||||||
public byte[] GetData()
|
public byte[] GetData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ namespace OpenRA.Graphics
|
|||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite Add(Png src)
|
public Sprite Add(Png src, float scale = 1f)
|
||||||
{
|
{
|
||||||
var rect = Allocate(new Size(src.Width, src.Height));
|
var rect = Allocate(new Size(src.Width, src.Height), scale);
|
||||||
Util.FastCopyIntoSprite(rect, src);
|
Util.FastCopyIntoSprite(rect, src);
|
||||||
current.CommitBufferedData();
|
current.CommitBufferedData();
|
||||||
return rect;
|
return rect;
|
||||||
@@ -114,8 +114,8 @@ namespace OpenRA.Graphics
|
|||||||
return (TextureChannel)nextChannel;
|
return (TextureChannel)nextChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite Allocate(Size imageSize) { return Allocate(imageSize, 0, float3.Zero); }
|
public Sprite Allocate(Size imageSize, float scale = 1f) { return Allocate(imageSize, 0, float3.Zero, scale); }
|
||||||
public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset)
|
public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset, float scale = 1f)
|
||||||
{
|
{
|
||||||
if (imageSize.Width + p.X + margin > current.Size.Width)
|
if (imageSize.Width + p.X + margin > current.Size.Width)
|
||||||
{
|
{
|
||||||
@@ -143,7 +143,7 @@ namespace OpenRA.Graphics
|
|||||||
p = int2.Zero;
|
p = int2.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha);
|
var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha, scale);
|
||||||
p += new int2(imageSize.Width + margin, 0);
|
p += new int2(imageSize.Width + margin, 0);
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
|
|||||||
@@ -26,25 +26,25 @@ namespace OpenRA.Graphics
|
|||||||
public readonly float3 FractionalOffset;
|
public readonly float3 FractionalOffset;
|
||||||
public readonly float Top, Left, Bottom, Right;
|
public readonly float Top, Left, Bottom, Right;
|
||||||
|
|
||||||
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel)
|
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, float scale = 1)
|
||||||
: this(sheet, bounds, 0, float2.Zero, channel) { }
|
: this(sheet, bounds, 0, float2.Zero, channel, BlendMode.Alpha, scale) { }
|
||||||
|
|
||||||
public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha)
|
public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha, float scale = 1f)
|
||||||
{
|
{
|
||||||
Sheet = sheet;
|
Sheet = sheet;
|
||||||
Bounds = bounds;
|
Bounds = bounds;
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
ZRamp = zRamp;
|
ZRamp = zRamp;
|
||||||
Channel = channel;
|
Channel = channel;
|
||||||
Size = new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp);
|
Size = scale * new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp);
|
||||||
BlendMode = blendMode;
|
BlendMode = blendMode;
|
||||||
FractionalOffset = Size.Z != 0 ? offset / Size :
|
FractionalOffset = Size.Z != 0 ? offset / Size :
|
||||||
new float3(offset.X / Size.X, offset.Y / Size.Y, 0);
|
new float3(offset.X / Size.X, offset.Y / Size.Y, 0);
|
||||||
|
|
||||||
Left = (float)Math.Min(bounds.Left, bounds.Right) * sheet.DPIScale / sheet.Size.Width;
|
Left = (float)Math.Min(bounds.Left, bounds.Right) / sheet.Size.Width;
|
||||||
Top = (float)Math.Min(bounds.Top, bounds.Bottom) * sheet.DPIScale / sheet.Size.Height;
|
Top = (float)Math.Min(bounds.Top, bounds.Bottom) / sheet.Size.Height;
|
||||||
Right = (float)Math.Max(bounds.Left, bounds.Right) * sheet.DPIScale / sheet.Size.Width;
|
Right = (float)Math.Max(bounds.Left, bounds.Right) / sheet.Size.Width;
|
||||||
Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) * sheet.DPIScale / sheet.Size.Height;
|
Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) / sheet.Size.Height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,10 +61,10 @@ namespace OpenRA.Graphics
|
|||||||
SecondarySheet = secondarySheet;
|
SecondarySheet = secondarySheet;
|
||||||
SecondaryBounds = secondaryBounds;
|
SecondaryBounds = secondaryBounds;
|
||||||
SecondaryChannel = secondaryChannel;
|
SecondaryChannel = secondaryChannel;
|
||||||
SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) * secondarySheet.DPIScale / s.Sheet.Size.Width;
|
SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width;
|
||||||
SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) * secondarySheet.DPIScale / s.Sheet.Size.Height;
|
SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height;
|
||||||
SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) * secondarySheet.DPIScale / s.Sheet.Size.Width;
|
SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width;
|
||||||
SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) * secondarySheet.DPIScale / s.Sheet.Size.Height;
|
SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ namespace OpenRA.Primitives
|
|||||||
return rect == Intersect(this, rect);
|
return rect == Intersect(this, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Rectangle operator *(int a, Rectangle b) { return new Rectangle(a * b.X, a * b.Y, a * b.Width, a * b.Height); }
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("{{X={0},Y={1},Width={2},Height={3}}}", X, Y, Width, Height);
|
return string.Format("{{X={0},Y={1},Width={2},Height={3}}}", X, Y, Width, Height);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace OpenRA.Mods.Cnc
|
|||||||
float2 loadingPos, versionPos;
|
float2 loadingPos, versionPos;
|
||||||
|
|
||||||
Sheet lastSheet;
|
Sheet lastSheet;
|
||||||
|
int lastDensity;
|
||||||
Size lastResolution;
|
Size lastResolution;
|
||||||
IReadOnlyDictionary<string, SpriteFont> lastFonts;
|
IReadOnlyDictionary<string, SpriteFont> lastFonts;
|
||||||
|
|
||||||
@@ -41,31 +42,32 @@ namespace OpenRA.Mods.Cnc
|
|||||||
versionText = modData.Manifest.Metadata.Version;
|
versionText = modData.Manifest.Metadata.Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DisplayInner(Renderer r, Sheet s)
|
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||||
{
|
{
|
||||||
if (s != lastSheet)
|
if (s != lastSheet || density != lastDensity)
|
||||||
{
|
{
|
||||||
lastSheet = s;
|
lastSheet = s;
|
||||||
|
lastDensity = density;
|
||||||
|
|
||||||
border = new[]
|
border = new[]
|
||||||
{
|
{
|
||||||
new Sprite(s, new Rectangle(129, 129, 32, 32), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(129, 129, 32, 32)),
|
||||||
new Sprite(s, new Rectangle(161, 129, 62, 32), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(161, 129, 62, 32)),
|
||||||
new Sprite(s, new Rectangle(223, 129, 32, 32), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(223, 129, 32, 32)),
|
||||||
new Sprite(s, new Rectangle(129, 161, 32, 62), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(129, 161, 32, 62)),
|
||||||
null,
|
null,
|
||||||
new Sprite(s, new Rectangle(223, 161, 32, 62), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(223, 161, 32, 62)),
|
||||||
new Sprite(s, new Rectangle(129, 223, 32, 32), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(129, 223, 32, 32)),
|
||||||
new Sprite(s, new Rectangle(161, 223, 62, 32), TextureChannel.RGBA),
|
CreateSprite(s, density, new Rectangle(161, 223, 62, 32)),
|
||||||
new Sprite(s, new Rectangle(223, 223, 32, 32), TextureChannel.RGBA)
|
CreateSprite(s, density, new Rectangle(223, 223, 32, 32))
|
||||||
};
|
};
|
||||||
|
|
||||||
nodLogo = new Sprite(s, new Rectangle(0, 256, 256, 256), TextureChannel.RGBA);
|
nodLogo = CreateSprite(s, density, new Rectangle(0, 256, 256, 256));
|
||||||
gdiLogo = new Sprite(s, new Rectangle(256, 256, 256, 256), TextureChannel.RGBA);
|
gdiLogo = CreateSprite(s, density, new Rectangle(256, 256, 256, 256));
|
||||||
evaLogo = new Sprite(s, new Rectangle(769, 320, 128, 64), TextureChannel.RGBA);
|
evaLogo = CreateSprite(s, density, new Rectangle(769, 320, 128, 64));
|
||||||
|
|
||||||
brightBlock = new Sprite(s, new Rectangle(777, 385, 16, 35), TextureChannel.RGBA);
|
brightBlock = CreateSprite(s, density, new Rectangle(777, 385, 16, 35));
|
||||||
dimBlock = new Sprite(s, new Rectangle(794, 385, 16, 35), TextureChannel.RGBA);
|
dimBlock = CreateSprite(s, density, new Rectangle(794, 385, 16, 35));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.Resolution != lastResolution)
|
if (r.Resolution != lastResolution)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
Sprite stripe, logo;
|
Sprite stripe, logo;
|
||||||
|
|
||||||
Sheet lastSheet;
|
Sheet lastSheet;
|
||||||
|
int lastDensity;
|
||||||
Size lastResolution;
|
Size lastResolution;
|
||||||
|
|
||||||
string[] messages = { "Loading..." };
|
string[] messages = { "Loading..." };
|
||||||
@@ -36,13 +37,14 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
messages = info["Text"].Split(',');
|
messages = info["Text"].Split(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DisplayInner(Renderer r, Sheet s)
|
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||||
{
|
{
|
||||||
if (s != lastSheet)
|
if (s != lastSheet || density != lastDensity)
|
||||||
{
|
{
|
||||||
lastSheet = s;
|
lastSheet = s;
|
||||||
logo = new Sprite(s, new Rectangle(0, 0, 256, 256), TextureChannel.RGBA);
|
lastDensity = density;
|
||||||
stripe = new Sprite(s, new Rectangle(258, 0, 253, 256), TextureChannel.RGBA);
|
logo = CreateSprite(s, density, new Rectangle(0, 0, 256, 256));
|
||||||
|
stripe = CreateSprite(s, density, new Rectangle(258, 0, 253, 256));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.Resolution != lastResolution)
|
if (r.Resolution != lastResolution)
|
||||||
|
|||||||
@@ -25,14 +25,16 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
Rectangle bounds;
|
Rectangle bounds;
|
||||||
|
|
||||||
Sheet lastSheet;
|
Sheet lastSheet;
|
||||||
|
int lastDensity;
|
||||||
Size lastResolution;
|
Size lastResolution;
|
||||||
|
|
||||||
public override void DisplayInner(Renderer r, Sheet s)
|
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||||
{
|
{
|
||||||
if (s != lastSheet)
|
if (s != lastSheet || density != lastDensity)
|
||||||
{
|
{
|
||||||
lastSheet = s;
|
lastSheet = s;
|
||||||
sprite = new Sprite(s, new Rectangle(0, 0, 1024, 480), TextureChannel.RGBA);
|
lastDensity = density;
|
||||||
|
sprite = CreateSprite(s, density, new Rectangle(0, 0, 1024, 480));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.Resolution != lastResolution)
|
if (r.Resolution != lastResolution)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.LoadScreens
|
namespace OpenRA.Mods.Common.LoadScreens
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,9 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
|
|
||||||
protected Dictionary<string, string> Info { get; private set; }
|
protected Dictionary<string, string> Info { get; private set; }
|
||||||
float dpiScale = 1;
|
float dpiScale = 1;
|
||||||
|
|
||||||
Sheet sheet;
|
Sheet sheet;
|
||||||
|
int density;
|
||||||
|
|
||||||
public override void Init(ModData modData, Dictionary<string, string> info)
|
public override void Init(ModData modData, Dictionary<string, string> info)
|
||||||
{
|
{
|
||||||
@@ -29,7 +32,7 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
Info = info;
|
Info = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void DisplayInner(Renderer r, Sheet s);
|
public abstract void DisplayInner(Renderer r, Sheet s, int density);
|
||||||
|
|
||||||
public override void Display()
|
public override void Display()
|
||||||
{
|
{
|
||||||
@@ -58,33 +61,37 @@ namespace OpenRA.Mods.Common.LoadScreens
|
|||||||
if (sheet == null && Info.ContainsKey("Image"))
|
if (sheet == null && Info.ContainsKey("Image"))
|
||||||
{
|
{
|
||||||
var key = "Image";
|
var key = "Image";
|
||||||
float sheetScale = 1;
|
density = 1;
|
||||||
if (dpiScale > 2 && Info.ContainsKey("Image3x"))
|
if (dpiScale > 2 && Info.ContainsKey("Image3x"))
|
||||||
{
|
{
|
||||||
key = "Image3x";
|
key = "Image3x";
|
||||||
sheetScale = 3;
|
density = 3;
|
||||||
}
|
}
|
||||||
else if (dpiScale > 1 && Info.ContainsKey("Image2x"))
|
else if (dpiScale > 1 && Info.ContainsKey("Image2x"))
|
||||||
{
|
{
|
||||||
key = "Image2x";
|
key = "Image2x";
|
||||||
sheetScale = 2;
|
density = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var stream = ModData.DefaultFileSystem.Open(Info[key]))
|
using (var stream = ModData.DefaultFileSystem.Open(Info[key]))
|
||||||
{
|
{
|
||||||
sheet = new Sheet(SheetType.BGRA, stream);
|
sheet = new Sheet(SheetType.BGRA, stream);
|
||||||
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
|
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
|
||||||
sheet.DPIScale = sheetScale;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.Renderer.BeginUI();
|
Game.Renderer.BeginUI();
|
||||||
DisplayInner(Game.Renderer, sheet);
|
DisplayInner(Game.Renderer, sheet, density);
|
||||||
Game.Renderer.EndFrame(new NullInputHandler());
|
Game.Renderer.EndFrame(new NullInputHandler());
|
||||||
|
|
||||||
lastUpdate.Restart();
|
lastUpdate.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static Sprite CreateSprite(Sheet s, int density, Rectangle rect)
|
||||||
|
{
|
||||||
|
return new Sprite(s, density * rect, TextureChannel.RGBA, 1f / density);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing && sheet != null)
|
if (disposing && sheet != null)
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(mixerSprite, RenderOrigin, new float2(RenderBounds.Size));
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(mixerSprite, RenderOrigin, new float2(RenderBounds.Size));
|
||||||
|
|
||||||
var sprite = ChromeProvider.GetImage("lobby-bits", "colorpicker");
|
var sprite = ChromeProvider.GetImage("lobby-bits", "colorpicker");
|
||||||
var pos = RenderOrigin + PxFromValue() - new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2;
|
var pos = RenderOrigin + PxFromValue() - new int2((int)sprite.Size.X, (int)sprite.Size.Y) / 2;
|
||||||
WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X + 1, pos.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), Color);
|
WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X + 1, pos.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), Color);
|
||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos);
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var image = ChromeProvider.GetImage("scrollbar", IsDisabled() ? "down_pressed" : "down_arrow");
|
var image = ChromeProvider.GetImage("scrollbar", IsDisabled() ? "down_pressed" : "down_arrow");
|
||||||
var rb = RenderBounds;
|
var rb = RenderBounds;
|
||||||
|
|
||||||
WidgetUtils.DrawRGBA(image, stateOffset + new float2((rb.Right - (rb.Height + image.Bounds.Width) / 2), rb.Top + (rb.Height - image.Bounds.Height) / 2));
|
WidgetUtils.DrawRGBA(image, stateOffset + new float2(rb.Right - (rb.Height + image.Size.X) / 2, rb.Top + (rb.Height - image.Size.Y) / 2));
|
||||||
|
|
||||||
var separator = ChromeProvider.GetImage(SeparatorCollection, SeparatorImage);
|
var separator = ChromeProvider.GetImage(SeparatorCollection, SeparatorImage);
|
||||||
WidgetUtils.DrawRGBA(separator, new float2(-3, 0) + new float2(rb.Right - rb.Height + 4, rb.Top + (rb.Height - separator.Bounds.Height) / 2));
|
WidgetUtils.DrawRGBA(separator, stateOffset + new float2(-3, 0) + new float2(rb.Right - rb.Height + 4, rb.Top + (rb.Height - separator.Size.Y) / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Widget Clone() { return new DropDownButtonWidget(this); }
|
public override Widget Clone() { return new DropDownButtonWidget(this); }
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(hueSprite, ro, new float2(rb.Size));
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(hueSprite, ro, new float2(rb.Size));
|
||||||
|
|
||||||
var sprite = ChromeProvider.GetImage("lobby-bits", "huepicker");
|
var sprite = ChromeProvider.GetImage("lobby-bits", "huepicker");
|
||||||
var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - sprite.Bounds.Width / 2, (rb.Height - sprite.Bounds.Height) / 2);
|
var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - (int)sprite.Size.X / 2, (rb.Height - (int)sprite.Size.Y) / 2);
|
||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos);
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
if (!orderManager.LocalClient.IsObserver && orderManager.LocalClient.State == Session.ClientState.Ready)
|
if (!orderManager.LocalClient.IsObserver && orderManager.LocalClient.State == Session.ClientState.Ready)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var spawnSize = new float2(ChromeProvider.GetImage("lobby-bits", "spawn-unclaimed").Bounds.Size);
|
var spawnSize = ChromeProvider.GetImage("lobby-bits", "spawn-unclaimed").Size.XY;
|
||||||
var selectedSpawn = preview.SpawnPoints
|
var selectedSpawn = preview.SpawnPoints
|
||||||
.Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp, preview.GridType), i))
|
.Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp, preview.GridType), i))
|
||||||
.Where(a => ((a.First - mi.Location).ToFloat2() / spawnSize * 2).LengthSquared <= 1)
|
.Where(a => ((a.First - mi.Location).ToFloat2() / spawnSize * 2).LengthSquared <= 1)
|
||||||
|
|||||||
@@ -191,10 +191,10 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
var owned = colors.ContainsKey(p);
|
var owned = colors.ContainsKey(p);
|
||||||
var pos = ConvertToPreview(p, gridType);
|
var pos = ConvertToPreview(p, gridType);
|
||||||
var sprite = owned ? spawnClaimed : spawnUnclaimed;
|
var sprite = owned ? spawnClaimed : spawnUnclaimed;
|
||||||
var offset = new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2;
|
var offset = sprite.Size.XY.ToInt2() / 2;
|
||||||
|
|
||||||
if (owned)
|
if (owned)
|
||||||
WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), colors[p]);
|
WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), colors[p]);
|
||||||
|
|
||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset);
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset);
|
||||||
var number = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString();
|
var number = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString();
|
||||||
|
|||||||
@@ -47,23 +47,28 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
public static void FillRectWithSprite(Rectangle r, Sprite s)
|
public static void FillRectWithSprite(Rectangle r, Sprite s)
|
||||||
{
|
{
|
||||||
for (var x = r.Left; x < r.Right; x += (int)s.Size.X)
|
var scale = s.Size.X / s.Bounds.Width;
|
||||||
for (var y = r.Top; y < r.Bottom; y += (int)s.Size.Y)
|
for (var x = (float)r.Left; x < r.Right; x += s.Size.X)
|
||||||
|
{
|
||||||
|
for (var y = (float)r.Top; y < r.Bottom; y += s.Size.Y)
|
||||||
{
|
{
|
||||||
var ss = s;
|
var ss = s;
|
||||||
var left = new int2(r.Right - x, r.Bottom - y);
|
var dx = r.Right - x;
|
||||||
if (left.X < (int)s.Size.X || left.Y < (int)s.Size.Y)
|
var dy = r.Bottom - y;
|
||||||
|
if (dx < s.Size.X || dy < s.Size.Y)
|
||||||
{
|
{
|
||||||
var rr = new Rectangle(s.Bounds.Left,
|
var rr = new Rectangle(
|
||||||
|
s.Bounds.Left,
|
||||||
s.Bounds.Top,
|
s.Bounds.Top,
|
||||||
Math.Min(left.X, (int)s.Size.X),
|
Math.Min(s.Bounds.Width, (int)(dx / scale)),
|
||||||
Math.Min(left.Y, (int)s.Size.Y));
|
Math.Min(s.Bounds.Height, (int)(dy / scale)));
|
||||||
ss = new Sprite(s.Sheet, rr, s.Channel);
|
ss = new Sprite(s.Sheet, rr, s.Channel, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawRGBA(ss, new float2(x, y));
|
DrawRGBA(ss, new float2(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void FillRectWithColor(Rectangle r, Color c)
|
public static void FillRectWithColor(Rectangle r, Color c)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user