mirror of https://github.com/buggins/dlangui.git
mesh and vertex buffers, continue development
This commit is contained in:
parent
bc9fe4f2f0
commit
82d7eb746f
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue