1 /** @file gltexture.h  GL texture.
2  *
3  * @authors Copyright (c) 2013-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  *
5  * @par License
6  * LGPL: http://www.gnu.org/licenses/lgpl.html
7  *
8  * <small>This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or (at your
11  * option) any later version. This program is distributed in the hope that it
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
14  * General Public License for more details. You should have received a copy of
15  * the GNU Lesser General Public License along with this program; if not, see:
16  * http://www.gnu.org/licenses</small>
17  */
18 
19 #ifndef LIBGUI_GLTEXTURE_H
20 #define LIBGUI_GLTEXTURE_H
21 
22 #include <de/libcore.h>
23 #include <de/Asset>
24 #include <de/Vector>
25 
26 #include "../gui/libgui.h"
27 #include "opengl.h"
28 #include "../Image"
29 #include "../GLPixelFormat"
30 
31 namespace de {
32 
33 namespace gl {
34     enum Filter {
35         Nearest,
36         Linear
37     };
38     enum MipFilter {
39         MipNone,
40         MipNearest,
41         MipLinear
42     };
43     enum Wrapping {
44         Repeat,
45         RepeatMirrored,
46         ClampToEdge
47     };
48     enum CubeFace {
49         PositiveX,
50         NegativeX,
51         PositiveY,
52         NegativeY,
53         PositiveZ,
54         NegativeZ
55     };
56 }
57 
58 /**
59  * GL texture object.
60  *
61  * Supports cube maps (6 faces/images instead of one). A GLTexture becomes a
62  * cube map automatically when one sets image content to one of the faces.
63  * Similarly a GLTexture reverts back to a 2D texture when setting non-cubeface
64  * image content.
65  *
66  * Mipmaps can be generated automatically (see GLTexture::generateMipmap() and
67  * GLTexture::setAutoGenMips()). By default, mipmaps are not generated
68  * automatically.
69  *
70  * @ingroup gl
71  */
72 class LIBGUI_PUBLIC GLTexture : public Asset
73 {
74 public:
75     typedef Vector2ui Size;
76     typedef Vector2<gl::Wrapping> Wraps;
77 
78 public:
79     /**
80      * Constructs a texture without any content. GLTexture instances are not
81      * ready until they have some content defined.
82      */
83     GLTexture();
84 
85     /**
86      * Constructs a texture from an existing OpenGL texture object. Ownership
87      * of the texture is transferred to the new GLTexture instance.
88      *
89      * @param existingTexture  Existing texture.
90      * @param size             Size of the texture in texels.
91      */
92     GLTexture(GLuint existingTexture, Size const &size);
93 
94     /**
95      * Release all image content associated with the texture.
96      */
97     void clear();
98 
99     void setMagFilter(gl::Filter magFilter);
100     void setMinFilter(gl::Filter minFilter, gl::MipFilter mipFilter);
setFilter(gl::Filter magFilter,gl::Filter minFilter,gl::MipFilter mipFilter)101     void setFilter(gl::Filter magFilter, gl::Filter minFilter, gl::MipFilter mipFilter) {
102         setMagFilter(magFilter);
103         setMinFilter(minFilter, mipFilter);
104     }
105     void setWrapS(gl::Wrapping mode);
106     void setWrapT(gl::Wrapping mode);
setWrap(gl::Wrapping s,gl::Wrapping t)107     inline void setWrap(gl::Wrapping s, gl::Wrapping t) {
108         setWrapS(s);
109         setWrapT(t);
110     }
setWrap(Wraps const & st)111     inline void setWrap(Wraps const &st) {
112         setWrapS(st.x);
113         setWrapT(st.y);
114     }
115     void setMaxAnisotropy(dfloat maxAnisotropy);
116     void setMaxLevel(dfloat maxLevel);
117 
118     gl::Filter minFilter() const;
119     gl::Filter magFilter() const;
120     gl::MipFilter mipFilter() const;
121     gl::Wrapping wrapS() const;
122     gl::Wrapping wrapT() const;
123     Wraps wrap() const;
124     dfloat maxAnisotropy() const;
125     dfloat maxLevel() const;
126 
127     bool isCubeMap() const;
128 
129     /**
130      * Enables or disables automatic mipmap generation on the texture. By
131      * default, automatic mipmap generation is disabled.
132      *
133      * @param genMips  @c true to generate mipmaps whenever level 0 changes.
134      */
135     void setAutoGenMips(bool genMips);
136 
137     bool autoGenMips() const;
138 
139     /**
140      * Reserves a specific size of undefined memory for a level.
141      *
142      * @param size    Size in texels.
143      * @param format  Pixel format that will be later used for uploading content.
144      *                Determines internal storage pixel format.
145      * @param level   Mipmap level.
146      */
147     void setUndefinedImage(Size const &size, Image::Format format, int level = 0);
148 
149     /**
150      * Reserves a specific size of undefined memory for a cube map level.
151      *
152      * @param face    Face of a cube map.
153      * @param size    Size in texels.
154      * @param format  Pixel format that will be later used for uploading content.
155      *                Determines internal storage pixel format.
156      * @param level   Mipmap level.
157      */
158     void setUndefinedImage(gl::CubeFace face, Size const &size, Image::Format format, int level = 0);
159 
160     void setUndefinedContent(Size const &size, GLPixelFormat const &glFormat, int level = 0);
161 
162     void setUndefinedContent(gl::CubeFace face, Size const &size, GLPixelFormat const &glFormat, int level = 0);
163 
164     void setDepthStencilContent(Size const &size);
165 
166     /**
167      * Sets the image content of the texture at a particular level. The format
168      * of the image determines which GL format is chosen for the texture.
169      *
170      * @param image  Image to upload to a GL texture.
171      * @param level  Level on which to store the image.
172      */
173     void setImage(Image const &image, int level = 0);
174 
175     /**
176      * Sets the image content of the texture at a particular level. The format
177      * of the image determines which GL format is chosen for the texture.
178      *
179      * @param face   Face of a cube map.
180      * @param image  Image to upload to a GL texture.
181      * @param level  Level on which to store the image.
182      */
183     void setImage(gl::CubeFace face, Image const &image, int level = 0);
184 
185     /**
186      * Replaces a portion of existing content. The image must be provided in
187      * the same format as the previous full content.
188      *
189      * @param image  Image to copy.
190      * @param pos    Position where the image is being copied.
191      * @param level  Mipmap level.
192      */
193     void setSubImage(Image const &image, Vector2i const &pos, int level = 0);
194 
195     /**
196      * Replaces a portion of existing content. The image must be provided in the same
197      * format as the previous full content.
198      *
199      * The image data is copied directly from the specified subregion of the image.
200      *
201      * @param image  Image to copy.
202      * @param rect   Region of the image to copy.
203      * @param level  Mipmap level.
204      */
205     void setSubImage(Image const &image, Rectanglei const &rect, int level = 0);
206 
207     void setSubImage(gl::CubeFace face, Image const &image, Vector2i const &pos, int level = 0);
208     void setSubImage(gl::CubeFace face, Image const &image, Rectanglei const &rect, int level = 0);
209 
210     /**
211      * Generate a full set of mipmap levels based on the content on level 0.
212      * Automatic mipmap generation can be enabled with setAutoGenMips().
213      */
214     void generateMipmap();
215 
216     /**
217      * Returns the size of the texture (mipmap level 0).
218      */
219     Size size() const;
220 
221     /**
222      * Returns the number of mipmap levels in use by the texture.
223      *
224      * Use levelsForSize() to determine the number of mipmap levels for an
225      * arbitrary texture size.
226      */
227     int mipLevels() const;
228 
229     /**
230      * Returns the size of a particular mipmap level. This can be called after
231      * the level 0 image content has been defined.
232      *
233      * @param level  Mip level.
234      * @return Size in texels. (0,0) for an invalid level.
235      */
236     Size levelSize(int level) const;
237 
238     GLuint glName() const;
239 
240     void glBindToUnit(int unit) const;
241 
242     /**
243      * Applies any cached parameter changes to the GL texture object. The texture is
244      * bound temporarily while this is done (so any previously bound texture is unbound).
245      */
246     void glApplyParameters();
247 
248     /**
249      * Returns the image format that was specified when image content was put
250      * into the texture (with setImage() or setSubImage()).
251      */
252     Image::Format imageFormat() const;
253 
254 public:
255     /**
256      * Determines the maximum supported texture size.
257      */
258     static Size maximumSize();
259 
260 protected:
261     /**
262      * Derived classes can override this to perform additional tasks
263      * immediately before the texture is bound for use. The default
264      * implementation does not need to be called.
265      */
266     virtual void aboutToUse() const;
267 
268 public:
269     /**
270      * Calculates how many mipmap levels are produced for a specific size
271      * of mipmap level 0 content.
272      *
273      * @param size  Size in texels at level 0.
274      *
275      * @return Number of mipmap levels.
276      */
277     static int levelsForSize(Size const &size);
278 
279     static Size levelSize(Size const &size0, int level);
280 
281 private:
282     DENG2_PRIVATE(d)
283 };
284 
285 } // namespace de
286 
287 #endif // LIBGUI_GLTEXTURE_H
288