glw/common.h
2025-06-03 14:29:27 -04:00

422 lines
12 KiB
C++
Executable File

// =====================================================================================================================
// glw, an open-source library that wraps OpenGL structures into classes.
// Copyright (C) 2024 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 GLW_COMMON_H
#define GLW_COMMON_H
#define GLW_STRINGIFY_(X) #X
#define GLW_STRINGIFY(X) GLW_STRINGIFY_(X)
#include <cstddef>
#include <gl/glew.h>
namespace glw
{
// Typedefs ============================================================================================================
using handle_t = GLuint;
using size_t = GLsizei;
using offset_t = GLintptr;
using flags_t = GLbitfield;
using index_t = GLint;
using location_t = GLuint;
using enum_t = GLenum;
using int_t = GLint;
using int64_t = GLint64;
using float_t = GLfloat;
using uint_t = GLuint;
using char_t = GLchar;
// Template Pack Contains Value
template<class...Ts> struct contains;
template<enum_t...Ts> struct contains_enum;
template<class T> struct contains<T> { static constexpr bool value = std::false_type{}; };
template<enum_t T> struct contains_enum<T> { static constexpr bool value = std::false_type{}; };
template<class T, class T0, class...Ts>
struct contains<T, T0, Ts...>
{
static constexpr bool value = std::is_same<T, T0>::value || (sizeof...(Ts) > 0 && contains<T, Ts...>::value);
constexpr operator bool() const { return value; }
};
template<enum_t T, enum_t T0, enum_t...Ts>
struct contains_enum<T, T0, Ts...>
{
static constexpr bool value = T == T0 || (sizeof...(Ts) > 0 && contains_enum<T, Ts...>::value);
constexpr operator bool() const { return value; }
};
// Math Functions
template<typename genType>
inline genType min(genType&& v) { return std::forward<genType>(v); }
template<typename genType>
inline genType min(genType&& a, genType&& b) { return std::forward<genType&&>(a < b ? a : b); }
template<typename genType>
inline genType min(genType&& a, genType&& b, genType&& rest...)
{
return max(std::forward<genType&&>(a < b ? a : b), std::forward<genType>(rest)...);
}
template<typename genType>
inline genType&& max(genType&& v) { return std::forward<genType>(v); }
template<typename genType>
inline genType&& max(genType&& a, genType&& b) { return std::forward<genType&&>(a > b ? a : b); }
template<typename genType>
inline genType&& max(genType&& a, genType&& b, genType&& rest...)
{
return max(std::forward<genType&&>(a > b ? a : b), std::forward<genType>(rest)...);
}
template<typename genType>
inline genType ceil_div(const genType& a, const genType& b)
{
return 1 + ((a - 1) / b);
}
// Enums ===============================================================================================================
enum access : enum_t
{
access_read = GL_READ_ONLY
, access_write = GL_WRITE_ONLY
, access_read_write = GL_READ_WRITE
};
enum layout : enum_t
{
// Floating Point Layouts ==============================================================================================
r = GL_RED
, rg = GL_RG
, rgb = GL_RGB
, bgr = GL_BGR
, rgba = GL_RGBA
, bgra = GL_BGRA
// Integer Layouts =====================================================================================================
, r_i = GL_RED_INTEGER
, rg_i = GL_RG_INTEGER
, rgb_i = GL_RGB_INTEGER
, bgr_i = GL_BGR_INTEGER
, rgba_i = GL_RGBA_INTEGER
, bgra_i = GL_BGRA_INTEGER
// Special Layouts =====================================================================================================
, depth = GL_DEPTH_COMPONENT
, stencil = GL_STENCIL_INDEX
, depth_stencil = GL_DEPTH_STENCIL
};
enum format : enum_t
{
// Fixed & Floating Points Formats =====================================================================================
r8 = GL_R8
, r8_snorm = GL_R8_SNORM
, r16 = GL_R16
, r16f = GL_R16F
, r16_snorm = GL_R16_SNORM
, r32 = GL_R32F
, rg8 = GL_RG8
, rg8_snorm = GL_RG8_SNORM
, rg16 = GL_RG16
, rg16f = GL_RG16F
, rg16_snorm = GL_RG16_SNORM
, rg32 = GL_RG32F
, rgb332 = GL_R3_G3_B2
, rgb4 = GL_RGB4
, rgb5 = GL_RGB5
, rbg8 = GL_RGB8
, srgb8 = GL_SRGB8
, rbg8_snorm = GL_RGB8_SNORM
, rgb9e5 = GL_RGB9_E5
, rgb10 = GL_RGB10
, rgb11_11_10f = GL_R11F_G11F_B10F
, rgb12 = GL_RGB12
, rgb16 = GL_RGB16
, rgb16f = GL_RGB16F
, rgb16_snorm = GL_RGB16_SNORM
, rgb32f = GL_RGB32F
, rgba2 = GL_RGBA2
, rgba4 = GL_RGBA4
, rgb5_a1 = GL_RGB5_A1
, rgba8 = GL_RGBA8
, srgba8 = GL_SRGB8_ALPHA8
, rbga8_snorm = GL_RGBA8_SNORM
, rgb10_a2 = GL_RGB10_A2
, rgba12 = GL_RGBA12
, rgba16 = GL_RGBA16
, rgba16f = GL_RGBA16F
, rgba16_snorm = GL_RGBA16_SNORM
, rgba32f = GL_RGBA32F
// Integer Formats =====================================================================================================
, r8_i = GL_R8I
, r8_ui = GL_R8UI
, r16_i = GL_R16I
, r16_ui = GL_R16UI
, r32_i = GL_R32I
, r32_ui = GL_R32UI
, rg8_i = GL_RG8I
, rg8_ui = GL_RG8UI
, rg16_i = GL_RG16I
, rg16_ui = GL_RG16UI
, rg32_i = GL_RG32I
, rg32_ui = GL_RG32UI
, rgb8_i = GL_RGB8I
, rgb8_ui = GL_RGB8UI
, rgb16_i = GL_RGB16I
, rgb16_ui = GL_RGB16UI
, rgb32_i = GL_RGB32I
, rgb32_ui = GL_RGB32UI
, rgba8_i = GL_RGBA8I
, rgba8_ui = GL_RGBA8UI
, rgb10_a2_ui = GL_RGB10_A2UI
, rgba16_i = GL_RGBA16I
, rgba16_ui = GL_RGBA16UI
, rgba32_i = GL_RGBA32I
, rgba32_ui = GL_RGBA32UI
// Depth / Stencil Formats =============================================================================================
, depth16 = GL_DEPTH_COMPONENT16
, depth24 = GL_DEPTH_COMPONENT24
, depth32 = GL_DEPTH_COMPONENT32
, depth32_f = GL_DEPTH_COMPONENT32F
, stencil1 = GL_STENCIL_INDEX1
, stencil4 = GL_STENCIL_INDEX4
, stencil8 = GL_STENCIL_INDEX8
, stencil16 = GL_STENCIL_INDEX16
, depth24_stencil = GL_DEPTH24_STENCIL8
, depth32_f_stencil = GL_DEPTH32F_STENCIL8
// Compressed Formats ==================================================================================================
// Generic Formats
, r_compressed = GL_COMPRESSED_RED
, rg_compressed = GL_COMPRESSED_RG
, rgb_compressed = GL_COMPRESSED_RGB
, srgb_compressed = GL_COMPRESSED_SRGB
, rgba_compressed = GL_COMPRESSED_RGBA
, srgba_compressed = GL_COMPRESSED_SRGB_ALPHA
// BPTC
, rgb_bptc = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
, rgb_bptc_signed = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT
, rgba_bptc_unorm = GL_COMPRESSED_RGBA_BPTC_UNORM
, srgba_bptc = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM
// RGTC
, r_rgtc = GL_COMPRESSED_RED_RGTC1
, r_rgtc_signed = GL_COMPRESSED_SIGNED_RED_RGTC1
, rg_rgtc = GL_COMPRESSED_RG_RGTC2
, rg_rgtc_signed = GL_COMPRESSED_SIGNED_RG_RGTC2
// EAC
, r_eac = GL_COMPRESSED_R11_EAC
, rg_eac = GL_COMPRESSED_RG11_EAC
, r_eac_signed = GL_COMPRESSED_SIGNED_R11_EAC
, rg_eac_signed = GL_COMPRESSED_SIGNED_RG11_EAC
, rgba_eac = GL_COMPRESSED_RGBA8_ETC2_EAC
, srgba_eac = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
// ASTC
, rgba_astc4x4 = GL_COMPRESSED_RGBA_ASTC_4x4_KHR
, rgba_astc5x4 = GL_COMPRESSED_RGBA_ASTC_5x4_KHR
, rgba_astc5x5 = GL_COMPRESSED_RGBA_ASTC_5x5_KHR
, rgba_astc6x5 = GL_COMPRESSED_RGBA_ASTC_6x5_KHR
, rgba_astc6x6 = GL_COMPRESSED_RGBA_ASTC_6x6_KHR
, rgba_astc8x5 = GL_COMPRESSED_RGBA_ASTC_8x5_KHR
, rgba_astc8x6 = GL_COMPRESSED_RGBA_ASTC_8x6_KHR
, rgba_astc8x8 = GL_COMPRESSED_RGBA_ASTC_8x8_KHR
, rgba_astc10x5 = GL_COMPRESSED_RGBA_ASTC_10x5_KHR
, rgba_astc10x6 = GL_COMPRESSED_RGBA_ASTC_10x6_KHR
, rgba_astc10x8 = GL_COMPRESSED_RGBA_ASTC_10x8_KHR
, rgba_astc10x10 = GL_COMPRESSED_RGBA_ASTC_10x10_KHR
, rgba_astc12x10 = GL_COMPRESSED_RGBA_ASTC_12x10_KHR
, rgba_astc12x12 = GL_COMPRESSED_RGBA_ASTC_12x12_KHR
, srgba_astc4x4 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
, srgba_astc5x4 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
, srgba_astc5x5 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
, srgba_astc6x5 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
, srgba_astc6x6 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
, srgba_astc8x5 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
, srgba_astc8x6 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
, srgba_astc8x8 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
, srgba_astc10x5 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
, srgba_astc10x6 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
, srgba_astc10x8 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
, srgba_astc10x10 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
, srgba_astc12x10 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
, srgba_astc12x12 = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
};
inline constexpr bool is_depth(enum_t fmt)
{
switch(fmt)
{
case(depth16): case(depth24):
case(depth32): case(depth32_f):
case(depth24_stencil): case(depth32_f_stencil):
return true;
default: return false;
}
}
inline constexpr bool is_stencil(enum_t fmt)
{
switch(fmt)
{
case(stencil1): case(stencil4):
case(stencil8): case(stencil16):
case(depth24_stencil): case(depth32_f_stencil):
return true;
default: return false;
}
}
template<enum_t F_>
struct format_traits
{
static constexpr enum_t format = F_;
static constexpr bool is_depth = glw::is_depth(format);
static constexpr bool is_stencil = glw::is_stencil(format);
static constexpr bool is_depth_stencil = std::is_same<std::bool_constant<is_depth>, std::bool_constant<is_stencil>>{};
};
enum type : enum_t
{
int8 = GL_BYTE
, uint8 = GL_UNSIGNED_BYTE
, int16 = GL_SHORT
, uint16 = GL_UNSIGNED_SHORT
, int32 = GL_INT
, uint32 = GL_UNSIGNED_INT
, float16 = GL_HALF_FLOAT
, float32 = GL_FLOAT
, float64 = GL_DOUBLE
, uint8_332 = GL_UNSIGNED_BYTE_3_3_2
, uint8_233r = GL_UNSIGNED_BYTE_2_3_3_REV
, uint16_565 = GL_UNSIGNED_SHORT_5_6_5
, uint16_565r = GL_UNSIGNED_SHORT_5_6_5_REV
, uint32_10_11_11 = GL_UNSIGNED_INT_10F_11F_11F_REV
, uint16_4444 = GL_UNSIGNED_SHORT_4_4_4_4
, uint16_4444r = GL_UNSIGNED_SHORT_4_4_4_4_REV
, uint16_5551 = GL_UNSIGNED_SHORT_5_5_5_1
, uint16_1555r = GL_UNSIGNED_SHORT_1_5_5_5_REV
, uint32_8888 = GL_UNSIGNED_INT_8_8_8_8
, uint32_8888r = GL_UNSIGNED_INT_8_8_8_8_REV
, uint32_rgb10_a2 = GL_UNSIGNED_INT_10_10_10_2
, uint32_a2_bgr10 = GL_UNSIGNED_INT_2_10_10_10_REV
, uint32_9995r = GL_UNSIGNED_INT_5_9_9_9_REV
};
inline constexpr enum_t size_of(enum_t type)
{
switch(type)
{
// 1 byte
case(int8): case(uint8):
case(uint8_332): case(uint8_233r):
return 1;
// 2 byte
case(int16): case(uint16):
case(uint16_565): case(uint16_565r):
case(uint16_4444): case(uint16_4444r):
case(uint16_5551): case(uint16_1555r):
case(float16):
return 2;
// 4 byte
case(int32): case(uint32):
case(uint32_10_11_11):
case(uint32_8888): case(uint32_8888r):
case(uint32_rgb10_a2): case(uint32_a2_bgr10):
case(uint32_9995r):
case(float32):
return 4;
// 8 byte
case(float64):
return 8;
}
return 0;
}
enum compare : enum_t
{
never = GL_NEVER
, always = GL_ALWAYS
, less = GL_LESS
, greater = GL_GREATER
, equal = GL_EQUAL
, lequal = GL_LEQUAL
, gequal = GL_GEQUAL
, nequal = GL_NOTEQUAL
};
}
#endif //COMMON_H