1 module d2d.rendering.mesh; 2 3 import d2d; 4 5 /// Class containing mesh IDs and length for OpenGL drawing. 6 class RenderableMesh 7 { 8 /// OpenGL id of the vao buffer. 9 public uint bufferID; 10 /// OpenGL array of the vbo buffers. 11 public uint * vbos; 12 /// Length of the index buffer. 13 public uint indexLength; 14 15 /// Constructor for creating a new RenderableMesh with existing data. 16 public this(uint bufferID, uint* vbos, uint indexLength) 17 { 18 this.bufferID = bufferID; 19 this.vbos = vbos; 20 this.indexLength = indexLength; 21 } 22 } 23 24 /// Class for raw geometry. 25 class Mesh : IDisposable, IVerifiable 26 { 27 ~this() 28 { 29 dispose(); 30 } 31 32 /// Array of the vertices. 33 public @property vec3[] vertices() 34 { 35 return _vertices; 36 } 37 38 /// Array of the indices. 39 public @property uint[] indices() 40 { 41 return _indices; 42 } 43 44 /// Array of the texture coordinates. 45 public @property vec2[] texCoords() 46 { 47 return _texCoords; 48 } 49 50 /// Checks if this Mesh can be drawn. 51 public @property bool valid() 52 { 53 return renderable !is null; 54 } 55 56 /// Adds one vertex. 57 public void addVertex(vec3 vertex) 58 { 59 _vertices ~= vertex; 60 } 61 62 /// Adds many vertices. 63 public void addVertices(const vec3[] vertices) 64 { 65 _vertices ~= vertices; 66 } 67 68 /// Adds one index. 69 public void addIndex(uint index) 70 { 71 _indices ~= index; 72 } 73 74 /// Adds many indices. 75 public void addIndices(const uint[] indices) 76 { 77 _indices ~= indices; 78 } 79 80 /// Adds one texture coordinate. 81 public void addTexCoord(vec2 texCoord) 82 { 83 _texCoords ~= texCoord; 84 } 85 86 /// Adds many texture coordinates. 87 public void addTexCoords(const vec2[] texCoords) 88 { 89 _texCoords ~= texCoords; 90 } 91 92 /// Deletes the mesh from memory and cleans up. 93 public void dispose() 94 { 95 if (valid) 96 { 97 glDeleteBuffers(3, renderable.vbos); 98 glDeleteVertexArrays(1, &renderable.bufferID); 99 renderable = null; 100 } 101 } 102 103 /// Generates the RenderableMesh from the previously defined vertices and makes `this` valid. 104 public void create() 105 { 106 uint vao; 107 glGenVertexArrays(1, &vao); 108 glBindVertexArray(vao); 109 110 uint* vbo = new uint[3].ptr; 111 112 glGenBuffers(3, vbo); 113 114 glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); 115 glBufferData(GL_ARRAY_BUFFER, vec3.sizeof * vertices.length, vertices.ptr, GL_STATIC_DRAW); 116 glVertexAttribPointer(0u, 3, GL_FLOAT, cast(ubyte) 0, 0, null); 117 glEnableVertexAttribArray(0); 118 119 glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); 120 glBufferData(GL_ARRAY_BUFFER, vec2.sizeof * texCoords.length, texCoords.ptr, GL_STATIC_DRAW); 121 glVertexAttribPointer(1u, 2, GL_FLOAT, cast(ubyte) 0, 0, null); 122 glEnableVertexAttribArray(1); 123 124 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]); 125 glBufferData(GL_ELEMENT_ARRAY_BUFFER, uint.sizeof * indices.length, indices.ptr, GL_STATIC_DRAW); 126 127 glBindVertexArray(0); 128 129 renderable = new RenderableMesh(vao, vbo, cast(uint) indices.length); 130 } 131 132 /// Renderable mesh when create got called. Before its `null`. 133 public RenderableMesh renderable = null; 134 135 private vec3[] _vertices; 136 private vec3[] _normals; 137 private vec2[] _texCoords; 138 private uint[] _indices; 139 }