From a4b6c556451c0d032a5fbdbd7d4f18d1281620d4 Mon Sep 17 00:00:00 2001 From: NaifBanana <30419422+NaifBanana@users.noreply.github.com> Date: Tue, 13 Oct 2026 02:37:58 -0500 Subject: [PATCH] Starting to isolate api --- CMakeLists.txt | 2 + engine/NBGraphics/CMakeLists.txt | 17 ++ .../include/NBGraphics/OGL/Buffers.hpp | 262 ++++++++++++++++++ engine/NBGraphics/src/{ => OGL}/Buffers.cpp | 0 .../NBGraphics/src/{ => OGL}/FrameBuffers.cpp | 0 .../NBGraphics/src/{ => OGL}/OGLObjects.cpp | 0 .../src/{ => OGL}/ProgramPipeline.cpp | 0 engine/NBGraphics/src/{ => OGL}/Textures.cpp | 0 .../NBGraphics/src/{ => OGL}/VertexArray.cpp | 0 9 files changed, 281 insertions(+) create mode 100644 engine/NBGraphics/include/NBGraphics/OGL/Buffers.hpp rename engine/NBGraphics/src/{ => OGL}/Buffers.cpp (100%) rename engine/NBGraphics/src/{ => OGL}/FrameBuffers.cpp (100%) rename engine/NBGraphics/src/{ => OGL}/OGLObjects.cpp (100%) rename engine/NBGraphics/src/{ => OGL}/ProgramPipeline.cpp (100%) rename engine/NBGraphics/src/{ => OGL}/Textures.cpp (100%) rename engine/NBGraphics/src/{ => OGL}/VertexArray.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f84f4e..6fdcbcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(NB_TARGET_LINUX ON) endif() +set(NB_GRAPHICS_API_OGL ON) + if(NB_BUILD_TESTS) message(STATUS "Building tests") enable_testing() diff --git a/engine/NBGraphics/CMakeLists.txt b/engine/NBGraphics/CMakeLists.txt index abf84c0..324bae8 100644 --- a/engine/NBGraphics/CMakeLists.txt +++ b/engine/NBGraphics/CMakeLists.txt @@ -56,6 +56,18 @@ toAbsolutePath(NB_GRAPHICS_INCLUDE set(NB_GRAPHICS_SOURCE ${NB_GRAPHICS_SOURCE} PARENT_SCOPE) set(NB_GRAPHICS_INCLUDE ${NB_GRAPHICS_INCLUDE} PARENT_SCOPE) +if (NB_GRAPHICS_API_OGL) + toAbsolutePath(NB_GRAPHICS_API_OGL_SOURCE + ./src/OGL/Buffers.cpp + ) + toAbsolutePath(NB_GRAPHICS_API_OGL_INCLUDE + ./include/NBGraphics/OGL/Buffers.hpp + ) + set(NB_GRAPHICS_SOURCE ${NB_GRAPHICS_SOURCE} ${NB_GRAPHICS_API_OGL_SOURCE} PARENT_SCOPE) + set(NB_GRAPHICS_INCLUDE ${NB_GRAPHICS_INCLUDE} ${NB_GRAPHICS_API_OGL_SOURCE} PARENT_SCOPE) + add_library(NBGraphicsAPI_OGL ${NB_GRAPHICS_API_OGL_SOURCE}) +endif() + add_library(NBGraphics ${NB_GRAPHICS_SOURCE} ${GLAD_PATH}/src/glad.c @@ -63,6 +75,11 @@ add_library(NBGraphics add_library(NBEngine::Graphics ALIAS NBGraphics) add_dependencies(NBGraphics NBCore) add_dependencies(NBGraphics glfw) + +if(NB_GRAPHICS_API_OGL) + add_dependencies(NBGraphics NBGraphicsAPI_OGL) +endif() + target_link_libraries(NBGraphics PUBLIC glfw PUBLIC NBCore diff --git a/engine/NBGraphics/include/NBGraphics/OGL/Buffers.hpp b/engine/NBGraphics/include/NBGraphics/OGL/Buffers.hpp new file mode 100644 index 0000000..2ff5ac8 --- /dev/null +++ b/engine/NBGraphics/include/NBGraphics/OGL/Buffers.hpp @@ -0,0 +1,262 @@ +#pragma once +#ifndef _NB_BUFFER +#define _NB_BUFFER + +#include + +#include + +#include +#include +#include + +#include + +namespace nb { + +extern const ConstantMap BufferTypes; + +template +struct GLSLEnum; +template +struct GLSLType; + +#define GLSLTypeTraits(type_, size_, value_) \ +template<>\ +struct GLSLEnum {\ + using type = type_;\ + static constexpr size_t size = size_;\ + static constexpr GLenum value=value_;\ +};\ +template<>\ +struct GLSLType {\ + using type = type_;\ + static constexpr size_t size = size_;\ + static constexpr GLenum value=value_;\ +}; + +#define GLSLTypeEquivalence(original, newtype) \ +template<>\ +struct GLSLType : public GLSLType {}; + +GLSLTypeTraits(uint8_t, 1, GL_UNSIGNED_BYTE); +GLSLTypeTraits(uint16_t, 2, GL_UNSIGNED_SHORT); +GLSLTypeTraits(uint32_t, 4, GL_UNSIGNED_INT); +GLSLTypeTraits(int8_t, 1, GL_BYTE); +GLSLTypeTraits(int16_t, 2, GL_SHORT); +GLSLTypeTraits(int32_t, 4, GL_INT); +GLSLTypeTraits(float, 4, GL_FLOAT); +GLSLTypeTraits(double, 8, GL_DOUBLE); + +class BufferError : public Error { + protected: + using Base = Error; + + public: + using Base::Base; + enum Codes : unsigned int { + UNDEFINED, + DATA_OVERFLOW, + DATA_ERROR, + BAD_DATA_TYPE + }; + static const std::string type; + static const ErrorCodeMap ErrorMessages; +}; + +class Buffer : public OpenGLObject { + protected: + using Codes = BufferError::Codes; + using OpenGLObject::_id; + GLenum _usage = GL_STATIC_DRAW; + size_t _size; + virtual GLuint declare() override { + if (!_id) { + OPENGL_CALL(glGenBuffers(1, &_id)); + } + this->bind(); + return _id; + } + virtual void remove() override { + if (_id) { + this->unbind(); + OPENGL_CALL(glDeleteBuffers(1, &_id)); + _id = 0; + } + } + + 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); + + virtual void bind() const override { + if (_id) { + OPENGL_CALL(glBindBuffer(Target, _id)); + } else { + THROW(OpenGLObjectError( + OpenGLObjectError::Codes::INVALID_OBJECT, + "w/ BufferType " + BufferTypes[Target] + )); + } + } + virtual void unbind() const override { + OPENGL_CALL(glBindBuffer(Target, 0)); + } + GLenum usage() const; + size_t size() const; + ByteVector data() const; + + void data(const ByteVector& data, GLenum usage=GL_STATIC_DRAW); + void data(const void* data, size_t size, GLenum usage=GL_STATIC_DRAW); + void subdata(const void* data, size_t size, GLintptr offset=0); + void subdata(const ByteVector& data_, GLintptr offset=0); + // virtual void clear() const { glClearBufferData(Target, ) } + +}; + +/* template +class ImmutableBuffer : public virtual Buffer { + public: + ImmutableBuffer() = default; + ImmutableBuffer( + size_t size_, + GLenum usage_ = GL_STATIC_DRAW, + GLbitfield flags_=0x0 + ) : size(size_), Base::usage(usage_) { + glBufferStorage(Target, size, nullptr, flags_); + } + + std::weak_ptr map(GLbitfield access_) { + if (_map && _mapAccess != access_) { unmap(); } + _mapAccess = access_; + if (!_map) { + bind(); + glMapBuffer(Target, _mapAccess); + } + return _map; + } + void unmap() { + bind(); + glUnmapBuffer(Target); + _map.reset(); + } + + const size_t size; + +protected: + std::shared_ptr _map = nullptr; + GLbitfield _mapAccess = 0; + +}; */ + +class UniformBuffer : public Buffer { + protected: + GLuint _index; + + public: + UniformBuffer(); + void bind() const override; + GLuint bufferIndex() const; + GLuint bufferIndex(GLuint); + +}; + +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: + 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::unbind; + using Buffer::usage; + using Buffer::size; + template + 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); + } + +}; + +} // namespace NB +#endif // _NB_BUFFER diff --git a/engine/NBGraphics/src/Buffers.cpp b/engine/NBGraphics/src/OGL/Buffers.cpp similarity index 100% rename from engine/NBGraphics/src/Buffers.cpp rename to engine/NBGraphics/src/OGL/Buffers.cpp diff --git a/engine/NBGraphics/src/FrameBuffers.cpp b/engine/NBGraphics/src/OGL/FrameBuffers.cpp similarity index 100% rename from engine/NBGraphics/src/FrameBuffers.cpp rename to engine/NBGraphics/src/OGL/FrameBuffers.cpp diff --git a/engine/NBGraphics/src/OGLObjects.cpp b/engine/NBGraphics/src/OGL/OGLObjects.cpp similarity index 100% rename from engine/NBGraphics/src/OGLObjects.cpp rename to engine/NBGraphics/src/OGL/OGLObjects.cpp diff --git a/engine/NBGraphics/src/ProgramPipeline.cpp b/engine/NBGraphics/src/OGL/ProgramPipeline.cpp similarity index 100% rename from engine/NBGraphics/src/ProgramPipeline.cpp rename to engine/NBGraphics/src/OGL/ProgramPipeline.cpp diff --git a/engine/NBGraphics/src/Textures.cpp b/engine/NBGraphics/src/OGL/Textures.cpp similarity index 100% rename from engine/NBGraphics/src/Textures.cpp rename to engine/NBGraphics/src/OGL/Textures.cpp diff --git a/engine/NBGraphics/src/VertexArray.cpp b/engine/NBGraphics/src/OGL/VertexArray.cpp similarity index 100% rename from engine/NBGraphics/src/VertexArray.cpp rename to engine/NBGraphics/src/OGL/VertexArray.cpp -- 2.43.0