Change DrawSprite calls to provide scales instead of sizes.

This allows us to remove a hacky workaround for calculating
depth offsets when sprites have size.Z == 0.
This commit is contained in:
Paul Chote
2021-07-24 20:56:51 +01:00
committed by reaperrr
parent 8e94e1d5ec
commit 70892a6661
12 changed files with 46 additions and 64 deletions

View File

@@ -196,17 +196,17 @@ namespace OpenRA.Graphics
// Render cursor in software
var doubleCursor = graphicSettings.CursorDouble;
var cursorSprite = cursor.Sprites[frame % cursor.Length];
var cursorSize = doubleCursor ? 2.0f * cursorSprite.Size : cursorSprite.Size;
var cursorScale = doubleCursor ? 2 : 1;
// Cursor is rendered in native window coordinates
// Apply same scaling rules as hardware cursors
if (Game.Renderer.NativeWindowScale > 1.5f)
cursorSize = 2 * cursorSize;
cursorScale *= 2;
var mousePos = isLocked ? lockedPosition : Viewport.LastMousePos;
renderer.RgbaSpriteRenderer.DrawSprite(cursorSprite,
mousePos,
cursorSize / Game.Renderer.WindowScale);
cursorScale / Game.Renderer.WindowScale);
}
public void Lock()

View File

@@ -22,36 +22,28 @@ namespace OpenRA.Graphics
this.parent = parent;
}
public void DrawSprite(Sprite s, in float3 location, in float3 size)
public void DrawSprite(Sprite s, in float3 location, in float3 scale)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, location, 0, size);
parent.DrawSprite(s, 0, location, scale);
}
public void DrawSprite(Sprite s, in float3 location)
public void DrawSprite(Sprite s, in float3 location, float scale = 1f)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, location, 0, s.Size);
parent.DrawSprite(s, 0, location, scale);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d)
public void DrawSprite(Sprite s, in float3 location, float scale, in float3 tint, float alpha)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, a, b, c, d);
}
public void DrawSprite(Sprite s, in float3 location, in float3 size, in float3 tint, float alpha)
{
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, location, 0, size, tint, alpha);
parent.DrawSprite(s, 0, location, scale, tint, alpha);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)
@@ -59,7 +51,7 @@ namespace OpenRA.Graphics
if (s.Channel != TextureChannel.RGBA)
throw new InvalidOperationException("DrawRGBASprite requires a RGBA sprite.");
parent.DrawSprite(s, a, b, c, d, tint, alpha);
parent.DrawSprite(s, 0, a, b, c, d, tint, alpha);
}
}
}

View File

@@ -23,7 +23,6 @@ namespace OpenRA.Graphics
public readonly float ZRamp;
public readonly float3 Size;
public readonly float3 Offset;
public readonly float3 FractionalOffset;
public readonly float Top, Left, Bottom, Right;
public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, float scale = 1)
@@ -38,8 +37,6 @@ namespace OpenRA.Graphics
Channel = channel;
Size = scale * new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp);
BlendMode = blendMode;
FractionalOffset = Size.Z != 0 ? offset / Size :
new float3(offset.X / Size.X, offset.Y / Size.Y, 0);
// Some GPUs suffer from precision issues when rendering into non 1:1 framebuffers that result
// in rendering a line of texels that sample outside the sprite rectangle.

View File

@@ -85,7 +85,7 @@ namespace OpenRA.Graphics
var contrastSprite = contrastGlyphs[(s, screenContrast)];
Game.Renderer.RgbaSpriteRenderer.DrawSprite(contrastSprite,
(screen + g.Offset - contrastVector) / deviceScale,
contrastSprite.Size / deviceScale,
1f / deviceScale,
tint, 1f);
}
@@ -116,7 +116,7 @@ namespace OpenRA.Graphics
if (g.Sprite != null)
Game.Renderer.RgbaSpriteRenderer.DrawSprite(g.Sprite,
(screen + g.Offset).ToFloat2() / deviceScale,
g.Sprite.Size / deviceScale,
1f / deviceScale,
tint, 1f);
screen += new int2((int)(g.Advance + 0.5f), 0);

View File

@@ -76,10 +76,7 @@ namespace OpenRA.Graphics
float3 ScreenPosition(WorldRenderer wr)
{
var xy = wr.ScreenPxPosition(pos) + wr.ScreenPxOffset(offset) - (0.5f * scale * sprite.Size.XY).ToInt2();
// HACK: The z offset needs to be applied somewhere, but this probably is the wrong place.
return new float3(xy, sprite.Offset.Z + wr.ScreenZPosition(pos, 0) - 0.5f * scale * sprite.Size.Z);
return wr.Screen3DPxPosition(pos) + wr.ScreenPxOffset(offset) - 0.5f * scale * sprite.Size;
}
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
@@ -95,7 +92,7 @@ namespace OpenRA.Graphics
if ((tintModifiers & TintModifiers.ReplaceColor) != 0)
a *= -1;
wsr.DrawSprite(sprite, ScreenPosition(wr), palette, scale * sprite.Size, t, a);
wsr.DrawSprite(sprite, palette, ScreenPosition(wr), scale, t, a);
}
public void RenderDebugGeometry(WorldRenderer wr)

View File

@@ -109,13 +109,6 @@ namespace OpenRA.Graphics
return new int2(sheetIndex, secondarySheetIndex);
}
internal void DrawSprite(Sprite s, in float3 location, float paletteTextureIndex, in float3 size)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, float3.Ones, 1f);
nv += 6;
}
float ResolveTextureIndex(Sprite s, PaletteReference pal)
{
if (pal == null)
@@ -130,39 +123,41 @@ namespace OpenRA.Graphics
return pal.TextureIndex;
}
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal)
{
DrawSprite(s, location, ResolveTextureIndex(s, pal), s.Size);
}
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal, float3 size)
{
DrawSprite(s, location, ResolveTextureIndex(s, pal), size);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, in float3 scale)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, float3.Ones, 1f, nv);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, 1f);
nv += 6;
}
internal void DrawSprite(Sprite s, in float3 location, float paletteTextureIndex, in float3 size, in float3 tint, float alpha)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, samplers, paletteTextureIndex, nv, size, tint, alpha);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, float3.Ones, 1f);
nv += 6;
}
public void DrawSprite(Sprite s, in float3 location, PaletteReference pal, in float3 size, in float3 tint, float alpha)
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale = 1f)
{
DrawSprite(s, location, ResolveTextureIndex(s, pal), size, tint, alpha);
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale);
}
public void DrawSprite(Sprite s, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 location, float scale, in float3 tint, float alpha)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, 0, tint, alpha, nv);
Util.FastCreateQuad(vertices, location + scale * s.Offset, s, samplers, paletteTextureIndex, nv, scale * s.Size, tint, alpha);
nv += 6;
}
public void DrawSprite(Sprite s, PaletteReference pal, in float3 location, float scale, in float3 tint, float alpha)
{
DrawSprite(s, ResolveTextureIndex(s, pal), location, scale, tint, alpha);
}
internal void DrawSprite(Sprite s, float paletteTextureIndex, in float3 a, in float3 b, in float3 c, in float3 d, in float3 tint, float alpha)
{
var samplers = SetRenderStateForSprite(s);
Util.FastCreateQuad(vertices, a, b, c, d, s, samplers, paletteTextureIndex, tint, alpha, nv);
nv += 6;
}

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Graphics
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
public void Render(WorldRenderer wr)
{
Game.Renderer.SpriteRenderer.DrawSprite(sprite, screenPos, palette, scale * sprite.Size, float3.Ones, alpha);
Game.Renderer.SpriteRenderer.DrawSprite(sprite, palette, screenPos, scale, float3.Ones, alpha);
}
public void RenderDebugGeometry(WorldRenderer wr)

View File

@@ -274,10 +274,10 @@ namespace OpenRA
screenBuffer.Bind();
var scale = Window.EffectiveWindowScale;
var bufferSize = new float2((int)(screenSprite.Bounds.Width / scale), (int)(-screenSprite.Bounds.Height / scale));
var bufferScale = new float3((int)(screenSprite.Bounds.Width / scale) / worldSprite.Size.X, (int)(-screenSprite.Bounds.Height / scale) / worldSprite.Size.Y, 1f);
SpriteRenderer.SetAntialiasingPixelsPerTexel(Window.SurfaceSize.Height * 1f / worldSprite.Bounds.Height);
RgbaSpriteRenderer.DrawSprite(worldSprite, float3.Zero, bufferSize);
RgbaSpriteRenderer.DrawSprite(worldSprite, float3.Zero, bufferScale);
Flush();
SpriteRenderer.SetAntialiasingPixelsPerTexel(0);
}
@@ -318,7 +318,7 @@ namespace OpenRA
// Render the compositor buffers to the screen
// HACK / PERF: Fudge the coordinates to cover the actual window while keeping the buffer viewport parameters
// This saves us two redundant (and expensive) SetViewportParams each frame
RgbaSpriteRenderer.DrawSprite(screenSprite, new float3(0, lastBufferSize.Height, 0), new float3(lastBufferSize.Width, -lastBufferSize.Height, 0));
RgbaSpriteRenderer.DrawSprite(screenSprite, new float3(0, lastBufferSize.Height, 0), new float3(lastBufferSize.Width / screenSprite.Size.X, -lastBufferSize.Height / screenSprite.Size.Y, 1f));
Flush();
Window.PumpInput(inputHandler);

View File

@@ -170,7 +170,7 @@ namespace OpenRA.Mods.Common.Graphics
a *= -1;
wrsr.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd, t, a);
wrsr.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size, renderProxy.Sprite.Size, t, a);
wrsr.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size, 1f, t, a);
}
public void RenderDebugGeometry(WorldRenderer wr)

View File

@@ -98,7 +98,7 @@ namespace OpenRA.Mods.Common.Graphics
var sb = pxOrigin + psb[2];
var sc = pxOrigin + psb[1];
var sd = pxOrigin + psb[3];
Game.Renderer.RgbaSpriteRenderer.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd, float3.Ones, 1f);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size);
}

View File

@@ -77,9 +77,8 @@ namespace OpenRA.Mods.Common.Widgets
cachedScale = scale;
}
var size = new float2(sprite.Size.X * scale, sprite.Size.Y * scale);
Game.Renderer.EnableAntialiasingFilter();
Game.Renderer.SpriteRenderer.DrawSprite(sprite, RenderOrigin + offset, pr, size);
Game.Renderer.SpriteRenderer.DrawSprite(sprite, pr, RenderOrigin + offset, scale);
Game.Renderer.DisableAntialiasingFilter();
}
}

View File

@@ -48,17 +48,19 @@ namespace OpenRA.Mods.Common.Widgets
public static void DrawSprite(Sprite s, float2 pos, Size size)
{
Game.Renderer.RgbaSpriteRenderer.DrawSprite(s, pos, new float2(size));
var scale = new float3(size.Width / s.Size.X, size.Height / s.Size.Y, 1f);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(s, pos, scale);
}
public static void DrawSprite(Sprite s, float2 pos, float2 size)
{
Game.Renderer.RgbaSpriteRenderer.DrawSprite(s, pos, size);
var scale = new float3(size.X / s.Size.X, size.Y / s.Size.Y, 1f);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(s, pos, scale);
}
public static void DrawSpriteCentered(Sprite s, PaletteReference p, float2 pos, float scale = 1f)
{
Game.Renderer.SpriteRenderer.DrawSprite(s, pos - 0.5f * scale * s.Size, p, scale * s.Size);
Game.Renderer.SpriteRenderer.DrawSprite(s, p, pos - 0.5f * scale * s.Size, scale);
}
public static void DrawPanel(string collection, Rectangle bounds)