Browse code

Add implementation

Robert Cranston authored on 29/12/2021 16:30:02
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,193 @@
1
+#ifndef GLTEXTURE_HPP_
2
+#define GLTEXTURE_HPP_
3
+
4
+
5
+#include <cstddef>
6
+#include <string>
7
+#include <vector>
8
+
9
+#include <globject.hpp>
10
+
11
+
12
+/// Class
13
+
14
+class GLTexture : public GLObject<GL_TEXTURE, glGenTextures, glDeleteTextures>
15
+{
16
+public:
17
+
18
+    /// Special member functions
19
+
20
+    explicit GLTexture(
21
+        std::string object_label,
22
+        GLenum      target,
23
+        GLenum      binding,
24
+        GLenum      internal_format = 0,
25
+        GLenum      wrap            = 0,
26
+        GLenum      min_filter      = 0,
27
+        GLenum      mag_filter      = 0
28
+    );
29
+
30
+    /// Core
31
+
32
+    GLOBJECT_ACCESS_THREAD(GLfloat, anisotropy)
33
+
34
+    GLint unit(bool force_active = false) const;
35
+
36
+    template<typename Data = GLubyte>
37
+    std::vector<Data> data(
38
+        GLenum target    = 0,
39
+        GLenum format    = DataTraits<Data>::format,
40
+        GLint  alignment = 1
41
+    ) const;
42
+
43
+    template<typename Data = GLubyte>
44
+    GLTexture & data(
45
+        std::vector<Data> const & data,
46
+        GLenum                    target    = 0,
47
+        GLenum                    format    = DataTraits<Data>::format,
48
+        GLint                     alignment = 1
49
+    );
50
+
51
+    template<typename Data = GLubyte>
52
+    GLTexture & clear(
53
+        Data   value     = Data{},
54
+        GLenum target    = 0,
55
+        GLenum format    = DataTraits<Data>::format,
56
+        GLint  alignment = 1
57
+    );
58
+
59
+    /// Path
60
+
61
+    GLOBJECT_ACCESS_THREAD(Path, prefix)
62
+
63
+protected:
64
+
65
+    /// Core
66
+
67
+    template<typename GLTextureDerived>
68
+    GLTextureDerived static const & empty_();
69
+
70
+    bool min_filter_mipmap_() const;
71
+
72
+    std::size_t virtual data_size_() const = 0;
73
+
74
+    void virtual data_(
75
+        void const * data,
76
+        GLenum       target,
77
+        GLenum       format,
78
+        GLenum       type
79
+    ) = 0;
80
+
81
+    /// Check
82
+
83
+    void check_unit_active_() const;
84
+    void check_unit_texture_() const;
85
+    void check_data_size_(std::size_t data_size) const;
86
+
87
+    /// String
88
+
89
+    std::string static str_target_(GLenum target);
90
+
91
+protected:
92
+
93
+    GLenum const target_;
94
+
95
+private:
96
+
97
+    /// Core
98
+
99
+    GLfloat static thread_local anisotropy_;
100
+
101
+    GLenum const   binding_;
102
+    GLenum const   min_filter_;
103
+    GLuint mutable unit_;
104
+
105
+    /// Path
106
+
107
+    Path static thread_local prefix_;
108
+};
109
+
110
+
111
+/// Core
112
+
113
+template<typename Data>
114
+inline std::vector<Data> GLTexture::data(
115
+    GLenum target,
116
+    GLenum format,
117
+    GLint  alignment
118
+) const
119
+try
120
+{
121
+    if (!target)
122
+        target = target_;
123
+    auto data = std::vector<Data>(data_size_());
124
+    unit(true);
125
+    glPixelStorei(GL_PACK_ALIGNMENT, alignment);
126
+    glGetTexImage(target, 0, format, DataTraits<Data>::type, data.data());
127
+    GLOBJECT_DEBUG_IF(1)
128
+        check_error_(glGetError());
129
+    return data;
130
+}
131
+catch (...)
132
+{
133
+    fail_action_("get data of");
134
+}
135
+
136
+template<typename Data>
137
+inline GLTexture & GLTexture::data(
138
+    std::vector<Data> const & data,
139
+    GLenum                    target,
140
+    GLenum                    format,
141
+    GLint                     alignment
142
+)
143
+try
144
+{
145
+    if (!target)
146
+        target = target_;
147
+    check_data_size_(data.size());
148
+    unit(true);
149
+    glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
150
+    data_(data.data(), target, format, DataTraits<Data>::type);
151
+    GLOBJECT_DEBUG_IF(1)
152
+        check_error_(glGetError());
153
+    if (min_filter_mipmap_())
154
+        if (supported({3, 0}, "GL_ARB_framebuffer_object"))
155
+            glGenerateMipmap(target);
156
+    return *this;
157
+}
158
+catch (...)
159
+{
160
+    fail_action_("set data of");
161
+}
162
+
163
+template<typename Data>
164
+GLTexture & GLTexture::clear(
165
+    Data   value,
166
+    GLenum target,
167
+    GLenum format,
168
+    GLint  alignment
169
+)
170
+{
171
+    auto static clear = std::vector<Data>{};
172
+    clear.resize(data_size_());
173
+    std::fill(clear.begin(), clear.end(), value);
174
+    data(clear, target, format, alignment);
175
+    return *this;
176
+}
177
+
178
+template<typename GLTextureDerived>
179
+inline GLTextureDerived const & GLTexture::empty_()
180
+{
181
+    auto static const empty = []()
182
+    {
183
+        auto size = typename GLTextureDerived::Size{};
184
+        size.fill(1);
185
+        auto tmp = GLTextureDerived("empty", size);
186
+        tmp.clear();
187
+        return tmp;
188
+    }();
189
+    return empty;
190
+}
191
+
192
+
193
+#endif // GLTEXTURE_HPP_