mesh and vertex buffer

This commit is contained in:
Vadim Lopatin 2016-02-19 11:16:58 +03:00
parent 5eea4c57b6
commit eda2ce8216
2 changed files with 94 additions and 25 deletions

View File

@ -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;
}
}

View File

@ -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,12 +138,24 @@ 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; }
@ -141,6 +165,7 @@ class Mesh {
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