diff --git a/CMakeLists.txt b/CMakeLists.txt index 84e08ce..c2b6fbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,9 @@ include("${FENNEC_SOURCE_DIR}/cmake/platform.cmake") include("${FENNEC_SOURCE_DIR}/cmake/build.cmake") include("${FENNEC_SOURCE_DIR}/cmake/compiler.cmake") +# common defines +list(APPEND FENNEC_COMPILE_DEFINITIONS "NULL=0") + # find dependencies find_package(Doxygen) fennec_check_platform() diff --git a/cmake/opengl.cmake b/cmake/opengl.cmake index 3d595e4..38e1eb0 100644 --- a/cmake/opengl.cmake +++ b/cmake/opengl.cmake @@ -18,13 +18,14 @@ if(FENNEC_GRAPHICS_WANT_EGL) find_package(OpenGL REQUIRED COMPONENTS EGL) + find_package(GLEW REQUIRED) message(STATUS "EGL Requested") else() find_package(OpenGL) endif() -if(TARGET OpenGL::GL) - list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL) +if(TARGET OpenGL::GL AND TARGET GLEW::GLEW) + list(APPEND FENNEC_LINK_LIBRARIES OpenGL::GL GLEW::GLEW) list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_OPENGL=1) else() message(FATAL_ERROR "No Suitable OpenGL implementation found.") @@ -38,9 +39,13 @@ if(FENNEC_GRAPHICS_WANT_EGL) list(APPEND FENNEC_LINK_LIBRARIES OpenGL::EGL) list(APPEND FENNEC_COMPILE_DEFINITIONS FENNEC_GRAPHICS_EGL=1) list(APPEND FENNEC_EXTRA_SOURCES - include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp + include/fennec/renderers/opengl/lib/fwd.h + include/fennec/renderers/opengl/lib/enum.h + include/fennec/renderers/opengl/lib/buffer.h include/fennec/renderers/opengl/modern.h include/fennec/renderers/opengl/fallback.h + + include/fennec/platform/opengl/egl/context.h source/platform/opengl/egl/context.cpp ) endif() \ No newline at end of file diff --git a/include/fennec/math/scalar.h b/include/fennec/math/scalar.h index 7296e03..d584d77 100644 --- a/include/fennec/math/scalar.h +++ b/include/fennec/math/scalar.h @@ -65,9 +65,10 @@ namespace fennec { -/// -/// \brief an unsigned integer -using uint = unsigned int; +using byte = uint8_t; +using ubyte = uint8_t; +using ushort = uint16_t; +using uint = uint32_t; } diff --git a/include/fennec/renderers/opengl/lib/buffer.h b/include/fennec/renderers/opengl/lib/buffer.h new file mode 100644 index 0000000..15c9c81 --- /dev/null +++ b/include/fennec/renderers/opengl/lib/buffer.h @@ -0,0 +1,149 @@ +// ===================================================================================================================== +// 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_PLATFORM_OPENGL_LIB_H +#define FENNEC_PLATFORM_OPENGL_LIB_H + +#include +#include +#include + +namespace fennec +{ + +namespace gl +{ + +template +class buffer { +private: + static constexpr GLenum get_mutable_traits() { + GLenum res; + + // Set READ/DRAW/COPY + if constexpr (read) { + res = GL_STREAM_READ; + } else if constexpr (write) { + res = GL_STREAM_DRAW; + } else { + res = GL_STREAM_COPY; + } + + // Set STATIC/DYNAMIC/STREAM + if constexpr (client or coherent) { + // do nothing + } else if constexpr (dynamic or persistent) { + res += 6; + } else { + res += 3; + } + + return res; + } + +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 dynamic = flags & DYNAMIC; + static constexpr GLboolean persistent = flags & PERSISTENT; + static constexpr GLboolean coherent = flags & COHERENT; + static constexpr GLboolean client = flags & CLIENT; + static constexpr GLenum usage = get_mutable_traits(); + + static_assert(not persistent or persistent == mapped); + static_assert(not coherent or coherent == persistent); + + constexpr buffer(void* data, GLsizeiptr size) + : _handle() + , _size(size) { + glGenBuffers(1, &_handle); + start(); + if constexpr(immutable) { + glBufferStorage(type, _size, data, flags); + } else { + glBufferData(type, _size, data, usage); + } + end(); + } + + constexpr buffer(buffer&& buff) noexcept + : _handle(buff) + , _size(buff._size) { + } + + constexpr buffer(const buffer&) = delete; + + constexpr buffer& operator=(buffer&& buff) noexcept { + glDeleteBuffers(1, &_handle); + _handle = buff._handle; + _size = buff._size; + return *this; + } + + constexpr void start() const { + glBindBuffer(type, _handle); + } + + constexpr void end() const { + glBindBuffer(type, NULL); + } + + constexpr void clear(GLsizeiptr size, GLintptr offset = 0, const void* data = nullptr, GLenum data_type = BYTE, GLenum format = R, GLenum internal = R8) { + size = min(size, _size - offset); + if (size <= 0) return; + glClearBufferSubData(type, internal, offset, size, format, type, data); + } + + template + constexpr void copy(const buffer& cpy, GLsizeiptr size, GLintptr write_offset = 0, GLintptr read_offset = 0) { + size = fennec::min(size, cpy._size - read_offset); + size = fennec::min(size, _size - write_offset); + if (size <= 0) return; + glBindBuffer(COPY_READ, cpy._handle); + glBindBuffer(COPY_WRITE, _handle); + glCopyBufferSubData(COPY_READ, COPY_WRITE, read_offset, write_offset, size); + glBindBuffer(COPY_READ, NULL); + glBindBuffer(COPY_WRITE, NULL); + } + + constexpr void write(const void* data, GLsizeiptr size, GLintptr offset = 0) { + static_assert(dynamic or persistent and not (client or coherent)); + size = min(size, _size - offset); + glBufferSubData(type, offset, size, data); + } + + constexpr void resize() + + constexpr void map() { + + } + +private: + GLuint _handle; + GLsizeiptr _size; +}; + +} + +} + +#endif // FENNEC_PLATFORM_OPENGL_LIB_H diff --git a/include/fennec/renderers/opengl/lib/enum.h b/include/fennec/renderers/opengl/lib/enum.h new file mode 100644 index 0000000..b45ed72 --- /dev/null +++ b/include/fennec/renderers/opengl/lib/enum.h @@ -0,0 +1,260 @@ +// ===================================================================================================================== +// 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_ENUM_H +#define FENNEC_RENDERERS_OPENGL_LIB_ENUM_H + +#include + +namespace fennec +{ + +namespace gl +{ + +enum buffer_ : GLenum { + VERTEX = GL_ARRAY_BUFFER, + ELEMENT = GL_ELEMENT_ARRAY_BUFFER, + UNIFORM = GL_UNIFORM_BUFFER, + SHADER_STORAGE = GL_SHADER_STORAGE_BUFFER, + QUERY = GL_QUERY_BUFFER, + TEXTURE = GL_TEXTURE_BUFFER, + TRANSFORM_FEEDBACK = GL_TRANSFORM_FEEDBACK_BUFFER, + ATOMIC_COUNTER = GL_ATOMIC_COUNTER_BUFFER, + PARAMETER = GL_PARAMETER_BUFFER, + INDIRECT_DRAW = GL_DRAW_INDIRECT_BUFFER, INDIRECT_DISPATCH = GL_DISPATCH_INDIRECT_BUFFER, + COPY_READ = GL_COPY_READ_BUFFER, COPY_WRITE = GL_COPY_WRITE_BUFFER, + PIXEL_PACK = GL_PIXEL_PACK_BUFFER, PIXEL_UNPACK = GL_PIXEL_UNPACK_BUFFER, +}; + +enum buffer_flag_ : GLbitfield { + NONE = 0, + READ = GL_MAP_READ_BIT, + WRITE = GL_MAP_WRITE_BIT, + DYNAMIC = GL_DYNAMIC_STORAGE_BIT, + PERSISTENT = GL_MAP_PERSISTENT_BIT, + COHERENT = GL_MAP_COHERENT_BIT, + CLIENT = GL_CLIENT_STORAGE_BIT, +}; + +enum type_ : GLenum { + BOOL = GL_BOOL, + BVEC2 = GL_BOOL_VEC2, + BVEC3 = GL_BOOL_VEC3, + BVEC4 = GL_BOOL_VEC4, + BYTE = GL_BYTE, + SHORT = GL_SHORT, + INT = GL_INT, + IVEC2 = GL_INT_VEC2, + IVEC3 = GL_INT_VEC3, + IVEC4 = GL_INT_VEC4, + UBYTE = GL_UNSIGNED_BYTE, + USHORT = GL_UNSIGNED_SHORT, + UINT = GL_UNSIGNED_INT, + UVEC2 = GL_UNSIGNED_INT_VEC2, + UVEC3 = GL_UNSIGNED_INT_VEC3, + UVEC4 = GL_UNSIGNED_INT_VEC4, + + HALF = GL_HALF_FLOAT, + FLOAT = GL_FLOAT, + VEC2 = GL_FLOAT_VEC2, + VEC3 = GL_FLOAT_VEC3, + VEC4 = GL_FLOAT_VEC4, + DOUBLE = GL_DOUBLE, + DVEC2 = GL_DOUBLE_VEC2, + DVEC3 = GL_DOUBLE_VEC3, + DVEC4 = GL_DOUBLE_VEC4, + + UBYTE332 = GL_UNSIGNED_BYTE_3_3_2, + UBYTE233R = GL_UNSIGNED_BYTE_2_3_3_REV, + USHORT565 = GL_UNSIGNED_SHORT_5_6_5, + USHORT565R = GL_UNSIGNED_SHORT_5_6_5_REV, + USHORT4444 = GL_UNSIGNED_SHORT_4_4_4_4, + USHORT4444R = GL_UNSIGNED_SHORT_4_4_4_4_REV, + USHORT5551 = GL_UNSIGNED_SHORT_5_5_5_1, + USHORT1555R = GL_UNSIGNED_SHORT_1_5_5_5_REV, + UINT8888 = GL_UNSIGNED_INT_8_8_8_8, + UINT8888R = GL_UNSIGNED_INT_8_8_8_8_REV, + UINTAAA2 = GL_UNSIGNED_INT_10_10_10_2, + UINT2AAAR = GL_UNSIGNED_INT_2_10_10_10_REV, + UINT24_8 = GL_UNSIGNED_INT_24_8, + + UINTABBFR = GL_UNSIGNED_INT_10F_11F_11F_REV, + UINT5999R = GL_UNSIGNED_INT_5_9_9_9_REV, + FLOAT32UINT24 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV, + + SAMPLER_1D = GL_SAMPLER_1D, + SAMPLER_1D_V = GL_SAMPLER_1D_ARRAY, + SHADOW_SAMPLER_1D = GL_SAMPLER_1D_SHADOW, + SHADOW_SAMPLER_1D_V = GL_SAMPLER_1D_ARRAY_SHADOW, + + SAMPLER_2D = GL_SAMPLER_2D, + SAMPLER_2D_V = GL_SAMPLER_2D_ARRAY, + SAMPLER_RECT_2D = GL_SAMPLER_2D_RECT, + SAMPLER_2D_MS = GL_SAMPLER_2D_MULTISAMPLE, + SAMPLER_2D_MS_V = GL_SAMPLER_2D_MULTISAMPLE_ARRAY, + SHADOW_SAMPLER_2D = GL_SAMPLER_2D_SHADOW, + SHADOW_SAMPLER_2D_V = GL_SAMPLER_2D_ARRAY_SHADOW, + SHADOW_SAMPLER_RECT_2D = GL_SAMPLER_2D_RECT_SHADOW, + SAMPLER_CUBEMAP = GL_SAMPLER_CUBE, + SHADOW_SAMPLER_CUBEMAP = GL_SAMPLER_CUBE_SHADOW, + SAMPLER_3D = GL_SAMPLER_3D, + SAMPLER_BUFFER = GL_SAMPLER_BUFFER, + + ISAMPLER_1D = GL_INT_SAMPLER_1D, + ISAMPLER_1D_V = GL_INT_SAMPLER_1D_ARRAY, + ISAMPLER_2D = GL_INT_SAMPLER_2D, + ISAMPLER_2D_V = GL_INT_SAMPLER_2D_ARRAY, + ISAMPLER_RECT_2D = GL_INT_SAMPLER_2D_RECT, + ISAMPLER_2D_MS = GL_INT_SAMPLER_2D_MULTISAMPLE, + ISAMPLER_2D_MS_V = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + ISAMPLER_CUBEMAP = GL_INT_SAMPLER_CUBE, + ISAMPLER_3D = GL_INT_SAMPLER_3D, + ISAMPLER_BUFFER = GL_INT_SAMPLER_BUFFER, + + USAMPLER_1D = GL_INT_SAMPLER_1D, + USAMPLER_1D_V = GL_INT_SAMPLER_1D_ARRAY, + USAMPLER_2D = GL_INT_SAMPLER_2D, + USAMPLER_2D_V = GL_INT_SAMPLER_2D_ARRAY, + USAMPLER_RECT_2D = GL_INT_SAMPLER_2D_RECT, + USAMPLER_2D_MS = GL_INT_SAMPLER_2D_MULTISAMPLE, + USAMPLER_2D_MS_V = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, + USAMPLER_CUBEMAP = GL_INT_SAMPLER_CUBE, + USAMPLER_3D = GL_INT_SAMPLER_3D, + USAMPLER_BUFFER = GL_INT_SAMPLER_BUFFER, + + IMAGE_1D = GL_IMAGE_1D, + IMAGE_1D_V = GL_IMAGE_1D_ARRAY, + IMAGE_2D = GL_IMAGE_2D, + IMAGE_2D_V = GL_IMAGE_2D_ARRAY, + IMAGE_RECT_2D = GL_IMAGE_2D_RECT, + IMAGE_2D_MS = GL_IMAGE_2D_MULTISAMPLE, + IMAGE_2D_MS_V = GL_IMAGE_2D_MULTISAMPLE_ARRAY, + IMAGE_CUBEMAP = GL_IMAGE_CUBE, + IMAGE_3D = GL_IMAGE_3D, + IMAGE_BUFFER = GL_IMAGE_BUFFER, + + IIMAGE_1D = GL_INT_IMAGE_1D, + IIMAGE_1D_V = GL_INT_IMAGE_1D_ARRAY, + IIMAGE_2D = GL_INT_IMAGE_2D, + IIMAGE_2D_V = GL_INT_IMAGE_2D_ARRAY, + IIMAGE_RECT_2D = GL_INT_IMAGE_2D_RECT, + IIMAGE_2D_MS = GL_INT_IMAGE_2D_MULTISAMPLE, + IIMAGE_2D_MS_V = GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY, + IIMAGE_CUBEMAP = GL_INT_IMAGE_CUBE, + IIMAGE_3D = GL_INT_IMAGE_3D, + IIMAGE_BUFFER = GL_INT_IMAGE_BUFFER, + + UIMAGE_1D = GL_UNSIGNED_INT_IMAGE_1D, + UIMAGE_1D_V = GL_UNSIGNED_INT_IMAGE_1D_ARRAY, + UIMAGE_2D = GL_UNSIGNED_INT_IMAGE_2D, + UIMAGE_2D_V = GL_UNSIGNED_INT_IMAGE_2D_ARRAY, + UIMAGE_RECT_2D = GL_UNSIGNED_INT_IMAGE_2D_RECT, + UIMAGE_2D_MS = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE, + UIMAGE_2D_MS_V = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY, + UIMAGE_CUBEMAP = GL_UNSIGNED_INT_IMAGE_CUBE, + UIMAGE_3D = GL_UNSIGNED_INT_IMAGE_3D, + UIMAGE_BUFFER = GL_UNSIGNED_INT_IMAGE_BUFFER, + + AtomicCounter = GL_UNSIGNED_INT_ATOMIC_COUNTER, +}; + +enum component_ : GLenum { + ZERO = GL_ZERO, + ONE = GL_ONE, + R = GL_RED, + G = GL_GREEN, + B = GL_BLUE, + A = GL_ALPHA, + RGB = GL_RGB, + BGR = GL_BGR, + RGBA = GL_RGBA, + BGRA = GL_BGRA, + RI = GL_RED_INTEGER, + GI = GL_GREEN_INTEGER, + BI = GL_BLUE_INTEGER, + AI = GL_ALPHA_INTEGER, + RGBI = GL_RGB_INTEGER, + BGRI = GL_BGR_INTEGER, + RGBAI = GL_RGBA_INTEGER, + BGRAI = GL_BGRA_INTEGER, + STENCIL = GL_STENCIL_INDEX, + DEPTH = GL_DEPTH_COMPONENT, + DEPTH_STENCIL = GL_DEPTH_STENCIL, +}; + +enum format_ : GLenum { + R8 = GL_R8, + R8_SNORM = GL_R8_SNORM, + R16 = GL_R16, + R16_SNORM = GL_R16_SNORM, + + RG8 = GL_RG8, + RG8_SNORM = GL_RG8_SNORM, + RG16 = GL_RG16, + RG16_SNORM = GL_RG16_SNORM, + + RGB332 = GL_R3_G3_B2, + RGB4 = GL_RGB4, + RGB5 = GL_RGB5, + RGB8 = GL_RGB8, + RGB8_SNORM = GL_RGB8_SNORM, + RGB10 = GL_RGB10, + RGB12 = GL_RGB12, + RGB16 = GL_RGB16, + RGB16_SNORM = GL_RGB16_SNORM, + + RGBA2 = GL_RGBA2, + RGBA4 = GL_RGBA4, + RGB5_A1 = GL_RGB5_A1, + RGBA8 = GL_RGBA8, + RGBA8_SNORM = GL_RGBA8_SNORM, + RGB10_A2 = GL_RGB10_A2, + RGB10_A2UI = GL_RGB10_A2UI, + RGBA12 = GL_RGBA12, + RGBA16 = GL_RGBA16, + + SRGB8 = GL_SRGB8, + SRGBA8 = GL_SRGB8_ALPHA8, + + R16F = GL_R16F, + RG16F = GL_RG16F, + RGB16F = GL_RGB16F, + RGBA16F = GL_RGBA16F, + + R32F = GL_R32F, + RG32F = GL_RG32F, + RGB32F = GL_RGB32F, + RGBA32F = GL_RGBA32F, + + R16I = GL_R16I, + RG16I = GL_RG16I, + RGB16I = GL_RGB16I, + RGBA16I = GL_RGBA16I, + + R32UI = GL_R32UI, + RG32UI = GL_RG32UI, + RGB32UI = GL_RGB32UI, + RGBA32UI = GL_RGBA32UI, +}; + +} + +} + +#endif // FENNEC_RENDERERS_OPENGL_LIB_ENUM_H diff --git a/include/fennec/renderers/opengl/lib/fwd.h b/include/fennec/renderers/opengl/lib/fwd.h new file mode 100644 index 0000000..f162301 --- /dev/null +++ b/include/fennec/renderers/opengl/lib/fwd.h @@ -0,0 +1,25 @@ +// ===================================================================================================================== +// 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_FWD_H +#define FENNEC_RENDERERS_OPENGL_LIB_FWD_H + +#include +#include + +#endif // FENNEC_RENDERERS_OPENGL_LIB_FWD_H diff --git a/include/fennec/renderers/opengl/modern.h b/include/fennec/renderers/opengl/modern.h index e183c35..9d23899 100644 --- a/include/fennec/renderers/opengl/modern.h +++ b/include/fennec/renderers/opengl/modern.h @@ -23,12 +23,14 @@ * * Requires the following: * OpenGL 4.6 OR - * - ARB_shader_draw_parameters - * - ARB_multi_draw_indirect - * - EXT_texture_array + * - ARB_buffer_storage * - ARB_compute_shader + * - ARB_multi_draw_indirect + * - ARB_shader_draw_parameters * - ARB_shader_image_load_store * - ARB_texture_cube_map_array + * - ARB_texture_storage + * - EXT_texture_array * * This will support >91.31% of devices on Steam, including all Desktop GPUs and iGPUs since 2012 */