Support nested scissor rectangles.

This commit is contained in:
Paul Chote
2013-10-23 18:40:04 +13:00
parent b31daf23ca
commit 94554d7678
8 changed files with 28 additions and 12 deletions

View File

@@ -39,12 +39,14 @@ namespace OpenRA.Graphics
Queue<IVertexBuffer<Vertex>> tempBuffers = new Queue<IVertexBuffer<Vertex>>(); Queue<IVertexBuffer<Vertex>> tempBuffers = new Queue<IVertexBuffer<Vertex>>();
public Dictionary<string, SpriteFont> Fonts; public Dictionary<string, SpriteFont> Fonts;
Stack<Rectangle> scissorState;
public Renderer() public Renderer()
{ {
TempBufferSize = Game.Settings.Graphics.BatchSize; TempBufferSize = Game.Settings.Graphics.BatchSize;
TempBufferCount = Game.Settings.Graphics.NumTempBuffers; TempBufferCount = Game.Settings.Graphics.NumTempBuffers;
SheetSize = Game.Settings.Graphics.SheetSize; SheetSize = Game.Settings.Graphics.SheetSize;
scissorState = new Stack<Rectangle>();
WorldSpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp")); WorldSpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp"));
WorldRgbaSpriteRenderer = new SpriteRenderer(this, device.CreateShader("rgba")); WorldRgbaSpriteRenderer = new SpriteRenderer(this, device.CreateShader("rgba"));
@@ -183,16 +185,30 @@ namespace OpenRA.Graphics
} }
} }
public void EnableScissor(int left, int top, int width, int height) public void EnableScissor(Rectangle rect)
{ {
// Must remain inside the current scissor rect
if (scissorState.Any())
rect.Intersect(scissorState.Peek());
Flush(); Flush();
Device.EnableScissor(left, top, width, height); Device.EnableScissor(rect.Left, rect.Top, rect.Width, rect.Height);
scissorState.Push(rect);
} }
public void DisableScissor() public void DisableScissor()
{ {
scissorState.Pop();
Flush(); Flush();
Device.DisableScissor();
// Restore previous scissor rect
if (scissorState.Any())
{
var rect = scissorState.Peek();
Device.EnableScissor(rect.Left, rect.Top, rect.Width, rect.Height);
}
else
Device.DisableScissor();
} }
public void EnableDepthBuffer() public void EnableDepthBuffer()

View File

@@ -115,7 +115,7 @@ namespace OpenRA.Graphics
var renderables = GenerateRenderables(); var renderables = GenerateRenderables();
var bounds = Viewport.ScissorBounds; var bounds = Viewport.ScissorBounds;
Game.Renderer.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height); Game.Renderer.EnableScissor(bounds);
terrainRenderer.Draw(this, Viewport); terrainRenderer.Draw(this, Viewport);
Game.Renderer.Flush(); Game.Renderer.Flush();

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Widgets
var chatpos = new int2(chatLogArea.X + 5, chatLogArea.Bottom - 5); var chatpos = new int2(chatLogArea.X + 5, chatLogArea.Bottom - 5);
var font = Game.Renderer.Fonts["Regular"]; var font = Game.Renderer.Fonts["Regular"];
Game.Renderer.EnableScissor(chatLogArea.Left, chatLogArea.Top, chatLogArea.Width, chatLogArea.Height); Game.Renderer.EnableScissor(chatLogArea);
foreach (var line in recentLines.AsEnumerable().Reverse()) foreach (var line in recentLines.AsEnumerable().Reverse())
{ {

View File

@@ -124,8 +124,8 @@ namespace OpenRA.Widgets
// Scissor when the text overflows // Scissor when the text overflows
if (textSize.X > Bounds.Width - LeftMargin - RightMargin) if (textSize.X > Bounds.Width - LeftMargin - RightMargin)
{ {
Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y, Game.Renderer.EnableScissor(new Rectangle(pos.X + LeftMargin, pos.Y,
Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom); Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom));
} }
var color = disabled ? DisabledColor : TextColor; var color = disabled ? DisabledColor : TextColor;

View File

@@ -115,7 +115,7 @@ namespace OpenRA.Widgets
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", DownPressed || downDisabled ? "down_pressed" : "down_arrow"), WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", DownPressed || downDisabled ? "down_pressed" : "down_arrow"),
new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset)); new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset));
Game.Renderer.EnableScissor(backgroundRect.X + 1, backgroundRect.Y + 1, backgroundRect.Width - 2, backgroundRect.Height - 2); Game.Renderer.EnableScissor(backgroundRect.InflateBy(-1, -1, -1, -1));
foreach (var child in Children) foreach (var child in Children)
child.DrawOuter(); child.DrawOuter();

View File

@@ -216,8 +216,8 @@ namespace OpenRA.Widgets
if (HasKeyboardFocus) if (HasKeyboardFocus)
textPos += new int2(Bounds.Width - LeftMargin - RightMargin - textSize.X, 0); textPos += new int2(Bounds.Width - LeftMargin - RightMargin - textSize.X, 0);
Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y, Game.Renderer.EnableScissor(new Rectangle(pos.X + LeftMargin, pos.Y,
Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom); Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom));
} }
var color = disabled ? DisabledColor : TextColor; var color = disabled ? DisabledColor : TextColor;

View File

@@ -157,7 +157,7 @@ namespace OpenRA.Mods.Cnc.Widgets
new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2)); new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2));
// Draw tab buttons // Draw tab buttons
Game.Renderer.EnableScissor(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height); Game.Renderer.EnableScissor(new Rectangle(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height));
var origin = new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y); var origin = new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y);
SpriteFont font = Game.Renderer.Fonts["TinyBold"]; SpriteFont font = Game.Renderer.Fonts["TinyBold"];
contentWidth = 0; contentWidth = 0;

View File

@@ -156,7 +156,7 @@ namespace OpenRA.Mods.RA.Widgets
var tl = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.TopLeft).ToCPos()); var tl = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.TopLeft).ToCPos());
var br = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.BottomRight).ToCPos()); var br = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.BottomRight).ToCPos());
Game.Renderer.EnableScissor(mapRect.Left, mapRect.Top, mapRect.Width, mapRect.Height); Game.Renderer.EnableScissor(mapRect);
Game.Renderer.LineRenderer.DrawRect(tl, br, Color.White); Game.Renderer.LineRenderer.DrawRect(tl, br, Color.White);
Game.Renderer.DisableScissor(); Game.Renderer.DisableScissor();
} }