diff --git a/Line.cs b/Line.cs deleted file mode 100644 index 3776171..0000000 --- a/Line.cs +++ /dev/null @@ -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 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 - { - 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 GetVerticeList() - { - List verticesList = new List(); - foreach(var node in this) - { - verticesList.AddRange(node.GenerateVerticeList()); - } - return verticesList; - } - - public List GetIndiceList() - { - List indeicesList = new List(); - foreach(var node in this) - { - indeicesList.AddRange(node.GenerateIndiceList()); - } - return indeicesList; - } - - public IEnumerator 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 GenerateVerticeList(); - public abstract List 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 GenerateVerticeList() - { - List vertices = new List(); - 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 GenerateIndiceList() - { - List indices = new List(); - 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 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 indices = new List(); - 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 GenerateVerticeList() - { - return new List(); - } - - public override int GetVertexCount() - { - return 0; - } - } - - public Line(List points) - : this(points, 1.0f) - {} - - public Line(List points, float thickness) - : this(points, thickness, Color.Black) - {} - - public Line(List points, float thickness, Color color) - : this(points,thickness, color, JoinType.None) - {} - - public Line(List points, float thickness, Color color, JoinType joinType) - : this(points, thickness, color, joinType, LineCaps.None) - {} - - public Line(List 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 vertices = meshList.GetVerticeList(); - List indices = meshList.GetIndiceList(); - - this.vbo = new VertexBuffer(device, typeof(VertexPositionColorTexture), vertices.Count, BufferUsage.WriteOnly); - this.vbo.SetData(vertices.ToArray()); - this.ibo = new IndexBuffer(device, typeof(ushort), indices.Count,BufferUsage.WriteOnly); - this.ibo.SetData(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); - } - } -} \ No newline at end of file diff --git a/ball.png b/assets/ball.png similarity index 100% rename from ball.png rename to assets/ball.png diff --git a/line.fx b/assets/shaders/line.fx similarity index 100% rename from line.fx rename to assets/shaders/line.fx diff --git a/src/Primitives/Line.cs b/src/Primitives/Line.cs new file mode 100644 index 0000000..a89c0ef --- /dev/null +++ b/src/Primitives/Line.cs @@ -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 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 + { + 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 GetVerticeList() + { + List verticesList = new List(); + foreach (var node in this) + { + verticesList.AddRange(node.GenerateVerticeList()); + } + return verticesList; + } + + public List GetIndiceList() + { + List indeicesList = new List(); + foreach (var node in this) + { + indeicesList.AddRange(node.GenerateIndiceList()); + } + return indeicesList; + } + + public IEnumerator 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 GenerateVerticeList(); + public abstract List 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 GenerateVerticeList() + { + List vertices = new List(); + 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 GenerateIndiceList() + { + List indices = new List(); + 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 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 indices = new List(); + 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 GenerateVerticeList() + { + return new List(); + } + + public override int GetVertexCount() + { + return 0; + } + } + + public Line(List points) + : this(points, 1.0f) + { } + + public Line(List points, float thickness) + : this(points, thickness, Color.Black) + { } + + public Line(List points, float thickness, Color color) + : this(points, thickness, color, JoinType.None) + { } + + public Line(List points, float thickness, Color color, JoinType joinType) + : this(points, thickness, color, joinType, LineCaps.None) + { } + + public Line(List 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 vertices = meshList.GetVerticeList(); + List indices = meshList.GetIndiceList(); + + this.vbo = new VertexBuffer(device, typeof(VertexPositionColorTexture), vertices.Count, BufferUsage.WriteOnly); + this.vbo.SetData(vertices.ToArray()); + this.ibo = new IndexBuffer(device, typeof(ushort), indices.Count, BufferUsage.WriteOnly); + this.ibo.SetData(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); + } + } + } +} \ No newline at end of file diff --git a/Program.cs b/src/Program.cs similarity index 96% rename from Program.cs rename to src/Program.cs index 96c91e4..1e6af42 100644 --- a/Program.cs +++ b/src/Program.cs @@ -4,6 +4,8 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; +using MyGame.Primitives; + namespace Barbs { class Program : Game, IDisposable @@ -20,7 +22,7 @@ namespace Barbs public Program() { graphics = new GraphicsDeviceManager(this); - Content.RootDirectory = "."; + Content.RootDirectory = "assets"; } protected override void Initialize() @@ -44,7 +46,7 @@ namespace Barbs projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 480f, 0.01f, 100f); basicEffect = new BasicEffect(GraphicsDevice); - lineEffect = Content.Load("line"); + lineEffect = Content.Load("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), new Vector2(0.7f,-0.5f), new Vector2(1.0f, 1.0f)};