1 using System; 2 using OpenTK.Graphics.OpenGL; 3 4 namespace LibRender2 5 { 6 /// <summary> 7 /// Class representing the abstract IBO 8 /// </summary> 9 public abstract class IndexBufferObject : IDisposable 10 { 11 /// <summary>The openGL buffer name</summary> 12 private readonly int handle; 13 protected readonly BufferUsageHint drawType; 14 private bool disposed; 15 16 /// <summary> 17 /// Constructor 18 /// </summary> 19 /// <param name="DrawType">The hint representing how the object is to be used and therefore guides OpenGL's optimization of the object</param> IndexBufferObject(BufferUsageHint DrawType)20 protected IndexBufferObject(BufferUsageHint DrawType) 21 { 22 GL.GenBuffers(1, out handle); 23 drawType = DrawType; 24 } 25 26 /// <summary> 27 /// Binds the IBO/EBO ready for use 28 /// </summary> Bind()29 internal void Bind() 30 { 31 GL.BindBuffer(BufferTarget.ElementArrayBuffer, handle); 32 } 33 34 /// <summary>Copies the Indices into the IBO/EBO</summary> 35 /// <remarks>Must be called before attempting to use the IBO/ EBO</remarks> BufferData()36 internal abstract void BufferData(); 37 38 /// <summary> 39 /// Draws the object 40 /// </summary> 41 /// <param name="DrawMode">Specifies the primitive or primitives that will be created from vertices</param> Draw(PrimitiveType DrawMode)42 internal abstract void Draw(PrimitiveType DrawMode); 43 44 /// <summary> 45 /// Draws the object 46 /// </summary> 47 /// <param name="DrawMode">Specifies the primitive or primitives that will be created from vertices</param> 48 /// <param name="Start">Start position of vertex index</param> 49 /// <param name="Count">Number of vertex indices to use</param> Draw(PrimitiveType DrawMode, int Start, int Count)50 internal abstract void Draw(PrimitiveType DrawMode, int Start, int Count); 51 52 /// <summary> 53 /// Dispose method to clean up the IBO/EBO releases the OpenGL Buffer 54 /// </summary> Dispose()55 public void Dispose() 56 { 57 if (disposed) 58 { 59 return; 60 } 61 62 GL.DeleteBuffer(handle); 63 GC.SuppressFinalize(this); 64 disposed = true; 65 } 66 ~IndexBufferObject()67 ~IndexBufferObject() 68 { 69 if (disposed) 70 { 71 return; 72 } 73 74 lock (BaseRenderer.iboToDelete) 75 { 76 BaseRenderer.iboToDelete.Add(handle); 77 } 78 } 79 } 80 81 public abstract class IndexBufferObject<T> : IndexBufferObject where T : struct 82 { 83 protected readonly T[] indexData; 84 85 /// <summary> 86 /// Constructor 87 /// </summary> 88 /// <param name="IndexData">An int array of vertex indices that make the object</param> 89 /// <param name="DrawType">The hint representing how the object is to be used and therefore guides OpenGL's optimization of the object</param> IndexBufferObject(T[] IndexData, BufferUsageHint DrawType)90 protected IndexBufferObject(T[] IndexData, BufferUsageHint DrawType) : base(DrawType) 91 { 92 indexData = IndexData; 93 } 94 } 95 96 public class IndexBufferObjectUS : IndexBufferObject<ushort> 97 { IndexBufferObjectUS(ushort[] IndexData, BufferUsageHint DrawType)98 public IndexBufferObjectUS(ushort[] IndexData, BufferUsageHint DrawType) : base(IndexData, DrawType) 99 { 100 } 101 BufferData()102 internal override void BufferData() 103 { 104 GL.BufferData(BufferTarget.ElementArrayBuffer, indexData.Length * sizeof(ushort), indexData, drawType); 105 } 106 Draw(PrimitiveType DrawMode)107 internal override void Draw(PrimitiveType DrawMode) 108 { 109 GL.DrawElements(DrawMode, indexData.Length, DrawElementsType.UnsignedShort, 0); 110 } 111 Draw(PrimitiveType DrawMode, int Start, int Count)112 internal override void Draw(PrimitiveType DrawMode, int Start, int Count) 113 { 114 GL.DrawElements(DrawMode, Count, DrawElementsType.UnsignedShort, Start * sizeof(ushort)); 115 } 116 } 117 118 public class IndexBufferObjectUI : IndexBufferObject<uint> 119 { IndexBufferObjectUI(uint[] IndexData, BufferUsageHint DrawType)120 public IndexBufferObjectUI(uint[] IndexData, BufferUsageHint DrawType) : base(IndexData, DrawType) 121 { 122 } 123 BufferData()124 internal override void BufferData() 125 { 126 GL.BufferData(BufferTarget.ElementArrayBuffer, indexData.Length * sizeof(uint), indexData, drawType); 127 } 128 Draw(PrimitiveType DrawMode)129 internal override void Draw(PrimitiveType DrawMode) 130 { 131 GL.DrawElements(DrawMode, indexData.Length, DrawElementsType.UnsignedInt, 0); 132 } 133 Draw(PrimitiveType DrawMode, int Start, int Count)134 internal override void Draw(PrimitiveType DrawMode, int Start, int Count) 135 { 136 GL.DrawElements(DrawMode, Count, DrawElementsType.UnsignedInt, Start * sizeof(uint)); 137 } 138 } 139 } 140