Support custom zoom levels

This commit is contained in:
Paul Chote
2011-06-03 20:23:21 +12:00
parent 926b396605
commit fc783ddf80
12 changed files with 55 additions and 55 deletions

View File

@@ -143,7 +143,7 @@ namespace OpenRA
{ {
++RenderFrame; ++RenderFrame;
viewport.DrawRegions(worldRenderer, new DefaultInputHandler( orderManager.world )); viewport.DrawRegions(worldRenderer, new DefaultInputHandler( orderManager.world ));
Sound.SetListenerPosition(viewport.Location + .5f * new float2(viewport.Width, viewport.Height)); Sound.SetListenerPosition(viewport.CenterLocation);
} }
PerfHistory.items["render"].Tick(); PerfHistory.items["render"].Tick();

View File

@@ -73,15 +73,15 @@ namespace OpenRA.Graphics
internal IGraphicsDevice Device { get { return device; } } internal IGraphicsDevice Device { get { return device; } }
public void BeginFrame(float2 scroll) public void BeginFrame(float2 scroll, float zoom)
{ {
device.Clear(Color.Black); device.Clear(Color.Black);
float2 r1 = new float2(2f/Resolution.Width, -2f/Resolution.Height); float2 r1 = new float2(2f/Resolution.Width, -2f/Resolution.Height);
float2 r2 = new float2(-1, 1); float2 r2 = new float2(-1, 1);
var zr1 = zoom*r1;
SetShaderParams( WorldSpriteShader, r1, r2, scroll ); SetShaderParams( WorldSpriteShader, zr1, r2, scroll );
SetShaderParams( WorldLineShader, r1, r2, scroll ); SetShaderParams( WorldLineShader, zr1, r2, scroll );
SetShaderParams( LineShader, r1, r2, scroll ); SetShaderParams( LineShader, r1, r2, scroll );
SetShaderParams( RgbaSpriteShader, r1, r2, scroll ); SetShaderParams( RgbaSpriteShader, r1, r2, scroll );
SetShaderParams( SpriteShader, r1, r2, scroll ); SetShaderParams( SpriteShader, r1, r2, scroll );

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Graphics
{ {
int verticesPerRow = map.Bounds.Width * 4; int verticesPerRow = map.Bounds.Width * 4;
int visibleRows = (int)(viewport.Height * 1f / Game.CellSize + 2); int visibleRows = (int)(viewport.Height * 1f / Game.CellSize / viewport.Zoom + 2);
int firstRow = (int)(viewport.Location.Y * 1f / Game.CellSize - map.Bounds.Top); int firstRow = (int)(viewport.Location.Y * 1f / Game.CellSize - map.Bounds.Top);
int lastRow = firstRow + visibleRows; int lastRow = firstRow + visibleRows;

View File

@@ -34,10 +34,13 @@ namespace OpenRA.Graphics
readonly Renderer renderer; readonly Renderer renderer;
readonly Rectangle adjustedMapBounds; readonly Rectangle adjustedMapBounds;
// Top-left of the viewport, in world-px units
public float2 Location { get { return scrollPosition; } } public float2 Location { get { return scrollPosition; } }
public float2 CenterLocation { get { return scrollPosition + 0.5f/Zoom*screenSize.ToFloat2(); } }
public int Width { get { return screenSize.X; } } public int Width { get { return screenSize.X; } }
public int Height { get { return screenSize.Y; } } public int Height { get { return screenSize.Y; } }
public float Zoom = 1f;
float cursorFrame = 0f; float cursorFrame = 0f;
@@ -51,7 +54,8 @@ namespace OpenRA.Graphics
public void Scroll(float2 delta, bool ignoreBorders) public void Scroll(float2 delta, bool ignoreBorders)
{ {
var d = delta.ToInt2(); // Convert from world-px to viewport-px
var d = (1f/Zoom*delta).ToInt2();
var newScrollPosition = scrollPosition + d; var newScrollPosition = scrollPosition + d;
if(!ignoreBorders) if(!ignoreBorders)
@@ -88,7 +92,7 @@ namespace OpenRA.Graphics
public void DrawRegions( WorldRenderer wr, IInputHandler inputHandler ) public void DrawRegions( WorldRenderer wr, IInputHandler inputHandler )
{ {
renderer.BeginFrame(scrollPosition); renderer.BeginFrame(scrollPosition, Zoom);
if (wr != null) if (wr != null)
wr.Draw(); wr.Draw();
@@ -116,22 +120,19 @@ namespace OpenRA.Graphics
cursorFrame += 0.5f; cursorFrame += 0.5f;
} }
// Convert from viewport coords to cell coords (not px)
public float2 ViewToWorld(MouseInput mi) { return ViewToWorld(mi.Location); }
public float2 ViewToWorld(int2 loc) public float2 ViewToWorld(int2 loc)
{ {
return (1f / Game.CellSize) * (loc.ToFloat2() + Location); return (1f / Game.CellSize) * (1f/Zoom*loc.ToFloat2() + Location);
} }
public float2 ViewToWorld(MouseInput mi) public int2 ViewToWorldPx(int2 loc) { return (1f/Zoom*loc.ToFloat2() + Location).ToInt2(); }
{
return ViewToWorld(mi.Location);
}
public int2 ViewToWorldPx(int2 loc) { return loc + Location.ToInt2(); }
public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); } public int2 ViewToWorldPx(MouseInput mi) { return ViewToWorldPx(mi.Location); }
public void Center(float2 loc) public void Center(float2 loc)
{ {
scrollPosition = this.NormalizeScrollPosition((Game.CellSize*loc - screenSize / 2).ToInt2()); scrollPosition = this.NormalizeScrollPosition((Game.CellSize*loc - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
} }
public void Center(IEnumerable<Actor> actors) public void Center(IEnumerable<Actor> actors)
@@ -141,27 +142,26 @@ namespace OpenRA.Graphics
var avgPos = actors var avgPos = actors
.Select(a => a.CenterLocation) .Select(a => a.CenterLocation)
.Aggregate((a, b) => a + b) / actors.Count(); .Aggregate((a, b) => a + b) / actors.Count();
scrollPosition = this.NormalizeScrollPosition((avgPos - screenSize / 2)); scrollPosition = this.NormalizeScrollPosition((avgPos - 1f/(2*Zoom)*screenSize.ToFloat2()).ToInt2());
} }
// Rectangle (in viewport coords) that contains things to be drawn
public Rectangle ViewBounds(World world) public Rectangle ViewBounds(World world)
{ {
var r = WorldBounds(world); var r = WorldBounds(world);
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X); var origin = Location.ToInt2();
var top = (int)(Game.CellSize * r.Top - Game.viewport.Location.Y); var left = Math.Max(0, Game.CellSize * r.Left - origin.X)*Zoom;
var right = left + (int)(Game.CellSize * r.Width); var top = Math.Max(0, Game.CellSize * r.Top - origin.Y)*Zoom;
var bottom = top + (int)(Game.CellSize * r.Height); var right = Math.Min((Game.CellSize * r.Right - origin.X) * Zoom, Width);
var bottom = Math.Min((Game.CellSize * r.Bottom - origin.Y) * Zoom, Height);
if (left < 0) left = 0; return Rectangle.FromLTRB((int)left, (int)top, (int)right, (int)bottom);
if (top < 0) top = 0;
if (right > Game.viewport.Width) right = Game.viewport.Width;
if (bottom > Game.viewport.Height) bottom = Game.viewport.Height;
return new Rectangle(left, top, right - left, bottom - top);
} }
int2 cachedScroll = new int2(int.MaxValue, int.MaxValue); int2 cachedScroll = new int2(int.MaxValue, int.MaxValue);
Rectangle cachedRect; Rectangle cachedRect;
// Rectangle (in cell coords) of cells that are currently visible on the screen
public Rectangle WorldBounds(World world) public Rectangle WorldBounds(World world)
{ {
if (cachedScroll != scrollPosition) if (cachedScroll != scrollPosition)
@@ -169,6 +169,7 @@ namespace OpenRA.Graphics
int2 boundary = new int2(1,1); // Add a curtain of cells around the viewport to account for rounding errors int2 boundary = new int2(1,1); // Add a curtain of cells around the viewport to account for rounding errors
var tl = ViewToWorld(int2.Zero).ToInt2() - boundary; var tl = ViewToWorld(int2.Zero).ToInt2() - boundary;
var br = ViewToWorld(new int2(Width, Height)).ToInt2() + boundary; var br = ViewToWorld(new int2(Width, Height)).ToInt2() + boundary;
cachedRect = Rectangle.Intersect(Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y), world.Map.Bounds); cachedRect = Rectangle.Intersect(Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y), world.Map.Bounds);
cachedScroll = scrollPosition; cachedScroll = scrollPosition;
} }

View File

@@ -52,14 +52,12 @@ namespace OpenRA.Graphics
IEnumerable<Renderable> SpritesToRender() IEnumerable<Renderable> SpritesToRender()
{ {
var bounds = Game.viewport.ViewBounds(world); var bounds = Game.viewport.WorldBounds(world);
var comparer = new SpriteComparer(); var comparer = new SpriteComparer();
bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y);
var actors = world.FindUnits( var actors = world.FindUnits(
new int2(bounds.Left, bounds.Top), new int2(Game.CellSize*bounds.Left, Game.CellSize*bounds.Top),
new int2(bounds.Right, bounds.Bottom)); new int2(Game.CellSize*bounds.Right, Game.CellSize*bounds.Bottom));
var renderables = actors.SelectMany(a => a.Render()) var renderables = actors.SelectMany(a => a.Render())
.OrderBy(r => r, comparer); .OrderBy(r => r, comparer);

View File

@@ -48,9 +48,7 @@ namespace OpenRA.Traits
float GetIntensity() float GetIntensity()
{ {
var cp = Game.viewport.Location var cp = Game.viewport.CenterLocation;
+ .5f * new float2(Game.viewport.Width, Game.viewport.Height);
var intensity = Game.CellSize * Game.CellSize * 100 * shakeEffects.Sum( var intensity = Game.CellSize * Game.CellSize * 100 * shakeEffects.Sum(
e => e.Intensity / (e.Position - cp).LengthSquared); e => e.Intensity / (e.Position - cp).LengthSquared);

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Cnc
loadTimer.Reset(); loadTimer.Reset();
loadTick = ++loadTick % 8; loadTick = ++loadTick % 8;
r.BeginFrame(float2.Zero); r.BeginFrame(float2.Zero, 1f);
r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos); r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos);
r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos); r.RgbaSpriteRenderer.DrawSprite(nodLogo, nodPos);
r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos); r.RgbaSpriteRenderer.DrawSprite(evaLogo, evaPos);

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Effects
string s; string s;
int remaining; int remaining;
int velocity; int velocity;
float2 pos; float2 pos, offset;
Color color; Color color;
public CashTick(int value, int lifetime, int velocity, float2 pos, Color color) public CashTick(int value, int lifetime, int velocity, float2 pos, Color color)
@@ -28,7 +28,8 @@ namespace OpenRA.Mods.RA.Effects
this.color = color; this.color = color;
this.velocity = velocity; this.velocity = velocity;
s = "{0}${1}".F(value < 0 ? "-" : "+", value); s = "{0}${1}".F(value < 0 ? "-" : "+", value);
this.pos = pos - 0.5f*Game.Renderer.Fonts["TinyBold"].Measure(s).ToFloat2(); this.pos = pos;
offset = 0.5f*Game.Renderer.Fonts["TinyBold"].Measure(s).ToFloat2();
remaining = lifetime; remaining = lifetime;
} }
@@ -41,7 +42,7 @@ namespace OpenRA.Mods.RA.Effects
public IEnumerable<Renderable> Render() public IEnumerable<Renderable> Render()
{ {
Game.Renderer.Fonts["TinyBold"].DrawTextWithContrast(s, pos - Game.viewport.Location, color, Color.Black,1); Game.Renderer.Fonts["TinyBold"].DrawTextWithContrast(s, Game.viewport.Zoom*(pos - Game.viewport.Location) - offset, color, Color.Black,1);
yield break; yield break;
} }
} }

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.RA
return; return;
// Draw a black screen // Draw a black screen
Game.Renderer.BeginFrame(float2.Zero); Game.Renderer.BeginFrame(float2.Zero, 1f);
Game.Renderer.EndFrame( new NullInputHandler() ); Game.Renderer.EndFrame( new NullInputHandler() );
} }

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA
var text = Comments.Random(Game.CosmeticRandom); var text = Comments.Random(Game.CosmeticRandom);
var textSize = r.Fonts["Bold"].Measure(text); var textSize = r.Fonts["Bold"].Measure(text);
r.BeginFrame(float2.Zero); r.BeginFrame(float2.Zero, 1f);
WidgetUtils.FillRectWithSprite(StripeRect, Stripe); WidgetUtils.FillRectWithSprite(StripeRect, Stripe);
r.RgbaSpriteRenderer.DrawSprite(Logo, LogoPos); r.RgbaSpriteRenderer.DrawSprite(Logo, LogoPos);
r.Fonts["Bold"].DrawText(text, new float2(Renderer.Resolution.Width - textSize.X - 20, Renderer.Resolution.Height - textSize.Y - 20), Color.White); r.Fonts["Bold"].DrawText(text, new float2(Renderer.Resolution.Width - textSize.X - 20, Renderer.Resolution.Height - textSize.Y - 20), Color.White);

View File

@@ -129,27 +129,28 @@ namespace OpenRA.Mods.RA.Widgets
if( world == null || world.LocalPlayer == null ) return; if( world == null || world.LocalPlayer == null ) return;
radarCollection = "radar-" + world.LocalPlayer.Country.Race; radarCollection = "radar-" + world.LocalPlayer.Country.Race;
var rsr = Game.Renderer.RgbaSpriteRenderer;
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "left"), radarOrigin); rsr.DrawSprite(ChromeProvider.GetImage(radarCollection, "left"), radarOrigin);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "right"), radarOrigin + new float2(201, 0)); rsr.DrawSprite(ChromeProvider.GetImage(radarCollection, "right"), radarOrigin + new float2(201, 0));
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "bottom"), radarOrigin + new float2(0, 192)); rsr.DrawSprite(ChromeProvider.GetImage(radarCollection, "bottom"), radarOrigin + new float2(0, 192));
Game.Renderer.RgbaSpriteRenderer.DrawSprite(ChromeProvider.GetImage(radarCollection, "bg"), radarOrigin + new float2(9, 0)); rsr.DrawSprite(ChromeProvider.GetImage(radarCollection, "bg"), radarOrigin + new float2(9, 0));
// Don't draw the radar if the tray is moving // Don't draw the radar if the tray is moving
if (radarAnimationFrame >= radarSlideAnimationLength) if (radarAnimationFrame >= radarSlideAnimationLength)
{ {
var o = new float2(mapRect.Location.X, mapRect.Location.Y + world.Map.Bounds.Height * previewScale * (1 - radarMinimapHeight)/2); var o = new float2(mapRect.Location.X, mapRect.Location.Y + world.Map.Bounds.Height * previewScale * (1 - radarMinimapHeight)/2);
var s = new float2(mapRect.Size.Width, mapRect.Size.Height*radarMinimapHeight); var s = new float2(mapRect.Size.Width, mapRect.Size.Height*radarMinimapHeight);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(terrainSprite, o, s); rsr.DrawSprite(terrainSprite, o, s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(customTerrainSprite, o, s); rsr.DrawSprite(customTerrainSprite, o, s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(actorSprite, o, s); rsr.DrawSprite(actorSprite, o, s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(shroudSprite, o, s); rsr.DrawSprite(shroudSprite, o, s);
// Draw viewport rect // Draw viewport rect
if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength) if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength)
{ {
var tl = CellToMinimapPixel(new int2((int)(Game.viewport.Location.X/Game.CellSize), (int)(Game.viewport.Location.Y/Game.CellSize))); var tl = CellToMinimapPixel(new int2((int)(Game.viewport.Location.X/Game.CellSize), (int)(Game.viewport.Location.Y/Game.CellSize)));
var br = CellToMinimapPixel(new int2((int)((Game.viewport.Location.X + Game.viewport.Width)/Game.CellSize), (int)((Game.viewport.Location.Y + Game.viewport.Height)/Game.CellSize))); var br = CellToMinimapPixel(new int2((int)((Game.viewport.Location.X + Game.viewport.Width)/Game.CellSize), (int)((Game.viewport.Location.Y + Game.viewport.Height)/Game.CellSize)));
Game.Renderer.EnableScissor((int)mapRect.Left, (int)mapRect.Top, (int)mapRect.Width, (int)mapRect.Height); Game.Renderer.EnableScissor((int)mapRect.Left, (int)mapRect.Top, (int)mapRect.Width, (int)mapRect.Height);
Game.Renderer.LineRenderer.DrawRect(tl, br, Color.White); Game.Renderer.LineRenderer.DrawRect(tl, br, Color.White);
Game.Renderer.DisableScissor(); Game.Renderer.DisableScissor();

View File

@@ -129,10 +129,11 @@ namespace OpenRA.Mods.RA.Widgets
var o = new float2(mapRect.Location.X, mapRect.Location.Y + world.Map.Bounds.Height * previewScale * (1 - radarMinimapHeight)/2); var o = new float2(mapRect.Location.X, mapRect.Location.Y + world.Map.Bounds.Height * previewScale * (1 - radarMinimapHeight)/2);
var s = new float2(mapRect.Size.Width, mapRect.Size.Height*radarMinimapHeight); var s = new float2(mapRect.Size.Width, mapRect.Size.Height*radarMinimapHeight);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(terrainSprite, o, s); var rsr = Game.Renderer.RgbaSpriteRenderer;
Game.Renderer.RgbaSpriteRenderer.DrawSprite(customTerrainSprite, o, s); rsr.DrawSprite(terrainSprite, o, s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(actorSprite, o, s); rsr.DrawSprite(customTerrainSprite, o, s);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(shroudSprite, o, s); rsr.DrawSprite(actorSprite, o, s);
rsr.DrawSprite(shroudSprite, o, s);
// Draw viewport rect // Draw viewport rect
if (hasRadar && !Animating) if (hasRadar && !Animating)