diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index ddfc9d49..4b61a6ef 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -1023,8 +1023,9 @@ alias VBO = GLObject!(GLObjectTypes.Buffer, GL_ARRAY_BUFFER); alias Tex2D = GLObject!(GLObjectTypes.Texture, GL_TEXTURE_2D); alias FBO = GLObject!(GLObjectTypes.Framebuffer, GL_FRAMEBUFFER); -class VertexBuffer : VertexBufferBase { +class GLVertexBuffer : VertexBuffer { protected VertexFormat _format; + protected IndexFragment[] _indexFragments; protected GLuint _vertexBuffer; protected GLuint _indexBuffer; protected GLuint _vao; @@ -1066,20 +1067,10 @@ class VertexBuffer : VertexBufferBase { } } - void updateVertexFormat() { - // TODO: use vertex attributes from format and shaders - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(0)); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(float.sizeof*3)); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(float.sizeof*6)); - - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - } - /// set or change data override void setData(Mesh mesh) { _format = mesh.vertexFormat; + _indexFragments = mesh.indexFragments; // vertex buffer checkgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); checkgl!glBufferData(GL_ARRAY_BUFFER, _format.vertexSize * mesh.vertexCount, mesh.vertexData.ptr, GL_STATIC_DRAW); @@ -1091,11 +1082,38 @@ class VertexBuffer : VertexBufferBase { checkgl!glBindVertexArray(_vao); // specify vertex buffer checkgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); - // set vertex buffer format - updateVertexFormat(); // specify index buffer checkgl!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); unbind(); } + + /// draw mesh using specified effect + override void draw(GraphicsEffect effect) { + bind(); + prepareDrawing(effect); + foreach (fragment; _indexFragments) { + glDrawRangeElements(primitiveTypeToGL(fragment.type), + fragment.start, fragment.end, + fragment.end - fragment.start, + GL_UNSIGNED_SHORT, null); + } + unbind(); + } +} + +GLenum primitiveTypeToGL(PrimitiveType type) { + switch(type) with (PrimitiveType) { + case triangles: + return GL_TRIANGLES; + case triangleStripes: + return GL_TRIANGLE_STRIP; + case lines: + return GL_LINES; + case lineStripes: + return GL_LINE_STRIP; + case points: + default: + return GL_POINTS; + } } diff --git a/src/dlangui/graphics/scene/mesh.d b/src/dlangui/graphics/scene/mesh.d index 5273ad6b..7cbbf1bb 100644 --- a/src/dlangui/graphics/scene/mesh.d +++ b/src/dlangui/graphics/scene/mesh.d @@ -3,6 +3,7 @@ module dlangui.graphics.scene.mesh; import dlangui.graphics.scene.material; import dlangui.core.math3d; +/// vertex element type enum VertexElementType : ubyte { POSITION = 1, NORMAL, @@ -17,8 +18,17 @@ enum VertexElementType : ubyte { TEXCOORD7, } +/// Graphics primitive type +enum PrimitiveType : int { + triangles, + triangleStripes, + lines, + lineStripes, + points, +} + /// Vertex buffer object base class -class VertexBufferBase { +class VertexBuffer { /// bind into current context void bind() {} /// unbind from current context @@ -27,6 +37,8 @@ class VertexBufferBase { void setData(Mesh mesh) { } /// update vertex element locations for effect/shader program void prepareDrawing(GraphicsEffect effect) { } + /// draw mesh using specified effect + void draw(GraphicsEffect effect) { } } /// location for element is not found @@ -61,7 +73,7 @@ struct VertexElement { case COLOR: size = 4; break; - default: + default: // tx coords size = 2; break; } @@ -126,21 +138,34 @@ struct VertexFormat { } } +struct IndexFragment { + PrimitiveType type; + ushort start; + ushort end; + this(PrimitiveType type, int start, int end) { + this.type = type; + this.start = cast(ushort)start; + this.end = cast(ushort)end; + } +} + /// Mesh class Mesh { protected VertexFormat _vertexFormat; protected int _vertexCount; protected float[] _vertexData; protected MeshPart[] _parts; + protected VertexBuffer _vertexBuffer; @property ref const(VertexFormat) vertexFormat() const { return _vertexFormat; } @property VertexFormat vertexFormat() { return _vertexFormat; } - @property void vertexFormat(VertexFormat format) { + @property void vertexFormat(VertexFormat format) { assert(_vertexCount == 0); _vertexFormat = format; } + /// returns vertex count @property int vertexCount() const { return _vertexCount; } @@ -166,6 +191,34 @@ class Mesh { return res; } + /// list of mesh fragments + @property IndexFragment[] indexFragments() const { + IndexFragment[] res; + int pos = 0; + foreach(p; _parts) { + res ~= IndexFragment(p.type, pos, pos + p.length); + pos += p.length; + } + return res; + } + + /// get vertex buffer object + @property VertexBuffer vertexBuffer() { + return _vertexBuffer; + } + + /// set vertex buffer object + @property void vertexBuffer(VertexBuffer buffer) { + if (_vertexBuffer) { + _vertexBuffer.destroy; + _vertexBuffer = null; + } + _vertexBuffer = buffer; + if (_vertexBuffer) { + _vertexBuffer.setData(this); + } + } + /// mesh part count @property int partCount() const { return cast(int)_parts.length; } /// returns mesh part by index @@ -206,15 +259,13 @@ class Mesh { this(VertexFormat vertexFormat) { _vertexFormat = vertexFormat; } -} -/// Graphics primitive type -enum PrimitiveType : int { - triangles, - triangleStripes, - lines, - lineStripes, - points, + ~this() { + if (_vertexBuffer) { + _vertexBuffer.destroy; + _vertexBuffer = null; + } + } } /// Mesh part - set of vertex indexes with graphics primitive type