Merge branch 'master'

This commit is contained in:
Julian Nießner
2021-05-14 11:20:59 +02:00
5 changed files with 343 additions and 331 deletions

329
Line.cs
View File

@@ -1,329 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections;
using System;
public class Line
{
private List<Vector2> points;
private float thickness;
public enum JoinType
{
None,
Miter,
Bevel,
Round
}
public enum LineCaps
{
None,
Round
}
private Color LineColor { get; set; }
private LineCaps LineEndings { get; set; }
private JoinType JoinTypes { get; set; }
//Graphical representation
private VertexBuffer vbo;
private IndexBuffer ibo;
private GraphicsDevice gDevice;
private class LinkedMeshList : IEnumerable<LinkedMeshListNode>
{
public int Count { get; set; }
public LinkedMeshListNode FirstNode { get; private set; }
public LinkedMeshListNode LastNode { get; private set; }
public LinkedMeshList()
{
this.Count = 0;
}
public void Remove(LinkedMeshListNode node)
{
throw new NotImplementedException();
}
public void AddBefore(LinkedMeshListNode node, LinkedMeshListNode beforeNode)
{
var oldBefore = node.Previous;
oldBefore.Next = beforeNode;
beforeNode.Previous = oldBefore;
beforeNode.Next = node;
node.Previous = beforeNode;
Count++;
}
public void AddAfter(LinkedMeshListNode node, LinkedMeshListNode afterNode)
{
var oldNext = node.Next;
node.Next = afterNode;
afterNode.Previous = node;
afterNode.Next = oldNext;
oldNext.Previous = afterNode;
Count++;
}
public void Append(LinkedMeshListNode node)
{
if(this.Count == 0)
{
this.FirstNode = node;
this.LastNode = node;
Count++;
return;
}
this.LastNode.Next = node;
node.Previous = this.LastNode;
this.LastNode = node;
this.Count++;
}
public List<VertexPositionColorTexture> GetVerticeList()
{
List<VertexPositionColorTexture> verticesList = new List<VertexPositionColorTexture>();
foreach(var node in this)
{
verticesList.AddRange(node.GenerateVerticeList());
}
return verticesList;
}
public List<ushort> GetIndiceList()
{
List<ushort> indeicesList = new List<ushort>();
foreach(var node in this)
{
indeicesList.AddRange(node.GenerateIndiceList());
}
return indeicesList;
}
public IEnumerator<LinkedMeshListNode> GetEnumerator()
{
LinkedMeshListNode curNode = this.FirstNode;
while(curNode != null)
{
yield
return curNode;
curNode = curNode.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
private abstract class LinkedMeshListNode
{
public LinkedMeshListNode Next { get; set; }
private LinkedMeshListNode previous;
public LinkedMeshListNode Previous {
get {
return this.previous;
}
set {
this.IndexOffset = value.IndexOffset + value.GetVertexCount();
this.previous = value;
}
}
public int IndexOffset { get; private set; }
public abstract int GetVertexCount();
public abstract List<VertexPositionColorTexture> GenerateVerticeList();
public abstract List<ushort> GenerateIndiceList();
public LinkedMeshListNode()
{
this.IndexOffset = 0;
}
}
private class Segment : LinkedMeshListNode {
public Vector2 Start { get; private set; }
public Vector2 End { get; private set; }
public Vector2 Normal { get; private set; }
public const ushort INDEX_BL = 0;
public const ushort INDEX_BR = 1;
public const ushort INDEX_TL = 2;
public const ushort INDEX_TR = 3;
private Color color { get; set; }
public Segment(Vector2 start, Vector2 end, Color color) : base()
{
this.Start = start;
this.End = end;
Vector2 dir = end - start;
Vector2 perpendincularVector = new Vector2(dir.Y, -dir.X);
perpendincularVector.Normalize();
this.Normal = perpendincularVector;
this.color = color;
}
public override List<VertexPositionColorTexture> GenerateVerticeList()
{
List<VertexPositionColorTexture> vertices = new List<VertexPositionColorTexture>();
var offsetPoint1 = new Vector3(this.Start.X, this.Start.Y ,0.0f);
vertices.Add(new VertexPositionColorTexture(offsetPoint1, this.color, this.Normal));
vertices.Add(new VertexPositionColorTexture(offsetPoint1, this.color, this.Normal * -1));
var offsetPoint1Next = new Vector3(this.End.X, this.End.Y ,0.0f);
vertices.Add(new VertexPositionColorTexture(offsetPoint1Next, this.color, this.Normal));
vertices.Add(new VertexPositionColorTexture(offsetPoint1Next, this.color, this.Normal * -1));
return vertices;
}
public override List<ushort> GenerateIndiceList()
{
List<ushort> indices = new List<ushort>();
indices.Add((ushort)(this.IndexOffset + INDEX_BL));
indices.Add((ushort)(this.IndexOffset + INDEX_BR));
indices.Add((ushort)(this.IndexOffset + INDEX_TL));
indices.Add((ushort)(this.IndexOffset + INDEX_TL));
indices.Add((ushort)(this.IndexOffset + INDEX_BR));
indices.Add((ushort)(this.IndexOffset + INDEX_TR));
return indices;
}
public override int GetVertexCount()
{
return 4;
}
}
private class BevelLineJoin : LinkedMeshListNode
{
private Color color { get; set; }
public BevelLineJoin(Color color) : base()
{
this.color = color;
}
public override List<ushort> GenerateIndiceList()
{
Debug.Assert(this.Previous != null);
Debug.Assert(this.Previous is Segment);
Debug.Assert(this.Next != null);
Debug.Assert(this.Next is Segment);
var next = this.Next as Segment;
var previous = this.Previous as Segment;
ushort lastOffset = (ushort) previous.IndexOffset;
ushort nextOffset = (ushort) next.IndexOffset;
List<ushort> indices = new List<ushort>();
indices.Add((ushort)(lastOffset+Segment.INDEX_TL));
indices.Add((ushort)(lastOffset+Segment.INDEX_TR));
indices.Add((ushort)(nextOffset+Segment.INDEX_BL));
indices.Add((ushort)(lastOffset+Segment.INDEX_TL));
indices.Add((ushort)(lastOffset+Segment.INDEX_TR));
indices.Add((ushort)(nextOffset+Segment.INDEX_BR));
return indices;
}
public override List<VertexPositionColorTexture> GenerateVerticeList()
{
return new List<VertexPositionColorTexture>();
}
public override int GetVertexCount()
{
return 0;
}
}
public Line(List<Vector2> points)
: this(points, 1.0f)
{}
public Line(List<Vector2> points, float thickness)
: this(points, thickness, Color.Black)
{}
public Line(List<Vector2> points, float thickness, Color color)
: this(points,thickness, color, JoinType.None)
{}
public Line(List<Vector2> points, float thickness, Color color, JoinType joinType)
: this(points, thickness, color, joinType, LineCaps.None)
{}
public Line(List<Vector2> points, float thickness, Color color, JoinType joinType, LineCaps caps)
{
this.points = points;
this.thickness = thickness;
this.LineColor = color;
this.JoinTypes = joinType;
this.LineEndings = caps;
}
public void InitOnGraphicalDevice(GraphicsDevice device)
{
this.gDevice = device;
Debug.Assert(this.points.Count >= 2);
LinkedMeshList meshList = new LinkedMeshList();
for(int i = 0; i < this.points.Count - 1 ; i++)
{
var p = this.points[i];
var pNext = this.points[i+1];
meshList.Append(new Segment(p, pNext, this.LineColor));
}
var curNode = meshList.FirstNode;
while(curNode != null && curNode.Next != null)
{
meshList.AddAfter(curNode, new BevelLineJoin(this.LineColor));
curNode = curNode.Next.Next;
}
List<VertexPositionColorTexture> vertices = meshList.GetVerticeList();
List<ushort> indices = meshList.GetIndiceList();
this.vbo = new VertexBuffer(device, typeof(VertexPositionColorTexture), vertices.Count, BufferUsage.WriteOnly);
this.vbo.SetData<VertexPositionColorTexture>(vertices.ToArray());
this.ibo = new IndexBuffer(device, typeof(ushort), indices.Count,BufferUsage.WriteOnly);
this.ibo.SetData<ushort>(indices.ToArray());
}
public void Draw(Effect lineEffect)
{
this.gDevice.SetVertexBuffer(this.vbo);
this.gDevice.Indices = this.ibo;
RasterizerState rasterizerState = new RasterizerState();
// rasterizerState.CullMode = CullMode.None;
//rasterizerState.FillMode = FillMode.WireFrame;
this.gDevice.RasterizerState = rasterizerState;
lineEffect.Parameters["thickness"].SetValue(this.thickness);
foreach (EffectPass pass in lineEffect.CurrentTechnique.Passes)
{
pass.Apply();
this.gDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,0,0,this.ibo.IndexCount / 3);
//this.gDevice.DrawPrimitives(PrimitiveType.LineList, 0, this.vbo.VertexCount);
}
}
}

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

339
src/Primitives/Line.cs Normal file
View File

@@ -0,0 +1,339 @@
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections;
using System;
namespace MyGame.Primitives
{
public class Line
{
private List<Vector2> points;
private float thickness;
public enum JoinType
{
None,
Miter,
Bevel,
Round
}
public enum LineCaps
{
None,
Round
}
private Color LineColor { get; set; }
private LineCaps LineEndings { get; set; }
private JoinType JoinTypes { get; set; }
//Graphical representation
private VertexBuffer vbo;
private IndexBuffer ibo;
private GraphicsDevice gDevice;
private class LinkedMeshList : IEnumerable<LinkedMeshListNode>
{
public int Count { get; set; }
public LinkedMeshListNode FirstNode { get; private set; }
public LinkedMeshListNode LastNode { get; private set; }
public LinkedMeshList()
{
this.Count = 0;
}
public void Remove(LinkedMeshListNode node)
{
throw new NotImplementedException();
}
public void AddBefore(LinkedMeshListNode node, LinkedMeshListNode beforeNode)
{
var oldBefore = node.Previous;
oldBefore.Next = beforeNode;
beforeNode.Previous = oldBefore;
beforeNode.Next = node;
node.Previous = beforeNode;
Count++;
}
public void AddAfter(LinkedMeshListNode node, LinkedMeshListNode afterNode)
{
var oldNext = node.Next;
node.Next = afterNode;
afterNode.Previous = node;
afterNode.Next = oldNext;
oldNext.Previous = afterNode;
Count++;
}
public void Append(LinkedMeshListNode node)
{
if (this.Count == 0)
{
this.FirstNode = node;
this.LastNode = node;
Count++;
return;
}
this.LastNode.Next = node;
node.Previous = this.LastNode;
this.LastNode = node;
this.Count++;
}
public List<VertexPositionColorTexture> GetVerticeList()
{
List<VertexPositionColorTexture> verticesList = new List<VertexPositionColorTexture>();
foreach (var node in this)
{
verticesList.AddRange(node.GenerateVerticeList());
}
return verticesList;
}
public List<ushort> GetIndiceList()
{
List<ushort> indeicesList = new List<ushort>();
foreach (var node in this)
{
indeicesList.AddRange(node.GenerateIndiceList());
}
return indeicesList;
}
public IEnumerator<LinkedMeshListNode> GetEnumerator()
{
LinkedMeshListNode curNode = this.FirstNode;
while (curNode != null)
{
yield
return curNode;
curNode = curNode.Next;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
private abstract class LinkedMeshListNode
{
public LinkedMeshListNode Next { get; set; }
private LinkedMeshListNode previous;
public LinkedMeshListNode Previous
{
get
{
return this.previous;
}
set
{
this.IndexOffset = value.IndexOffset + value.GetVertexCount();
this.previous = value;
}
}
public int IndexOffset { get; private set; }
public abstract int GetVertexCount();
public abstract List<VertexPositionColorTexture> GenerateVerticeList();
public abstract List<ushort> GenerateIndiceList();
public LinkedMeshListNode()
{
this.IndexOffset = 0;
}
}
private class Segment : LinkedMeshListNode
{
public Vector2 Start { get; private set; }
public Vector2 End { get; private set; }
public Vector2 Normal { get; private set; }
public const ushort INDEX_BL = 0;
public const ushort INDEX_BR = 1;
public const ushort INDEX_TL = 2;
public const ushort INDEX_TR = 3;
private Color color { get; set; }
public Segment(Vector2 start, Vector2 end, Color color) : base()
{
this.Start = start;
this.End = end;
Vector2 dir = end - start;
Vector2 perpendincularVector = new Vector2(dir.Y, -dir.X);
perpendincularVector.Normalize();
this.Normal = perpendincularVector;
this.color = color;
}
public override List<VertexPositionColorTexture> GenerateVerticeList()
{
List<VertexPositionColorTexture> vertices = new List<VertexPositionColorTexture>();
var offsetPoint1 = new Vector3(this.Start.X, this.Start.Y, 0.0f);
vertices.Add(new VertexPositionColorTexture(offsetPoint1, this.color, this.Normal));
vertices.Add(new VertexPositionColorTexture(offsetPoint1, this.color, this.Normal * -1));
var offsetPoint1Next = new Vector3(this.End.X, this.End.Y, 0.0f);
vertices.Add(new VertexPositionColorTexture(offsetPoint1Next, this.color, this.Normal));
vertices.Add(new VertexPositionColorTexture(offsetPoint1Next, this.color, this.Normal * -1));
return vertices;
}
public override List<ushort> GenerateIndiceList()
{
List<ushort> indices = new List<ushort>();
indices.Add((ushort)(this.IndexOffset + INDEX_BL));
indices.Add((ushort)(this.IndexOffset + INDEX_BR));
indices.Add((ushort)(this.IndexOffset + INDEX_TL));
indices.Add((ushort)(this.IndexOffset + INDEX_TL));
indices.Add((ushort)(this.IndexOffset + INDEX_BR));
indices.Add((ushort)(this.IndexOffset + INDEX_TR));
return indices;
}
public override int GetVertexCount()
{
return 4;
}
}
private class BevelLineJoin : LinkedMeshListNode
{
private Color color { get; set; }
public BevelLineJoin(Color color) : base()
{
this.color = color;
}
public override List<ushort> GenerateIndiceList()
{
Debug.Assert(this.Previous != null);
Debug.Assert(this.Previous is Segment);
Debug.Assert(this.Next != null);
Debug.Assert(this.Next is Segment);
var next = this.Next as Segment;
var previous = this.Previous as Segment;
ushort lastOffset = (ushort)previous.IndexOffset;
ushort nextOffset = (ushort)next.IndexOffset;
List<ushort> indices = new List<ushort>();
indices.Add((ushort)(lastOffset + Segment.INDEX_TL));
indices.Add((ushort)(lastOffset + Segment.INDEX_TR));
indices.Add((ushort)(nextOffset + Segment.INDEX_BL));
indices.Add((ushort)(lastOffset + Segment.INDEX_TL));
indices.Add((ushort)(lastOffset + Segment.INDEX_TR));
indices.Add((ushort)(nextOffset + Segment.INDEX_BR));
return indices;
}
public override List<VertexPositionColorTexture> GenerateVerticeList()
{
return new List<VertexPositionColorTexture>();
}
public override int GetVertexCount()
{
return 0;
}
}
public Line(List<Vector2> points)
: this(points, 1.0f)
{ }
public Line(List<Vector2> points, float thickness)
: this(points, thickness, Color.Black)
{ }
public Line(List<Vector2> points, float thickness, Color color)
: this(points, thickness, color, JoinType.None)
{ }
public Line(List<Vector2> points, float thickness, Color color, JoinType joinType)
: this(points, thickness, color, joinType, LineCaps.None)
{ }
public Line(List<Vector2> points, float thickness, Color color, JoinType joinType, LineCaps caps)
{
this.points = points;
this.thickness = thickness;
this.LineColor = color;
this.JoinTypes = joinType;
this.LineEndings = caps;
}
public void InitOnGraphicalDevice(GraphicsDevice device)
{
this.gDevice = device;
Debug.Assert(this.points.Count >= 2);
LinkedMeshList meshList = new LinkedMeshList();
for (int i = 0; i < this.points.Count - 1; i++)
{
var p = this.points[i];
var pNext = this.points[i + 1];
meshList.Append(new Segment(p, pNext, this.LineColor));
}
var curNode = meshList.FirstNode;
while (curNode != null && curNode.Next != null)
{
meshList.AddAfter(curNode, new BevelLineJoin(this.LineColor));
curNode = curNode.Next.Next;
}
List<VertexPositionColorTexture> vertices = meshList.GetVerticeList();
List<ushort> indices = meshList.GetIndiceList();
this.vbo = new VertexBuffer(device, typeof(VertexPositionColorTexture), vertices.Count, BufferUsage.WriteOnly);
this.vbo.SetData<VertexPositionColorTexture>(vertices.ToArray());
this.ibo = new IndexBuffer(device, typeof(ushort), indices.Count, BufferUsage.WriteOnly);
this.ibo.SetData<ushort>(indices.ToArray());
}
public void Draw(Effect lineEffect)
{
this.gDevice.SetVertexBuffer(this.vbo);
this.gDevice.Indices = this.ibo;
RasterizerState rasterizerState = new RasterizerState();
// rasterizerState.CullMode = CullMode.None;
//rasterizerState.FillMode = FillMode.WireFrame;
this.gDevice.RasterizerState = rasterizerState;
lineEffect.Parameters["thickness"].SetValue(this.thickness);
foreach (EffectPass pass in lineEffect.CurrentTechnique.Passes)
{
pass.Apply();
this.gDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, this.ibo.IndexCount / 3);
//this.gDevice.DrawPrimitives(PrimitiveType.LineList, 0, this.vbo.VertexCount);
}
}
}
}

View File

@@ -4,6 +4,8 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using MyGame.Primitives;
namespace Barbs namespace Barbs
{ {
class Program : Game, IDisposable class Program : Game, IDisposable
@@ -20,7 +22,7 @@ namespace Barbs
public Program() public Program()
{ {
graphics = new GraphicsDeviceManager(this); graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "."; Content.RootDirectory = "assets";
} }
protected override void Initialize() protected override void Initialize()
@@ -44,7 +46,7 @@ namespace Barbs
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.01f, 100f); projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.01f, 100f);
basicEffect = new BasicEffect(GraphicsDevice); basicEffect = new BasicEffect(GraphicsDevice);
lineEffect = Content.Load<Effect>("line"); lineEffect = Content.Load<Effect>("shaders/line");
Vector2[] arr = { new Vector2(0.0f,0.0f), new Vector2(0.2f,0.5f), new Vector2(0.2f,0.0f), new Vector2(0.5f,0.0f), Vector2[] arr = { new Vector2(0.0f,0.0f), new Vector2(0.2f,0.5f), new Vector2(0.2f,0.0f), new Vector2(0.5f,0.0f),
new Vector2(0.7f,-0.5f), new Vector2(1.0f, 1.0f)}; new Vector2(0.7f,-0.5f), new Vector2(1.0f, 1.0f)};