diff --git a/rwengine/include/render/DrawBuffer.hpp b/rwengine/include/render/DrawBuffer.hpp new file mode 100644 index 00000000..725cad95 --- /dev/null +++ b/rwengine/include/render/DrawBuffer.hpp @@ -0,0 +1,24 @@ +#pragma once +#ifndef _DRAWBUFFER_HPP_ +#define _DRAWBUFFER_HPP_ +#include + +class GeometryBuffer; +class DrawBuffer { + GLuint vao; + +public: + + DrawBuffer(); + ~DrawBuffer(); + + GLuint getVAOName() const + { return vao; } + + /** + * Adds a Geometry Buffer to the Draw Buffer. + */ + void addGeometry(GeometryBuffer* gbuff); +}; + +#endif \ No newline at end of file diff --git a/rwengine/include/render/GeometryBuffer.hpp b/rwengine/include/render/GeometryBuffer.hpp new file mode 100644 index 00000000..638e249d --- /dev/null +++ b/rwengine/include/render/GeometryBuffer.hpp @@ -0,0 +1,61 @@ +#pragma once +#ifndef _GEOMETRYBUFFER_HPP_ +#define _GEOMETRYBUFFER_HPP_ +#include +#include + +/** + * Enum used to determine which shader input an attribute maps to + */ +enum AttributeSemantic { + ATRS_Position, + ATRS_Normal, + ATRS_Colour, + ATRS_TexCoord +}; + +/** + * Stores Vertex Attribute data + */ +struct AttributeIndex { + AttributeSemantic sem; + GLsizei size; + /*GLenum type*/ + GLsizei stride; + GLsizei offset; +}; + +typedef std::vector AttributeList; + +class GeometryBuffer { + GLuint vbo; + GLsizei num; + + AttributeList attributes; +public: + + GeometryBuffer(); + ~GeometryBuffer(); + + GLuint getVBOName() const + { return vbo; } + + /** + * Uploads Vertex Buffer data from an STL vector + */ + template void uploadVertices(const std::vector& data) { + uploadVertices(data.size(), data.size()*sizeof(T), data.data()); + // Assume T has a static method for attributes; + attributes = T::vertex_attributes(); + } + + /** + * Uploads raw memory into the buffer. + */ + void uploadVertices(GLsizei num, GLsizeiptr size, const GLvoid* mem); + + const AttributeList& getDataAttributes() const + { return attributes; } +}; + +#endif \ No newline at end of file diff --git a/rwengine/src/render/DrawBuffer.cpp b/rwengine/src/render/DrawBuffer.cpp new file mode 100644 index 00000000..352beb31 --- /dev/null +++ b/rwengine/src/render/DrawBuffer.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +/* TODO: Come up with a more elegant solution to "WHICH ARRAY IS IT?" */ +std::map semantic_to_attrib_array = { + {ATRS_Position, 0}, + {ATRS_Normal, 4}, + {ATRS_Colour, 8}, + {ATRS_TexCoord, 12} +}; + +DrawBuffer::DrawBuffer() +: vao(0) +{ + +} + +DrawBuffer::~DrawBuffer() +{ + if(vao) { + glDeleteVertexArrays(1, &vao); + } +} + +void DrawBuffer::addGeometry(GeometryBuffer* gbuff) +{ + if(vao == 0) { + glGenVertexArrays(1, &vao); + } + + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, gbuff->getVBOName()); + // Iterate the attributes present in the gbuff + for(const AttributeIndex& at : gbuff->getDataAttributes()) { + GLuint vaoindex = semantic_to_attrib_array[at.sem]; + glEnableVertexAttribArray(vaoindex); + glVertexAttribPointer(vaoindex, at.size, GL_FLOAT, GL_FALSE, at.stride, reinterpret_cast(at.offset)); + } +} diff --git a/rwengine/src/render/GeometryBuffer.cpp b/rwengine/src/render/GeometryBuffer.cpp new file mode 100644 index 00000000..2c7696d5 --- /dev/null +++ b/rwengine/src/render/GeometryBuffer.cpp @@ -0,0 +1,17 @@ +#include + +GeometryBuffer::GeometryBuffer() + : vbo(0), num(0) +{ + +} + +void GeometryBuffer::uploadVertices(GLsizei num, GLsizeiptr size, const GLvoid* mem) +{ + if(vbo == 0) { + glGenBuffers(1, &vbo); + } + this->num = num; + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, size, mem, GL_STATIC_DRAW); +}