Simulant  21.12-194
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 /*
56  * Simulant intentionally only supports a handful of formats for portability.
57  *
58  * This list isn't fixed though, if you need more, just file an issue.
59  *
60  * Format is:
61  *
62  * {ORDER}_{COUNT}{TYPE}_{LAYOUT}_{COMPRESSION}_{TWIDDLED}
63  *
64  * Where TYPE is UB (unsigned byte), US (unsigned short)
65  * or UI (unsigned int)
66  *
67  * In some compressed formats the count+type don't make sense
68  * in which case they are omitted.
69  */
70 enum TextureFormat {
71  // Standard formats
72  TEXTURE_FORMAT_R_1UB_8,
73  TEXTURE_FORMAT_RGB_3UB_888,
74  TEXTURE_FORMAT_RGBA_4UB_8888,
75 
76  // Packed short formats
77  TEXTURE_FORMAT_RGB_1US_565,
78  TEXTURE_FORMAT_RGBA_1US_4444,
79  TEXTURE_FORMAT_RGBA_1US_5551,
80  TEXTURE_FORMAT_ARGB_1US_1555,
81  TEXTURE_FORMAT_ARGB_1US_4444,
82  TEXTURE_FORMAT_RGB_1US_565_TWID,
83  TEXTURE_FORMAT_ARGB_1US_4444_TWID,
84  TEXTURE_FORMAT_ARGB_1US_1555_TWID,
85 
86  // Paletted formats
87  TEXTURE_FORMAT_RGB8_PALETTED4,
88  TEXTURE_FORMAT_RGBA8_PALETTED4,
89  TEXTURE_FORMAT_RGB565_PALETTED4,
90  TEXTURE_FORMAT_RGB8_PALETTED8,
91  TEXTURE_FORMAT_RGBA8_PALETTED8,
92  TEXTURE_FORMAT_RGB565_PALETTED8,
93 
94  // Dreamcast PVR VQ compressed
95  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID,
96  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID,
97  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID,
98 
99  // PVR VQ Compressed but with mipmap data included
100  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID_MIP,
101  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID_MIP,
102  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID_MIP,
103 
104  TEXTURE_FORMAT_INVALID
105 };
106 
107 std::size_t texture_format_stride(TextureFormat format);
108 std::size_t texture_format_channels(TextureFormat format);
109 
112 bool texture_format_contains_mipmaps(TextureFormat format);
113 
114 enum TextureFreeData {
115  TEXTURE_FREE_DATA_NEVER,
116  TEXTURE_FREE_DATA_AFTER_UPLOAD
117 };
118 
119 class Renderer;
120 
121 enum TextureChannel {
122  TEXTURE_CHANNEL_RED,
123  TEXTURE_CHANNEL_GREEN,
124  TEXTURE_CHANNEL_BLUE,
125  TEXTURE_CHANNEL_ALPHA,
126  TEXTURE_CHANNEL_ZERO,
127  TEXTURE_CHANNEL_ONE
128 };
129 
130 typedef std::array<TextureChannel, 4> TextureChannelSet;
131 
132 class Texture :
133  public Asset,
134  public Loadable,
135  public generic::Identifiable<TextureID>,
136  public RefCounted<Texture>,
137  public Updateable,
138  public RenderTarget,
139  public ChainNameable<Texture> {
140 
141 public:
142  static const TextureChannelSet DEFAULT_SOURCE_CHANNELS;
143 
144  struct BuiltIns {
145  static const std::string CHECKERBOARD;
146  static const std::string BUTTON;
147  };
148 
149  typedef std::shared_ptr<Texture> ptr;
150  typedef std::vector<uint8_t> Data;
151 
152  Texture(TextureID id, AssetManager* asset_manager, uint16_t width, uint16_t height, TextureFormat format=TEXTURE_FORMAT_RGBA_4UB_8888);
153  ~Texture();
154 
155 
156  TextureFormat format() const;
157  void set_format(TextureFormat format);
158 
160  bool is_paletted_format() const;
161 
164  uint32_t palette_size() const;
165 
174  bool update_palette(const uint8_t* palette);
175 
177  bool convert(
178  TextureFormat new_format,
179  const TextureChannelSet& channels=Texture::DEFAULT_SOURCE_CHANNELS
180  );
181 
186  void resize(uint16_t width, uint16_t height, uint32_t data_size);
187 
192  void resize(uint16_t width, uint16_t height);
193 
198  void flip_vertically();
199 
200  void set_source(const smlt::Path& source);
201 
203  void set_texture_filter(TextureFilter filter);
204 
208  void set_free_data_mode(TextureFreeData mode);
209 
211  void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v, TextureWrap wrap_w);
212  void set_texture_wrap_u(TextureWrap wrap_u);
213  void set_texture_wrap_v(TextureWrap wrap_v);
214  void set_texture_wrap_w(TextureWrap wrap_w);
215 
220  void set_auto_upload(bool v=true);
221  void set_mipmap_generation(MipmapGenerate type);
222 
224  std::vector<uint8_t> data_copy() const;
225 
228  const uint8_t* data() const;
229 
234  uint32_t data_size() const;
235 
241  static std::size_t required_data_size(TextureFormat fmt, uint16_t width, uint16_t height);
242 
243  void set_data(const uint8_t* data, std::size_t size);
244  void set_data(const std::vector<uint8_t>& data);
245 
247  void free();
248 
250  bool has_data() const;
251 
256  void flush();
257 
258  typedef std::function<void (uint8_t*, uint16_t, uint16_t, TextureFormat)> MutationFunc;
259 
261  void mutate_data(MutationFunc func);
262 
263  uint16_t width() const override;
264  uint16_t height() const override;
265  Vec2 dimensions() const { return Vec2(width(), height()); }
266 
270  bool is_compressed() const;
271 
275  uint8_t channels() const;
276 
281  void save_to_file(const Path& filename);
282 
283  Path source() const;
284  TextureFilter texture_filter() const;
285  TextureWrap wrap_u() const;
286  TextureWrap wrap_v() const;
287  TextureWrap wrap_w() const;
288  MipmapGenerate mipmap_generation() const;
289  TextureFreeData free_data_mode() const;
290 
292  bool init() override;
293  void clean_up() override;
294  void update(float dt) override;
295 
298  bool has_mipmaps() const;
299 
300  bool auto_upload() const;
301 
303  void _set_renderer_specific_id(const uint32_t id);
304  uint32_t _renderer_specific_id() const;
305 
307  void _set_params_clean();
308 
310  bool _data_dirty() const;
311 
313  void _set_data_clean();
314 
316  bool _params_dirty() const;
317  void _set_has_mipmaps(bool v);
318 
320  uint8_t* _stash_paletted_data();
321 private:
322  Renderer* renderer_ = nullptr;
323 
324  uint16_t width_ = 0;
325  uint16_t height_ = 0;
326 
327  TextureFormat format_ = TEXTURE_FORMAT_RGBA_4UB_8888;
328 
329  Path source_;
330 
331  bool auto_upload_ = true; /* If true, the texture is uploaded by the renderer asap */
332 
333  void resize_data(uint32_t byte_size);
334 
335  bool data_dirty_ = true;
336  uint8_t* data_ = nullptr;
337  uint32_t data_size_ = 0;
338 
339  /* This is used to store the palette, followed by the index data if:
340  * - The format is a paletted format
341  * - OES_compressed_paletted_texture is unsupported.
342  *
343  * If OES_compressed_paletted_texture is supported then paletted data is
344  * uploaded directly. If it is not, then we store the paletted_data here
345  * and keep it resident in RAM so we can update the main data if the palette
346  * changes */
347  uint8_t* paletted_data_ = nullptr;
348 
349  TextureFreeData free_data_mode_ = TEXTURE_FREE_DATA_AFTER_UPLOAD;
350 
351  MipmapGenerate mipmap_generation_ = MIPMAP_GENERATE_COMPLETE;
352  bool has_mipmaps_ = false;
353 
354  bool params_dirty_ = true;
355  TextureFilter filter_ = TEXTURE_FILTER_POINT;
356  TextureWrap wrap_u_ = TEXTURE_WRAP_REPEAT;
357  TextureWrap wrap_v_ = TEXTURE_WRAP_REPEAT;
358  TextureWrap wrap_w_ = TEXTURE_WRAP_REPEAT;
359 
360  uint32_t renderer_id_ = 0;
361 };
362 
363 }
364 
365 #endif // TEXTURE_H_INCLUDED
smlt::Texture::has_mipmaps
bool has_mipmaps() const
Definition: texture.cpp:624
smlt::Texture::init
bool init() override
Definition: texture.cpp:608
smlt::Texture::set_texture_filter
void set_texture_filter(TextureFilter filter)
Definition: texture.cpp:507
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:527
smlt::Texture::_set_data_clean
void _set_data_clean()
Definition: texture.cpp:535
smlt::Texture::set_texture_wrap
void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v, TextureWrap wrap_w)
Definition: texture.cpp:539
smlt::Texture::set_free_data_mode
void set_free_data_mode(TextureFreeData mode)
Definition: texture.cpp:514
smlt::Updateable
The Updateable class.
Definition: updateable.h:13
smlt::Texture::_params_dirty
bool _params_dirty() const
Definition: texture.cpp:523
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::Texture::flush
void flush()
Definition: texture.cpp:426
smlt::Texture
Definition: texture.h:139
smlt::Texture::BuiltIns
Definition: texture.h:144
smlt::Texture::is_paletted_format
bool is_paletted_format() const
Definition: texture.cpp:156
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::Texture::_stash_paletted_data
uint8_t * _stash_paletted_data()
Definition: texture.cpp:468
smlt::Texture::_data_dirty
bool _data_dirty() const
Definition: texture.cpp:531
smlt::UniqueID< TexturePtr >
smlt::Texture::_set_renderer_specific_id
void _set_renderer_specific_id(const uint32_t id)
Definition: texture.cpp:632
smlt::Texture::required_data_size
static std::size_t required_data_size(TextureFormat fmt, uint16_t width, uint16_t height)
Definition: texture.cpp:119
smlt::RenderTarget
Definition: interfaces.h:27
smlt::Path
Definition: path.h:7
smlt::Texture::data_size
uint32_t data_size() const
Definition: texture.cpp:459
smlt::Texture::data_copy
std::vector< uint8_t > data_copy() const
Definition: texture.cpp:576
smlt::Loadable
Definition: loadable.h:26
smlt::Texture::set_auto_upload
void set_auto_upload(bool v=true)
Definition: texture.cpp:566
smlt::Texture::convert
bool convert(TextureFormat new_format, const TextureChannelSet &channels=Texture::DEFAULT_SOURCE_CHANNELS)
Definition: texture.cpp:333
smlt::Texture::channels
uint8_t channels() const
Definition: texture.cpp:451
smlt::ChainNameable
Definition: nameable.h:34
smlt::Texture::palette_size
uint32_t palette_size() const
Definition: texture.cpp:170
smlt::Texture::update_palette
bool update_palette(const uint8_t *palette)
smlt::Texture::has_data
bool has_data() const
Definition: texture.cpp:422
smlt::Texture::mutate_data
void mutate_data(MutationFunc func)
Definition: texture.cpp:433
smlt::Renderer
Definition: renderer.h:40
smlt::Texture::save_to_file
void save_to_file(const Path &filename)
Definition: texture.cpp:478
smlt::Asset
Definition: asset.h:37
smlt::Texture::resize
void resize(uint16_t width, uint16_t height, uint32_t data_size)
Definition: texture.cpp:193
smlt::Texture::flip_vertically
void flip_vertically()
Definition: texture.cpp:404
smlt::Texture::data
const uint8_t * data() const
Definition: texture.cpp:455
smlt::Vec2
Definition: vec2.h:13
smlt::AssetManager
Definition: asset_manager.h:100
smlt::Texture::is_compressed
bool is_compressed() const
Definition: texture.cpp:440
smlt::Texture::free
void free()
Definition: texture.cpp:412