line rendering - selection box!!

This commit is contained in:
Chris Forbes
2009-10-08 21:53:59 +13:00
parent 62f0a67d28
commit 2e4279664f
11 changed files with 206 additions and 42 deletions

View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ijw.DirectX;
using System.Runtime.InteropServices;
using System.Drawing;
namespace OpenRa.Game.Graphics
{
class LineRenderer
{
Renderer renderer;
FvfVertexBuffer<Vertex> vertexBuffer;
IndexBuffer indexBuffer; /* kindof a waste of space, but the GPU likes indexing, oh well */
const int linesPerBatch = 1024;
Vertex[] vertices = new Vertex[2 * linesPerBatch];
ushort[] indices = new ushort[2 * linesPerBatch];
int lines = 0;
int nv = 0, ni = 0;
public LineRenderer(Renderer renderer)
{
this.renderer = renderer;
vertexBuffer = new FvfVertexBuffer<Vertex>(renderer.Device, vertices.Length, Vertex.Format);
indexBuffer = new IndexBuffer(renderer.Device, indices.Length);
}
public void Flush()
{
if (lines > 0)
{
renderer.LineShader.Render(() =>
{
vertexBuffer.SetData(vertices);
indexBuffer.SetData(indices);
renderer.DrawBatch(vertexBuffer, indexBuffer,
nv, ni / 2, null, PrimitiveType.LineList);
});
nv = 0; ni = 0;
lines = 0;
}
}
public void DrawLine(float2 start, float2 end, Color startColor, Color endColor)
{
indices[ni++] = (ushort)nv;
vertices[nv++] = new Vertex(start,
new float2(startColor.R / 255.0f, startColor.G / 255.0f),
new float2(startColor.B / 255.0f, startColor.A / 255.0f));
indices[ni++] = (ushort)nv;
vertices[nv++] = new Vertex(end,
new float2(endColor.R / 255.0f, endColor.G / 255.0f),
new float2(endColor.B / 255.0f, endColor.A / 255.0f));
if (++lines >= linesPerBatch)
Flush();
}
}
}

View File

@@ -14,6 +14,7 @@ namespace OpenRa.Game.Graphics
get { return location + new int2( (int)viewport.Location.X, (int)viewport.Location.Y ); } // WTF HACK HACK HACK
}
public int2 Position { get { return location; } }
public readonly float2 Size;
Action drawFunction;

View File

@@ -9,13 +9,12 @@ namespace OpenRa.Game.Graphics
class Renderer
{
readonly GraphicsDevice device;
readonly Shader shader;
const string shaderName = "diffuse.fx";
public Shader SpriteShader { get; private set; } /* note: shared shader params */
public Shader LineShader { get; private set; }
public void SetPalette(HardwarePalette hp)
{
shader.SetValue("Palette", hp.Texture);
SpriteShader.SetValue("Palette", hp.Texture);
}
public Renderer(Control host, Size resolution, bool windowed)
@@ -24,8 +23,10 @@ namespace OpenRa.Game.Graphics
device = GraphicsDevice.Create(host,
resolution.Width, resolution.Height, windowed, false);
shader = new Shader(device, FileSystem.Open(shaderName));
shader.Quality = ShaderQuality.Low;
SpriteShader = new Shader(device, FileSystem.Open("sprite.fx"));
SpriteShader.Quality = ShaderQuality.Low;
LineShader = new Shader(device, FileSystem.Open("line.fx"));
LineShader.Quality = ShaderQuality.High;
}
public GraphicsDevice Device { get { return device; } }
@@ -34,9 +35,10 @@ namespace OpenRa.Game.Graphics
{
device.Begin();
shader.SetValue("Scroll", scroll);
shader.SetValue("r1", r1);
shader.SetValue("r2", r2);
SpriteShader.SetValue("Scroll", scroll);
SpriteShader.SetValue("r1", r1);
SpriteShader.SetValue("r2", r2);
SpriteShader.Commit();
}
public void EndFrame()
@@ -45,24 +47,32 @@ namespace OpenRa.Game.Graphics
device.Present();
}
public void DrawWithShader(ShaderQuality quality, Action task)
{
shader.Quality = quality;
shader.Render(() => task());
}
public void DrawBatch<T>(FvfVertexBuffer<T> vertices, IndexBuffer indices,
Range<int> vertexRange, Range<int> indexRange, Texture texture)
Range<int> vertexRange, Range<int> indexRange, Texture texture, PrimitiveType type)
where T : struct
{
shader.SetValue("DiffuseTexture", texture);
shader.Commit();
SpriteShader.SetValue("DiffuseTexture", texture);
SpriteShader.Commit();
vertices.Bind(0);
indices.Bind();
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
device.DrawIndexedPrimitives(type,
vertexRange, indexRange);
}
public void DrawBatch<T>(FvfVertexBuffer<T> vertices, IndexBuffer indices,
int vertexPool, int numPrimitives, Texture texture, PrimitiveType type)
where T : struct
{
SpriteShader.SetValue("DiffuseTexture", texture);
SpriteShader.Commit();
vertices.Bind(0);
indices.Bind();
device.DrawIndexedPrimitives(type,
vertexPool, numPrimitives);
}
}
}

View File

@@ -36,15 +36,16 @@ namespace OpenRa.Game.Graphics
{
if (sprites > 0)
{
renderer.DrawWithShader(quality, () =>
{
vertexBuffer.SetData(vertices);
indexBuffer.SetData(indices);
renderer.DrawBatch(vertexBuffer, indexBuffer,
new Range<int>(0, nv),
new Range<int>(0, ni),
currentSheet.Texture);
});
renderer.SpriteShader.Quality = quality;
renderer.SpriteShader.Render(() =>
{
vertexBuffer.SetData(vertices);
indexBuffer.SetData(indices);
renderer.DrawBatch(vertexBuffer, indexBuffer,
new Range<int>(0, nv),
new Range<int>(0, ni),
currentSheet.Texture, PrimitiveType.TriangleList);
});
nv = 0; ni = 0;
currentSheet = null;

View File

@@ -16,10 +16,12 @@ namespace OpenRa.Game.Graphics
Renderer renderer;
Map map;
Viewport viewport;
public TerrainRenderer(Renderer renderer, Map map, Viewport viewport)
{
this.renderer = renderer;
this.viewport = viewport;
region = Region.Create(viewport, DockStyle.Left, viewport.Width - 128, Draw, null );
viewport.AddRegion(region);
this.map = map;
@@ -61,7 +63,7 @@ namespace OpenRa.Game.Graphics
int visibleRows = (int)(region.Size.Y / 24.0f + 2);
int firstRow = (int)(region.Location.Y / 24.0f);
int firstRow = (int)((region.Position.Y + viewport.Location.Y) / 24.0f);
int lastRow = firstRow + visibleRows;
if (lastRow < 0 || firstRow > map.Height)
@@ -70,11 +72,12 @@ namespace OpenRa.Game.Graphics
if (firstRow < 0) firstRow = 0;
if (lastRow > map.Height) lastRow = map.Height;
renderer.DrawWithShader(ShaderQuality.Low, () =>
renderer.DrawBatch(vertexBuffer, indexBuffer,
new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow),
new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow),
terrainSheet.Texture));
renderer.SpriteShader.Quality = ShaderQuality.Low;
renderer.SpriteShader.Render(() =>
renderer.DrawBatch(vertexBuffer, indexBuffer,
new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow),
new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow),
terrainSheet.Texture, PrimitiveType.TriangleList));
}
}
}

View File

@@ -6,6 +6,7 @@ namespace OpenRa.Game.Graphics
class WorldRenderer
{
public readonly SpriteRenderer spriteRenderer;
public readonly LineRenderer lineRenderer;
public readonly World world;
public readonly Region region;
public readonly UiOverlay uiOverlay;
@@ -21,13 +22,15 @@ namespace OpenRa.Game.Graphics
world.game.viewport.AddRegion(region);
spriteRenderer = new SpriteRenderer(renderer, true);
lineRenderer = new LineRenderer(renderer);
uiOverlay = new UiOverlay(spriteRenderer, world.game);
this.world = world;
}
public void Draw()
{
var rect = new RectangleF(region.Location.ToPointF(), region.Size.ToSizeF());
var rect = new RectangleF((region.Position + world.game.viewport.Location).ToPointF(),
region.Size.ToSizeF());
foreach (Actor a in world.Actors)
{
@@ -46,7 +49,33 @@ namespace OpenRa.Game.Graphics
}
}
uiOverlay.Draw();
spriteRenderer.Flush();
var selectedUnit = world.game.controller.orderGenerator as Unit;
if (selectedUnit != null)
{
var center = selectedUnit.CenterLocation;
var size = selectedUnit.SelectedSize;
var xy = center - 0.5f * size;
var XY = center + 0.5f * size;
var Xy = new float2( XY.X, xy.Y );
var xY = new float2( xy.X, XY.Y );
lineRenderer.DrawLine(xy, xy + new float2(4, 0), Color.White, Color.White);
lineRenderer.DrawLine(xy, xy + new float2(0, 4), Color.White, Color.White);
lineRenderer.DrawLine(Xy, Xy + new float2(-4, 0), Color.White, Color.White);
lineRenderer.DrawLine(Xy, Xy + new float2(0, 4), Color.White, Color.White);
lineRenderer.DrawLine(xY, xY + new float2(4, 0), Color.White, Color.White);
lineRenderer.DrawLine(xY, xY + new float2(0, -4), Color.White, Color.White);
lineRenderer.DrawLine(XY, XY + new float2(-4, 0), Color.White, Color.White);
lineRenderer.DrawLine(XY, XY + new float2(0, -4), Color.White, Color.White);
}
lineRenderer.Flush();
}
}
}