-
Notifications
You must be signed in to change notification settings - Fork 91
Examples C#
snowinmars edited this page Sep 22, 2016
·
1 revision
This is example of Poly2Tri usage on C# Monogame engine.
I have only one problem here.
On the one hand, I want to have array of VertexPositionColor: all framework's methods use array.
On the other, I want to have option to add elements into collection.
So, in code there's the simplest way to work. If your app feels confortable with ToArray casts - that's ok. If no - try another way, and if it will be better, than my - post it here.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Poly2Tri;
using SandS.Algorithm.CommonNamespace;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Game1
{
public static class Extension
{
#region Public Methods
public static Color NextColor(this Random rnd)
{
return new Color(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
}
#endregion Public Methods
}
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
#region Private Fields
private BasicEffect effect;
private GraphicsDeviceManager graphics;
private Matrix projectionMatrix;
private SpriteBatch spriteBatch;
private IList<VertexPositionColor> triangleVertices;
private VertexBuffer vertexBuffer;
private Matrix viewMatrix;
private Matrix worldMatrix;
#endregion Private Fields
#region Public Constructors
public Game1()
{
this.graphics = new GraphicsDeviceManager(this);
this.Content.RootDirectory = "Content";
this.IsMouseVisible = true;
}
#endregion Public Constructors
#region Protected Methods
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
this.GraphicsDevice.Clear(Color.CornflowerBlue);
this.GraphicsDevice.SetVertexBuffer(this.vertexBuffer); // due to buffer can change in Update()
// there can be more than one pass
foreach (EffectPass pass in this.effect.CurrentTechnique.Passes)
{
pass.Apply();
this.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList,
this.triangleVertices.ToArray(),
0,
this.triangleVertices.Count / 3);
}
base.Draw(gameTime);
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
this.triangleVertices = new List<VertexPositionColor>();
this.InitializeMatrix();
this.InitializeTriangles();
this.InitializeVertexBuffer();
this.InitializeEffect();
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
{
this.Exit();
}
this.vertexBuffer.SetData(this.triangleVertices.ToArray());
base.Update(gameTime);
}
#endregion Protected Methods
#region Private Methods
private static PolygonPoint[] GetPoints()
{
return new[]
{
new PolygonPoint(0,0),
new PolygonPoint(5,0),
new PolygonPoint(5,-3),
new PolygonPoint(1,-4),
new PolygonPoint(1,-5),
new PolygonPoint(5,-5),
new PolygonPoint(5,-6),
new PolygonPoint(-1,-6),
new PolygonPoint(-1,-4),
new PolygonPoint(-4,-4),
new PolygonPoint(-4,-2),
new PolygonPoint(0,-2),
};
}
private void InitializeEffect()
{
this.effect = new BasicEffect(this.GraphicsDevice)
{
VertexColorEnabled = true,
World = this.worldMatrix,
View = this.viewMatrix,
Projection = this.projectionMatrix
};
}
private void InitializeMatrix()
{
this.viewMatrix = Matrix.CreateLookAt(cameraPosition: new Vector3(0, 0, 16),
cameraTarget: Vector3.Zero,
cameraUpVector: Vector3.Up);
this.projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
this.GraphicsDevice.DisplayMode.AspectRatio,
nearPlaneDistance: 1,
farPlaneDistance: 100);
this.worldMatrix = Matrix.CreateWorld(position: new Vector3(0, 0, 0),
forward: Vector3.Forward,
up: Vector3.Up);
}
private void InitializeTriangles()
{
Polygon p = new Polygon(Game1.GetPoints());
P2T.Triangulate(p);
this.MapPolygonTrianglesToVertexPositions(p);
}
private void InitializeVertexBuffer()
{
this.vertexBuffer = new VertexBuffer(this.GraphicsDevice,
typeof(VertexPositionColor), this.triangleVertices.Count,
BufferUsage.None);
}
private void MapPolygonTrianglesToVertexPositions(Polygon p)
{
foreach (var tr in p.Triangles)
{
Vector3 v0 = new Vector3((float)tr.Points._0.X, (float)tr.Points._0.Y, 0);
Vector3 v1 = new Vector3((float)tr.Points._1.X, (float)tr.Points._1.Y, 0);
Vector3 v2 = new Vector3((float)tr.Points._2.X, (float)tr.Points._2.Y, 0);
this.triangleVertices.Add(new VertexPositionColor(v2, CommonValues.Random.NextColor()));
this.triangleVertices.Add(new VertexPositionColor(v1, CommonValues.Random.NextColor()));
this.triangleVertices.Add(new VertexPositionColor(v0, CommonValues.Random.NextColor()));
}
}
#endregion Private Methods
}
}