using SFML.Graphics;
using System;
using System.Collections.Generic;
namespace Otter {
///
/// Graphic used for rendering a set of Vert objects. Basically a wrapper for SFML's VertexArray.
///
public class Vertices : Graphic {
#region Private Fields
VertexPrimitiveType primitiveType = VertexPrimitiveType.Quads;
#endregion
#region Public Fields
///
/// The list of Verts.
///
public List Verts = new List();
#endregion
#region Public Properties
///
/// The primitive type drawing mode for the Verts.
///
public VertexPrimitiveType PrimitiveType {
get {
return primitiveType;
}
set {
primitiveType = value;
NeedsUpdate = true;
}
}
#endregion
#region Static Fields
public static VertexPrimitiveType DefaultPrimitiveType = VertexPrimitiveType.TrianglesFan;
#endregion
#region Constructors
///
/// Create a new set of Vertices using a file path to a Texture.
///
/// The file path to the Texture.
/// The Verts to use.
public Vertices(string source, params Vert[] vertices)
: this(vertices) {
SetTexture(new Texture(source));
Initialize(vertices);
}
///
/// Create a new set of Vertices using a Texture.
///
/// The Texture to use.
/// The Verts to use.
public Vertices(Texture texture, params Vert[] vertices)
: this(vertices) {
SetTexture(texture);
Initialize(vertices);
}
///
/// Create a new set of Vertices using an AtlasTexture.
///
/// The AtlasTexture to use.
/// The Verts to use.
public Vertices(AtlasTexture texture, params Vert[] vertices)
: this(vertices) {
SetTexture(texture);
Initialize(vertices);
}
///
/// Create a new set of Vertices with no Texture.
///
/// The Verts to use.
public Vertices(params Vert[] vertices)
: base() {
Initialize(vertices);
}
#endregion
#region Private Methods
void Initialize(params Vert[] vertices) {
PrimitiveType = DefaultPrimitiveType;
Add(vertices);
}
protected override void UpdateDrawable() {
base.UpdateDrawable();
SFMLVertices = new VertexArray((SFML.Graphics.PrimitiveType)PrimitiveType);
foreach (var v in Verts) {
// Adjust texture for potential atlas offset.
v.U += TextureLeft;
v.V += TextureTop;
v.U = Util.Clamp(v.U, TextureLeft, TextureRight);
v.V = Util.Clamp(v.V, TextureTop, TextureBottom);
//copy to new vert and apply color and alpha
var vCopy = new Vert(v);
vCopy.Color *= Color;
vCopy.Color.A *= Alpha;
SFMLVertices.Append(vCopy);
}
}
void UpdateDimensions() {
float minX = float.MaxValue;
float maxX = float.MinValue;
float minY = float.MaxValue;
float maxY = float.MinValue;
foreach (var v in Verts) {
minX = Util.Min(v.X, minX);
minY = Util.Min(v.Y, minY);
maxX = Util.Max(v.X, maxX);
maxY = Util.Max(v.Y, maxY);
}
Width = (int)Util.Round(Math.Abs(maxX - minX));
Height = (int)Util.Round(Math.Abs(maxY - minY));
}
#endregion
#region Public Methods
///
/// Clears all Verts from the Vertices.
///
public void Clear() {
Verts.Clear();
NeedsUpdate = true;
UpdateDimensions();
}
///
/// Add a Vert.
///
/// The X position.
/// The Y position.
/// The Color.
/// The X position on the Texture.
/// The Y position on the Texture.
public void Add(float x, float y, Color color, float u, float v) {
var vert = new Vert(x, y, color, u, v);
Add(vert);
}
///
/// Add a Vert.
///
/// The X position.
/// The Y position.
/// The X position on the Texture.
/// The Y position on the Texture.
public void Add(float x, float y, float u, float v) {
var vert = new Vert(x, y, u, v);
Add(vert);
}
///
/// Add a Vert.
///
/// The X position.
/// The Y position.
/// The Color.
public void Add(float x, float y, Color color) {
var vert = new Vert(x, y, color);
Add(vert);
}
///
/// Add a Vert.
///
/// The X position.
/// The Y position.
public void Add(float x, float y) {
var vert = new Vert(x, y);
Add(vert);
}
///
/// Add a set of Verts.
///
/// The Verts to add.
public void Add(params Vert[] vertices) {
foreach (var v in vertices) {
Verts.Add(v);
}
NeedsUpdate = true;
UpdateDimensions();
}
///
/// Remove Verts.
///
/// The Verts to remove.
public void Remove(params Vert[] vertices) {
foreach (var v in vertices) {
Verts.RemoveIfContains(v);
}
NeedsUpdate = true;
UpdateDimensions();
}
///
/// Remove Verts at a specific coordinate.
///
/// The X position of the Vert to remove.
/// The Y position of the Vert to remove.
public void RemoveAt(float x, float y) {
var vertsToRemove = new List();
foreach (var v in Verts) {
if (v.X == x && v.Y == y) {
vertsToRemove.Add(v);
}
}
Remove(vertsToRemove.ToArray());
}
#endregion
#region Internal
internal SFML.Graphics.VertexArray SFMLVertexArray {
get {
Update(); //update if needed
return SFMLVertices;
}
}
#endregion
}
#region Enum
public enum VertexPrimitiveType {
Points = 0,
Lines = 1,
LinesStrip = 2,
Triangles = 3,
TrianglesStrip = 4,
TrianglesFan = 5,
Quads = 6,
}
#endregion
}