mesh and vertex buffers, continue development

This commit is contained in:
Vadim Lopatin 2016-02-18 15:09:09 +03:00
parent bc9fe4f2f0
commit 82d7eb746f
2 changed files with 96 additions and 40 deletions

View File

@ -1003,44 +1003,75 @@ alias FBO = GLObject!(GLObjectTypes.Framebuffer, GL_FRAMEBUFFER);
import dlangui.graphics.scene.mesh; import dlangui.graphics.scene.mesh;
class VertexBuffer { class VertexBufferBase {
protected GLuint _vertexBuffer; /// bind into current context
protected bool _dynamic; void bind() {}
this(Mesh mesh, bool dynamic = false) { /// unbind from current context
_dynamic = dynamic; void unbind() {}
assertgl!glGenBuffers(1, &_vertexBuffer); /// set or change data
assertgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); void setData(Mesh mesh) { }
assertgl!glBufferData(GL_ARRAY_BUFFER, mesh.vertexFormat.vertexSize * mesh.vertexCount, null, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
}
void setVertexData(float[] data) {
assertgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
assertgl!glBufferData(GL_ARRAY_BUFFER, float.sizeof * cast(int)data.length , data.ptr, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
}
~this() {
if (_vertexBuffer) {
checkgl!glDeleteBuffers(1, &_vertexBuffer);
_vertexBuffer = 0;
}
}
} }
class VertexAttributeBinding { class VertexBuffer : VertexBufferBase {
protected GLuint _handle; protected VertexFormat _format;
this(Mesh mesh) { protected GLuint _vertexBuffer;
protected GLuint _indexBuffer;
protected GLuint _vao;
this() {
assertgl!glGenBuffers(1, &_vertexBuffer);
assertgl!glGenBuffers(1, &_indexBuffer);
assertgl!glGenVertexArrays(1, &_vao);
}
~this() {
checkgl!glDeleteBuffers(1, &_vertexBuffer);
checkgl!glDeleteBuffers(1, &_indexBuffer);
checkgl!glDeleteVertexArrays(1, &_vao);
}
/// bind into current context
override void bind() {
glBindVertexArray(_vao);
}
/// unbind from current context
override void unbind() {
checkgl!glBindVertexArray(0);
checkgl!glBindBuffer(GL_ARRAY_BUFFER, 0); checkgl!glBindBuffer(GL_ARRAY_BUFFER, 0);
checkgl!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); checkgl!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
checkgl!glGenVertexArrays(1, &_handle);
if (!_handle) {
Log.e("Cannot generate vertex array id");
return;
} }
checkgl!glBindVertexArray(_handle);
//glBindBuffer(_handle, void updateVertexFormat() {
checkgl!glBindVertexArray(0); // TODO: use vertex attributes from format and shaders
} glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(0));
~this() { glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(float.sizeof*3));
if (_handle) { glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, _format.vertexSize, cast(char*)(float.sizeof*6));
checkgl!glDeleteVertexArrays(1, &_handle);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
} }
/// set or change data
override void setData(Mesh mesh) {
_format = mesh.vertexFormat;
// vertex buffer
checkgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
checkgl!glBufferData(GL_ARRAY_BUFFER, _format.vertexSize * mesh.vertexCount, mesh.vertexData.ptr, GL_STATIC_DRAW);
// index buffer
checkgl!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
const(ushort[]) indexData = mesh.indexData;
checkgl!glBufferData(GL_ELEMENT_ARRAY_BUFFER, ushort.sizeof * mesh.indexData.length, indexData.ptr, GL_STATIC_DRAW);
// vertex layout
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();
} }
} }

View File

@ -87,7 +87,7 @@ struct VertexFormat {
return false; return false;
} }
/// compare /// compare
bool opEquals(immutable ref VertexFormat fmt) { bool opEquals(immutable ref VertexFormat fmt) const {
if (_vertexSize != fmt._vertexSize) if (_vertexSize != fmt._vertexSize)
return false; return false;
for(int i = 0; i < _elements.length; i++) for(int i = 0; i < _elements.length; i++)
@ -105,6 +105,9 @@ class Mesh {
protected MeshPart[] _parts; protected MeshPart[] _parts;
@property ref const(VertexFormat) vertexFormat() const { return _vertexFormat; } @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); assert(_vertexCount == 0);
_vertexFormat = format; _vertexFormat = format;
@ -112,6 +115,28 @@ class Mesh {
/// returns vertex count /// returns vertex count
@property int vertexCount() const { return _vertexCount; } @property int vertexCount() const { return _vertexCount; }
/// returns vertex data array
@property const(float[]) vertexData() const { return _vertexData; }
/// return index data for all parts
@property const(ushort[]) indexData() const {
if (!_parts)
return null;
if (_parts.length == 1)
return _parts[0].data;
int sz = 0;
foreach(p; _parts)
sz += p.length;
ushort[] res;
res.length = 0;
int pos = 0;
foreach(p; _parts) {
res[pos .. pos + p.length] = p.data[0 .. $];
pos += p.length;
}
return res;
}
/// mesh part count /// mesh part count
@property int partCount() const { return cast(int)_parts.length; } @property int partCount() const { return cast(int)_parts.length; }
/// returns mesh part by index /// returns mesh part by index
@ -122,7 +147,7 @@ class Mesh {
return meshPart; return meshPart;
} }
MeshPart addPart(PrimitiveType type, int[] indexes) { MeshPart addPart(PrimitiveType type, ushort[] indexes) {
return addPart(new MeshPart(type, indexes)); return addPart(new MeshPart(type, indexes));
} }
@ -166,14 +191,14 @@ enum PrimitiveType : int {
/// Mesh part - set of vertex indexes with graphics primitive type /// Mesh part - set of vertex indexes with graphics primitive type
class MeshPart { class MeshPart {
protected PrimitiveType _type; protected PrimitiveType _type;
protected int[] _indexData; protected ushort[] _indexData;
this(PrimitiveType type, int[] indexes = null) { this(PrimitiveType type, ushort[] indexes = null) {
_type = type; _type = type;
_indexData.assumeSafeAppend; _indexData.assumeSafeAppend;
add(indexes); add(indexes);
} }
void add(int[] indexes) { void add(ushort[] indexes) {
if (indexes.length) if (indexes.length)
_indexData ~= indexes; _indexData ~= indexes;
} }
@ -188,5 +213,5 @@ class MeshPart {
@property int length() const { return cast(int)_indexData.length; } @property int length() const { return cast(int)_indexData.length; }
/// index data /// index data
@property int[] data() { return _indexData; } @property const(ushort[]) data() const { return _indexData; }
} }