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;
class VertexBuffer {
protected GLuint _vertexBuffer;
protected bool _dynamic;
this(Mesh mesh, bool dynamic = false) {
_dynamic = dynamic;
assertgl!glGenBuffers(1, &_vertexBuffer);
assertgl!glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
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 VertexBufferBase {
/// bind into current context
void bind() {}
/// unbind from current context
void unbind() {}
/// set or change data
void setData(Mesh mesh) { }
}
class VertexAttributeBinding {
protected GLuint _handle;
this(Mesh mesh) {
class VertexBuffer : VertexBufferBase {
protected VertexFormat _format;
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_ELEMENT_ARRAY_BUFFER, 0);
checkgl!glGenVertexArrays(1, &_handle);
if (!_handle) {
Log.e("Cannot generate vertex array id");
return;
}
checkgl!glBindVertexArray(_handle);
//glBindBuffer(_handle,
checkgl!glBindVertexArray(0);
}
~this() {
if (_handle) {
checkgl!glDeleteVertexArrays(1, &_handle);
}
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;
// 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;
}
/// compare
bool opEquals(immutable ref VertexFormat fmt) {
bool opEquals(immutable ref VertexFormat fmt) const {
if (_vertexSize != fmt._vertexSize)
return false;
for(int i = 0; i < _elements.length; i++)
@ -105,6 +105,9 @@ class Mesh {
protected MeshPart[] _parts;
@property ref const(VertexFormat) vertexFormat() const { return _vertexFormat; }
@property VertexFormat vertexFormat() { return _vertexFormat; }
@property void vertexFormat(VertexFormat format) {
assert(_vertexCount == 0);
_vertexFormat = format;
@ -112,6 +115,28 @@ class Mesh {
/// returns vertex count
@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
@property int partCount() const { return cast(int)_parts.length; }
/// returns mesh part by index
@ -122,7 +147,7 @@ class Mesh {
return meshPart;
}
MeshPart addPart(PrimitiveType type, int[] indexes) {
MeshPart addPart(PrimitiveType type, ushort[] indexes) {
return addPart(new MeshPart(type, indexes));
}
@ -166,14 +191,14 @@ enum PrimitiveType : int {
/// Mesh part - set of vertex indexes with graphics primitive type
class MeshPart {
protected PrimitiveType _type;
protected int[] _indexData;
this(PrimitiveType type, int[] indexes = null) {
protected ushort[] _indexData;
this(PrimitiveType type, ushort[] indexes = null) {
_type = type;
_indexData.assumeSafeAppend;
add(indexes);
}
void add(int[] indexes) {
void add(ushort[] indexes) {
if (indexes.length)
_indexData ~= indexes;
}
@ -188,5 +213,5 @@ class MeshPart {
@property int length() const { return cast(int)_indexData.length; }
/// index data
@property int[] data() { return _indexData; }
@property const(ushort[]) data() const { return _indexData; }
}