#region usings
using System;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Mesh
{
///
/// Contains information for meshes
///
public abstract class GenericMesh : GLObject
{
private bool _boundingBoxUpdated = false;
///
protected override bool AutoCompile { get; set; } = true;
///
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.VertexArray;
///
/// The primitive type, that determinants how the mesh is drawn.
/// Default: Triangles
///
public virtual PrimitiveType PrimitiveType { get; protected set; } = PrimitiveType.Triangles;
///
/// Contains the vertices for the mesh.
///
public virtual VBO Vertex { get; protected set; }
///
/// Contains the texture coords for the mesh.
///
public virtual VBO UVs { get; protected set; }
///
/// Contains the normals for the mesh.
///
public virtual VBO Normals { get; protected set; }
///
/// Represents the bounding box.
///
public virtual BoundingBox BoundingBox { get; } = new BoundingBox();
///
/// Connects the different buffer objects with ids.
///
public MeshAttributeList Attributes { get; }
///
/// Stores indices for a more performance friendly method to draw objects.
///
public virtual int[] Indices { get; set; }
///
/// Generates the AttribDataIndex
///
protected GenericMesh()
{
Attributes = new MeshAttributeList()
{
{0, "vertex", Vertex},
{1, "uv", UVs},
{2, "normal", Normals}
};
}
///
/// Updates the object bounding box.
///
public void UpdateBoundingBox()
{
BoundingBox.Update(this);
_boundingBoxUpdated = true;
}
///
/// Activates the object to be rendered.
///
public void Activate()
{
GL.BindVertexArray(ID);
}
///
public override void Compile()
{
_id = GL.GenVertexArray();
GL.BindVertexArray(_id);
if (Attributes == null || Attributes.Count == 0) throw new Exception("[Critical] The model requires attributes.");
if (!_boundingBoxUpdated)
UpdateBoundingBox();
foreach (var kvp in Attributes)
{
if (kvp.ConnectedVBO == null) continue;
kvp.ConnectedVBO.AttributeID = kvp.Index;
kvp.ConnectedVBO.Compile();
}
GL.BindVertexArray(0);
}
///
/// This updates the parts of the mesh, that needs updating.
///
public void Update()
{
if (!WasCompiled)
{
Compile();
return;
}
GL.BindVertexArray(_id);
UpdateBoundingBox();
foreach(var attrib in Attributes)
{
if (attrib.ConnectedVBO == null || !attrib.ConnectedVBO.Active || !attrib.ConnectedVBO.CanBeUpdated) continue;
attrib.ConnectedVBO.Update();
}
}
///
public override void Dispose()
{
GL.DeleteVertexArray(_id);
base.Dispose();
}
}
}