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