58cc126e |
/// Guards
#ifndef GLBASE_HPP_
#define GLBASE_HPP_
/// Includes
#include <array>
#include <functional>
#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
#ifndef GLBASE_INCLUDE
#define GLBASE_INCLUDE <GL/glew.h>
#endif
#include GLBASE_INCLUDE // IWYU pragma: export
/// Accessors
#define GLBASE_GET_(TYPE, NAME, STATIC, CONST) \
TYPE STATIC const & NAME() CONST \
{ \
return NAME##_; \
}
#define GLBASE_SET_(TYPE, NAME, STATIC, CONST) \
template<typename Type> \
TYPE STATIC NAME(Type && NAME) \
{ \
auto NAME##_old = std::move (NAME##_); \
NAME##_ = std::forward(NAME); \
return NAME##_old; \
}
#define GLBASE_GET( TYPE, NAME) GLBASE_GET_(TYPE, NAME,, const)
#define GLBASE_SET( TYPE, NAME) GLBASE_SET_(TYPE, NAME,, const)
#define GLBASE_GET_GLOBAL(TYPE, NAME) GLBASE_GET_(TYPE, NAME, static,)
#define GLBASE_SET_GLOBAL(TYPE, NAME) GLBASE_SET_(TYPE, NAME, static,)
#define GLBASE_ACCESS(TYPE, NAME) \
GLBASE_GET(TYPE, NAME) \
GLBASE_SET(TYPE, NAME)
#define GLBASE_ACCESS_GLOBAL(TYPE, NAME) \
GLBASE_GET_GLOBAL(TYPE, NAME) \
GLBASE_SET_GLOBAL(TYPE, NAME)
#define GLBASE_GLOBAL(NAME, INIT) \
decltype(NAME) thread_local NAME INIT;
/// GLBase
class GLBase
{
public:
//// Base
using Version = std::array<GLint, 2>;
GLBASE_ACCESS_GLOBAL(Version, version_max)
bool static supported(
Version version_min,
std::string const & extension = {}
);
char static const * string (GLenum name);
char static const * string (GLenum name, GLuint index);
GLint static integer(GLenum name);
//// Path
using Path = std::string;
using Paths = std::vector<Path>;
//// Exceptions
struct Exception : std::runtime_error
{
using std::runtime_error::runtime_error;
};
//// Debug
using DebugCallback = std::function<void (std::string const & message)>;
GLBASE_GET_GLOBAL(int, debug)
int static debug(int debug);
GLBASE_ACCESS_GLOBAL(DebugCallback, debug_callback)
void static debug_message(std::string const & message)
{
if (debug_callback())
debug_callback()(message);
}
//// Check
void static check_supported(
Version version_min,
std::string const & extension = {}
);
protected:
//// Special member functions
explicit GLBase() = default;
~GLBase() = default;
//// Path
Path static path_prefix_(
Path const & path,
Path const & prefix
);
//// TGA
class TGA_
{
public:
using Size = std::array<GLsizei, 2>;
using Data = std::vector<GLubyte>;
explicit TGA_(Size size, Data data, Path const & path = {});
TGA_ static read (Path const & path);
void write (Path const & path) const;
GLBASE_GET(Size, size);
GLBASE_GET(Data, data);
protected:
struct Header_ : std::array<GLubyte, 18>
{
explicit Header_(Size size);
Size tga_size() const;
};
std::string static name_(Path const & path);
void static check_header_(Header_ const & header);
void check_data_size_() const;
private:
Size size_;
Data data_;
};
//// Debug
void static debug_action_(
std::string const & action,
std::string const & name
);
//// Check
void static check_path_(Path const & path);
void static check_error_(GLenum error);
void static check_type_(
GLenum type,
GLenum type_expected
);
void static check_format_(
GLenum format,
GLenum format_expected
);
void static check_internal_format_(
GLenum internal_format
);
//// Fail
[[noreturn]]
void static fail_action_(
std::string const & action,
std::string const & name
);
//// String
std::string static str_path_ (Path const & path);
std::string static str_paths_ (Paths const & paths);
std::string static str_enum_ (GLenum name);
std::string static str_error_ (GLenum error);
std::string static str_object_type_ (GLenum object_type);
std::string static str_glsl_ (GLenum glsl);
std::string static str_format_ (GLenum format);
std::string static str_type_ (GLenum type);
std::string static str_internal_format_(GLenum internal_format);
private:
//// Base
Version static thread_local version_max_;
//// Debug
int static thread_local debug_;
DebugCallback static thread_local debug_callback_;
};
/// Guards
#endif
|