Browse code

Add implementation

Robert Cranston authored on 10/01/2022 00:25:45
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,164 @@
1
+/// Guards
2
+
3
+#ifndef GLOBJECT_HPP_
4
+#define GLOBJECT_HPP_
5
+
6
+
7
+/// Includes
8
+
9
+#include <string>
10
+
11
+#include <glbase.hpp>
12
+#include <gltraits.hpp>
13
+
14
+
15
+/// GLObject
16
+
17
+template<GLenum object_type>
18
+class GLObject;
19
+
20
+template<>
21
+class GLObject<0> : protected GLBase
22
+{
23
+
24
+protected:
25
+
26
+    //// Object
27
+
28
+    std::string static label_(
29
+        GLenum object_type,
30
+        GLuint object
31
+    );
32
+    void static label_(
33
+        GLenum              object_type,
34
+        GLuint              object,
35
+        std::string const & label
36
+    );
37
+
38
+    //// Name
39
+
40
+    std::string static name_(
41
+        GLenum              object_type,
42
+        GLuint              object,
43
+        std::string const & label = {}
44
+    );
45
+
46
+};
47
+
48
+template<GLenum object_type>
49
+class GLObject
50
+:
51
+    public    GLObject<0>,
52
+    protected GLTraits::Object<object_type>
53
+{
54
+
55
+public:
56
+
57
+    //// Special member functions
58
+
59
+    template<typename... Args>
60
+    explicit GLObject(std::string const & label, Args... args)
61
+    try
62
+    :
63
+        object_{0}
64
+    {
65
+        if (debug() >= 2)
66
+            this->debug_action_("construct", name_(object_type, 0, label));
67
+        this->gen_objects(1, &object_, args...);
68
+        try
69
+        {
70
+            // Strictly speaking `glObjectLabel` needs a *created* object.
71
+            // `glGen*s` does not create objects (`glCreate*` does though), it
72
+            // just reserves names for them. *Binding* that name for the first
73
+            // time creates the object. Therefore, the below is not guaranteed
74
+            // to work, but seems to on most drivers... Forcing our subclasses
75
+            // to bind the name and call us back to set the label is deemed too
76
+            // inconvenient so here we are.
77
+            label_(object_type, object_, label);
78
+            check_error_(glGetError());
79
+        }
80
+        catch (...)
81
+        {
82
+            this->delete_objects(1, &object_);
83
+            object_ = 0;
84
+            throw;
85
+        }
86
+    }
87
+    catch (...)
88
+    {
89
+        this->fail_action_("construct", name_(object_type, 0, label));
90
+    }
91
+
92
+    ~GLObject()
93
+    {
94
+        if (debug() >= 2)
95
+            debug_action_("destroy");
96
+        this->delete_objects(1, &object_);
97
+    }
98
+
99
+    GLObject(GLObject && other) noexcept
100
+    :
101
+        object_{other.object_}
102
+    {
103
+        if (debug() >= 2)
104
+            debug_action_("move construct");
105
+        other.object_ = 0;
106
+    }
107
+
108
+    GLObject & operator=(GLObject && other) noexcept
109
+    {
110
+        if (debug() >= 2)
111
+            debug_action_("move assign");
112
+        if (&other != this)
113
+        {
114
+            this->delete_objects(1, &object_);
115
+            object_ = other.object_;
116
+            other.object_ = 0;
117
+        }
118
+        return *this;
119
+    }
120
+
121
+    GLObject(GLObject const &) = delete;
122
+    GLObject & operator=(GLObject const &) = delete;
123
+
124
+    //// Object
125
+
126
+    GLBASE_GET(GLuint, object)
127
+
128
+    operator GLuint() const { return object(); }
129
+
130
+    //// Name
131
+
132
+    std::string name() const
133
+    {
134
+        return name_(object_type, object_);
135
+    }
136
+
137
+protected:
138
+
139
+    //// Debug
140
+
141
+    void debug_action_(std::string const & action) const
142
+    {
143
+        return this->debug_action_(action, name());
144
+    }
145
+
146
+    //// Fail
147
+
148
+    void fail_action_(std::string const & action) const
149
+    {
150
+        return this->fail_action_(action, name());
151
+    }
152
+
153
+private:
154
+
155
+    //// Object
156
+
157
+    GLuint object_;
158
+
159
+};
160
+
161
+
162
+/// Guards
163
+
164
+#endif