Browse code

Add implementation

Robert Cranston authored on 14/10/2022 20:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,211 @@
1
+/// Guards
2
+
3
+#ifndef GLBASE_HPP_
4
+#define GLBASE_HPP_
5
+
6
+
7
+/// Includes
8
+
9
+#include <array>
10
+#include <functional>
11
+#include <stdexcept>
12
+#include <string>
13
+#include <utility>
14
+#include <vector>
15
+
16
+#ifndef GLBASE_INCLUDE
17
+#define GLBASE_INCLUDE <GL/glew.h>
18
+#endif
19
+#include GLBASE_INCLUDE // IWYU pragma: export
20
+
21
+
22
+/// Accessors
23
+
24
+#define GLBASE_GET_(TYPE, NAME, STATIC, CONST) \
25
+    TYPE STATIC const & NAME() CONST \
26
+    { \
27
+        return NAME##_; \
28
+    }
29
+
30
+#define GLBASE_SET_(TYPE, NAME, STATIC, CONST) \
31
+    template<typename Type> \
32
+    TYPE STATIC NAME(Type && NAME) \
33
+    { \
34
+        auto NAME##_old = std::move   (NAME##_); \
35
+        NAME##_         = std::forward(NAME); \
36
+        return NAME##_old; \
37
+    }
38
+
39
+#define GLBASE_GET(       TYPE, NAME) GLBASE_GET_(TYPE, NAME,, const)
40
+#define GLBASE_SET(       TYPE, NAME) GLBASE_SET_(TYPE, NAME,, const)
41
+#define GLBASE_GET_GLOBAL(TYPE, NAME) GLBASE_GET_(TYPE, NAME, static,)
42
+#define GLBASE_SET_GLOBAL(TYPE, NAME) GLBASE_SET_(TYPE, NAME, static,)
43
+
44
+#define GLBASE_ACCESS(TYPE, NAME) \
45
+    GLBASE_GET(TYPE, NAME) \
46
+    GLBASE_SET(TYPE, NAME)
47
+
48
+#define GLBASE_ACCESS_GLOBAL(TYPE, NAME) \
49
+    GLBASE_GET_GLOBAL(TYPE, NAME) \
50
+    GLBASE_SET_GLOBAL(TYPE, NAME)
51
+
52
+#define GLBASE_GLOBAL(NAME, INIT) \
53
+    decltype(NAME) thread_local NAME INIT;
54
+
55
+
56
+/// GLBase
57
+
58
+class GLBase
59
+{
60
+
61
+public:
62
+
63
+    //// Base
64
+
65
+    using Version = std::array<GLint, 2>;
66
+
67
+    GLBASE_ACCESS_GLOBAL(Version, version_max)
68
+
69
+    bool static supported(
70
+        Version             version_min,
71
+        std::string const & extension = {}
72
+    );
73
+
74
+    char  static const * string (GLenum name);
75
+    char  static const * string (GLenum name, GLuint index);
76
+    GLint static         integer(GLenum name);
77
+
78
+    //// Path
79
+
80
+    using Path  = std::string;
81
+    using Paths = std::vector<Path>;
82
+
83
+    //// Exceptions
84
+
85
+    struct Exception : std::runtime_error
86
+    {
87
+        using std::runtime_error::runtime_error;
88
+    };
89
+
90
+    //// Debug
91
+
92
+    using DebugCallback = std::function<void (std::string const & message)>;
93
+
94
+    GLBASE_GET_GLOBAL(int, debug)
95
+    int static debug(int debug);
96
+
97
+    GLBASE_ACCESS_GLOBAL(DebugCallback, debug_callback)
98
+
99
+    void static debug_message(std::string const & message)
100
+    {
101
+        if (debug_callback())
102
+            debug_callback()(message);
103
+    }
104
+
105
+    //// Check
106
+
107
+    void static check_supported(
108
+        Version             version_min,
109
+        std::string const & extension = {}
110
+    );
111
+
112
+protected:
113
+
114
+    //// Special member functions
115
+
116
+    explicit GLBase() = default;
117
+    ~GLBase() = default;
118
+
119
+    //// Path
120
+
121
+    Path static path_prefix_(
122
+        Path const & path,
123
+        Path const & prefix
124
+    );
125
+
126
+    //// TGA
127
+
128
+    class TGA_
129
+    {
130
+    public:
131
+        using Size = std::array<GLsizei, 2>;
132
+        using Data = std::vector<GLubyte>;
133
+        explicit TGA_(Size size, Data data, Path const & path = {});
134
+        TGA_ static read  (Path const & path);
135
+        void        write (Path const & path) const;
136
+        GLBASE_GET(Size, size);
137
+        GLBASE_GET(Data, data);
138
+    protected:
139
+        struct Header_ : std::array<GLubyte, 18>
140
+        {
141
+            explicit Header_(Size size);
142
+            Size tga_size() const;
143
+        };
144
+        std::string static name_(Path const & path);
145
+        void static check_header_(Header_ const & header);
146
+        void        check_data_size_() const;
147
+    private:
148
+        Size size_;
149
+        Data data_;
150
+    };
151
+
152
+    //// Debug
153
+
154
+    void static debug_action_(
155
+        std::string const & action,
156
+        std::string const & name
157
+    );
158
+
159
+    //// Check
160
+
161
+    void static check_path_(Path const & path);
162
+    void static check_error_(GLenum error);
163
+    void static check_type_(
164
+        GLenum type,
165
+        GLenum type_expected
166
+    );
167
+    void static check_format_(
168
+        GLenum format,
169
+        GLenum format_expected
170
+    );
171
+    void static check_internal_format_(
172
+        GLenum internal_format
173
+    );
174
+
175
+    //// Fail
176
+
177
+    [[noreturn]]
178
+    void static fail_action_(
179
+        std::string const & action,
180
+        std::string const & name
181
+    );
182
+
183
+    //// String
184
+
185
+    std::string static str_path_           (Path  const & path);
186
+    std::string static str_paths_          (Paths const & paths);
187
+    std::string static str_enum_           (GLenum name);
188
+    std::string static str_error_          (GLenum error);
189
+    std::string static str_object_type_    (GLenum object_type);
190
+    std::string static str_glsl_           (GLenum glsl);
191
+    std::string static str_format_         (GLenum format);
192
+    std::string static str_type_           (GLenum type);
193
+    std::string static str_internal_format_(GLenum internal_format);
194
+
195
+private:
196
+
197
+    //// Base
198
+
199
+    Version static thread_local version_max_;
200
+
201
+    //// Debug
202
+
203
+    int           static thread_local debug_;
204
+    DebugCallback static thread_local debug_callback_;
205
+
206
+};
207
+
208
+
209
+/// Guards
210
+
211
+#endif