line rendering - selection box!!
This commit is contained in:
66
OpenRa.Game/Graphics/LineRenderer.cs
Normal file
66
OpenRa.Game/Graphics/LineRenderer.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
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;
|
public readonly float2 Size;
|
||||||
|
|
||||||
Action drawFunction;
|
Action drawFunction;
|
||||||
|
|||||||
@@ -9,13 +9,12 @@ namespace OpenRa.Game.Graphics
|
|||||||
class Renderer
|
class Renderer
|
||||||
{
|
{
|
||||||
readonly GraphicsDevice device;
|
readonly GraphicsDevice device;
|
||||||
readonly Shader shader;
|
public Shader SpriteShader { get; private set; } /* note: shared shader params */
|
||||||
|
public Shader LineShader { get; private set; }
|
||||||
const string shaderName = "diffuse.fx";
|
|
||||||
|
|
||||||
public void SetPalette(HardwarePalette hp)
|
public void SetPalette(HardwarePalette hp)
|
||||||
{
|
{
|
||||||
shader.SetValue("Palette", hp.Texture);
|
SpriteShader.SetValue("Palette", hp.Texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderer(Control host, Size resolution, bool windowed)
|
public Renderer(Control host, Size resolution, bool windowed)
|
||||||
@@ -24,8 +23,10 @@ namespace OpenRa.Game.Graphics
|
|||||||
device = GraphicsDevice.Create(host,
|
device = GraphicsDevice.Create(host,
|
||||||
resolution.Width, resolution.Height, windowed, false);
|
resolution.Width, resolution.Height, windowed, false);
|
||||||
|
|
||||||
shader = new Shader(device, FileSystem.Open(shaderName));
|
SpriteShader = new Shader(device, FileSystem.Open("sprite.fx"));
|
||||||
shader.Quality = ShaderQuality.Low;
|
SpriteShader.Quality = ShaderQuality.Low;
|
||||||
|
LineShader = new Shader(device, FileSystem.Open("line.fx"));
|
||||||
|
LineShader.Quality = ShaderQuality.High;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphicsDevice Device { get { return device; } }
|
public GraphicsDevice Device { get { return device; } }
|
||||||
@@ -34,9 +35,10 @@ namespace OpenRa.Game.Graphics
|
|||||||
{
|
{
|
||||||
device.Begin();
|
device.Begin();
|
||||||
|
|
||||||
shader.SetValue("Scroll", scroll);
|
SpriteShader.SetValue("Scroll", scroll);
|
||||||
shader.SetValue("r1", r1);
|
SpriteShader.SetValue("r1", r1);
|
||||||
shader.SetValue("r2", r2);
|
SpriteShader.SetValue("r2", r2);
|
||||||
|
SpriteShader.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndFrame()
|
public void EndFrame()
|
||||||
@@ -45,24 +47,32 @@ namespace OpenRa.Game.Graphics
|
|||||||
device.Present();
|
device.Present();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawWithShader(ShaderQuality quality, Action task)
|
|
||||||
{
|
|
||||||
shader.Quality = quality;
|
|
||||||
shader.Render(() => task());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawBatch<T>(FvfVertexBuffer<T> vertices, IndexBuffer indices,
|
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
|
where T : struct
|
||||||
{
|
{
|
||||||
shader.SetValue("DiffuseTexture", texture);
|
SpriteShader.SetValue("DiffuseTexture", texture);
|
||||||
shader.Commit();
|
SpriteShader.Commit();
|
||||||
|
|
||||||
vertices.Bind(0);
|
vertices.Bind(0);
|
||||||
indices.Bind();
|
indices.Bind();
|
||||||
|
|
||||||
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
|
device.DrawIndexedPrimitives(type,
|
||||||
vertexRange, indexRange);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,15 +36,16 @@ namespace OpenRa.Game.Graphics
|
|||||||
{
|
{
|
||||||
if (sprites > 0)
|
if (sprites > 0)
|
||||||
{
|
{
|
||||||
renderer.DrawWithShader(quality, () =>
|
renderer.SpriteShader.Quality = quality;
|
||||||
{
|
renderer.SpriteShader.Render(() =>
|
||||||
vertexBuffer.SetData(vertices);
|
{
|
||||||
indexBuffer.SetData(indices);
|
vertexBuffer.SetData(vertices);
|
||||||
renderer.DrawBatch(vertexBuffer, indexBuffer,
|
indexBuffer.SetData(indices);
|
||||||
new Range<int>(0, nv),
|
renderer.DrawBatch(vertexBuffer, indexBuffer,
|
||||||
new Range<int>(0, ni),
|
new Range<int>(0, nv),
|
||||||
currentSheet.Texture);
|
new Range<int>(0, ni),
|
||||||
});
|
currentSheet.Texture, PrimitiveType.TriangleList);
|
||||||
|
});
|
||||||
|
|
||||||
nv = 0; ni = 0;
|
nv = 0; ni = 0;
|
||||||
currentSheet = null;
|
currentSheet = null;
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ namespace OpenRa.Game.Graphics
|
|||||||
|
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
Map map;
|
Map map;
|
||||||
|
Viewport viewport;
|
||||||
|
|
||||||
public TerrainRenderer(Renderer renderer, Map map, Viewport viewport)
|
public TerrainRenderer(Renderer renderer, Map map, Viewport viewport)
|
||||||
{
|
{
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
|
this.viewport = viewport;
|
||||||
region = Region.Create(viewport, DockStyle.Left, viewport.Width - 128, Draw, null );
|
region = Region.Create(viewport, DockStyle.Left, viewport.Width - 128, Draw, null );
|
||||||
viewport.AddRegion(region);
|
viewport.AddRegion(region);
|
||||||
this.map = map;
|
this.map = map;
|
||||||
@@ -61,7 +63,7 @@ namespace OpenRa.Game.Graphics
|
|||||||
|
|
||||||
int visibleRows = (int)(region.Size.Y / 24.0f + 2);
|
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;
|
int lastRow = firstRow + visibleRows;
|
||||||
|
|
||||||
if (lastRow < 0 || firstRow > map.Height)
|
if (lastRow < 0 || firstRow > map.Height)
|
||||||
@@ -70,11 +72,12 @@ namespace OpenRa.Game.Graphics
|
|||||||
if (firstRow < 0) firstRow = 0;
|
if (firstRow < 0) firstRow = 0;
|
||||||
if (lastRow > map.Height) lastRow = map.Height;
|
if (lastRow > map.Height) lastRow = map.Height;
|
||||||
|
|
||||||
renderer.DrawWithShader(ShaderQuality.Low, () =>
|
renderer.SpriteShader.Quality = ShaderQuality.Low;
|
||||||
renderer.DrawBatch(vertexBuffer, indexBuffer,
|
renderer.SpriteShader.Render(() =>
|
||||||
new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow),
|
renderer.DrawBatch(vertexBuffer, indexBuffer,
|
||||||
new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow),
|
new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow),
|
||||||
terrainSheet.Texture));
|
new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow),
|
||||||
|
terrainSheet.Texture, PrimitiveType.TriangleList));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace OpenRa.Game.Graphics
|
|||||||
class WorldRenderer
|
class WorldRenderer
|
||||||
{
|
{
|
||||||
public readonly SpriteRenderer spriteRenderer;
|
public readonly SpriteRenderer spriteRenderer;
|
||||||
|
public readonly LineRenderer lineRenderer;
|
||||||
public readonly World world;
|
public readonly World world;
|
||||||
public readonly Region region;
|
public readonly Region region;
|
||||||
public readonly UiOverlay uiOverlay;
|
public readonly UiOverlay uiOverlay;
|
||||||
@@ -21,13 +22,15 @@ namespace OpenRa.Game.Graphics
|
|||||||
world.game.viewport.AddRegion(region);
|
world.game.viewport.AddRegion(region);
|
||||||
|
|
||||||
spriteRenderer = new SpriteRenderer(renderer, true);
|
spriteRenderer = new SpriteRenderer(renderer, true);
|
||||||
|
lineRenderer = new LineRenderer(renderer);
|
||||||
uiOverlay = new UiOverlay(spriteRenderer, world.game);
|
uiOverlay = new UiOverlay(spriteRenderer, world.game);
|
||||||
this.world = world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw()
|
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)
|
foreach (Actor a in world.Actors)
|
||||||
{
|
{
|
||||||
@@ -46,7 +49,33 @@ namespace OpenRa.Game.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uiOverlay.Draw();
|
||||||
|
|
||||||
spriteRenderer.Flush();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace OpenRa.Game
|
|||||||
renderer = new Renderer(this, GetResolution(settings), windowed);
|
renderer = new Renderer(this, GetResolution(settings), windowed);
|
||||||
SheetBuilder.Initialize( renderer );
|
SheetBuilder.Initialize( renderer );
|
||||||
|
|
||||||
game = new Game( settings.GetValue( "map", "scg11eb.ini" ), renderer, new int2( ClientSize ) );
|
game = new Game( settings.GetValue( "map", "scm12ea.ini" ), renderer, new int2( ClientSize ) );
|
||||||
|
|
||||||
SequenceProvider.ForcePrecache();
|
SequenceProvider.ForcePrecache();
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@
|
|||||||
<Compile Include="Graphics\Animation.cs" />
|
<Compile Include="Graphics\Animation.cs" />
|
||||||
<Compile Include="Building.cs" />
|
<Compile Include="Building.cs" />
|
||||||
<Compile Include="Game.cs" />
|
<Compile Include="Game.cs" />
|
||||||
|
<Compile Include="Graphics\LineRenderer.cs" />
|
||||||
<Compile Include="Graphics\WorldRenderer.cs" />
|
<Compile Include="Graphics\WorldRenderer.cs" />
|
||||||
<Compile Include="IOrderGenerator.cs" />
|
<Compile Include="IOrderGenerator.cs" />
|
||||||
<Compile Include="TechTree\Item.cs" />
|
<Compile Include="TechTree\Item.cs" />
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ namespace OpenRa.Game
|
|||||||
var loc = location - 0.5f * s.size;
|
var loc = location - 0.5f * s.size;
|
||||||
return Pair.New( s, loc.Round() );
|
return Pair.New( s, loc.Round() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float2 SelectedSize { get { return this.CurrentImages.First().First.size; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
class TurretedUnit : Unit
|
class TurretedUnit : Unit
|
||||||
@@ -129,12 +131,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
public override IEnumerable<Pair<Sprite, float2>> CurrentImages
|
||||||
{
|
{
|
||||||
get
|
get { return base.CurrentImages.Concat(new[] { Centered(turretAnim.Image, CenterLocation) }); }
|
||||||
{
|
|
||||||
foreach( var x in base.CurrentImages )
|
|
||||||
yield return x;
|
|
||||||
yield return Centered( turretAnim.Image, CenterLocation );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
line.fx
Normal file
54
line.fx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// OpenRA gui lines shader
|
||||||
|
// Author: C. Forbes
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
shared float2 Scroll;
|
||||||
|
|
||||||
|
shared float2 r1, r2; // matrix elements
|
||||||
|
|
||||||
|
struct VertexIn {
|
||||||
|
float4 Position: POSITION;
|
||||||
|
float2 RG: TEXCOORD0;
|
||||||
|
float2 BA: TEXCOORD1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexOut {
|
||||||
|
float4 Position: POSITION;
|
||||||
|
float4 Color: COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FragmentIn {
|
||||||
|
float4 Color: COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VertexOut Simple_vp(VertexIn v) {
|
||||||
|
VertexOut o;
|
||||||
|
float2 p = (v.Position.xy - Scroll.xy) * r1 + r2;
|
||||||
|
o.Position = float4(p.x,p.y,0,1);
|
||||||
|
o.Color.rg = v.RG.xy;
|
||||||
|
o.Color.ba = v.BA.xy;
|
||||||
|
o.Color.a = 1.0f;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float2 texelOffset = float2( 0, 1.0f/32.0f );
|
||||||
|
|
||||||
|
float4 Simple_fp(FragmentIn f) : COLOR0 {
|
||||||
|
return float4(1,1,1,1);
|
||||||
|
//return f.Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
technique high_quality {
|
||||||
|
pass p0 {
|
||||||
|
AlphaBlendEnable = false;
|
||||||
|
ZWriteEnable = false;
|
||||||
|
ZEnable = false;
|
||||||
|
CullMode = None;
|
||||||
|
FillMode = Wireframe;
|
||||||
|
VertexShader = compile vs_2_0 Simple_vp();
|
||||||
|
PixelShader = compile ps_2_0 Simple_fp();
|
||||||
|
|
||||||
|
SrcBlend = SrcAlpha;
|
||||||
|
DestBlend = InvSrcAlpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -77,6 +77,7 @@ technique low_quality {
|
|||||||
ZWriteEnable = false;
|
ZWriteEnable = false;
|
||||||
ZEnable = false;
|
ZEnable = false;
|
||||||
CullMode = None;
|
CullMode = None;
|
||||||
|
FillMode = Solid;
|
||||||
VertexShader = compile vs_2_0 Simple_vp();
|
VertexShader = compile vs_2_0 Simple_vp();
|
||||||
PixelShader = compile ps_2_0 Palette_fp();
|
PixelShader = compile ps_2_0 Palette_fp();
|
||||||
}
|
}
|
||||||
@@ -88,6 +89,7 @@ technique high_quality {
|
|||||||
ZWriteEnable = false;
|
ZWriteEnable = false;
|
||||||
ZEnable = false;
|
ZEnable = false;
|
||||||
CullMode = None;
|
CullMode = None;
|
||||||
|
FillMode = Solid;
|
||||||
VertexShader = compile vs_2_0 Simple_vp();
|
VertexShader = compile vs_2_0 Simple_vp();
|
||||||
PixelShader = compile ps_2_0 Palette_fp();
|
PixelShader = compile ps_2_0 Palette_fp();
|
||||||
|
|
||||||
Reference in New Issue
Block a user