#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(); } } }