Consolidate viewport clip calculations into one place (except for TerrainRenderer, but changing that calculation crashes my gfx card).

This commit is contained in:
Paul Chote
2010-11-26 18:23:13 +13:00
parent 7c5c989eb2
commit fb0e399ab9
8 changed files with 43 additions and 68 deletions

View File

@@ -136,8 +136,6 @@ namespace OpenRA.Graphics
{ {
int* c = (int*)bitmapData.Scan0; int* c = (int*)bitmapData.Scan0;
var player = world.LocalPlayer;
foreach (var t in world.Queries.WithTraitMultiple<IRadarSignature>()) foreach (var t in world.Queries.WithTraitMultiple<IRadarSignature>())
{ {
if (!world.LocalShroud.IsVisible(t.Actor)) if (!world.LocalShroud.IsVisible(t.Actor))

View File

@@ -122,20 +122,30 @@ namespace OpenRA.Graphics
scrollPosition = this.NormalizeScrollPosition((avgPos.ToInt2() - screenSize / 2)); scrollPosition = this.NormalizeScrollPosition((avgPos.ToInt2() - screenSize / 2));
} }
public Rectangle ShroudBounds( World world )
{
if( world.LocalShroud.Disabled || !world.LocalShroud.Bounds.HasValue )
return world.Map.Bounds;
return Rectangle.Intersect( world.LocalShroud.Bounds.Value, world.Map.Bounds );
}
public Rectangle ViewBounds() public Rectangle ViewBounds(World world)
{
var r = WorldBounds(world);
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X);
var top = (int)(Game.CellSize * r.Top - Game.viewport.Location.Y);
var right = left + (int)(Game.CellSize * r.Width);
var bottom = top + (int)(Game.CellSize * r.Height);
if (left < 0) left = 0;
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);
}
public Rectangle WorldBounds(World world)
{ {
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;
return Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y); var view = Rectangle.Intersect(Rectangle.FromLTRB(tl.X, tl.Y, br.X, br.Y), world.Map.Bounds);
var b = world.LocalShroud.Bounds;
return (b.HasValue) ? Rectangle.Intersect(view, b.Value) : view;
} }
} }
} }

View File

@@ -51,27 +51,9 @@ namespace OpenRA.Graphics
} }
} }
Rectangle GetBoundsRect()
{
var r = (!world.LocalShroud.Disabled && world.LocalShroud.Bounds.HasValue)?
Rectangle.Intersect(world.LocalShroud.Bounds.Value,world.Map.Bounds) : world.Map.Bounds;
var left = (int)(Game.CellSize * r.Left - Game.viewport.Location.X);
var top = (int)(Game.CellSize * r.Top - Game.viewport.Location.Y);
var right = left + (int)(Game.CellSize * r.Width);
var bottom = top + (int)(Game.CellSize * r.Height);
if (left < 0) left = 0;
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);
}
IEnumerable<Renderable> SpritesToRender() IEnumerable<Renderable> SpritesToRender()
{ {
var bounds = GetBoundsRect(); var bounds = Game.viewport.ViewBounds(world);
var comparer = new SpriteComparer(); var comparer = new SpriteComparer();
bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y); bounds.Offset((int)Game.viewport.Location.X, (int)Game.viewport.Location.Y);
@@ -91,7 +73,7 @@ namespace OpenRA.Graphics
public void Draw() public void Draw()
{ {
RefreshPalette(); RefreshPalette();
var bounds = GetBoundsRect(); var bounds = Game.viewport.ViewBounds(world);
Game.Renderer.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height); Game.Renderer.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height);
terrainRenderer.Draw(this, Game.viewport); terrainRenderer.Draw(this, Game.viewport);

View File

@@ -116,25 +116,19 @@ namespace OpenRA
fogSprites[i, j] = ChooseFog(i, j); fogSprites[i, j] = ChooseFog(i, j);
} }
var clipRect = (shroud != null && shroud.Bounds.HasValue) ? Rectangle.Intersect(shroud.Bounds.Value, map.Bounds) : map.Bounds; var clipRect = Game.viewport.WorldBounds(wr.world);
clipRect = Rectangle.Intersect(Game.viewport.ViewBounds(), clipRect); DrawShroud( wr, clipRect, fogSprites, "fog" );
var miny = clipRect.Top; DrawShroud( wr, clipRect, sprites, "shroud" );
var maxy = clipRect.Bottom;
var minx = clipRect.Left;
var maxx = clipRect.Right;
DrawShroud( wr, minx, miny, maxx, maxy, fogSprites, "fog" );
DrawShroud( wr, minx, miny, maxx, maxy, sprites, "shroud" );
} }
void DrawShroud( WorldRenderer wr, int minx, int miny, int maxx, int maxy, Sprite[,] s, string pal ) void DrawShroud( WorldRenderer wr, Rectangle clip, Sprite[,] s, string pal )
{ {
var shroudPalette = wr.GetPaletteIndex(pal); var shroudPalette = wr.GetPaletteIndex(pal);
for (var j = miny; j < maxy; j++) for (var j = clip.Top; j < clip.Bottom; j++)
{ {
var starti = minx; var starti = clip.Left;
for (var i = minx; i < maxx; i++) for (var i = clip.Left; i < clip.Right; i++)
{ {
if (s[i, j] == shadowBits[0x0f]) if (s[i, j] == shadowBits[0x0f])
continue; continue;
@@ -154,11 +148,11 @@ namespace OpenRA
starti = i + 1; starti = i + 1;
} }
if (starti < maxx) if (starti < clip.Right)
s[starti, j].DrawAt( s[starti, j].DrawAt(
Game.CellSize * new float2(starti, j), Game.CellSize * new float2(starti, j),
shroudPalette, shroudPalette,
new float2(Game.CellSize * (maxx - starti), Game.CellSize)); new float2(Game.CellSize * (clip.Right - starti), Game.CellSize));
} }
} }
} }

View File

@@ -26,20 +26,12 @@ namespace OpenRA.Traits
public void Render( WorldRenderer wr ) public void Render( WorldRenderer wr )
{ {
var cliprect = Game.viewport.ShroudBounds( world );
cliprect = Rectangle.Intersect(Game.viewport.ViewBounds(), cliprect);
var minx = cliprect.Left;
var maxx = cliprect.Right;
var miny = cliprect.Top;
var maxy = cliprect.Bottom;
foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() ) foreach( var rt in world.WorldActor.TraitsImplementing<ResourceType>() )
rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette); rt.info.PaletteIndex = wr.GetPaletteIndex(rt.info.Palette);
for (int x = minx; x < maxx; x++) var clip = Game.viewport.WorldBounds(world);
for (int y = miny; y < maxy; y++) for (int x = clip.Left; x < clip.Right; x++)
for (int y = clip.Top; y < clip.Bottom; y++)
{ {
if (!world.LocalShroud.IsExplored(new int2(x, y))) if (!world.LocalShroud.IsExplored(new int2(x, y)))
continue; continue;

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Traits
public int[,] visibleCells; public int[,] visibleCells;
public bool[,] exploredCells; public bool[,] exploredCells;
public Rectangle? exploredBounds; Rectangle? exploredBounds;
bool disabled = false; bool disabled = false;
public bool Disabled public bool Disabled
{ {
@@ -34,7 +34,11 @@ namespace OpenRA.Traits
set { disabled = value; Dirty(); } set { disabled = value; Dirty(); }
} }
public Rectangle? Bounds { get { return exploredBounds; } } public Rectangle? Bounds
{
get { return !disabled ? exploredBounds : null; }
}
public event Action Dirty = () => { }; public event Action Dirty = () => { };
public Shroud(World world) public Shroud(World world)
@@ -42,7 +46,6 @@ namespace OpenRA.Traits
map = world.Map; map = world.Map;
visibleCells = new int[map.MapSize.X, map.MapSize.Y]; visibleCells = new int[map.MapSize.X, map.MapSize.Y];
exploredCells = new bool[map.MapSize.X, map.MapSize.Y]; exploredCells = new bool[map.MapSize.X, map.MapSize.Y];
world.ActorAdded += AddActor; world.ActorAdded += AddActor;
world.ActorRemoved += RemoveActor; world.ActorRemoved += RemoveActor;
} }
@@ -98,8 +101,7 @@ namespace OpenRA.Traits
} }
var box = new Rectangle(p.X - v.range, p.Y - v.range, 2 * v.range + 1, 2 * v.range + 1); var box = new Rectangle(p.X - v.range, p.Y - v.range, 2 * v.range + 1, 2 * v.range + 1);
exploredBounds = exploredBounds.HasValue ? exploredBounds = (exploredBounds.HasValue) ? Rectangle.Union(exploredBounds.Value, box) : box;
Rectangle.Union(exploredBounds.Value, box) : box;
} }
vis[a] = v; vis[a] = v;
@@ -165,8 +167,7 @@ namespace OpenRA.Traits
exploredCells[q.X, q.Y] = true; exploredCells[q.X, q.Y] = true;
var box = new Rectangle(center.X - range, center.Y - range, 2 * range + 1, 2 * range + 1); var box = new Rectangle(center.X - range, center.Y - range, 2 * range + 1, 2 * range + 1);
exploredBounds = exploredBounds.HasValue ? exploredBounds = (exploredBounds.HasValue) ? Rectangle.Union(exploredBounds.Value, box) : box;
Rectangle.Union(exploredBounds.Value, box) : box;
Dirty(); Dirty();
} }

View File

@@ -74,8 +74,7 @@ namespace OpenRA.Mods.RA.Buildings
public void Render( WorldRenderer wr ) public void Render( WorldRenderer wr )
{ {
var cliprect = Game.viewport.ShroudBounds( world ); var cliprect = Game.viewport.WorldBounds(world);
cliprect = Rectangle.Intersect(Game.viewport.ViewBounds(), cliprect);
foreach (var kv in tiles) foreach (var kv in tiles)
{ {
if (!cliprect.Contains(kv.Key.X, kv.Key.Y)) if (!cliprect.Contains(kv.Key.X, kv.Key.Y))

View File

@@ -75,8 +75,7 @@ namespace OpenRA.Mods.RA
public void Render( WorldRenderer wr ) public void Render( WorldRenderer wr )
{ {
var cliprect = Game.viewport.ShroudBounds( world ); var cliprect = Game.viewport.WorldBounds(world);
cliprect = Rectangle.Intersect(Game.viewport.ViewBounds(), cliprect);
var localPlayer = world.LocalPlayer; var localPlayer = world.LocalPlayer;
foreach (var kv in tiles) foreach (var kv in tiles)
{ {