From 6644065388c28051c128d1a504eae010ff0f27bd Mon Sep 17 00:00:00 2001 From: NaifBanana <30419422+NaifBanana@users.noreply.github.com> Date: Sun, 11 Oct 2026 13:29:21 -0500 Subject: [PATCH] Heavy buffer update, window update, object tracking --- engine/NBGraphics/CMakeLists.txt | 5 +- .../NBGraphics/include/NBGraphics/Buffers.hpp | 139 +++++--- engine/NBGraphics/include/NBGraphics/Draw.hpp | 83 ----- engine/NBGraphics/include/NBGraphics/Mesh.hpp | 81 +++++ .../include/NBGraphics/OGLObjects.hpp | 1 + .../include/NBGraphics/VertexArray.hpp | 167 ++-------- .../include/NBGraphics/VertexData.hpp | 43 +++ .../NBGraphics/include/NBGraphics/Window.hpp | 54 ++- engine/NBGraphics/src/Buffers.cpp | 38 +-- engine/NBGraphics/src/Draw.cpp | 307 ------------------ engine/NBGraphics/src/Mesh.cpp | 73 +++++ engine/NBGraphics/src/OGLObjects.cpp | 19 +- engine/NBGraphics/src/VertexArray.cpp | 227 +++---------- engine/NBGraphics/src/VertexData.cpp | 16 + engine/NBGraphics/src/Window.cpp | 132 +++++--- engine/NBGraphics/tests/TestWindow.cpp | 11 +- 16 files changed, 553 insertions(+), 843 deletions(-) delete mode 100644 engine/NBGraphics/include/NBGraphics/Draw.hpp create mode 100644 engine/NBGraphics/include/NBGraphics/Mesh.hpp create mode 100644 engine/NBGraphics/include/NBGraphics/VertexData.hpp delete mode 100644 engine/NBGraphics/src/Draw.cpp create mode 100644 engine/NBGraphics/src/Mesh.cpp create mode 100644 engine/NBGraphics/src/VertexData.cpp diff --git a/engine/NBGraphics/CMakeLists.txt b/engine/NBGraphics/CMakeLists.txt index f7b6b76..abf84c0 100644 --- a/engine/NBGraphics/CMakeLists.txt +++ b/engine/NBGraphics/CMakeLists.txt @@ -30,23 +30,26 @@ toAbsolutePath(NB_GRAPHICS_SOURCE ./src/Buffers.cpp ./src/FrameBuffers.cpp ./src/Image.cpp + ./src/Mesh.cpp ./src/OGLObjects.cpp ./src/ProgramPipeline.cpp ./src/Textures.cpp ./src/VertexArray.cpp + ./src/VertexData.cpp ./src/Window.cpp ) toAbsolutePath(NB_GRAPHICS_INCLUDE ./include/NBGraphics/Buffers.hpp ./include/NBGraphics/Camera.hpp - ./include/NBGraphics/Draw.hpp ./include/NBGraphics/FrameBuffers.hpp ./include/NBGraphics/GLLoad.hpp ./include/NBGraphics/Image.hpp + ./include/NBGraphics/Mesh.hpp ./include/NBGraphics/OGLObjects.hpp ./include/NBGraphics/ProgramPipeline.hpp ./include/NBGraphics/Textures.hpp ./include/NBGraphics/VertexArray.hpp + ./include/NBGraphics/VertexData.hpp ./include/NBGraphics/Window.hpp ) diff --git a/engine/NBGraphics/include/NBGraphics/Buffers.hpp b/engine/NBGraphics/include/NBGraphics/Buffers.hpp index 968ee17..2ff5ac8 100644 --- a/engine/NBGraphics/include/NBGraphics/Buffers.hpp +++ b/engine/NBGraphics/include/NBGraphics/Buffers.hpp @@ -57,7 +57,8 @@ class BufferError : public Error { enum Codes : unsigned int { UNDEFINED, DATA_OVERFLOW, - DATA_ERROR + DATA_ERROR, + BAD_DATA_TYPE }; static const std::string type; static const ErrorCodeMap ErrorMessages; @@ -69,7 +70,6 @@ class Buffer : public OpenGLObject { using OpenGLObject::_id; GLenum _usage = GL_STATIC_DRAW; size_t _size; - Buffer(GLenum target) : Target(target) {} virtual GLuint declare() override { if (!_id) { OPENGL_CALL(glGenBuffers(1, &_id)); @@ -88,6 +88,8 @@ class Buffer : public OpenGLObject { public: const GLenum Target; using OpenGLObject::OpenGLObject; + Buffer(GLenum target); + Buffer(GLenum target, const ByteVector&, GLenum usage=GL_STATIC_DRAW); Buffer(Buffer&& other); Buffer& operator=(Buffer&& rhs); @@ -151,15 +153,6 @@ protected: }; */ -class ArrayBuffer : public Buffer { - public: - template - ArrayBuffer(const std::vector& data, GLenum usage=GL_STATIC_DRAW) - : Buffer(GL_ARRAY_BUFFER) { - Buffer::data(vectorToBytes(data), usage); - } -}; - class UniformBuffer : public Buffer { protected: GLuint _index; @@ -172,58 +165,96 @@ class UniformBuffer : public Buffer { }; -class ElementBuffer : protected Buffer { +template +struct IsValidGLElementIndexType { + static constexpr bool value = false; + +}; + +template +struct ValidGLElementIndexType { + static constexpr bool value = true; + static constexpr GLenum glsltype = GLSLType::value; +}; + + +template<> +struct IsValidGLElementIndexType : public ValidGLElementIndexType {}; +template<> +struct IsValidGLElementIndexType : public ValidGLElementIndexType {}; +template<> +struct IsValidGLElementIndexType : public ValidGLElementIndexType {}; + +class ElementBuffer : Buffer { + private: + template + inline void checkForElementDataType() { + static_assert(IsValidGLElementIndexType::value, + "ElementBuffer data type must resolve to one of GL_UNSIGNED_BYTE," + "GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT" + ); + } + protected: - GLenum _glslType; - size_t _typeSize; + using Codes = BufferError::Codes; + using OpenGLObject::_id; + using Buffer::_usage; + using Buffer::_size; + using Buffer::declare; + using Buffer::remove; + GLenum _datatype; + template + inline void checkDatatypeConsistency() { + if (_datatype != ValidGLElementIndexType::value) { + THROW(BufferError( + Codes::BAD_DATA_TYPE, + GLenumTable[ValidGLElementIndexType::value] + " not same as buffer " + "data type "+GLenumTable[_datatype] + )); + } + } public: using Buffer::Target; + using Buffer::OpenGLObject; using Buffer::bind; - using Buffer::usage; using Buffer::unbind; - ElementBuffer(); + using Buffer::usage; + using Buffer::size; template - ElementBuffer(const T* const data_ptr, size_t size, GLenum usage=GL_STATIC_DRAW) - : Buffer(GL_ELEMENT_ARRAY_BUFFER) { - data(data_ptr, size, usage); - } - template - ElementBuffer(const std::vector& data_, GLenum usage_=GL_STATIC_DRAW) - : ElementBuffer(data_.data(), data_.size(), usage_) {} - - size_t size() const; - size_t typeSize() const; - ByteVector data() const; - GLenum glslType() const; - template - void data(const T* data_, size_t size_, GLenum usage_=GL_STATIC_DRAW) { - declare(); - using TypeInfo = GLSLType; - _typeSize = TypeInfo::size; - Buffer::data(data_, size_*_typeSize, usage_); - _glslType = TypeInfo::value; - } - template - void data(const std::vector& data_, GLenum usage_=GL_STATIC_DRAW) { - data(data_.data(), data_.size(), usage_); - } - template - void subdata(const T* data, size_t size, size_t offset) { - using TypeInfo = GLSLType; - if ( _glslType != TypeInfo::value ) { - THROW( BufferError( - Codes::DATA_ERROR, - "Check element buffer data types" - ) ); - } - Buffer::subdata(data, size*_typeSize, offset); - } - template - void subdata(const std::vector& data, size_t offset=0) { - subdata(data.data(), data.size(), offset); + ElementBuffer(const std::vector& indices, GLenum usage=GL_STATIC_DRAW) : Buffer(GL_ELEMENT_ARRAY_BUFFER) { + data(indices, usage); } + inline GLenum datatype() { return _datatype; } + + template + void data(const std::vector& data, GLenum usage=GL_STATIC_DRAW) { + checkForElementDataType(); + _datatype = ValidGLElementIndexType::glsltype; + Buffer::data(vectorToBytes(data), usage); + } + + template + void data(const T* data, size_t size, GLenum usage=GL_STATIC_DRAW) { + checkForElementDataType(); + _datatype = ValidGLElementIndexType::glsltype; + Buffer::data((void*)data, size * sizeof(T), usage); + } + + template + void subdata(const T* data, size_t size, GLintptr offset=0) { + checkForElementDataType(); + checkDatatypeConsistency(); + Buffer::subdata((void*)data, size * sizeof(T), offset); + } + + template + void subdata(const std::vector& data_, GLintptr offset=0) { + checkForElementDataType(); + checkDatatypeConsistency(); + Buffer::subdata(vectorToBytes(data_), offset); + } }; diff --git a/engine/NBGraphics/include/NBGraphics/Draw.hpp b/engine/NBGraphics/include/NBGraphics/Draw.hpp deleted file mode 100644 index 1b5602b..0000000 --- a/engine/NBGraphics/include/NBGraphics/Draw.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once -#ifndef _NB_DRAW -#define _NB_DRAW - -#include - -#include -#include -#include -#include - -#include -#include - -#define THROW_DRAW_ERROR(msg) throw DrawError(msg, __FILE__, __LINE__); - -namespace nb{ - -class DrawError : public std::runtime_error { -public: - DrawError(const std::string&, const std::string& file="", int line=-1); -}; - -uint8_t VerticesFromPrimitives(GLenum, unsigned int num_prims=1); - -uint8_t PrimitivesFromVertices(GLenum, unsigned int); - -void copyVertexAttribute(const VertexAttribute&, VertexAttribute&); - -class DrawBuffer { -public: -typedef std::shared_ptr BufferManagerPointer; - DrawBuffer(VertexAttributeList, GLenum prim_type=GL_TRIANGLES); - //DrawBuffer(std::initializer_list, std::initializer_list); - - unsigned int vertSize() const; - const std::shared_ptr shader() const; - unsigned int elementBufferID() const; - unsigned int vertexBufferID() const; - virtual void draw() const; - RawVec vertAttrData(unsigned int); - - VertexAttributeList changeVertLayout(unsigned int, VertexAttributePointer); - RawVec vertAttrData(unsigned int, const RawVec&); - virtual void elementData(const std::vector&); - virtual void elementData(unsigned int); - virtual void elementData(const std::vector&, unsigned int offset); - virtual void vertexData(const RawVec&); - virtual void vertexData(unsigned int num_verts); - virtual void vertexData(const RawVec&, unsigned int offset); - - BufferManagerPointer _vert_data; - BufferManagerPointer _elmt_data; - VAOManager _VAO; - const GLenum _gl_primitive_type=0; - virtual VertexAttributeList defaultVAO(VertexAttributeList); - - unsigned int _num_verts, _num_prims; -protected: -}; - -class DrawInstanceBuffer : public DrawBuffer { -public: - DrawInstanceBuffer(VertexAttributeList, VertexAttributeList, GLenum primt_type=GL_TRIANGLES); - - unsigned int instSize() const; - unsigned int instanceBufferID() const; - virtual void draw() const override; - - VertexAttributeList changeInstanceLayout(unsigned int, VertexAttributePointer); - virtual void instanceData(const RawVec&); - virtual void instanceData(unsigned int); - virtual void instanceData(const RawVec&, unsigned int offset); - - BufferManagerPointer _inst_data; - virtual VertexAttributeList defaultVAO(VertexAttributeList); - unsigned int _num_inst; - -protected: -}; - -} -#endif \ No newline at end of file diff --git a/engine/NBGraphics/include/NBGraphics/Mesh.hpp b/engine/NBGraphics/include/NBGraphics/Mesh.hpp new file mode 100644 index 0000000..a5b2139 --- /dev/null +++ b/engine/NBGraphics/include/NBGraphics/Mesh.hpp @@ -0,0 +1,81 @@ +#pragma once +#ifndef _NB_MESH +#define _NB_MESH + +#include + +#include +#include +#include + +namespace nb{ + +class Mesh { + protected: + const GLenum _primitive; + const unsigned int _count; + std::shared_ptr _vao; + + public: + Mesh( + VertexDataPointerList vao, + unsigned int count, + GLenum primitive=GL_TRIANGLES + ); + Mesh(GLenum primitive, const std::shared_ptr& vertex_array, unsigned int count); + Mesh(GLenum primitive, const VertexData& vertex_data, unsigned int count); + Mesh( + GLenum primitive, + const ByteVector& data, + unsigned int count, + const std::vector& attributes + ); + + Mesh(Mesh&&); + Mesh(const Mesh&&) = delete; + Mesh& operator=(Mesh&&) = delete; + Mesh& operator=(const Mesh&) = delete; + + inline virtual void draw() const { this->draw(_count); } + inline virtual void draw(unsigned int count) const { this->draw(0, count); } + virtual void draw(unsigned int offset, unsigned int count) const; + inline GLenum primitive() const { return _primitive; } + inline unsigned int count() const { return _count; } + inline std::shared_ptr vao() const { return _vao; } +}; + +class InstancedMesh : public Mesh { + protected: + using Mesh::_primitive; + using Mesh::_count; + using Mesh::_vao; + + public: + virtual void draw(unsigned int offset, unsigned int count) const; +}; + +class IndexedMesh : public Mesh { + protected: + std::shared_ptr _ebo; + + public: + template + IndexedMesh( + GLenum primitive, + const ByteVector& data, + const std::vector& attributes, + const std::vector& indices + ) : Mesh(primitive, data, indices.size(), attributes) { + _vao->bind(); + _ebo = std::make_shared(indices); + } + + using Mesh::draw; + virtual void draw(unsigned int offset, unsigned int count) const; +}; + +class InstancedIndexedMesh : virtual public IndexedMesh {}; + + +} +#endif \ No newline at end of file diff --git a/engine/NBGraphics/include/NBGraphics/OGLObjects.hpp b/engine/NBGraphics/include/NBGraphics/OGLObjects.hpp index 9a5ab98..c38a6f8 100644 --- a/engine/NBGraphics/include/NBGraphics/OGLObjects.hpp +++ b/engine/NBGraphics/include/NBGraphics/OGLObjects.hpp @@ -11,6 +11,7 @@ namespace nb { typedef ConstantMap GLEnumTableType; extern const GLEnumTableType GLenumTable; +extern const ConstantMap TypeToGLSL; class OpenGLError : public Error { using Base = Error; diff --git a/engine/NBGraphics/include/NBGraphics/VertexArray.hpp b/engine/NBGraphics/include/NBGraphics/VertexArray.hpp index 9688313..d335a8b 100644 --- a/engine/NBGraphics/include/NBGraphics/VertexArray.hpp +++ b/engine/NBGraphics/include/NBGraphics/VertexArray.hpp @@ -8,6 +8,7 @@ #include #include +#include namespace nb { @@ -33,32 +34,13 @@ static uint8_t GLSLTypeSize(GLenum type) { } } -struct VertexAttributeLayout { - int32_t offset = 0; - GLsizei stride = 0; - GLuint divisor = 0; -}; - -struct VertexAttribute { - GLint GLSLSize; - GLenum GLSLType; - GLboolean GLSLNormalization; - VertexAttributeLayout layout; -}; - -struct VertexAttributePointer { - VertexAttribute attribute; - GLuint buffer; - GLuint index; -}; - static bool isIndexInVertexAttribute(int i, const VertexAttribute& va) { if ((i -= va.layout.offset) < 0) { return false; } - return (i%va.layout.stride) < GLSLTypeSize(va.GLSLType) * va.GLSLSize; + return (i%va.layout.stride) < GLSLTypeSize(TypeToGLSL[va.type]) * va.size; } -typedef std::vector VertexAttributeList; -typedef std::vector VertexAttributePointerList; +typedef std::vector VertexDataList; +typedef std::vector VertexDataPointerList; class VAOError : public Error { using Base = Error; @@ -78,10 +60,30 @@ class VAO : public OpenGLObject { using Base = OpenGLObject; using Codes = VAOError::Codes; + protected: + using Base::_id; + VertexDataPointerList _vertexdata; + + virtual void remove() override { + if(_id) { + disable(); + bind(); + OPENGL_CALL(glDeleteVertexArrays(1, &_id)); + _id = 0; + } + } + virtual GLuint declare() override { + if (!_id) { + OPENGL_CALL(glGenVertexArrays(1, &_id)); + } + bind(); + return _id; + } + public: using Base::Base; VAO() = default; - VAO(const VertexAttributePointerList&); + VAO(const VertexDataPointerList&); VAO(VAO&&); VAO& operator=(VAO&&); @@ -100,34 +102,15 @@ class VAO : public OpenGLObject { OPENGL_CALL(glBindVertexArray(0)); } - VertexAttributePointerList attributes() const; - VertexAttributePointerList attributes(const VertexAttributePointerList&); - VertexAttributePointer attr(GLuint) const; + VertexDataPointerList attributes() const; + VertexDataPointerList attributes(const VertexDataPointerList&); + VertexDataPointerList attributes(const VertexDataList&); + VertexDataPointer attribute(GLuint) const; void enable() const; void enable(GLuint) const; void disable() const; void disable(GLuint) const; - protected: - using Base::_id; - VertexAttributePointerList _attrs; - - virtual void remove() override { - if(_id) { - disable(); - bind(); - OPENGL_CALL(glDeleteVertexArrays(1, &_id)); - _id = 0; - } - } - virtual GLuint declare() override { - if (!_id) { - OPENGL_CALL(glGenVertexArrays(1, &_id)); - } - bind(); - return _id; - } - }; class VertexError : public Error { @@ -144,97 +127,5 @@ class VertexError : public Error { }; -using VBO = ArrayBuffer; -using VertBufVec = SharedVector; -using EBO = ElementBuffer; - -struct VertexData { - std::shared_ptr vbo; - VertexAttributeList attrs; -}; - -using VertexDataVec = std::vector; - -class VertexGroup { - protected: - using Codes = VertexError::Codes; - VertexDataVec _vertex_data; - std::shared_ptr _ebo; - std::shared_ptr _vao; - GLenum _primitive; - - public: - GLenum primitive=GL_TRIANGLES; - VertexGroup(VertexGroup&&); - VertexGroup& operator=(VertexGroup&&); - - VertexGroup( - const VertexDataVec& vertex_data, - const std::shared_ptr& ebo - ) - : _vao(std::make_shared()), _ebo(ebo) { - setBuffers(vertex_data); - } - - template - VertexGroup( - const VertexDataVec& vertex_data, - T... args - ) - : VertexGroup(vertex_data, std::make_shared(args...)) { - setBuffers(vertex_data); - } - - template - VertexGroup( - const VertexData& vertex_data, - T... args - ) - : VertexGroup(VertexDataVec{vertex_data}, args...) {} - - template - VertexGroup( - const ByteVector& vertex_data, - const VertexAttributeList& vertex_specification, - T... args - ) : VertexGroup({ - std::make_shared(vertex_data), - vertex_specification}, - args... - ) {} - - void bind() const { - _vao->bind(); - _ebo->bind(); - } - void unbind() const { - _vao->unbind(); - _ebo->unbind(); - } - - void draw() const; - - VertexDataVec getBuffers(); - VertexData getBuffers(size_t); - size_t setBuffers(const VertexDataVec&); - size_t addBuffer(const VertexData&); - size_t addBuffer(const ByteVector& data, const VertexAttributeList& attrs); - VertexDataVec dropBuffers(); - VertexData dropBuffer(size_t); - - VertexAttributePointer attribute(size_t) const; - void enableAttr(GLuint); - void disableAttr(GLuint); - void enableBuffer(size_t); - void disableBuffer(size_t); - void enable(); - void disable(); - - std::shared_ptr indices() const; - std::shared_ptr indices(const std::vector& data); - std::shared_ptr indices(std::shared_ptr buffer); - -}; - } // namespace nb #endif // _NB_VERTEX_ARRAY \ No newline at end of file diff --git a/engine/NBGraphics/include/NBGraphics/VertexData.hpp b/engine/NBGraphics/include/NBGraphics/VertexData.hpp new file mode 100644 index 0000000..387194c --- /dev/null +++ b/engine/NBGraphics/include/NBGraphics/VertexData.hpp @@ -0,0 +1,43 @@ +#pragma once +#ifndef _NB_VERTEX_DATA +#define _NB_VERTEX_DATA + +#include +#include + +#include +#include +#include +#include + +// #include + +namespace nb { + +struct VertexAtrributeLayout { + unsigned int offset = 0; + int stride = 0; + unsigned int divisor = 0; +}; + +struct VertexAttribute { + unsigned int size; + TypeCodes type; + bool normalized; + VertexAtrributeLayout layout; +}; + +struct VertexData { + std::shared_ptr data; + std::vector attributes; + VertexData(std::shared_ptr, const std::vector&); + VertexData(const ByteVector&, const std::vector&); +}; + +struct VertexDataPointer { + std::shared_ptr vertexdata; + unsigned int index; +}; + +} // namespace nb +#endif \ No newline at end of file diff --git a/engine/NBGraphics/include/NBGraphics/Window.hpp b/engine/NBGraphics/include/NBGraphics/Window.hpp index 5acfff9..ff96529 100644 --- a/engine/NBGraphics/include/NBGraphics/Window.hpp +++ b/engine/NBGraphics/include/NBGraphics/Window.hpp @@ -42,32 +42,44 @@ class OGLWindow { protected: static std::atomic _count; static std::atomic _glfwInitialized; - static thread_local std::shared_ptr _currWindow; - static thread_local GLFWwindow* _currArena; - - std::string _title; - GLFWwindow* _window_ptr; - GLFWwindow* _arena; - + static thread_local GLFWwindow* _currWindow; + static thread_local const GLFWwindow* _currArena; + static void SetHintInteger(const std::array&); static void SetHintString(const std::tuple&); + + std::string _title; + GLFWwindow* _window_ptr; + const GLFWwindow* _arena; OGLWindow( unsigned int, unsigned int, const std::string&, const std::vector>&, - const std::vector>& + const std::vector>&, + GLFWwindow* sharingContext = NULL ); + GLFWwindow* makeCurrent() const; + void detachWindow(); public: + enum Callbacks { + KEY, CHAR, CHAR_MODS, MOUSE_BUTTON, CURSOR_POS, CURSOR_ENTER, + SCROLL, DROP, WINDOW_POS, WINDOW_SIZE, WINDOW_CLOSE, WINDOW_REFRESH, + WINDOW_FOCUS, WINDOW_ICONIFY, WINDOW_MAX, FRAMEBUFFER_SIZE, WINDOW_SCALE, + }; + template + using CallbackFunc = void(*)(OGLWindow*, T...); + static inline bool IsGLFWInitialized() { return _glfwInitialized; } static bool InitGLFW(const std::vector& hints={}); static bool TerminateGLFW(); - static inline std::shared_ptr getCurrentWindow() { return _currWindow; } - static inline const GLFWwindow* getCurrentObjectArena() { return _currArena; } - static std::shared_ptr MakeCurrent(const std::shared_ptr&); - static inline std::shared_ptr DropCurrent() { return MakeCurrent(nullptr); } + static inline GLFWwindow* GetCurrentWindow() { return _currWindow; } + static inline const GLFWwindow* GetCurrentObjectArena() { return _currArena; } + static GLFWwindow* MakeCurrent(const std::shared_ptr&); + static inline GLFWwindow* DropCurrent() { return MakeCurrent(nullptr); } + static void DestroyWindow(std::shared_ptr&); static std::shared_ptr CreateWindow( unsigned int x, unsigned int y, @@ -75,21 +87,33 @@ class OGLWindow { const std::vector>& integerHints={}, const std::vector>& stringHints={} ); + static std::shared_ptr CreateSharedWindow( + unsigned int x, + unsigned int y, + const std::string& title, + std::shared_ptr sharingWindow, + const std::vector>& integerHints={}, + const std::vector>& stringHints={} + ); OGLWindow(OGLWindow&&) = delete; OGLWindow(const OGLWindow&) = delete; ~OGLWindow(); inline bool operator==(const OGLWindow& rhs) { return _window_ptr==rhs._window_ptr; } - int getWindowAttribute(int) const; inline GLFWwindow* getWindowPtr() const { return _window_ptr; } + inline const GLFWwindow* getObjectArena() const { return _arena; } inline std::string getTitle() const { return _title; } std::array getSize() const; - std::shared_ptr makeSharedContext(); + bool shouldClose() const; + inline void processEvents() const { CheckForMainThread(); glfwPollEvents(); } + inline void refresh() const { glfwSwapBuffers(_window_ptr); } - void makeCurrent() const; void setSize(unsigned int x, unsigned int y); void setTitle(const std::string&); + void shouldClose(bool); +/* template + void setCallBack(Func); */ }; }; diff --git a/engine/NBGraphics/src/Buffers.cpp b/engine/NBGraphics/src/Buffers.cpp index 7d28d2a..4ffe8bb 100644 --- a/engine/NBGraphics/src/Buffers.cpp +++ b/engine/NBGraphics/src/Buffers.cpp @@ -12,10 +12,21 @@ const std::string BufferError::type = "nb::BufferError"; const ErrorCodeMap BufferError::ErrorMessages = { { BufferErrorCodes::UNDEFINED, "Error" }, { BufferErrorCodes::DATA_OVERFLOW, "Attempting buffer overflow" }, - {BufferErrorCodes::DATA_ERROR, "Invalid memory operation"} - + { BufferErrorCodes::DATA_ERROR, "Invalid memory operation" }, + { BufferErrorCodes::BAD_DATA_TYPE, "Entered data type not allowed for buffer type"} }; +// class Buffer + +Buffer::Buffer(GLenum target_) : OpenGLObject(), Target(target_) { + declare(); +} + +Buffer::Buffer(GLenum target_, const ByteVector& data_, GLenum usage_) : Buffer(target_) { + bind(); + data(data_, usage_); +} + Buffer::Buffer(Buffer&& rval) : Target(rval.Target) { *this = std::move(rval); } @@ -89,17 +100,6 @@ GLuint UniformBuffer::bufferIndex(GLuint idx) { } // class ElementBuffer -ElementBuffer::ElementBuffer() : Buffer(GL_ELEMENT_ARRAY_BUFFER) {} - -ByteVector ElementBuffer::data() const { - return data(); -} - -size_t ElementBuffer::size() const { return _size / _typeSize; } - -size_t ElementBuffer::typeSize() const { return _typeSize; } - -GLenum ElementBuffer::glslType() const { return _glslType; } template void ElementBuffer::data(const std::vector& data, GLenum usage); template void ElementBuffer::data(const std::vector& data, GLenum usage); @@ -108,11 +108,11 @@ template void ElementBuffer::data(const uint8_t* const data, size_t siz template void ElementBuffer::data(const uint16_t* const data, size_t size, GLenum usage); template void ElementBuffer::data(const uint32_t* const data, size_t size, GLenum usage); -template void ElementBuffer::subdata(const uint8_t* const data, size_t size, size_t offset=0); -template void ElementBuffer::subdata(const uint16_t* const data, size_t size, size_t offset=0); -template void ElementBuffer::subdata(const uint32_t* const data, size_t size, size_t offset=0); -template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); -template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); -template void ElementBuffer::subdata(const std::vector& data, size_t offset=0); +template void ElementBuffer::subdata(const uint8_t* const data, size_t size, GLintptr offset=0); +template void ElementBuffer::subdata(const uint16_t* const data, size_t size, GLintptr offset=0); +template void ElementBuffer::subdata(const uint32_t* const data, size_t size, GLintptr offset=0); +template void ElementBuffer::subdata(const std::vector& data, GLintptr offset=0); +template void ElementBuffer::subdata(const std::vector& data, GLintptr offset=0); +template void ElementBuffer::subdata(const std::vector& data, GLintptr offset=0); } \ No newline at end of file diff --git a/engine/NBGraphics/src/Draw.cpp b/engine/NBGraphics/src/Draw.cpp deleted file mode 100644 index 5438287..0000000 --- a/engine/NBGraphics/src/Draw.cpp +++ /dev/null @@ -1,307 +0,0 @@ -#include - -namespace NB{ - -DrawError::DrawError( - const std::string& msg, - const std::string& file, - int line) : std::runtime_error(NB::formatDebugString(msg, file, line)) {} - -uint8_t VerticesFromPrimitives(GLenum type, unsigned int num_prims) { - switch(type) { - case GL_POINTS: - return num_prims; - case GL_LINES: - return num_prims*2; - break; - case GL_LINE_STRIP: - return num_prims+1; - break; - case GL_LINE_LOOP: - return num_prims; - break; - case GL_TRIANGLES: - return num_prims*3; - break; - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - return num_prims+2; - break; - case GL_QUADS: - return 4*num_prims; - break; - case GL_QUAD_STRIP: - return 2*num_prims+2; - break; - default: - return num_prims; - break; - } -} - -uint8_t PrimitivesFromVertices(GLenum type, unsigned int num_verts) { - switch(type) { - case GL_POINTS: - return num_verts; - case GL_LINES: - return num_verts/2; - break; - case GL_LINE_STRIP: - return num_verts-1; - break; - case GL_LINE_LOOP: - return num_verts; - break; - case GL_TRIANGLES: - return num_verts/3; - break; - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - return num_verts-2; - break; - case GL_QUADS: - return num_verts/4; - break; - case GL_QUAD_STRIP: - return num_verts/2 - 1; - break; - default: - return num_verts; - break; - } -} - - -// DrawBuffer class -DrawBuffer::DrawBuffer(VertexAttributeList vas, GLenum prim_type) -: _gl_primitive_type(prim_type), _VAO() { - _vert_data = std::make_shared(GL_ARRAY_BUFFER); - _elmt_data = std::make_shared(GL_ELEMENT_ARRAY_BUFFER); - _VAO.addVBO(_vert_data); - _VAO.changeEBO(_elmt_data); - try { - throw _VAO.checkValid(vas); - } catch (VAOError vaoe) { - if (vaoe.error) { - _VAO.addVertexAttributes(DrawBuffer::defaultVAO(vas)); - } else { - _VAO.addVertexAttributes(vas); - } - } -} - -VertexAttributeList DrawBuffer::defaultVAO(VertexAttributeList vert_attrs) { - GLuint vert_id = _vert_data->id(); - unsigned int vert_size = 0; - for (const VertexAttribute& va : vert_attrs) { - vert_size += va.GLSLSize * GLSLTypeSize(va.GLSLType); - } - unsigned int curr_byte = 0; - for (VertexAttribute& va : vert_attrs) { - va.ptr.buffer = vert_id; - va.ptr.stride = vert_size; - va.ptr.offset = curr_byte; - va.ptr.divisor = 0; - curr_byte += va.GLSLSize * GLSLTypeSize(va.GLSLType); - } - return vert_attrs; -} - -VertexAttributeList DrawBuffer::changeVertLayout(unsigned int i, VertexAttributePointer vap) { - GLuint vert_id = _vert_data->id(); - vap.buffer = (vap.buffer) ? vap.buffer : vert_id; - VertexAttributeList vas = _VAO.getLayout(); - unsigned int idx = 0; - for (const VertexAttribute& va : vas) { - if (va.ptr.buffer == vert_id) { - if (idx == i) { - return _VAO.changeLayout(i, vap); - } - idx++; - } - } - THROW_DRAW_ERROR("Could not find vertex attribute with index " + std::to_string(i)); -} - -unsigned int DrawBuffer::vertSize() const { return _VAO.vertSize(_vert_data->id()); } - -void DrawBuffer::draw() const { - _VAO.bind(); - glDrawElements(_gl_primitive_type, _elmt_data->size() / GLSLTypeSize(GL_INT), GL_UNSIGNED_INT, 0); - _VAO.unbind(); -} - -unsigned int DrawBuffer::elementBufferID() const { return _elmt_data->id(); } - -unsigned int DrawBuffer::vertexBufferID() const { return _vert_data->id(); } - -RawVec DrawBuffer::vertAttrData(unsigned int i) { - if (!_vert_data->isInitialized()) { - throw DrawError("Vertex buffer is not initialized."); - } - return _VAO.attributeData(i); -} - -RawVec DrawBuffer::vertAttrData(unsigned int i, const RawVec& newdata) { - if (!(_vert_data->isInitialized())) { - VertexAttribute va = _VAO.getLayout()[i]; - vertexData(newdata.size() / (va.GLSLSize*GLSLTypeSize(va.GLSLType))); - std::cout << "From DrawBuffer::vertAttrData(int, RawVec) - vert buf size: " << _vert_data->size() << "\n"; - } - return _VAO.attributeData(i, newdata); -} - -void DrawBuffer::elementData(unsigned int num_prims) { - elementData(std::vector(VerticesFromPrimitives(_gl_primitive_type, num_prims))); -} - -void DrawBuffer::elementData(const std::vector& elements) { - _num_prims = PrimitivesFromVertices(_gl_primitive_type, elements.size()); - _elmt_data->data(vectorToRaw(elements)); -} - -void DrawBuffer::elementData(const std::vector& elements, unsigned int offset) { - _VAO.bind(); - if (!_elmt_data->isInitialized()) { - std::vector init_elmts(elements); - init_elmts.insert(init_elmts.cbegin(), offset, 0); - elementData(init_elmts, 0); - } else { - _elmt_data->data(vectorToRaw(elements), offset); - } - _VAO.unbind(); -} - -void DrawBuffer::vertexData(unsigned int num_verts) { - vertexData(RawVec(num_verts * vertSize())); -} - -void DrawBuffer::vertexData(const RawVec& vert_data) { - // Check for uninitialized Vertex Pointers. If so, will fallback to default VAO setup. - // Otherwise, set VAO to provided Vertex Atributes. - int vert_size = vertSize(); - if (vert_data.size() % vert_size != 0) { - THROW_DRAW_ERROR("Initializing data does not match vertex size of " + std::to_string(vert_size) + "."); - } - _num_verts = vert_data.size() / vert_size; - // TODO: Make it not static draw all the time - - _VAO.bind(); - _vert_data->data(vert_data); - _VAO.unbind(); -} - -void DrawBuffer::vertexData(const RawVec& data, unsigned int offset) { - _VAO.bind(); - if (!_vert_data->isInitialized()) { - RawVec load_data(offset); - load_data.insert(load_data.end(), data.begin(), data.end()); - vertexData(load_data, 0); - } else { - try{ - _vert_data->data(data, offset); - } catch(BufferError& e) { - THROW_DRAW_ERROR("NB::BufferError in loadVBO:\n\t" + std::string(e.what())); - } - } - _VAO.unbind(); -} - -// DrawInstanceBufferClass -DrawInstanceBuffer::DrawInstanceBuffer( - VertexAttributeList vert_vas, - VertexAttributeList inst_vas, - GLenum prim_type -): DrawBuffer(vert_vas, prim_type) { - _inst_data = std::make_shared(GL_ARRAY_BUFFER); - _VAO.addVBO(_inst_data); - try { - throw _VAO.checkValid(inst_vas); - } catch (VAOError vaoe) { - if (vaoe.error) { - _VAO.addVertexAttributes(defaultVAO(inst_vas)); - } else { - _VAO.addVertexAttributes(inst_vas); - } - } -} - -unsigned int DrawInstanceBuffer::instSize() const { return _VAO.vertSize(_inst_data->id()); } - -unsigned int DrawInstanceBuffer::instanceBufferID() const { return _inst_data->id(); } - -void DrawInstanceBuffer::instanceData(unsigned int num_inst) { - instanceData(RawVec(instSize() * num_inst)); -} - -void DrawInstanceBuffer::instanceData(const RawVec& inst_data) { - int inst_size = instSize(); - if (inst_data.size() % inst_size != 0) { - THROW_DRAW_ERROR("Initializing data does not match instance size of " + std::to_string(inst_size) + "."); - } - _num_inst = inst_data.size() / inst_size; - - _VAO.bind(); - _inst_data->data(inst_data); - _VAO.unbind(); -} - -void DrawInstanceBuffer::instanceData(const RawVec& data, unsigned int offset) { - _VAO.bind(); - if (!_inst_data->isInitialized()) { - RawVec load_data(offset); - load_data.insert(load_data.end(), data.begin(), data.end()); - instanceData(load_data, 0); - } else { - try{ - _inst_data->data(data, offset); - } catch(BufferError& e) { - THROW_DRAW_ERROR("NB::BufferError in loadIBO:\n\t" + std::string(e.what())); - } - } - _VAO.unbind(); -} - -VertexAttributeList DrawInstanceBuffer::defaultVAO(VertexAttributeList inst_attrs) { - GLuint inst_id = _inst_data->id(); - unsigned int vert_size = 0; - for (const VertexAttribute& va : inst_attrs) { - vert_size += va.GLSLSize * GLSLTypeSize(va.GLSLType); - } - unsigned int curr_byte = 0; - for (VertexAttribute& va : inst_attrs) { - va.ptr.buffer = inst_id; - va.ptr.stride = vert_size; - va.ptr.offset = curr_byte; - va.ptr.divisor = 1; - curr_byte += va.GLSLSize * GLSLTypeSize(va.GLSLType); - } - return inst_attrs; -} - -VertexAttributeList DrawInstanceBuffer::changeInstanceLayout(unsigned int i, VertexAttributePointer vap) { - GLuint inst_id = _inst_data->id(); - vap.buffer = (vap.buffer) ? vap.buffer : inst_id; - VertexAttributeList vas = _VAO.getLayout(); - unsigned int vas_size = vas.size(); - unsigned int inst_idx = 0; - unsigned int idx = 0; - for (const VertexAttribute& va : vas) { - if (va.ptr.buffer == inst_id) { - if (inst_idx == i) { - return _VAO.changeLayout(idx, vap); - } - inst_idx++; - } - idx++; - } - THROW_DRAW_ERROR("Could not find instance attribute with index " + std::to_string(i)); -} - -void DrawInstanceBuffer::draw() const { - _VAO.bind(); - glDrawElementsInstanced(_gl_primitive_type, _elmt_data->size() / GLSLTypeSize(GL_UNSIGNED_INT), GL_UNSIGNED_INT, (void*)_elmt_data->id(), _num_inst); - _VAO.unbind(); -} - -} \ No newline at end of file diff --git a/engine/NBGraphics/src/Mesh.cpp b/engine/NBGraphics/src/Mesh.cpp new file mode 100644 index 0000000..f3cc3e2 --- /dev/null +++ b/engine/NBGraphics/src/Mesh.cpp @@ -0,0 +1,73 @@ +#pragma clang diagnostic ignored "-Wint-to-pointer-cast" +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" + +#include + +namespace nb{ + +// class Mesh +Mesh::Mesh( + VertexDataPointerList vertexdata_, + unsigned int count_, + GLenum primitive_ +) : + _primitive(primitive_), + _count(count_), + _vao(std::make_shared(vertexdata_)) +{} + +Mesh::Mesh( + GLenum primitive_, + const std::shared_ptr& vao_, + unsigned int count_ +) : + _primitive(primitive_), + _count(count_), + _vao(vao_) +{} + +Mesh::Mesh( + GLenum primitive_, + const VertexData& vertex_data_, + unsigned int count_ +) : Mesh(primitive_, std::make_shared(), count_) { + _vao->attributes({vertex_data_}); +} + +Mesh::Mesh( + GLenum primitive_, + const ByteVector& data_, + unsigned int count_, + const std::vector& attributes_ +) : Mesh( + primitive_, + VertexData(data_, attributes_), + count_ +) {} + +void Mesh::draw(unsigned int offset, unsigned int count) const { + _vao->bind(); + OPENGL_CALL( + glDrawArrays(_primitive, offset, count); + ); +} + +// class InstancedMesh + +void InstancedMesh::draw(unsigned int offset, unsigned instancecount) const { + _vao->bind(); + OPENGL_CALL( + glDrawArraysInstanced(_primitive, 0, _count, instancecount); + ); +} + +// class IndexMeshes + +void IndexedMesh::draw(unsigned int offset, unsigned numindices) const { + _vao->bind(); + OPENGL_CALL( + glDrawElements(Mesh::_primitive, _count, _ebo->datatype(), (void*)offset) + ); +} + +} // namespace nb \ No newline at end of file diff --git a/engine/NBGraphics/src/OGLObjects.cpp b/engine/NBGraphics/src/OGLObjects.cpp index 189a85d..d9e0d47 100644 --- a/engine/NBGraphics/src/OGLObjects.cpp +++ b/engine/NBGraphics/src/OGLObjects.cpp @@ -36,11 +36,22 @@ OpenGLError OpenGLError::status(const std::string& note) { return OpenGLError(glGetError(), note); } +const ConstantMap TypeToGLSL = { + {TypeCodes::FLOAT16, GL_HALF_FLOAT}, + {TypeCodes::FLOAT32, GL_FLOAT}, + {TypeCodes::DOUBLE64, GL_DOUBLE}, + {TypeCodes::INT8, GL_BYTE}, + {TypeCodes::INT16, GL_SHORT}, + {TypeCodes::INT32, GL_INT}, + {TypeCodes::UINT8, GL_UNSIGNED_BYTE}, + {TypeCodes::UINT16, GL_UNSIGNED_SHORT}, + {TypeCodes::UINT32, GL_UNSIGNED_INT}, +}; // class OpenGLObject void OpenGLObject::checkObjectContextValidity() { - if (_arena != OGLWindow::getCurrentObjectArena()) { + if (_arena != OGLWindow::GetCurrentObjectArena()) { THROW(OpenGLObjectError(OpenGLObjectError::INVALID_CONTEXT)); } } @@ -50,7 +61,7 @@ OpenGLObject::OpenGLObject(OpenGLObject&& rval) : _arena(rval._arena) { *this = std::move(rval); } -OpenGLObject::OpenGLObject() : _arena(OGLWindow::getCurrentObjectArena()) {} +OpenGLObject::OpenGLObject() : _arena(OGLWindow::GetCurrentObjectArena()) {} OpenGLObject& OpenGLObject::operator=(OpenGLObject&& rhs) { rhs.checkObjectContextValidity(); @@ -79,6 +90,10 @@ const GLEnumTableType GLenumTable = { GLENUMSTRPAIR(GL_RGB8UI), GLENUMSTRPAIR(GL_RGBA8UI), GLENUMSTRPAIR(GL_RGBA), + GLENUMSTRPAIR(GL_ELEMENT_ARRAY_BUFFER), + GLENUMSTRPAIR(GL_UNSIGNED_INT), + GLENUMSTRPAIR(GL_UNSIGNED_SHORT), + GLENUMSTRPAIR(GL_UNSIGNED_BYTE), }; } // namespace nb \ No newline at end of file diff --git a/engine/NBGraphics/src/VertexArray.cpp b/engine/NBGraphics/src/VertexArray.cpp index 9a468d8..7bbf8bb 100644 --- a/engine/NBGraphics/src/VertexArray.cpp +++ b/engine/NBGraphics/src/VertexArray.cpp @@ -1,3 +1,6 @@ +#pragma clang diagnostic ignored "-Wint-to-pointer-cast" +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" + #include namespace nb { @@ -16,7 +19,7 @@ const ErrorCodeMap VertexError::ErrorMessages = { { VertexError::MISALIGNED_DATA, "Data does not match vertex layout"} }; -VAO::VAO(const VertexAttributePointerList& attr_ptrs) { +VAO::VAO(const VertexDataPointerList& attr_ptrs) { attributes(attr_ptrs); } @@ -26,41 +29,58 @@ VAO::VAO(VAO&& other) { VAO& VAO::operator=(VAO&& rhs) { OpenGLObject::operator=(std::move(rhs)); - _attrs = rhs._attrs; - rhs._attrs = {}; + _vertexdata = rhs._vertexdata; + rhs._vertexdata = {}; return *this; } -VertexAttributePointerList VAO::attributes() const { - return _attrs; +VertexDataPointerList VAO::attributes() const { + return _vertexdata; } -VertexAttributePointerList VAO::attributes(const VertexAttributePointerList& attrs_) { +VertexDataPointerList VAO::attributes(const VertexDataPointerList& vertdatalist) { declare(); disable(); - _attrs = attrs_; + _vertexdata = vertdatalist; bind(); - for (auto attr_ptr : attrs_) { - OPENGL_CALL(glBindBuffer(GL_ARRAY_BUFFER, attr_ptr.buffer)); - GLuint idx = attr_ptr.index; - OPENGL_CALL(glVertexAttribPointer( - idx, - attr_ptr.attribute.GLSLSize, - attr_ptr.attribute.GLSLType, - attr_ptr.attribute.GLSLNormalization, - attr_ptr.attribute.layout.stride, - (void*)attr_ptr.attribute.layout.offset - )); - OPENGL_CALL(glEnableVertexAttribArray(idx)); + for (const auto vdata : _vertexdata) { + OPENGL_CALL(glBindBuffer(GL_ARRAY_BUFFER, vdata.vertexdata->data->id())); + for (const auto attr : vdata.vertexdata->attributes) { + GLuint idx = vdata.index; + OPENGL_CALL(glVertexAttribPointer( + idx, + attr.size, + TypeToGLSL[attr.type], + attr.normalized, + attr.layout.stride, + (const void*) attr.layout.offset + )); + OPENGL_CALL(glEnableVertexAttribArray(idx)); + if (attr.layout.divisor) { + OPENGL_CALL(glVertexAttribDivisor(idx, attr.layout.divisor)); + } + } } unbind(); - return _attrs; + enable(); + return _vertexdata; } -VertexAttributePointer VAO::attr(GLuint idx) const { - for (auto attr_ptr : _attrs) { - if (idx == attr_ptr.index) { - return attr_ptr; +VertexDataPointerList VAO::attributes(const VertexDataList& vertdatalist) { + VertexDataPointerList vdatas; + for (unsigned int i = 0; i < vertdatalist.size(); ++i) { + vdatas.emplace_back(VertexDataPointer{ + std::make_shared(vertdatalist[i]), + i + }); + } + return attributes(vdatas); +} + +VertexDataPointer VAO::attribute(GLuint idx) const { + for (auto vdata : _vertexdata) { + if (idx == vdata.index) { + return vdata; } } THROW(VAOError(Codes::INVALID_ATTRIBUTE)); @@ -69,8 +89,8 @@ VertexAttributePointer VAO::attr(GLuint idx) const { void VAO::enable() const { if (_id) { bind(); - for(auto attr_ptr : _attrs) { - OPENGL_CALL(glEnableVertexAttribArray(attr_ptr.index)); + for(auto vdata : _vertexdata) { + OPENGL_CALL(glEnableVertexAttribArray(vdata.index)); } unbind(); } @@ -79,7 +99,7 @@ void VAO::enable() const { void VAO::enable(GLuint idx) const { if(_id) { bind(); - OPENGL_CALL(glEnableVertexAttribArray(attr(idx).index)); + OPENGL_CALL(glEnableVertexAttribArray(attribute(idx).index)); unbind(); } } @@ -87,8 +107,8 @@ void VAO::enable(GLuint idx) const { void VAO::disable() const { if(_id) { bind(); - for(auto attr_ptr : _attrs) { - OPENGL_CALL(glDisableVertexAttribArray(attr_ptr.index)); + for(auto vdata : _vertexdata) { + OPENGL_CALL(glDisableVertexAttribArray(vdata.index)); } unbind(); } @@ -97,157 +117,10 @@ void VAO::disable() const { void VAO::disable(GLuint idx) const { if(_id) { bind(); - OPENGL_CALL(glDisableVertexAttribArray(attr(idx).index)); + OPENGL_CALL(glDisableVertexAttribArray(attribute(idx).index)); unbind(); } } -VertexGroup::VertexGroup(VertexGroup&& other) { - *this = std::move(other); -} - -VertexGroup& VertexGroup::operator=(VertexGroup&& rhs) { - _vertex_data = rhs._vertex_data; - _ebo = rhs._ebo; - _vao = rhs._vao; - - rhs._vertex_data = {}; - rhs._ebo = nullptr; - rhs._vao = nullptr; - - return *this; -} - -void VertexGroup::draw() const { - bind(); - OPENGL_CALL( - glDrawElements(primitive, _ebo->size(), _ebo->glslType(), 0) - ); -} - -size_t VertexGroup::addBuffer(const VertexData& vertex_data_) { - VertexData data = vertex_data_; - _vertex_data.emplace_back(data); - VertexAttributePointerList attrs = _vao->attributes(); - GLuint idx = attrs.size(); - for (const auto& attr : data.attrs) { - attrs.emplace_back( - VertexAttributePointer{attr, data.vbo->id(),idx} - ); - idx++; - } - _vao->attributes(attrs); - return _vertex_data.size(); -} - -size_t VertexGroup::addBuffer(const ByteVector& data_, const VertexAttributeList& attrs_) { - return addBuffer({ - std::make_shared(data_), - attrs_ - }); -} - -VertexData VertexGroup::getBuffers(size_t idx) { - return _vertex_data[idx]; -} - - VertexDataVec VertexGroup::getBuffers() { - return _vertex_data; -} - -size_t VertexGroup::setBuffers(const VertexDataVec& vertex_data_) { - _vertex_data = vertex_data_; - VertexAttributePointerList attr_ptrs; - GLuint idx = 0; - for (const auto& data : _vertex_data) { - for (const auto& attr : data.attrs) { - attr_ptrs.emplace_back( - VertexAttributePointer{attr, data.vbo->id(), idx} - ); - idx++; - } - } - _vao->attributes(attr_ptrs); - return _vertex_data.size(); -} - -VertexDataVec VertexGroup::dropBuffers() { - auto ret = _vertex_data; - setBuffers({}); - return ret; -} - -VertexData VertexGroup::dropBuffer(size_t idx) { - if (idx >= _vertex_data.size()) { - THROW(Error(Error<>::OUT_OF_RANGE)); - } - VertexDataVec tmp; - VertexData ret; - size_t i = 0; - for (auto buf : _vertex_data) { - if (i == idx) { - ret = tmp[idx]; - } else { - tmp.emplace_back(buf); - } - i++; - } - setBuffers(tmp); - return ret; -} - -VertexAttributePointer VertexGroup::attribute(size_t idx_) const { - return _vao->attr(idx_); -} - -void VertexGroup::enableAttr(GLuint idx) { - bind(); - _vao->enable(idx); - unbind(); -} - -void VertexGroup::disableAttr(GLuint idx) { - bind(); - _vao->disable(idx); - unbind(); -} - -void VertexGroup::disableBuffer(size_t idx) { - auto buf_idx = _vertex_data[idx].vbo->id(); - bind(); - for (auto attr : _vao->attributes()) { - if (attr.buffer == buf_idx) { - _vao->disable(attr.index); - } - } - unbind(); -} - -void VertexGroup::enableBuffer(size_t idx) { - auto buf_idx = _vertex_data[idx].vbo->id(); - bind(); - for (auto attr : _vao->attributes()) { - if (attr.buffer == buf_idx) { - _vao->enable(attr.index); - } - } - unbind(); -} - -void VertexGroup::enable() { _vao->enable(); } - -void VertexGroup::disable() { _vao->disable(); } - -std::shared_ptr VertexGroup::indices() const { return _ebo; } - -std::shared_ptr VertexGroup::indices(const std::vector& data) { - _ebo->data(data); - return _ebo; -} - -std::shared_ptr VertexGroup::indices(std::shared_ptr buffer) { - _ebo = buffer; - return _ebo; -} } // namespace nb diff --git a/engine/NBGraphics/src/VertexData.cpp b/engine/NBGraphics/src/VertexData.cpp new file mode 100644 index 0000000..806d5c9 --- /dev/null +++ b/engine/NBGraphics/src/VertexData.cpp @@ -0,0 +1,16 @@ +#include + +namespace nb { + +VertexData::VertexData( + std::shared_ptr data_, + const std::vector& attrs_ +) : data(data_), attributes(attrs_) {} + +VertexData::VertexData( + const ByteVector& data_, + const std::vector& attrs_ +) : data(std::make_shared(GL_ARRAY_BUFFER, data_)), + attributes(attrs_) {} + +} // namespace nb \ No newline at end of file diff --git a/engine/NBGraphics/src/Window.cpp b/engine/NBGraphics/src/Window.cpp index d0d31b1..383f749 100644 --- a/engine/NBGraphics/src/Window.cpp +++ b/engine/NBGraphics/src/Window.cpp @@ -16,8 +16,8 @@ const ErrorCodeMap GLFWError::ErrorMessages = { // class OGLWindow std::atomic OGLWindow::_glfwInitialized = false; -thread_local std::shared_ptr OGLWindow::_currWindow = nullptr; -thread_local GLFWwindow* OGLWindow::_currArena = nullptr; +thread_local GLFWwindow* OGLWindow::_currWindow = nullptr; +thread_local const GLFWwindow* OGLWindow::_currArena = nullptr; std::atomic OGLWindow::_count = 0; bool OGLWindow::InitGLFW(const std::vector& hints) { @@ -58,11 +58,11 @@ void OGLWindow::SetHintString(const std::tuple& hint) { glfwWindowHintString(std::get<0>(hint), std::get<1>(hint).c_str()); } -std::shared_ptr OGLWindow::MakeCurrent(const std::shared_ptr& window) { +GLFWwindow* OGLWindow::MakeCurrent(const std::shared_ptr& window) { auto tmp = _currWindow; - _currWindow = window; + _currWindow = window->getWindowPtr(); if (window) { - glfwMakeContextCurrent(_currWindow->_window_ptr); + glfwMakeContextCurrent(_currWindow); _currArena = window->_arena; } else { glfwMakeContextCurrent(nullptr); @@ -71,41 +71,6 @@ std::shared_ptr OGLWindow::MakeCurrent(const std::shared_ptr>& integerHints, - const std::vector>& stringHints -) : _title(title) { - CheckForMainThread(); - InitGLFW(); - for (const auto& hint : integerHints) { - SetHintInteger(hint); - } - for (const auto& hint : stringHints) { - SetHintString(hint); - } - _window_ptr = glfwCreateWindow( - x, - y, - _title.c_str(), - NULL, - NULL - ); - if (_window_ptr == NULL) { - THROW(GLFWError(GLFWError::Codes::WINDOW_FAILED)); - } - _arena = _window_ptr; - auto tmp = glfwGetCurrentContext(); - glfwMakeContextCurrent(_window_ptr); - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - THROW(GLFWError(GLFWError::Codes::GLAD_FAILED)); - } - glfwMakeContextCurrent(tmp); - OGLWindow::_count.fetch_add(1); -} - std::shared_ptr OGLWindow::CreateWindow( unsigned int x, unsigned int y, @@ -122,10 +87,63 @@ std::shared_ptr OGLWindow::CreateWindow( ) ); } +std::shared_ptr OGLWindow::CreateSharedWindow( + unsigned int x, + unsigned int y, + const std::string& title, + std::shared_ptr sharingWindow, + const std::vector>& integerHints, + const std::vector>& stringHints +) { + return std::shared_ptr( new OGLWindow( + x, + y, + title, + integerHints, + stringHints, + sharingWindow->getWindowPtr() + ) ); +} + +OGLWindow::OGLWindow( + unsigned int x, + unsigned int y, + const std::string& title, + const std::vector>& integerHints, + const std::vector>& stringHints, + GLFWwindow* sharingContext +) : _title(title) { + CheckForMainThread(); + InitGLFW(); + for (const auto& hint : integerHints) { + SetHintInteger(hint); + } + for (const auto& hint : stringHints) { + SetHintString(hint); + } + _window_ptr = glfwCreateWindow( + x, + y, + _title.c_str(), + NULL, + sharingContext + ); + if (_window_ptr == NULL) { + THROW(GLFWError(GLFWError::Codes::WINDOW_FAILED)); + } + _arena = _window_ptr; + auto tmp = makeCurrent(); + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + THROW(GLFWError(GLFWError::Codes::GLAD_FAILED)); + } + glfwMakeContextCurrent(tmp); + OGLWindow::_count.fetch_add(1); +} + OGLWindow::~OGLWindow() { CheckForMainThread(); if (_window_ptr) { - if (_window_ptr == _currWindow->_window_ptr) { + if (_window_ptr == _currWindow) { _currWindow = nullptr; _currArena = nullptr; } @@ -137,6 +155,12 @@ OGLWindow::~OGLWindow() { } } +void OGLWindow::detachWindow() { + _title = ""; + _window_ptr = nullptr; + _arena = nullptr; +} + int OGLWindow::getWindowAttribute(int attr) const { CheckForMainThread(); return glfwGetWindowAttrib(_window_ptr, attr); @@ -149,6 +173,22 @@ std::array OGLWindow::getSize() const { return {x, y}; } +bool OGLWindow::shouldClose() const { + CheckForMainThread(); + return glfwWindowShouldClose(_window_ptr); +} + +void OGLWindow::shouldClose(bool val) { + CheckForMainThread(); + glfwSetWindowShouldClose(_window_ptr, val); +} + +GLFWwindow* OGLWindow::makeCurrent() const { + auto tmp = glfwGetCurrentContext(); + glfwMakeContextCurrent(_window_ptr); + return tmp; +} + void OGLWindow::setSize(unsigned int x, unsigned int y) { CheckForMainThread(); glfwSetWindowSize(_window_ptr, x, y); @@ -160,4 +200,14 @@ void OGLWindow::setTitle(const std::string& name) { glfwSetWindowTitle(_window_ptr, _title.c_str()); } +/* template<> void OGLWindow::setCallBack( CallbackFunc func) { + CheckForMainThread(); + auto tmp = makeCurrent(); + auto tmp_func = + [=](GLFWwindow* window, int a, int b, int c, int d){ + func(this, a, b, c, d); + }; + glfwSetKeyCallback(_window_ptr, tmp_func); +} */ + }; \ No newline at end of file diff --git a/engine/NBGraphics/tests/TestWindow.cpp b/engine/NBGraphics/tests/TestWindow.cpp index ed5d614..72f12e1 100644 --- a/engine/NBGraphics/tests/TestWindow.cpp +++ b/engine/NBGraphics/tests/TestWindow.cpp @@ -4,8 +4,9 @@ #include #include +#include #include -#include +#include #include #include @@ -60,14 +61,12 @@ int main() { std::vector indxs = {0, 1, 2}; - nb::VertexGroup tri(data, { - nb::VertexAttribute{ + nb::IndexedMesh tri(GL_TRIANGLES, data, {nb::VertexAttribute{ 2, - GL_FLOAT, + nb::TypeCodes::FLOAT32, false, {0, 8} - }, - }, indxs); + }}, indxs); LOG(prog.log()); GLFWwindow* window_ptr = window->getWindowPtr();