Simulant  21.12-1292
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
7  * by the Free Software Foundation, either version 3 of the License, or (at your
8  * 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 "asset.h"
23 #include "assets/texture_flags.h"
24 #include "generic/identifiable.h"
25 #include "generic/managed.h"
26 #include "interfaces.h"
27 #include "loadable.h"
28 #include "path.h"
29 #include "types.h"
30 #include <cstdint>
31 #include <memory>
32 #include <queue>
33 #include <vector>
34 
35 namespace smlt {
36 
37 enum BlurType {
38  BLUR_TYPE_SIMPLE,
39  BLUR_TYPE_GAUSSIAN,
40 };
41 
42 /*
43  * Simulant intentionally only supports a handful of formats for portability.
44  *
45  * This list isn't fixed though, if you need more, just file an issue.
46  *
47  * Format is:
48  *
49  * {ORDER}_{COUNT}{TYPE}_{LAYOUT}_{COMPRESSION}_{TWIDDLED}
50  *
51  * Where TYPE is UB (unsigned byte), US (unsigned short)
52  * or UI (unsigned int)
53  *
54  * In some compressed formats the count+type don't make sense
55  * in which case they are omitted.
56  */
57 enum TextureFormat {
58  TEXTURE_FORMAT_INVALID = 0,
59 
60  // Standard formats
61  TEXTURE_FORMAT_R_1UB_8,
62  TEXTURE_FORMAT_RGB_3UB_888,
63  TEXTURE_FORMAT_RGBA_4UB_8888,
64 
65  // Packed short formats
66  TEXTURE_FORMAT_RGB_1US_565,
67  TEXTURE_FORMAT_RGBA_1US_4444,
68  TEXTURE_FORMAT_RGBA_1US_5551,
69  TEXTURE_FORMAT_ARGB_1US_1555,
70  TEXTURE_FORMAT_ARGB_1US_4444,
71  TEXTURE_FORMAT_RGB_1US_565_TWID,
72  TEXTURE_FORMAT_ARGB_1US_4444_TWID,
73  TEXTURE_FORMAT_ARGB_1US_1555_TWID,
74 
75  // Paletted formats
76  TEXTURE_FORMAT_RGB8_PALETTED4,
77  TEXTURE_FORMAT_RGBA8_PALETTED4,
78  TEXTURE_FORMAT_RGB565_PALETTED4,
79  TEXTURE_FORMAT_RGB8_PALETTED8,
80  TEXTURE_FORMAT_RGBA8_PALETTED8,
81  TEXTURE_FORMAT_RGB565_PALETTED8,
82 
83  // Dreamcast PVR VQ compressed
84  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID,
85  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID,
86  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID,
87 
88  // PVR VQ Compressed but with mipmap data included
89  TEXTURE_FORMAT_RGB_1US_565_VQ_TWID_MIP,
90  TEXTURE_FORMAT_ARGB_1US_4444_VQ_TWID_MIP,
91  TEXTURE_FORMAT_ARGB_1US_1555_VQ_TWID_MIP
92 };
93 
94 std::size_t texture_format_stride(TextureFormat format);
95 std::size_t texture_format_channels(TextureFormat format);
96 
99 bool texture_format_contains_mipmaps(TextureFormat format);
100 
101 class Renderer;
102 
103 enum TextureChannel {
104  TEXTURE_CHANNEL_RED,
105  TEXTURE_CHANNEL_GREEN,
106  TEXTURE_CHANNEL_BLUE,
107  TEXTURE_CHANNEL_ALPHA,
108  TEXTURE_CHANNEL_ZERO,
109  TEXTURE_CHANNEL_ONE,
110  TEXTURE_CHANNEL_INVERSE_RED,
111 };
112 
113 struct Pixel {
114  Pixel() = default;
115  Pixel(uint8_t r, uint8_t g, uint8_t b, uint8_t a) :
116  rgba{r, g, b, a} {}
117 
118  uint8_t rgba[4];
119 
123  std::vector<uint8_t> to_format(TextureFormat fmt);
124 };
125 
126 typedef std::array<TextureChannel, 4> TextureChannelSet;
127 
128 class Texture:
129  public Asset,
130  public Loadable,
131  public generic::Identifiable<AssetID>,
132  public RefCounted<Texture>,
133  public RenderTarget,
134  public ChainNameable<Texture> {
135 
136 public:
137  static const TextureChannelSet DEFAULT_SOURCE_CHANNELS;
138 
139  struct BuiltIns {
140  static const std::string CHECKERBOARD;
141  static const std::string BUTTON;
142  };
143 
144  typedef std::shared_ptr<Texture> ptr;
145  typedef std::vector<uint8_t> Data;
146 
147  Texture(AssetID id, AssetManager* asset_manager, uint16_t width,
148  uint16_t height,
149  TextureFormat format = TEXTURE_FORMAT_RGBA_4UB_8888);
150  ~Texture();
151 
152  TextureFormat format() const;
153  void set_format(TextureFormat format);
154 
156  bool is_paletted_format() const;
157 
160  uint32_t palette_size() const;
161 
170  bool update_palette(const uint8_t* palette);
171 
172  /* Applies a blur to the texture, this must be called before
173  * a texture is uploaded to the GPU. This function will return false
174  * if the blur type is unimplemented (patches welcome!) or the
175  * texture data is empty */
176  bool blur(BlurType blur_type, std::size_t radius);
177 
178  /* Returns the byte color data for the specified location. Will return
179  * nothing if the texture data is empty, or it's a compressed texture */
180  smlt::optional<Pixel> pixel(std::size_t x, std::size_t y);
181 
184  bool convert(
185  TextureFormat new_format,
186  const TextureChannelSet& channels = Texture::DEFAULT_SOURCE_CHANNELS);
187 
192  void resize(uint16_t width, uint16_t height, uint32_t data_size);
193 
198  void resize(uint16_t width, uint16_t height);
199 
204  void flip_vertically();
205 
206  void set_source(const smlt::Path& source);
207 
209  void set_texture_filter(TextureFilter filter);
210 
214  void set_free_data_mode(TextureFreeData mode);
215 
217  void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v,
218  TextureWrap wrap_w);
219  void set_texture_wrap_u(TextureWrap wrap_u);
220  void set_texture_wrap_v(TextureWrap wrap_v);
221  void set_texture_wrap_w(TextureWrap wrap_w);
222 
227  void set_auto_upload(bool v = true);
228  void set_mipmap_generation(MipmapGenerate type);
229 
231  std::vector<uint8_t> data_copy() const;
232 
235  const uint8_t* data() const;
236 
241  uint32_t data_size() const;
242 
249  static std::size_t required_data_size(TextureFormat fmt, uint16_t width,
250  uint16_t height);
251 
252  void set_data(const uint8_t* data, std::size_t size);
253  void set_data(const std::vector<uint8_t>& data);
254 
256  void free();
257 
259  bool has_data() const;
260 
266  void flush();
267 
268  typedef std::function<void(uint8_t*, uint16_t, uint16_t, TextureFormat)>
269  MutationFunc;
270 
272  void mutate_data(MutationFunc func);
273 
274  uint16_t width() const override;
275  uint16_t height() const override;
276  Vec2 dimensions() const {
277  return Vec2(width(), height());
278  }
279 
283  bool is_compressed() const;
284 
288  uint8_t channels() const;
289 
294  void save_to_file(const Path& filename);
295 
296  Path source() const;
297  TextureFilter texture_filter() const;
298  TextureWrap wrap_u() const;
299  TextureWrap wrap_v() const;
300  TextureWrap wrap_w() const;
301  MipmapGenerate mipmap_generation() const;
302  TextureFreeData free_data_mode() const;
303 
305  bool on_init() override;
306  void on_clean_up() override;
307 
310  bool has_mipmaps() const;
311 
312  bool auto_upload() const;
313 
315  void _set_renderer_specific_id(const uint32_t id);
316  uint32_t _renderer_specific_id() const;
317 
319  void _set_params_clean();
320 
322  bool _data_dirty() const;
323 
325  void _set_data_clean();
326 
328  bool _params_dirty() const;
329  void _set_has_mipmaps(bool v);
330 
332  uint8_t* _stash_paletted_data();
333 
334 private:
335  Renderer* renderer_ = nullptr;
336 
337  uint16_t width_ = 0;
338  uint16_t height_ = 0;
339 
340  TextureFormat format_ = TEXTURE_FORMAT_RGBA_4UB_8888;
341 
342  Path source_;
343 
344  bool auto_upload_ =
345  true; /* If true, the texture is uploaded by the renderer asap */
346 
347  void resize_data(uint32_t byte_size);
348 
349  bool data_dirty_ = true;
350  uint8_t* data_ = nullptr;
351  uint32_t data_size_ = 0;
352 
353  /* This is used to store the palette, followed by the index data if:
354  * - The format is a paletted format
355  * - OES_compressed_paletted_texture is unsupported.
356  *
357  * If OES_compressed_paletted_texture is supported then paletted data is
358  * uploaded directly. If it is not, then we store the paletted_data here
359  * and keep it resident in RAM so we can update the main data if the palette
360  * changes */
361  uint8_t* paletted_data_ = nullptr;
362 
363  TextureFreeData free_data_mode_ = TEXTURE_FREE_DATA_AFTER_UPLOAD;
364 
365  MipmapGenerate mipmap_generation_ = MIPMAP_GENERATE_COMPLETE;
366  bool has_mipmaps_ = false;
367 
368  bool params_dirty_ = true;
369  TextureFilter filter_ = TEXTURE_FILTER_POINT;
370  TextureWrap wrap_u_ = TEXTURE_WRAP_REPEAT;
371  TextureWrap wrap_v_ = TEXTURE_WRAP_REPEAT;
372  TextureWrap wrap_w_ = TEXTURE_WRAP_REPEAT;
373 
374  uint32_t renderer_id_ = 0;
375 };
376 
377 } // namespace smlt
378 
379 #endif // TEXTURE_H_INCLUDED
smlt::Texture::has_mipmaps
bool has_mipmaps() const
Definition: texture.cpp:769
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:671
smlt::Texture::_set_data_clean
void _set_data_clean()
Definition: texture.cpp:679
smlt::Texture::set_texture_wrap
void set_texture_wrap(TextureWrap wrap_u, TextureWrap wrap_v, TextureWrap wrap_w)
Definition: texture.cpp:683
smlt::Texture::set_free_data_mode
void set_free_data_mode(TextureFreeData mode)
Definition: texture.cpp:656
smlt::Texture::_params_dirty
bool _params_dirty() const
Definition: texture.cpp:667
smlt::RefCounted
Definition: managed.h:71
smlt
Definition: animation.cpp:25
smlt::Texture::flush
void flush()
Definition: texture.cpp:565
smlt::Texture
Definition: texture.h:134
smlt::Texture::BuiltIns
Definition: texture.h:139
smlt::Texture::is_paletted_format
bool is_paletted_format() const
Definition: texture.cpp:178
smlt::generic::Identifiable
Definition: identifiable.h:28
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:675
smlt::Texture::_set_renderer_specific_id
void _set_renderer_specific_id(const uint32_t id)
Definition: texture.cpp:777
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:113
smlt::optional
Definition: optional.h:19
smlt::Texture::on_init
bool on_init() override
Definition: texture.cpp:757
smlt::Pixel::to_format
std::vector< uint8_t > to_format(TextureFormat fmt)
Definition: texture.cpp:804
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:724
smlt::Loadable
Definition: loadable.h:26
smlt::Texture::set_auto_upload
void set_auto_upload(bool v=true)
Definition: texture.cpp:710
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:16
smlt::AssetManager
Definition: asset_manager.h:92
smlt::Texture::is_compressed
bool is_compressed() const
Definition: texture.cpp:579
smlt::Texture::free
void free()
Definition: texture.cpp:551