- Moved OpenGL library wrapper into platform
- Finished reorganizing PLANNING.md
This commit is contained in:
250
include/fennec/platform/opengl/lib/buffer.h
Normal file
250
include/fennec/platform/opengl/lib/buffer.h
Normal file
@@ -0,0 +1,250 @@
|
||||
// =====================================================================================================================
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_RENDERERS_OPENGL_LIB_BUFFER_H
|
||||
#define FENNEC_RENDERERS_OPENGL_LIB_BUFFER_H
|
||||
|
||||
#include <fennec/math/common.h>
|
||||
#include <fennec/renderers/opengl/lib/fwd.h>
|
||||
#include <fennec/renderers/opengl/lib/enum.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using vertex_buffer = buffer<VERTEX, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using element_buffer = buffer<ELEMENT, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using uniform_buffer = buffer<UNIFORM, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using shader_storage_buffer = buffer<SHADER_STORAGE, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using query_buffer = buffer<QUERY, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using texture_buffer = buffer<TEXTURE, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using transform_feedback_buffer = buffer<TRANSFORM_FEEDBACK, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using atomic_counter_buffer = buffer<ATOMIC_COUNTER, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using parameter_buffer = buffer<PARAMETER, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using indirect_draw_buffer = buffer<INDIRECT_DRAW, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using indirect_dispatch_buffer = buffer<INDIRECT_DISPATCH, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using copy_read_buffer = buffer<COPY_READ, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using copy_write_buffer = buffer<COPY_WRITE, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using pixel_pack_buffer = buffer<PIXEL_PACK, FlagsV, ImmutableV>;
|
||||
template<GLbitfield FlagsV, GLboolean ImmutableV> using pixel_unpack_buffer = buffer<PIXEL_UNPACK, FlagsV, ImmutableV>;
|
||||
|
||||
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV>
|
||||
class buffer {
|
||||
|
||||
// HELPER FUNCTIONS ====================================================================================================
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// CONSTANTS ===========================================================================================================
|
||||
|
||||
public:
|
||||
static constexpr GLenum type = TypeV;
|
||||
static constexpr GLboolean immutable = ImmutableV;
|
||||
static constexpr GLbitfield flags = FlagsV;
|
||||
static constexpr GLboolean indexed = type == ATOMIC_COUNTER or type == SHADER_STORAGE or type == TRANSFORM_FEEDBACK or type == UNIFORM;
|
||||
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;
|
||||
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);
|
||||
|
||||
|
||||
// CONSTRUCTORS & ASSIGNMENT ===========================================================================================
|
||||
|
||||
constexpr buffer(const 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);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr buffer(buffer&& buff) noexcept
|
||||
: _handle(buff)
|
||||
, _size(buff._size)
|
||||
, _mapping(nullptr) {
|
||||
}
|
||||
|
||||
constexpr buffer& operator=(buffer&& buff) noexcept {
|
||||
glDeleteBuffers(1, &_handle);
|
||||
_handle = buff._handle;
|
||||
_size = buff._size;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr buffer(const buffer&) = delete;
|
||||
constexpr buffer& operator=(const buffer&) = delete;
|
||||
|
||||
|
||||
// OBJECT FUNCTIONS ====================================================================================================
|
||||
|
||||
constexpr void start() const {
|
||||
glBindBuffer(type, _handle);
|
||||
}
|
||||
|
||||
constexpr void end() const {
|
||||
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 ==============================================================================================
|
||||
|
||||
constexpr void resize(GLsizei size) requires not immutable {
|
||||
unmap();
|
||||
glBufferData(type, _size = size, nullptr, usage);
|
||||
}
|
||||
|
||||
constexpr void* map(GLbitfield access, GLsizeiptr size, GLintptr offset = 0) {
|
||||
if (_mapping) {
|
||||
return _mapping;
|
||||
}
|
||||
offset = max(offset, GLintptr(0));
|
||||
size = size < 0 ? _size : size;
|
||||
size = min(size, _size - offset);
|
||||
if (size <= 0) return nullptr;
|
||||
return _mapping = glMapBufferRange(type, offset, size, _mapflags = access);
|
||||
}
|
||||
|
||||
constexpr void unmap() {
|
||||
glUnmapBuffer(type);
|
||||
_mapping = nullptr;
|
||||
}
|
||||
|
||||
constexpr void clear(GLsizeiptr size = -1, GLintptr offset = 0, const void* data = nullptr, GLenum data_type = BYTE, GLenum format = R, GLenum internal = R8) {
|
||||
offset = max(offset, GLintptr(0));
|
||||
size = size < 0 ? _size : size;
|
||||
size = min(size, _size - offset);
|
||||
if (size <= 0) return;
|
||||
glClearBufferSubData(type, internal, offset, size, format, type, data);
|
||||
}
|
||||
|
||||
template<GLenum OTypeV, GLbitfield OFlagsV, GLboolean OImmutableV>
|
||||
constexpr void copy(const buffer<OTypeV, OFlagsV, OImmutableV>& cpy, GLsizeiptr size = -1, GLintptr write_offset = 0, GLintptr read_offset = 0) {
|
||||
write_offset = max(write_offset, GLintptr(0));
|
||||
read_offset = max(read_offset, GLintptr(0));
|
||||
size = size < 0 ? _size : size;
|
||||
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 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;
|
||||
size = min(size, _size - offset);
|
||||
if (size <= 0) return;
|
||||
glBufferSubData(type, offset, size, data);
|
||||
}
|
||||
|
||||
constexpr void flush(GLsizeiptr size = -1, GLintptr offset = 0) {
|
||||
if (not _mapping) return;
|
||||
if (not (_mapflags & EXPLICIT_FLUSH)) return;
|
||||
offset = max(offset, GLintptr(0));
|
||||
size = size < 0 ? _size : size;
|
||||
size = min(size, _size - offset);
|
||||
if (size <= 0) return;
|
||||
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 =====================================================================================================
|
||||
|
||||
template<typename TypeT>
|
||||
constexpr TypeT* map(GLbitfield access, GLsizeiptr n, GLintptr offset = 0) {
|
||||
return static_cast<TypeT*>(map(access, n * sizeof(TypeT), offset * sizeof(TypeT)));
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint _handle;
|
||||
GLsizeiptr _size;
|
||||
void* _mapping;
|
||||
GLbitfield _mapflags;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_PLATFORM_OPENGL_LIB_H
|
||||
317
include/fennec/platform/opengl/lib/enum.h
Normal file
317
include/fennec/platform/opengl/lib/enum.h
Normal file
@@ -0,0 +1,317 @@
|
||||
// =====================================================================================================================
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
|
||||
#define FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
|
||||
|
||||
#include <fennec/renderers/opengl/lib/fwd.h>
|
||||
|
||||
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 {
|
||||
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,
|
||||
EXPLICIT_FLUSH = GL_MAP_FLUSH_EXPLICIT_BIT,
|
||||
INVALIDATE = GL_MAP_INVALIDATE_BUFFER_BIT,
|
||||
};
|
||||
|
||||
enum access_ : GLbitfield {
|
||||
READ_ONLY = GL_READ_ONLY,
|
||||
WRITE_ONLY = GL_WRITE_ONLY,
|
||||
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,
|
||||
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_ : GLint {
|
||||
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,
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
|
||||
39
include/fennec/platform/opengl/lib/fwd.h
Normal file
39
include/fennec/platform/opengl/lib/fwd.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// =====================================================================================================================
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_RENDERERS_OPENGL_LIB_FWD_H
|
||||
#define FENNEC_RENDERERS_OPENGL_LIB_FWD_H
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
template<GLenum TypeV, GLbitfield FlagsV, GLboolean ImmutableV = false> class buffer;
|
||||
template<GLenum TypeV, GLint FormatV, GLboolean ImmutableV> class texture;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // FENNEC_RENDERERS_OPENGL_LIB_FWD_H
|
||||
312
include/fennec/platform/opengl/lib/texture.h
Normal file
312
include/fennec/platform/opengl/lib/texture.h
Normal file
@@ -0,0 +1,312 @@
|
||||
// =====================================================================================================================
|
||||
// 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 <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H
|
||||
#define FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H
|
||||
|
||||
/* Because our implementation targets minimum OpenGL ES 3.2,
|
||||
* we are guaranteed to have the following relevant extensions (Starting from OpenGL ES 3.0):
|
||||
*
|
||||
* OES_texture_compression_astc
|
||||
* EXT_texture_border_clamp
|
||||
* OES_EGL_image_external_essl3
|
||||
* ARB_shader_image_load_store
|
||||
* ARB_stencil_texturing
|
||||
* ARG_shader_image_size
|
||||
* ARB_texture_multisample
|
||||
* ARB_texture_storage_multisample
|
||||
* ARB_sample_locations
|
||||
* OES_texture_view
|
||||
* NV_image_formats
|
||||
* EXT_render_snorm
|
||||
* EXT_render_norm16
|
||||
* EXT_color_buffer_float
|
||||
* OES_copy_image
|
||||
* OES_shader_image_atomic
|
||||
* OES_texture_border_clamp
|
||||
* OES_texture_buffer
|
||||
* OES_texture_cube_map_array
|
||||
* OES_texture_stencil8
|
||||
* OES_texture_storage_multisample_2d_array
|
||||
*/
|
||||
|
||||
|
||||
#include <fennec/math/common.h>
|
||||
#include <fennec/renderers/opengl/lib/fwd.h>
|
||||
#include <fennec/renderers/opengl/lib/enum.h>
|
||||
|
||||
namespace fennec
|
||||
{
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture1d = texture<TEX_1D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture1dv = texture<TEX_1D_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d = texture<TEX_2D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2dv = texture<TEX_2D_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture_rect = texture<TEX_RECT, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2d_ms = texture<TEX_2D_MS, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture2dv_ms = texture<TEX_2D_MS_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using cubemap = texture<TEX_CUBEMAP, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using cubemapv = texture<TEX_CUBEMAP_V, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using texture3d = texture<TEX_3D, FormatV, ImmutableV>;
|
||||
template<GLint FormatV, GLboolean ImmutableV> using buffer_texture = texture<TEX_BUFFER, FormatV, ImmutableV>;
|
||||
|
||||
///
|
||||
/// \brief Wrapper for OpenGL Texture Objects
|
||||
/// \tparam TypeV The type of the texture
|
||||
/// \tparam FormatV The internal format of the texels
|
||||
/// \tparam ImmutableV Whether the texture is immutable, i.e. cannot be resized after creation
|
||||
///
|
||||
/// \details Immutable textures require EXT_texture_storage or ARB_texture_storage
|
||||
/// Immutable multisample textures require ARB_texture_storage_multisample of OES_texture_storage_multisample_2d_array
|
||||
template<GLenum TypeV, GLint FormatV, GLboolean ImmutableV>
|
||||
class texture {
|
||||
|
||||
// Constants ===========================================================================================================
|
||||
|
||||
public:
|
||||
static constexpr GLenum type = TypeV;
|
||||
static constexpr GLint format = FormatV;
|
||||
static constexpr GLboolean immutable = ImmutableV;
|
||||
static constexpr GLboolean is_rect = type == TEX_RECT;
|
||||
static constexpr GLboolean is_buffered = type == TEX_BUFFER;
|
||||
static constexpr GLboolean sampled = type == TEX_2D_MS or type == TEX_2D_MS_V;
|
||||
static constexpr GLboolean cubemap = type == TEX_CUBEMAP or type == TEX_CUBEMAP_V;
|
||||
static constexpr GLboolean is_1d = type == TEX_1D or type == TEX_1D_V;
|
||||
static constexpr GLboolean is_2d = sampled or is_rect or type == TEX_2D or type == TEX_2D_V or cubemap;
|
||||
static constexpr GLboolean is_array = TypeV == TEX_1D_V or TypeV == TEX_2D_V or type == TEX_2D_MS_V or type == TEX_CUBEMAP_V;
|
||||
static constexpr GLboolean is_3d = TypeV == TEX_3D;
|
||||
static constexpr GLboolean has_mipmaps = not(sampled or is_rect or is_buffered);
|
||||
|
||||
static constexpr GLboolean use_1d = is_1d and not is_array;
|
||||
static constexpr GLboolean use_2d = (is_2d and not is_array) or (is_1d and is_array) and not sampled;
|
||||
static constexpr GLboolean use_3d = is_3d or (is_2d and is_array) and not sampled and not cubemap;
|
||||
|
||||
static constexpr GLint cubemap_faces = 6;
|
||||
static constexpr GLenum base_cubemap_face = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
|
||||
static constexpr GLboolean compressed = type == RGB_DXT1 or type == RGBA_DXT1 or type == RGBA_DXT3 or type == RGBA_DXT5
|
||||
or type == SRGB_DXT1 or type == SRGBA_DXT1 or type == SRGBA_DXT3 or type == SRGBA_DXT5;
|
||||
|
||||
|
||||
// Constructors ========================================================================================================
|
||||
|
||||
///
|
||||
/// \brief 1D Texture Constructor
|
||||
/// \param width The width of the texture
|
||||
/// \param mips The number of mipmap levels
|
||||
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
|
||||
/// \param component The type of each component
|
||||
/// \param layout The layout of components in each pixel
|
||||
texture(GLsizei width, GLint mips,
|
||||
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_1d
|
||||
: _handle(NULL)
|
||||
, _width(width), _height(1), _depth(1)
|
||||
, _samples(1), _mips(mips) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage1D(type, _mips, format, _width);
|
||||
glTexSubImage1D(type, 0, 0, _width, layout, component, data);
|
||||
} else if constexpr(compressed) {
|
||||
glCompressedTexImage1D(type, 0, format, _width, 0, size, data);
|
||||
} else {
|
||||
glTexImage1D(type, 0, format, _width, 0, layout, component, data);
|
||||
}
|
||||
genmips();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief 2D Texture Constructor
|
||||
/// \param width The width of the texture
|
||||
/// \param height The height of the texture, or number of layers for arrays
|
||||
/// \param mips The number of mipmap levels
|
||||
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
|
||||
/// \param component The type of each component
|
||||
/// \param layout The layout of components in each pixel
|
||||
texture(GLsizei width, GLsizei height, GLint mips,
|
||||
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_2d and not cubemap
|
||||
: _handle(NULL)
|
||||
, _width(width), _height(height), _depth(1)
|
||||
, _samples(1), _mips(mips) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage2D(type, _mips, format, _width, _height);
|
||||
glTexSubImage2D(type, 0, 0, 0, _width, _height, layout, component, data);
|
||||
} else if constexpr(compressed) {
|
||||
glCompressedTexImage2D(type, 0, format, _width, _height, 0, size, data);
|
||||
} else {
|
||||
glTexImage2D(type, 0, format, _width, _height, 0, layout, component, data);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief 2D Texture Constructor
|
||||
/// \param width The width of the texture
|
||||
/// \param height The height of the texture
|
||||
/// \param depth The depth of the texture, or number of layers for arrays
|
||||
/// \param mips The number of mipmap levels
|
||||
/// \param data A pointer to a buffer containing pixel values, used as an offset if a PIXEL_UNPACK_BUFFER is bound.
|
||||
/// \param component The type of each component
|
||||
/// \param layout The layout of components in each pixel
|
||||
texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei mips,
|
||||
void* data = nullptr, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires use_3d and not cubemap
|
||||
: _handle(NULL)
|
||||
, _width(width), _height(height), _depth(depth)
|
||||
, _samples(1), _mips(mips) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage3D(type, _mips, format, _width, _height, _depth);
|
||||
glTexSubImage3D(type, 0, 0, 0, 0, _width, _height, _depth, layout, component, data);
|
||||
} else if constexpr(compressed) {
|
||||
glCompressedTexImage3D(type, 0, format, _width, _height, _depth, 0, size, data);
|
||||
} else {
|
||||
glTexImage3D(type, 0, format, _width, _height, _depth, 0, layout, component, data);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief 2D Multisample Texture Constructor
|
||||
/// \param width The width of the texture
|
||||
/// \param height The height of the texture
|
||||
/// \param samples The number of samples per pixel
|
||||
/// \param fixed When true, a fixed set of sample locations is used
|
||||
texture(GLsizei width, GLsizei height, GLsizei samples, GLboolean fixed = true) requires sampled and not is_array
|
||||
: _handle(NULL)
|
||||
, _width(width), _height(height), _depth(1)
|
||||
, _samples(samples), _mips(0) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage2DMultisample(type, _samples, format, _width, _height, fixed);
|
||||
} else {
|
||||
glTexImage2DMultisample(type, _samples, format, _width, _height, fixed);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief 2D Multisample Array Texture Constructor
|
||||
/// \param width The width of the texture
|
||||
/// \param height The height of the texture
|
||||
/// \param depth The number of layers in the array
|
||||
/// \param samples The number of samples per pixel
|
||||
/// \param fixed When true, a fixed set of sample locations is used
|
||||
texture(GLsizei width, GLsizei height, GLsizei depth, GLsizei samples, GLboolean fixed = true) requires sampled and is_array
|
||||
: _handle(NULL)
|
||||
, _width(width), _height(height), _depth(depth)
|
||||
, _samples(samples), _mips(0) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage3DMultisample(type, _samples, format, _width, _height, _depth, fixed);
|
||||
} else {
|
||||
glTexImage3DMultisample(type, _samples, format, _width, _height, _depth, fixed);
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Cubemap Constructor
|
||||
/// \param size The size of each face texture
|
||||
/// \param mips The number of mipmap layers
|
||||
/// \param faces An array of pointers to textures containing pixel data for each face
|
||||
/// \param component The component type of the data
|
||||
/// \param layout The layout of the components in the pixel
|
||||
texture(GLsizei size, GLsizei mips,
|
||||
const void* faces[6], GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
|
||||
: _handle(NULL)
|
||||
, _width(size), _height(size), _depth(1)
|
||||
, _samples(1), _mips(mips) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage2D(type, _mips, format, _width, _height);
|
||||
for (int i = 0; i < cubemap_faces; ++i) {
|
||||
glTexSubImage2D(base_cubemap_face + i, 0, 0, 0, _width, _height, layout, component, faces[i]);
|
||||
}
|
||||
} else if constexpr(compressed) {
|
||||
} else {
|
||||
for (int i = 0; i < cubemap_faces; ++i) {
|
||||
glTexImage2D(base_cubemap_face + i, 0, format, _width, _height, 0, layout, component, faces[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Cubemap Array Constructor
|
||||
/// \param size The size of each face texture
|
||||
/// \param depth The number of layers in the array
|
||||
/// \param mips The number of mipmap layers
|
||||
/// \param data A pointer to a buffer containing image data
|
||||
/// \param component The component type of the data
|
||||
/// \param layout The layout of the components in the pixel
|
||||
///
|
||||
/// \details Requires OES_texture_cube_map_array
|
||||
texture(GLsizei size, GLsizei depth, GLsizei mips,
|
||||
const void* data, GLenum component = BYTE, GLenum layout = R, GLsizei size = 0) requires is_2d and cubemap
|
||||
: _handle(NULL)
|
||||
, _width(size), _height(size), _depth(depth)
|
||||
, _samples(1), _mips(mips) {
|
||||
glGenTextures(1, &_handle);
|
||||
start();
|
||||
if constexpr(immutable) {
|
||||
glTexStorage3D(type, _mips, format, _width, _height, _depth * 6);
|
||||
glTexSubImage3D(type, 0, 0, 0, 0, _width, _height, _depth * 6, layout, component, data);
|
||||
} else if constexpr(compressed) {
|
||||
} else {
|
||||
glTexImage3D(type, 0, format, _width, _height, _depth * 6, 0, layout, component, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Basic Functions =====================================================================================================
|
||||
|
||||
void start() {
|
||||
glBindTexture(type, _handle);
|
||||
}
|
||||
|
||||
void end() {
|
||||
glBindTexture(type, NULL);
|
||||
}
|
||||
|
||||
void bind(GLint i) {
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
start();
|
||||
}
|
||||
|
||||
void genmips() {
|
||||
glGenerateMipmap(type);
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint _handle;
|
||||
GLsizei _width;
|
||||
GLsizei _height;
|
||||
GLsizei _depth;
|
||||
GLsizei _samples;
|
||||
GLint _mips;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FENNEC_RENDERERS_OPENGL_LIB_TEXTURE_H
|
||||
67
include/fennec/platform/opengl/lib/vertex_array.h
Normal file
67
include/fennec/platform/opengl/lib/vertex_array.h
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
// =====================================================================================================================
|
||||
|
||||
#ifndef FENNEC_RENDERERS_OPENGL_LIB_VERTEX_ARRAY_H
|
||||
#define FENNEC_RENDERERS_OPENGL_LIB_VERTEX_ARRAY_H
|
||||
|
||||
#include <fennec/renderers/opengl/lib/fwd.h>
|
||||
#include <fennec/renderers/opengl/lib/enum.h>
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user