Gamedev Framework (gf)  0.1.0
A C++11 framework for 2D games
Texture.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 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 "Filesystem.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::FontTexture)
61  *
62  * Generally, you do not manipulated 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 Bind a texture for rendering
248  *
249  * This function is for internal use only.
250  *
251  * @param texture Pointer to the texture to bind, can be `nullptr` to use no texture
252  */
253  static void bind(const BareTexture *texture);
254 
255  protected:
256  /**
257  * @brief Create the texture
258  *
259  * If this function fails, the texture is left unchanged.
260  *
261  * @param size Size of the texture
262  * @param data Initial pixels of the texture (can be `nullptr`)
263  *
264  * @return True if creation was successful
265  */
266  bool create(Vector2u size, const uint8_t *data);
267 
268  private:
269  Format m_format;
270  unsigned m_name;
271  Vector2u m_size;
272  bool m_smooth;
273  bool m_repeated;
274  };
275 
276 
277  /**
278  * @ingroup graphics
279  * @brief A texture for colored images
280  *
281  * A texture can be loaded from an image, but also directly
282  * from a file/memory/stream. The necessary shortcuts are defined
283  * so that you don't need an image first for the most common cases.
284  * However, if you want to perform some modifications on the pixels
285  * before creating the final texture, you can load your file to a
286  * gf::Image, do whatever you need with the pixels, and then call
287  * Texture::loadFromImage.
288  *
289  * Like gf::Image, gf::Texture can handle a unique internal
290  * representation of pixels, which is RGBA. This means
291  * that a pixel must be composed of 8 bits red, green, blue and
292  * alpha channels.
293  *
294  * Usage example:
295  *
296  * ~~~{.cc}
297  * // This example shows the most common use of gf::Texture:
298  * // drawing a sprite
299  *
300  * // Load a texture from a file
301  * gf::Texture texture;
302  *
303  * if (!texture.loadFromFile("texture.png")) {
304  * return -1;
305  * }
306  *
307  * // Assign it to a sprite
308  * gf::Sprite sprite;
309  * sprite.setTexture(texture);
310  *
311  * // Draw the textured sprite
312  * window.draw(sprite);
313  * ~~~
314  *
315  * @sa gf::Sprite, gf::Image, gf::RenderTexture
316  */
317  class GF_API Texture : public BareTexture {
318  public:
319  /**
320  * @brief Constructor
321  *
322  * No texture is created.
323  */
324  Texture();
325 
326  /**
327  * @brief Create the texture
328  *
329  * If this function fails, the texture is left unchanged.
330  *
331  * @param size Size of the texture
332  *
333  * @return True if creation was successful
334  */
335  bool create(Vector2u size);
336 
337  /**
338  * @brief Load the texture from an image
339  *
340  * If this function fails, the texture is left unchanged.
341  *
342  * @param image Image to load into the texture
343  *
344  * @return True if loading was successful
345  *
346  * @sa loadFromFile(), loadFromMemory(), loadFromStream()
347  */
348  bool loadFromImage(const Image& image);
349 
350  /**
351  * @brief Load the texture from a file on disk
352  *
353  * This function is a shortcut for the following code:
354  *
355  * ~~~{.cc}
356  * gf::Image image;
357  * image.loadFromFile(filename);
358  * texture.loadFromImage(image);
359  * ~~~
360  *
361  * If this function fails, the texture is left unchanged.
362  *
363  * @param filename Path of the image file to load
364  *
365  * @return True if loading was successful
366  *
367  * @sa loadFromMemory(), loadFromStream(), loadFromImage()
368  */
369  bool loadFromFile(const Path& filename);
370 
371  /**
372  * @brief Load the texture from a custom stream
373  *
374  * This function is a shortcut for the following code:
375  *
376  * ~~~{.cc}
377  * gf::Image image;
378  * image.loadFromStream(stream);
379  * texture.loadFromImage(image);
380  * ~~~
381  *
382  * If this function fails, the texture is left unchanged.
383  *
384  * @param stream Source stream to read from
385  * @return True if loading was successful
386  *
387  * @see loadFromFile(), loadFromMemory(), loadFromImage()
388  */
389  bool loadFromStream(InputStream& stream);
390 
391  /**
392  * @brief Load the texture from a file in memory
393  *
394  * This function is a shortcut for the following code:
395  *
396  * ~~~{.cc}
397  * gf::Image image;
398  * image.loadFromMemory(data, length);
399  * texture.loadFromImage(image);
400  * ~~~
401  *
402  * If this function fails, the texture is left unchanged.
403  *
404  * @param data Pointer to the file data in memory
405  * @param length Length of the data to load, in bytes
406  * @return True if loading was successful
407  *
408  * @see loadFromFile(), loadFromStream(), loadFromImage()
409  */
410  bool loadFromMemory(const uint8_t *data, std::size_t length);
411 
412  /**
413  * @brief Update the texture from an image
414  *
415  * Although the source image can be smaller than the texture,
416  * this function is usually used for updating the whole texture.
417  *
418  * No additional check is performed on the size of the image,
419  * passing an image bigger than the texture will lead to an
420  * undefined behavior.
421  *
422  * This function does nothing if the texture was not
423  * previously created.
424  *
425  * @param image Image to copy to the texture
426  */
427  void update(const Image& image);
428 
429  /**
430  * @brief Copy the texture pixels to an image
431  *
432  * This function performs a slow operation that downloads
433  * the texture's pixels from the graphics card and copies
434  * them to a new image, potentially applying transformations
435  * to pixels if necessary (texture may be padded or flipped).
436  *
437  * @return An image containing the texture's pixels
438  *
439  * @sa loadFromImage()
440  */
441  Image copyToImage() const;
442 
443  };
444 
445 
446  /**
447  * @ingroup graphics
448  * @brief A texture with a single alpha channel
449  *
450  * This texture is used internally by gf::Font
451  */
452  class GF_API AlphaTexture : public BareTexture {
453  public:
454  /**
455  * @brief Constructor
456  *
457  * No texture is created
458  */
459  AlphaTexture();
460 
461  /**
462  * @brief Create the texture
463  *
464  * If this function fails, the texture is left unchanged.
465  *
466  * @param size Size of the texture
467  *
468  * @return True if creation was successful
469  */
470  bool create(Vector2u size);
471  };
472 
473 #ifndef DOXYGEN_SHOULD_SKIP_THIS
474 }
475 #endif
476 }
477 
478 #endif // GF_TEXTURE_H
static void bind(const BareTexture *texture)
Bind a texture for rendering.
Vector< unsigned, 2 > Vector2u
A unsigned vector with 2 components.
Definition: Vector.h:795
void update(const Image &image)
Update the texture from an image.
Vector2u getSize() const
Return the size of the texture.
Definition: Texture.h:138
Rect< unsigned > RectU
A unsigned rectangle.
Definition: Rect.h:318
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.
bool loadFromFile(const Path &filename)
Load the texture from a file on disk.
bool create(Vector2u size)
Create the texture.
Image copyToImage() const
Copy the texture pixels to an image.
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.
unsigned getName() const
Get the internal representation of the texture.
Definition: Texture.h:129
~BareTexture()
Destructor.
BareTexture & operator=(BareTexture &&other)
Move assignment.
bool loadFromImage(const Image &image)
Load the texture from an image.
A texture for colored images.
Definition: Texture.h:317
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.
Rect< float > RectF
A float rectangle.
Definition: Rect.h:306
void setSmooth(bool smooth=true)
Enable or disable the smooth filter.
Class for loading, manipulating and saving images.
Definition: Image.h:92
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.
BareTexture(Format format)
Constructor.
Format
Format of the texture.
Definition: Texture.h:74
Format getFormat() const
Get the format of the texture.
Definition: Texture.h:118
RectF computeTextureCoords(const RectU &rect) const
Compute normalized texture coordinates.
Texture()
Constructor.
bool loadFromStream(InputStream &stream)
Load the texture from a custom stream.
A texture with a single alpha channel.
Definition: Texture.h:452
#define GF_API
Definition: Portability.h:35
void update(const uint8_t *data)
Update the whole texture from an array of pixels.
void setRepeated(bool repeated=true)
Enable or disable repeating.