diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b6fbf..66ee675 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,6 +197,8 @@ add_library(fennec STATIC include/fennec/scene/scene.h include/fennec/scene/component.h include/fennec/core/system.h + include/fennec/renderers/opengl/lib/vertex_array.h + include/fennec/renderers/opengl/texture.h ) add_dependencies(fennec metaprogramming) diff --git a/include/fennec/renderers/opengl/lib/buffer.h b/include/fennec/renderers/opengl/lib/buffer.h index 7bc1410..836c131 100644 --- a/include/fennec/renderers/opengl/lib/buffer.h +++ b/include/fennec/renderers/opengl/lib/buffer.h @@ -16,8 +16,8 @@ // along with this program. If not, see . // ===================================================================================================================== -#ifndef FENNEC_PLATFORM_OPENGL_LIB_H -#define FENNEC_PLATFORM_OPENGL_LIB_H +#ifndef FENNEC_RENDERERS_OPENGL_LIB_BUFFER_H +#define FENNEC_RENDERERS_OPENGL_LIB_BUFFER_H #include #include @@ -66,9 +66,9 @@ public: static constexpr GLenum type = TypeV; static constexpr GLboolean immutable = ImmutableV; static constexpr GLbitfield flags = FlagsV; - static constexpr GLboolean read = flags & READ; - static constexpr GLboolean write = flags & WRITE; - static constexpr GLboolean mapped = read or write; + static constexpr GLboolean map_read = flags & READ; + static constexpr GLboolean map_write = flags & WRITE; + static constexpr GLboolean mapped = map_read or map_write; static constexpr GLboolean dynamic = flags & DYNAMIC; static constexpr GLboolean persistent = flags & PERSISTENT; static constexpr GLboolean coherent = flags & COHERENT; @@ -120,6 +120,14 @@ public: glBindBuffer(type, NULL); } + constexpr void bind(GLuint i, GLsizeiptr size = -1, GLintptr offset = 0) { + offset = max(offset, GLintptr(0)); + size = size < 0 ? _size : size; + size = min(size, _size - offset); + if (size <= 0) return; + glBindBufferRange(type, i, _handle, offset, size); + } + // BASIC BUFFER FUNCTIONS ============================================================================================== @@ -162,7 +170,16 @@ public: glBindBuffer(COPY_WRITE, NULL); } - constexpr void write(const void* data, GLsizeiptr size = -1, GLintptr offset = 0) { + constexpr void read(void* data, GLsizeiptr size, GLintptr offset = 0) const { + static_assert(dynamic or persistent and not (client or coherent)); + offset = max(offset, GLintptr(0)); + size = size < 0 ? _size : size; + size = min(size, _size - offset); + if (size <= 0) return; + glGetBufferSubData(type, offset, size, data); + } + + constexpr void write(const void* data, GLsizeiptr size, GLintptr offset = 0) { static_assert(dynamic or persistent and not (client or coherent)); offset = max(offset, GLintptr(0)); size = size < 0 ? _size : size; @@ -181,6 +198,14 @@ public: glFlushMappedBufferRange(type, offset, size); } + constexpr void invalidate(GLsizeiptr size, GLintptr offset = 0) { + offset = max(offset, GLintptr(0)); + size = size < 0 ? _size : size; + size = min(size, _size - offset); + if (size <= 0) return; + glInvalidateBufferSubData(type, offset, size); + } + // TYPED FUNCTIONS ===================================================================================================== @@ -189,10 +214,6 @@ public: return static_cast(map(access, n * sizeof(TypeT), offset * sizeof(TypeT))); } - constexpr void clear(float x, GLsizeiptr n, GLintptr offset = 0) { - clear(n * sizeof(float), offset * sizeof(float), &x, FLOAT, R, R32F); - } - private: GLuint _handle; GLsizeiptr _size; diff --git a/include/fennec/renderers/opengl/lib/enum.h b/include/fennec/renderers/opengl/lib/enum.h index 6e7cf76..a9c61f3 100644 --- a/include/fennec/renderers/opengl/lib/enum.h +++ b/include/fennec/renderers/opengl/lib/enum.h @@ -50,6 +50,7 @@ enum buffer_flag_ : GLbitfield { COHERENT = GL_MAP_COHERENT_BIT, CLIENT = GL_CLIENT_STORAGE_BIT, EXPLICIT_FLUSH = GL_MAP_FLUSH_EXPLICIT_BIT, + INVALIDATE = GL_MAP_INVALIDATE_BUFFER_BIT, }; enum access_ : GLbitfield { @@ -58,6 +59,24 @@ enum access_ : GLbitfield { READ_WRITE = GL_READ_WRITE, }; +enum texture_ : GLenum { + TEX_1D = GL_TEXTURE_1D, + TEX_1D_V = GL_TEXTURE_1D_ARRAY, + + TEX_2D = GL_TEXTURE_2D, + TEX_2D_V = GL_TEXTURE_2D_ARRAY, + TEX_2D_MS = GL_TEXTURE_2D_MULTISAMPLE, + TEX_2D_MS_V = GL_TEXTURE_2D_MULTISAMPLE_ARRAY, + TEX_RECT = GL_TEXTURE_RECTANGLE, + + TEX_CUBEMAP = GL_TEXTURE_CUBE_MAP, + TEX_CUBEMAP_V = GL_TEXTURE_CUBE_MAP_ARRAY, + + TEX_3D = GL_TEXTURE_3D, + + TEX_BUFFER = GL_TEXTURE_BUFFER, +}; + enum type_ : GLenum { BOOL = GL_BOOL, BVEC2 = GL_BOOL_VEC2, @@ -206,7 +225,7 @@ enum component_ : GLenum { DEPTH_STENCIL = GL_DEPTH_STENCIL, }; -enum format_ : GLenum { +enum format_ : GLint { R8 = GL_R8, R8_SNORM = GL_R8_SNORM, R16 = GL_R16, @@ -250,15 +269,45 @@ enum format_ : GLenum { RGB32F = GL_RGB32F, RGBA32F = GL_RGBA32F, + R8I = GL_R8I, + RG8I = GL_RG8I, + RGB8I = GL_RGB8I, + RGBA8I = GL_RGBA8I, + R16I = GL_R16I, RG16I = GL_RG16I, RGB16I = GL_RGB16I, RGBA16I = GL_RGBA16I, + R32I = GL_R32I, + RG32I = GL_RG32I, + RGB32I = GL_RGB32I, + RGBA32I = GL_RGBA32I, + + R8UI = GL_R8UI, + RG8UI = GL_RG8UI, + RGB8UI = GL_RGB8UI, + RGBA8UI = GL_RGBA8UI, + + R16UI = GL_R16UI, + RG16UI = GL_RG16UI, + RGB16UI = GL_RGB16UI, + RGBA16UI = GL_RGBA16UI, + R32UI = GL_R32UI, RG32UI = GL_RG32UI, RGB32UI = GL_RGB32UI, RGBA32UI = GL_RGBA32UI, + + RGB_DXT1 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + RGBA_DXT1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + RGBA_DXT3 = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, + RGBA_DXT5 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, + + SRGB_DXT1 = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, + SRGBA_DXT1 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + SRGBA_DXT3 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, + SRGBA_DXT5 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, }; } diff --git a/include/fennec/renderers/opengl/lib/texture.h b/include/fennec/renderers/opengl/lib/texture.h new file mode 100644 index 0000000..95ebb3e --- /dev/null +++ b/include/fennec/renderers/opengl/lib/texture.h @@ -0,0 +1,86 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#ifndef FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H +#define FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H + +#include +#include + +namespace fennec +{ + +namespace gl +{ + +template +class texture { +public: + static constexpr GLenum type = TypeV; + static constexpr GLint format = FormatV; + static constexpr bool immutable = ImmutableV; + static constexpr bool sampled = TypeV == TEX_2D_MS or TypeV == TEX_2D_MS_V; + static constexpr bool is_rect = TypeV == TEX_RECT; + static constexpr bool is_buffered = TypeV == TEX_BUFFER; + static constexpr bool is_2d = sampled or is_rect or TypeV == TEX_2D or TypeV == TEX_2D_V; + static constexpr bool is_1d = TypeV == TEX_1D or TypeV == TEX_1D_V; + static constexpr bool is_array = TypeV == TEX_1D_V or TypeV == TEX_2D_V or TypeV == TEX_2D_MS_V or TypeV == TEX_CUBEMAP_V; + static constexpr bool has_mipmaps = not(sampled or is_rect or is_buffered); + + texture(GLsizei width, GLint mips, void* data) requires is_1d and not is_array + : _handle(NULL) + , _width(width), _height(1), _depth(1) + , _samples(1) + , _mips(mips) { + glGenTextures(1, &_handle); + } + + texture(GLsizei width, GLsizei height, GLint mips) requires is_2d and not (is_array or sampled) or (is_1d and is_array) + : _handle(NULL) + , _width(width), _height(height), _depth(1) + , _samples(1) + , _mips(mips) { + } + + void start() { + glBindTexture(type, _handle); + } + + void end() { + glBindTexture(type, NULL); + } + + void bind(GLint i) { + glActiveTexture(GL_TEXTURE0 + i); + start(); + } + +private: + GLuint _handle; + GLsizei _width; + GLsizei _height; + GLsizei _depth; + GLsizei _samples; + GLint _mips; +}; + +} + +} + +#endif // FENNEC_RENDERERS_OPENGL_TEXTURE_H diff --git a/include/fennec/renderers/opengl/lib/vertex_array.h b/include/fennec/renderers/opengl/lib/vertex_array.h new file mode 100644 index 0000000..ca05db3 --- /dev/null +++ b/include/fennec/renderers/opengl/lib/vertex_array.h @@ -0,0 +1,67 @@ +// ===================================================================================================================== +// fennec, a free and open source game engine +// Copyright © 2025 Medusa Slockbower +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// ===================================================================================================================== + +#ifndef FENNEC_RENDERERS_OPENGL_LIB_VERTEX_ARRAY_H +#define FENNEC_RENDERERS_OPENGL_LIB_VERTEX_ARRAY_H + +#include +#include + +namespace fennec +{ + +namespace gl +{ + +class vertex_array { +public: + constexpr vertex_array() + : _handle(NULL) { + glGenVertexArrays(1, &_handle); + } + + constexpr ~vertex_array() { + glDeleteVertexArrays(1, &_handle); + } + + constexpr void start() const { + glBindVertexArray(_handle); + } + + constexpr void end() const { + glBindVertexArray(NULL); + } + + constexpr void set_attribute(GLuint i, GLenum type, GLint n, GLintptr offset, GLboolean normalized = false) { + glVertexAttribFormat(i, n, type, normalized, offset); + glEnableVertexAttribArray(i); + } + + constexpr void clear_attribute(GLuint i) { + glDisableVertexAttribArray(i); + } + +private: + GLuint _handle; +}; + +} + +} + +#endif // FENNEC_RENDERERS_OPENGL_LIB_VERTEX_ARRAY_H