Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
Texture.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  *
21  * Part of this file comes from SFML, with the same license:
22  * Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
23  */
24 #ifndef GF_TEXTURE_H
25 #define GF_TEXTURE_H
26 
27 #include <cstdint>
28 
29 #include "Path.h"
30 #include "Portability.h"
31 #include "Rect.h"
32 #include "Vector.h"
33 
34 namespace gf {
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 inline namespace v1 {
37 #endif
38 
39  class Image;
40  class InputStream;
41 
42  /**
43  * @ingroup graphics
44  * @brief An image that lives in the graphic memory that can be used for drawing
45  *
46  * gf::BareTexture stores pixels that can be drawn, with a sprite
47  * for example. A texture lives in the graphics card memory,
48  * therefore it is very fast to draw a texture to a render target,
49  * or copy a render target to a texture (the graphics card can
50  * access both directly).
51  *
52  * Being stored in the graphics card memory has some drawbacks.
53  * A texture cannot be manipulated as freely as a gf::Image,
54  * you need to prepare the pixels first and then upload them
55  * to the texture in a single operation (see BareTexture::update()).
56  *
57  * gf::BareTexture can handle two types of texture:
58  *
59  * - colored texture that stores RGBA channels (see gf::Texture)
60  * - alpha texture that stores a single alpha channel (see gf::AlphaTexture)
61  *
62  * Generally, you do not manipulate a gf::BareTexture directly but you can
63  * use a gf::Texture.
64  *
65  * @sa gf::Texture, gf::AlphaTexture
66  */
68  public:
69  /**
70  * @brief Format of the texture
71  *
72  * @sa gf::BareTexture
73  */
74  enum class Format {
75  Color, ///< RGBA format
76  Alpha, ///< Alpha format
77  };
78 
79  /**
80  * @brief Constructor
81  *
82  * @param format The format of the texture
83  *
84  * Once set, the format can not be changed.
85  */
86  BareTexture(Format format);
87 
88  /**
89  * @brief Destructor
90  */
91  ~BareTexture();
92 
93  /**
94  * @brief Deleted copy constructor
95  */
96  BareTexture(const BareTexture&) = delete;
97 
98  /**
99  * @brief Deleted copy assignment
100  */
101  BareTexture& operator=(const BareTexture&) = delete;
102 
103  /**
104  * @brief Move constructor
105  */
106  BareTexture(BareTexture&& other);
107 
108  /**
109  * @brief Move assignment
110  */
111  BareTexture& operator=(BareTexture&& other);
112 
113  /**
114  * @brief Get the format of the texture
115  *
116  * @return The format of the texture
117  */
118  Format getFormat() const {
119  return m_format;
120  }
121 
122  /**
123  * @brief Get the internal representation of the texture
124  *
125  * This function is for internal use only.
126  *
127  * @return The OpenGL name of the texture
128  */
129  unsigned getName() const {
130  return m_name;
131  }
132 
133  /**
134  * @brief Return the size of the texture
135  *
136  * @return Size in pixels
137  */
138  Vector2u getSize() const {
139  return m_size;
140  }
141 
142  /**
143  * @brief Enable or disable the smooth filter
144  *
145  * When the filter is activated, the texture appears smoother
146  * so that pixels are less noticeable. However if you want
147  * the texture to look exactly the same as its source file,
148  * you should leave it disabled.
149  *
150  * The smooth filter is disabled by default.
151  *
152  * @param smooth True to enable smoothing, false to disable it
153  *
154  * @see isSmooth()
155  */
156  void setSmooth(bool smooth = true);
157 
158  /**
159  * @brief Check if the smooth filter is enabled or not
160  *
161  * @return True if smoothing is enabled, false if it is disabled
162  *
163  * @see setSmooth()
164  */
165  bool isSmooth() const noexcept {
166  return m_smooth;
167  }
168 
169  /**
170  * @brief Enable or disable repeating
171  *
172  * Repeating is involved when using texture coordinates
173  * outside the texture rectangle @f$ [0, 1] @times [0, 1] @f$.
174  * In this case, if repeat mode is enabled, the whole texture
175  * will be repeated as many times as needed to reach the
176  * coordinate (for example, if the @f$ u @f$ texture coordinate is
177  * 3, the texture will be repeated 3 times).
178  *
179  * If repeat mode is disabled, the "extra space" will instead
180  * be filled with border pixels.
181  *
182  * Repeating is disabled by default.
183  *
184  * @param repeated True to repeat the texture, false to disable repeating
185  *
186  * @see isRepeated()
187  */
188  void setRepeated(bool repeated = true);
189 
190  /**
191  * @brief Check if the texture is repeated or not
192  *
193  * @return True if repeat mode is enabled, false if it is disabled
194  *
195  * @see setRepeated()
196  */
197  bool isRepeated() const noexcept {
198  return m_repeated;
199  }
200 
201  /**
202  * @brief Update the whole texture from an array of pixels
203  *
204  * The `data` array is assumed to be in the right format (4 channels
205  * for colored texture and 1 channel for alpha texture) and have the
206  * right size.
207  *
208  * No additional check is performed on the size of the pixel
209  * array, passing invalid arguments will lead to an undefined
210  * behavior.
211  *
212  * This function does nothing if `data` is `nullptr` or if the
213  * texture was not previously created.
214  *
215  * @param data An array of pixels to copy to the texture
216  */
217  void update(const uint8_t *data);
218 
219  /**
220  * @brief Update a part of the texture from an array of pixels
221  *
222  * The `data` array is assumed to be in the right format (4 channels
223  * for colored texture and 1 channel for alpha texture) and its size
224  * must match the size of the `rect` argument.
225  *
226  * No additional check is performed on the size of the pixel
227  * array or the bounds of the area to update, passing invalid
228  * arguments will lead to an undefined behavior.
229  *
230  * This function does nothing if `data` is `nullptr` or if the
231  * texture was not previously created.
232  *
233  * @param data An array of pixels to copy to the texture
234  * @param rect The region of the texture to update
235  */
236  void update(const uint8_t *data, const RectU& rect);
237 
238  /**
239  * @brief Compute normalized texture coordinates
240  *
241  * @param rect The rectangle in the texture, in pixels
242  * @return Normalized texture coordinates
243  */
244  RectF computeTextureCoords(const RectU& rect) const;
245 
246  /**
247  * @brief Generate a mipmap using the current texture data
248  *
249  * Mipmaps are pre-computed chains of optimized textures. Each
250  * level of texture in a mipmap is generated by halving each of
251  * the previous level's dimensions. This is done until the final
252  * level has the size of 1x1. The textures generated in this process may
253  * make use of more advanced filters which might improve the visual quality
254  * of textures when they are applied to objects much smaller than they are.
255  * This is known as minification. Because fewer texels (texture elements)
256  * have to be sampled from when heavily minified, usage of mipmaps
257  * can also improve rendering performance in certain scenarios.
258  *
259  * Mipmap data is only valid from the time it is generated until the next
260  * time the base level image is modified, at which point this function
261  * will have to be called again to regenerate it.
262  *
263  * @return True if mipmap generation was successful, false if unsuccessful
264  */
265  bool generateMipmap();
266 
267  /**
268  * @brief Bind a texture for rendering
269  *
270  * This function is for internal use only.
271  *
272  * @param texture Pointer to the texture to bind, can be `nullptr` to use no texture
273  */
274  static void bind(const BareTexture *texture);
275 
276  protected:
277  /**
278  * @brief Create the texture
279  *
280  * If this function fails, the texture is left unchanged.
281  *
282  * @param size Size of the texture
283  * @param data Initial pixels of the texture (can be `nullptr`)
284  *
285  * @return True if creation was successful
286  */
287  bool create(Vector2u size, const uint8_t *data);
288 
289  private:
290  Format m_format;
291  unsigned m_name;
292  Vector2u m_size;
293  bool m_smooth;
294  bool m_repeated;
295  bool m_mipmap;
296  };
297 
298 
299  /**
300  * @ingroup graphics
301  * @brief A texture for colored images
302  *
303  * A texture can be loaded from an image, but also directly
304  * from a file/memory/stream. The necessary shortcuts are defined
305  * so that you don't need an image first for the most common cases.
306  * However, if you want to perform some modifications on the pixels
307  * before creating the final texture, you can load your file to a
308  * gf::Image, do whatever you need with the pixels, and then call
309  * Texture::loadFromImage.
310  *
311  * Like gf::Image, gf::Texture can handle a unique internal
312  * representation of pixels, which is RGBA. This means
313  * that a pixel must be composed of 8 bits red, green, blue and
314  * alpha channels.
315  *
316  * Usage example:
317  *
318  * ~~~{.cc}
319  * // This example shows the most common use of gf::Texture:
320  * // drawing a sprite
321  *
322  * // Load a texture from a file
323  * gf::Texture texture;
324  *
325  * if (!texture.loadFromFile("texture.png")) {
326  * return -1;
327  * }
328  *
329  * // Assign it to a sprite
330  * gf::Sprite sprite;
331  * sprite.setTexture(texture);
332  *
333  * // Draw the textured sprite
334  * window.draw(sprite);
335  * ~~~
336  *
337  * @sa gf::Sprite, gf::Image, gf::RenderTexture
338  */
339  class GF_API Texture : public BareTexture {
340  public:
341  /**
342  * @brief Constructor
343  *
344  * No texture is created.
345  */
346  Texture();
347 
348  /**
349  * @brief Create the texture
350  *
351  * If this function fails, the texture is left unchanged.
352  *
353  * @param size Size of the texture
354  *
355  * @return True if creation was successful
356  */
357  bool create(Vector2u size);
358 
359  /**
360  * @brief Load the texture from an image
361  *
362  * If this function fails, the texture is left unchanged.
363  *
364  * @param image Image to load into the texture
365  *
366  * @return True if loading was successful
367  *
368  * @sa loadFromFile(), loadFromMemory(), loadFromStream()
369  */
370  bool loadFromImage(const Image& image);
371 
372  /**
373  * @brief Load the texture from a file on disk
374  *
375  * This function is a shortcut for the following code:
376  *
377  * ~~~{.cc}
378  * gf::Image image;
379  * image.loadFromFile(filename);
380  * texture.loadFromImage(image);
381  * ~~~
382  *
383  * If this function fails, the texture is left unchanged.
384  *
385  * @param filename Path of the image file to load
386  *
387  * @return True if loading was successful
388  *
389  * @sa loadFromMemory(), loadFromStream(), loadFromImage()
390  */
391  bool loadFromFile(const Path& filename);
392 
393  /**
394  * @brief Load the texture from a custom stream
395  *
396  * This function is a shortcut for the following code:
397  *
398  * ~~~{.cc}
399  * gf::Image image;
400  * image.loadFromStream(stream);
401  * texture.loadFromImage(image);
402  * ~~~
403  *
404  * If this function fails, the texture is left unchanged.
405  *
406  * @param stream Source stream to read from
407  * @return True if loading was successful
408  *
409  * @see loadFromFile(), loadFromMemory(), loadFromImage()
410  */
411  bool loadFromStream(InputStream& stream);
412 
413  /**
414  * @brief Load the texture from a file in memory
415  *
416  * This function is a shortcut for the following code:
417  *
418  * ~~~{.cc}
419  * gf::Image image;
420  * image.loadFromMemory(data, length);
421  * texture.loadFromImage(image);
422  * ~~~
423  *
424  * If this function fails, the texture is left unchanged.
425  *
426  * @param data Pointer to the file data in memory
427  * @param length Length of the data to load, in bytes
428  * @return True if loading was successful
429  *
430  * @see loadFromFile(), loadFromStream(), loadFromImage()
431  */
432  bool loadFromMemory(const uint8_t *data, std::size_t length);
433 
434  /**
435  * @brief Update the texture from an image
436  *
437  * Although the source image can be smaller than the texture,
438  * this function is usually used for updating the whole texture.
439  *
440  * No additional check is performed on the size of the image,
441  * passing an image bigger than the texture will lead to an
442  * undefined behavior.
443  *
444  * This function does nothing if the texture was not
445  * previously created.
446  *
447  * @param image Image to copy to the texture
448  */
449  void update(const Image& image);
450 
451  /**
452  * @brief Copy the texture pixels to an image
453  *
454  * This function performs a slow operation that downloads
455  * the texture's pixels from the graphics card and copies
456  * them to a new image, potentially applying transformations
457  * to pixels if necessary (texture may be padded or flipped).
458  *
459  * @return An image containing the texture's pixels
460  *
461  * @sa loadFromImage()
462  */
463  Image copyToImage() const;
464 
465  };
466 
467 
468  /**
469  * @ingroup graphics
470  * @brief A texture with a single alpha channel
471  *
472  * This texture is used internally by gf::Font
473  */
474  class GF_API AlphaTexture : public BareTexture {
475  public:
476  /**
477  * @brief Constructor
478  *
479  * No texture is created
480  */
481  AlphaTexture();
482 
483  /**
484  * @brief Create the texture
485  *
486  * If this function fails, the texture is left unchanged.
487  *
488  * @param size Size of the texture
489  *
490  * @return True if creation was successful
491  */
492  bool create(Vector2u size);
493  };
494 
495 #ifndef DOXYGEN_SHOULD_SKIP_THIS
496 }
497 #endif
498 }
499 
500 #endif // GF_TEXTURE_H
static void bind(const BareTexture *texture)
Bind a texture for rendering.
void update(const Image &image)
Update the texture from an image.
RectF computeTextureCoords(const RectU &rect) const
Compute normalized texture coordinates.
BareTexture & operator=(const BareTexture &)=delete
Deleted copy assignment.
bool create(Vector2u size)
Create the texture.
void update(const uint8_t *data, const RectU &rect)
Update a part of the texture from an array of pixels.
Format
Format of the texture.
Definition: Texture.h:74
bool loadFromFile(const Path &filename)
Load the texture from a file on disk.
bool create(Vector2u size)
Create the texture.
bool isRepeated() const noexcept
Check if the texture is repeated or not.
Definition: Texture.h:197
bool create(Vector2u size, const uint8_t *data)
Create the texture.
~BareTexture()
Destructor.
BareTexture & operator=(BareTexture &&other)
Move assignment.
Image copyToImage() const
Copy the texture pixels to an image.
bool loadFromImage(const Image &image)
Load the texture from an image.
A texture for colored images.
Definition: Texture.h:339
bool isSmooth() const noexcept
Check if the smooth filter is enabled or not.
Definition: Texture.h:165
BareTexture(BareTexture &&other)
Move constructor.
BareTexture(const BareTexture &)=delete
Deleted copy constructor.
void setSmooth(bool smooth=true)
Enable or disable the smooth filter.
Class for loading, manipulating and saving images.
Definition: Image.h:92
The namespace for gf classes.
Definition: Action.h:34
An image that lives in the graphic memory that can be used for drawing.
Definition: Texture.h:67
Abstract class for custom file input streams.
Definition: InputStream.h:51
bool loadFromMemory(const uint8_t *data, std::size_t length)
Load the texture from a file in memory.
AlphaTexture()
Constructor.
unsigned getName() const
Get the internal representation of the texture.
Definition: Texture.h:129
BareTexture(Format format)
Constructor.
Texture()
Constructor.
bool loadFromStream(InputStream &stream)
Load the texture from a custom stream.
A texture with a single alpha channel.
Definition: Texture.h:474
#define GF_API
Definition: Portability.h:35
void update(const uint8_t *data)
Update the whole texture from an array of pixels.
Format getFormat() const
Get the format of the texture.
Definition: Texture.h:118
Vector2u getSize() const
Return the size of the texture.
Definition: Texture.h:138
bool generateMipmap()
Generate a mipmap using the current texture data.
void setRepeated(bool repeated=true)
Enable or disable repeating.