Simulant  21.12-574
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
texture.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef TEXTURE_H_INCLUDED
20 #define TEXTURE_H_INCLUDED
21 
22 #include <cstdint>
23 #include <memory>
24 #include <queue>
25 #include <vector>
26 #include "generic/identifiable.h"
27 #include "generic/managed.h"
28 #include "loadable.h"
29 #include "types.h"
30 #include "asset.h"
31 #include "interfaces.h"
32 #include "interfaces/updateable.h"
33 #include "path.h"
34 
35 namespace smlt {
36 
37 enum MipmapGenerate {
38  MIPMAP_GENERATE_NONE,
39  MIPMAP_GENERATE_COMPLETE
40 };
41 
42 enum TextureWrap {
43  TEXTURE_WRAP_REPEAT,
44  TEXTURE_WRAP_CLAMP_TO_EDGE,
45  TEXTURE_WRAP_MIRRORED_REPEAT,
46  TEXTURE_WRAP_MIRRORED_CLAMP_TO_EDGE
47 };
48 
49 enum TextureFilter {
50  TEXTURE_FILTER_POINT,
51  TEXTURE_FILTER_BILINEAR,
52  TEXTURE_FILTER_TRILINEAR
53 };
54 
55 enum BlurType {
56  BLUR_TYPE_SIMPLE,
57  BLUR_TYPE_GAUSSIAN,
58 };
59 
60 /*
61  * Simulant intentionally only supports a handful of formats for portability.
62  *
63  * This list isn't fixed though, if you need more, just file an issue.
64  *
65  * Format is:
66  *
67  * {ORDER}_{COUNT}{TYPE}_{LAYOUT}_{COMPRESSION}_{TWIDDLED}
68  *
69  * Where TYPE is UB (unsigned byte), US (unsigned short)
70  * or UI (unsigned int)
71  *
72  * In some compressed formats the count+type don't make sense
73  * in which case they are omitted.
74  */
75 enum TextureFormat {
76  TEXTURE_FORMAT_INVALID = 0,
77 
78  // Standard formats
79  TEXTURE_FORMAT_R_1UB_8,
80  TEXTURE_FORMAT_RGB_3UB_888,
81  TEXTURE_FORMAT_RGBA_4UB_8888,
82 
83  // Packed short formats
84  TEXTURE_FORMAT_RGB_1US_565,
85  TEXTURE_FORMAT_RGBA_1US_4444,
86  TEXTURE_FORMAT_RGBA_1US_5551,
87  TEXTURE_FORMAT_ARGB_1US_1555,
88  TEXTURE_FORMAT_ARGB_1US_4444,
89  TEXTURE_FORMAT_RGB_1US_565_TWID,
90  TEXTURE_FORMAT_ARGB_1US_4444_TWID,
91  TEXTURE_FORMAT_ARGB_1US_1555_TWID,
92 
93  // Paletted formats
94  TEXTURE_FORMAT_RGB8_PALETTED4,
95  TEXTURE_FORMAT_RGBA8_PALETTED4,
96  TEXTURE_FORMAT_RGB565_PALETTED4,
97  TEXTURE_FORMAT_RGB8_PALETTED8,
98  TEXTURE_FORMAT_RGBA8_PALETTED8,
99  TEXTURE_FORMAT_RGB565_PALETTED8,
100 
101  // Dreamcast PVR VQ compressed
102  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID,
103  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID,
104  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID,
105 
106  // PVR VQ Compressed but with mipmap data included
107  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID_MIP,
108  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID_MIP,
109  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID_MIP
110 };
111 
112 std::size_t texture_format_stride(TextureFormat format);
113 std::size_t texture_format_channels(TextureFormat format);
114 
117 bool texture_format_contains_mipmaps(TextureFormat format);
118 
119 enum TextureFreeData {
120  TEXTURE_FREE_DATA_NEVER,
121  TEXTURE_FREE_DATA_AFTER_UPLOAD
122 };
123 
124 class Renderer;
125 
126 enum TextureChannel {
127  TEXTURE_CHANNEL_RED,
128  TEXTURE_CHANNEL_GREEN,
129  TEXTURE_CHANNEL_BLUE,
130  TEXTURE_CHANNEL_ALPHA,
131  TEXTURE_CHANNEL_ZERO,
132  TEXTURE_CHANNEL_ONE,
133  TEXTURE_CHANNEL_INVERSE_RED,
134 };
135 
136 struct Pixel {
137  Pixel() = default;
138  Pixel(uint8_t r, uint8_t g, uint8_t b, uint8_t a):
139  rgba{r, g, b, a} {}
140 
141  uint8_t rgba[4];
142 
146  std::vector<uint8_t> to_format(TextureFormat fmt);
147 };
148 
149 typedef std::array<TextureChannel, 4> TextureChannelSet;
150 
151 class Texture :
152  public Asset,
153  public Loadable,
154  public generic::Identifiable<TextureID>,
155  public RefCounted<Texture>,
156  public Updateable,
157  public RenderTarget,
158  public ChainNameable<Texture> {
159 
160 public:
161  static const TextureChannelSet DEFAULT_SOURCE_CHANNELS;
162 
163  struct BuiltIns {
164  static const std::string CHECKERBOARD;
165  static const std::string BUTTON;
166  };
167 
168  typedef std::shared_ptr<Texture> ptr;
169  typedef std::vector<uint8_t> Data;
170 
171  Texture(TextureID id, AssetManager* asset_manager, uint16_t width, uint16_t height, TextureFormat format=TEXTURE_FORMAT_RGBA_4UB_8888);
172  ~Texture();
173 
174 
175  TextureFormat format() const;
176  void set_format(TextureFormat format);
177 
179  bool is_paletted_format() const;
180 
183  uint32_t palette_size() const;
184 
193  bool update_palette(const uint8_t* palette);
194 
195  /* Applies a blur to the texture, this must be called before
196  * a texture is uploaded to the GPU. This function will return false
197  * if the blur type is unimplemented (patches welcome!) or the
198  * texture data is empty */
199  bool blur(BlurType blur_type, std::size_t radius);
200 
201  /* Returns the byte colour data for the specified location. Will return
202  * nothing if the texture data is empty, or it's a compressed texture */
203  smlt::optional<Pixel> pixel(std::size_t x, std::size_t y);
204 
206  bool convert(
207  TextureFormat new_format,
208  const TextureChannelSet& channels=Texture::DEFAULT_SOURCE_CHANNELS
209  );
210 
215  void resize(uint16_t width, uint16_t height, uint32_t data_size);
216 
221  void resize(uint16_t width, uint16_t height);
222 
227  void flip_vertically();
228 
229  void set_source(const smlt::Path& source);
230 
232  void set_texture_filter(TextureFilter filter);
233 
237  void set_free_data_mode(TextureFreeData mode);
238 
240  void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v, TextureWrap wrap_w);
241  void set_texture_wrap_u(TextureWrap wrap_u);
242  void set_texture_wrap_v(TextureWrap wrap_v);
243  void set_texture_wrap_w(TextureWrap wrap_w);
244 
249  void set_auto_upload(bool v=true);
250  void set_mipmap_generation(MipmapGenerate type);
251 
253  std::vector<uint8_t> data_copy() const;
254 
257  const uint8_t* data() const;
258 
263  uint32_t data_size() const;
264 
270  static std::size_t required_data_size(TextureFormat fmt, uint16_t width, uint16_t height);
271 
272  void set_data(const uint8_t* data, std::size_t size);
273  void set_data(const std::vector<uint8_t>& data);
274 
276  void free();
277 
279  bool has_data() const;
280 
285  void flush();
286 
287  typedef std::function<void (uint8_t*, uint16_t, uint16_t, TextureFormat)> MutationFunc;
288 
290  void mutate_data(MutationFunc func);
291 
292  uint16_t width() const override;
293  uint16_t height() const override;
294  Vec2 dimensions() const { return Vec2(width(), height()); }
295 
299  bool is_compressed() const;
300 
304  uint8_t channels() const;
305 
310  void save_to_file(const Path& filename);
311 
312  Path source() const;
313  TextureFilter texture_filter() const;
314  TextureWrap wrap_u() const;
315  TextureWrap wrap_v() const;
316  TextureWrap wrap_w() const;
317  MipmapGenerate mipmap_generation() const;
318  TextureFreeData free_data_mode() const;
319 
321  bool init() override;
322  void clean_up() override;
323  void update(float dt) override;
324 
327  bool has_mipmaps() const;
328 
329  bool auto_upload() const;
330 
332  void _set_renderer_specific_id(const uint32_t id);
333  uint32_t _renderer_specific_id() const;
334 
336  void _set_params_clean();
337 
339  bool _data_dirty() const;
340 
342  void _set_data_clean();
343 
345  bool _params_dirty() const;
346  void _set_has_mipmaps(bool v);
347 
349  uint8_t* _stash_paletted_data();
350 private:
351  Renderer* renderer_ = nullptr;
352 
353  uint16_t width_ = 0;
354  uint16_t height_ = 0;
355 
356  TextureFormat format_ = TEXTURE_FORMAT_RGBA_4UB_8888;
357 
358  Path source_;
359 
360  bool auto_upload_ = true; /* If true, the texture is uploaded by the renderer asap */
361 
362  void resize_data(uint32_t byte_size);
363 
364  bool data_dirty_ = true;
365  uint8_t* data_ = nullptr;
366  uint32_t data_size_ = 0;
367 
368  /* This is used to store the palette, followed by the index data if:
369  * - The format is a paletted format
370  * - OES_compressed_paletted_texture is unsupported.
371  *
372  * If OES_compressed_paletted_texture is supported then paletted data is
373  * uploaded directly. If it is not, then we store the paletted_data here
374  * and keep it resident in RAM so we can update the main data if the palette
375  * changes */
376  uint8_t* paletted_data_ = nullptr;
377 
378  TextureFreeData free_data_mode_ = TEXTURE_FREE_DATA_AFTER_UPLOAD;
379 
380  MipmapGenerate mipmap_generation_ = MIPMAP_GENERATE_COMPLETE;
381  bool has_mipmaps_ = false;
382 
383  bool params_dirty_ = true;
384  TextureFilter filter_ = TEXTURE_FILTER_POINT;
385  TextureWrap wrap_u_ = TEXTURE_WRAP_REPEAT;
386  TextureWrap wrap_v_ = TEXTURE_WRAP_REPEAT;
387  TextureWrap wrap_w_ = TEXTURE_WRAP_REPEAT;
388 
389  uint32_t renderer_id_ = 0;
390 };
391 
392 }
393 
394 #endif // TEXTURE_H_INCLUDED
smlt::Texture::has_mipmaps
bool has_mipmaps() const
Definition: texture.cpp:767
smlt::Texture::init
bool init() override
Definition: texture.cpp:751
smlt::Texture::set_texture_filter
void set_texture_filter(TextureFilter filter)
Definition: texture.cpp:649
smlt::texture_format_contains_mipmaps
bool texture_format_contains_mipmaps(TextureFormat format)
Definition: texture.cpp:46
smlt::Texture::_set_params_clean
void _set_params_clean()
Definition: texture.cpp:669
smlt::Texture::_set_data_clean
void _set_data_clean()
Definition: texture.cpp:677
smlt::Texture::set_texture_wrap
void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v, TextureWrap wrap_w)
Definition: texture.cpp:681
smlt::Texture::set_free_data_mode
void set_free_data_mode(TextureFreeData mode)
Definition: texture.cpp:656
smlt::Updateable
The Updateable class.
Definition: updateable.h:13
smlt::Texture::_params_dirty
bool _params_dirty() const
Definition: texture.cpp:665
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::Texture::flush
void flush()
Definition: texture.cpp:565
smlt::Texture
Definition: texture.h:158
smlt::Texture::BuiltIns
Definition: texture.h:163
smlt::Texture::is_paletted_format
bool is_paletted_format() const
Definition: texture.cpp:178
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::Texture::_stash_paletted_data
uint8_t * _stash_paletted_data()
Definition: texture.cpp:610
smlt::Texture::_data_dirty
bool _data_dirty() const
Definition: texture.cpp:673
smlt::UniqueID< TexturePtr >
smlt::Texture::_set_renderer_specific_id
void _set_renderer_specific_id(const uint32_t id)
Definition: texture.cpp:775
smlt::Texture::required_data_size
static std::size_t required_data_size(TextureFormat fmt, uint16_t width, uint16_t height)
Definition: texture.cpp:126
smlt::RenderTarget
Definition: interfaces.h:27
smlt::Pixel
Definition: texture.h:136
smlt::optional
Definition: optional.h:13
smlt::Pixel::to_format
std::vector< uint8_t > to_format(TextureFormat fmt)
Definition: texture.cpp:802
smlt::Path
Definition: path.h:7
smlt::Texture::data_size
uint32_t data_size() const
Definition: texture.cpp:601
smlt::Texture::data_copy
std::vector< uint8_t > data_copy() const
Definition: texture.cpp:718
smlt::Loadable
Definition: loadable.h:26
smlt::Texture::set_auto_upload
void set_auto_upload(bool v=true)
Definition: texture.cpp:708
smlt::Texture::convert
bool convert(TextureFormat new_format, const TextureChannelSet &channels=Texture::DEFAULT_SOURCE_CHANNELS)
Definition: texture.cpp:472
smlt::Texture::channels
uint8_t channels() const
Definition: texture.cpp:593
smlt::ChainNameable
Definition: nameable.h:34
smlt::Texture::palette_size
uint32_t palette_size() const
Definition: texture.cpp:192
smlt::Texture::update_palette
bool update_palette(const uint8_t *palette)
smlt::Texture::has_data
bool has_data() const
Definition: texture.cpp:561
smlt::Texture::mutate_data
void mutate_data(MutationFunc func)
Definition: texture.cpp:572
smlt::Renderer
Definition: renderer.h:40
smlt::Texture::save_to_file
void save_to_file(const Path &filename)
Definition: texture.cpp:620
smlt::Asset
Definition: asset.h:37
smlt::Texture::resize
void resize(uint16_t width, uint16_t height, uint32_t data_size)
Definition: texture.cpp:314
smlt::Texture::flip_vertically
void flip_vertically()
Definition: texture.cpp:543
smlt::Texture::data
const uint8_t * data() const
Definition: texture.cpp:597
smlt::Vec2
Definition: vec2.h:14
smlt::AssetManager
Definition: asset_manager.h:107
smlt::Texture::is_compressed
bool is_compressed() const
Definition: texture.cpp:579
smlt::Texture::free
void free()
Definition: texture.cpp:551