Symphony Of Empires
texture.hpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // texture.hpp
20 //
21 // Abstract:
22 // This file implements a texture which is based from the binary image
23 // class to avoid code repetition. The difference of the texture from the
24 // binary image is that the texture is oriented towards OpenGL rendering
25 // more than the aforementioned binary image. A binary image is usable on
26 // any context but rendering, while the texture is intended to be used in
27 // rendering cases only.
28 // ----------------------------------------------------------------------------
29 
30 #pragma once
31 
32 #include <cstddef>
33 #include <cstdint>
34 #include <string>
35 #include <unordered_map>
36 #include <functional>
37 #include <memory>
38 #include <mutex>
39 
40 #include "eng3d/ttf.hpp"
41 #include "eng3d/binary_image.hpp"
42 #include "eng3d/color.hpp"
43 
44 struct SDL_Surface;
45 namespace Eng3D::IO::Asset {
46  struct Base;
47 }
48 
49 namespace Eng3D {
50  class State;
51  class TextureManager;
52 
54  public:
55  TextureException(const std::string& filename, const std::string& message)
56  : BinaryImageException(filename, message)
57  {
58 
59  }
60  };
61 
63  public:
64  TextureOptions() = default;
65  enum Target {
67  } target = Eng3D::TextureOptions::Target::TEXTURE_2D;
68  enum Wrap {
71  } wrap_s = Eng3D::TextureOptions::Wrap::REPEAT;
72  Wrap wrap_t = Eng3D::TextureOptions::Wrap::REPEAT;
73  enum Filter {
80  } min_filter = Eng3D::TextureOptions::Filter::NEAREST;
81  Filter mag_filter = Eng3D::TextureOptions::Filter::NEAREST;
82  enum Format {
84  RED,
88  } format = Eng3D::TextureOptions::Format::RGBA;
89  Format internal_format = Eng3D::TextureOptions::Format::RGBA;
90  enum Type {
92  } type = Eng3D::TextureOptions::Type::UNSIGNED_BYTE;
93  bool editable = false;
94  bool compressed = true;
95  bool instant_upload = false; // Has to be uploaded immediately and not async
96 
97  constexpr bool operator==(const TextureOptions& o) const {
98  return target == o.target && wrap_s == o.wrap_s && wrap_t == o.wrap_t && min_filter == o.min_filter && mag_filter == o.mag_filter && internal_format == o.internal_format && format == o.format && type == o.type && editable == o.editable;
99  }
100  };
102 
103  class Texture: public Eng3D::BinaryImage {
104  void _upload(TextureOptions options = default_options);
105  void _upload(SDL_Surface* surface);
106  public:
107  Texture() = default;
108  Texture(const std::string& path)
109  : Eng3D::BinaryImage(path)
110  {
111 
112  }
114  : Eng3D::BinaryImage((asset == nullptr) ? "" : asset->abs_path)
115  {
116 
117  }
118  Texture(size_t _width, size_t _height, size_t _bpp = 32)
119  : Eng3D::BinaryImage(_width, _height, _bpp)
120  {
121 
122  }
123  ~Texture() override;
124  void create_dummy();
125 
129  this->_upload(options); // Do upload instantly
130  }
131 
136  void upload(SDL_Surface* surface) {
137  this->_upload(surface);
138  }
139 
140  void gen_mipmaps() const;
141  void bind() const;
142  void delete_gputex();
143  void guillotine(const Eng3D::Texture& map, int x, int y, int w, int h);
144  void to_file(const std::string& filename) override;
145 
146  unsigned int id = 0;
147  bool managed = false;
148  friend class Eng3D::TextureManager;
149  };
150 
151  // Array of textures
153  public:
154  TextureArray(const std::string& path, size_t _tiles_x, size_t _tiles_y)
155  : Eng3D::BinaryImage(path),
156  tiles_x{ _tiles_x },
157  tiles_y{ _tiles_y }
158  {
159 
160  }
161 
162  void upload();
163  size_t layers;
164  size_t tiles_x, tiles_y;
165  unsigned int id = 0;
166  };
167 
168  template <class T>
169  inline void hash_combine(std::size_t& s, const T& v) {
170  std::hash<T> h;
171  s ^= h(v) + 0x9e3779b9 + (s << 6) + (s >> 2);
172  }
173 
175  struct TextureMapHash {
176  inline std::size_t operator()(const std::pair<std::string, TextureOptions>& key) const {
177  std::size_t res = 0;
178  hash_combine(res, key.first);
179  TextureOptions s = key.second;
180  hash_combine(res, s.target);
181  hash_combine(res, s.wrap_s);
182  hash_combine(res, s.wrap_t);
183  hash_combine(res, s.min_filter);
184  hash_combine(res, s.mag_filter);
186  hash_combine(res, s.format);
187  hash_combine(res, s.type);
188  hash_combine(res, s.editable);
189  return res;
190  }
191  };
192 
194  public:
197  SDL_Surface* surface = nullptr;
198  };
199 
203  private:
204  std::unordered_map<std::pair<std::string, TextureOptions>, std::shared_ptr<Eng3D::Texture>, TextureMapHash> textures;
205  std::vector<TextureUploadRequest> unuploaded_textures; // Textures that needs to be uploaded
206  std::mutex unuploaded_lock;
207  std::shared_ptr<Eng3D::Texture> white;
210  std::unordered_map<std::string, std::shared_ptr<Eng3D::Texture>> text_textures;
211  Eng3D::State& s;
212  public:
213  TextureManager() = delete;
215  : s{ _s }
216  {
217 
218  }
219  ~TextureManager();
220  std::shared_ptr<Eng3D::Texture> load(const std::string& path, TextureOptions options = default_options);
221  std::shared_ptr<Eng3D::Texture> load(std::shared_ptr<Eng3D::IO::Asset::Base> asset, TextureOptions options = default_options);
222  std::shared_ptr<Eng3D::Texture> gen_text(Eng3D::TrueType::Font& font, Eng3D::Color color, const std::string& msg);
223  std::shared_ptr<Eng3D::Texture> get_white();
224 
225  friend class Eng3D::Texture;
226  };
227 }
TextureArray(const std::string &path, size_t _tiles_x, size_t _tiles_y)
Definition: texture.hpp:154
void upload()
Uploads the TextureArray to the driver.
Definition: texture.cpp:370
TextureException(const std::string &filename, const std::string &message)
Definition: texture.hpp:55
void bind() const
Binds the texture to the current OpenGL context.
Definition: texture.cpp:332
void to_file(const std::string &filename) override
Definition: texture.cpp:350
void create_dummy()
This dummy texture helps to avoid crashes due to missing buffers or so, and also gives visual aid of ...
Definition: texture.cpp:64
void upload(SDL_Surface *surface)
Uploads a text texture (shceduled or not) if it's scheduled, the surface is handed ownership over to ...
Definition: texture.hpp:136
Texture(const std::string &path)
Definition: texture.hpp:108
void upload(TextureOptions options=default_options)
Frontend for uploading (schedules or instantly uploads)
Definition: texture.hpp:128
Texture(const Eng3D::IO::Asset::Base *asset)
Definition: texture.hpp:113
Texture()=default
Texture(size_t _width, size_t _height, size_t _bpp=32)
Definition: texture.hpp:118
void delete_gputex()
Deletes the OpenGL representation of this texture.
Definition: texture.cpp:339
~Texture() override
Definition: texture.cpp:46
void guillotine(const Eng3D::Texture &map, int x, int y, int w, int h)
void gen_mipmaps() const
Definition: texture.cpp:324
General manager for textures, caches textures into the memory instead of reading them off the disk ev...
Definition: texture.hpp:202
TextureManager(Eng3D::State &_s)
Definition: texture.hpp:214
std::shared_ptr< Eng3D::Texture > load(const std::string &path, TextureOptions options=default_options)
Finds a texture in the list of a texture manager if the texture is already in the list we load the sa...
Definition: texture.cpp:432
std::shared_ptr< Eng3D::Texture > get_white()
Definition: texture.cpp:417
std::shared_ptr< Eng3D::Texture > gen_text(Eng3D::TrueType::Font &font, Eng3D::Color color, const std::string &msg)
Definition: texture.cpp:458
enum Eng3D::TextureOptions::Filter min_filter
enum Eng3D::TextureOptions::Target target
enum Eng3D::TextureOptions::Wrap wrap_s
constexpr bool operator==(const TextureOptions &o) const
Definition: texture.hpp:97
enum Eng3D::TextureOptions::Type type
enum Eng3D::TextureOptions::Format format
TextureOptions options
Definition: texture.hpp:196
const TextureOptions default_options
Definition: texture.hpp:101
void hash_combine(std::size_t &s, const T &v)
Definition: texture.hpp:169
This binary image class helps load images and visual resources from the disk; the binary image IS NOT...
Primitive color type used through the engine.
Definition: color.hpp:32
Texture map has implementation.
Definition: texture.hpp:175
std::size_t operator()(const std::pair< std::string, TextureOptions > &key) const
Definition: texture.hpp:176