SuperTuxKart
sp_texture.hpp
1 // SuperTuxKart - a fun racing game with go-kart
2 // Copyright (C) 2018 SuperTuxKart-Team
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 3
7 // of the License, or (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, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 #ifndef HEADER_SP_TEXTURE_HPP
19 #define HEADER_SP_TEXTURE_HPP
20 
21 #include "graphics/gl_headers.hpp"
22 #include "utils/log.hpp"
23 #include "utils/no_copy.hpp"
24 
25 #include <atomic>
26 #include <cassert>
27 #include <memory>
28 #include <string>
29 
30 #include <dimension2d.h>
31 
32 namespace irr
33 {
34  namespace video { class IImageLoader; class IImage; }
35 }
36 
37 class Material;
38 
39 using namespace irr;
40 
41 // ----------------------------------------------------------------------------
42 extern "C" void squishCompressImage(uint8_t* rgba, int width, int height,
43  int pitch, void* blocks, unsigned flags);
44 
45 namespace SP
46 {
47 
48 class SPTexture : public NoCopy
49 {
50 private:
51  std::string m_path;
52 
53  std::string m_container_id;
54 
55  GLuint m_texture_name = 0;
56 
57  std::atomic_uint m_width;
58 
59  std::atomic_uint m_height;
60 
61  Material* m_material;
62 
63  const bool m_undo_srgb;
64 
65  // ------------------------------------------------------------------------
66  void generateHQMipmap(void* in,
67  const std::vector<std::pair<core::dimension2du,
68  unsigned> >&, uint8_t* out);
69  // ------------------------------------------------------------------------
70  void generateQuickMipmap(std::shared_ptr<video::IImage> first_image,
71  const std::vector<std::pair<core::dimension2du,
72  unsigned> >&, uint8_t* out);
73  // ------------------------------------------------------------------------
74  std::shared_ptr<video::IImage>
75  getImageFromPath(const std::string& path) const;
76  // ------------------------------------------------------------------------
77  std::shared_ptr<video::IImage> getMask(const core::dimension2du& s) const;
78  // ------------------------------------------------------------------------
79  void applyMask(video::IImage* texture, video::IImage* mask);
80  // ------------------------------------------------------------------------
81  void createTransparent()
82  {
83 #ifndef SERVER_ONLY
84  glBindTexture(GL_TEXTURE_2D, m_texture_name);
85  static uint32_t data[4] = { 0, 0, 0, 0 };
86  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0,
87 #ifdef USE_GLES2
88  GL_RGBA,
89 #else
90  GL_BGRA,
91 #endif
92  GL_UNSIGNED_BYTE, data);
93  glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0,
94 #ifdef USE_GLES2
95  GL_RGBA,
96 #else
97  GL_BGRA,
98 #endif
99  GL_UNSIGNED_BYTE, data);
100  glBindTexture(GL_TEXTURE_2D, 0);
101  m_width.store(2);
102  m_height.store(2);
103 #endif
104  }
105  // ------------------------------------------------------------------------
106  void createWhite(bool private_init = true)
107  {
108 #ifndef SERVER_ONLY
109  glBindTexture(GL_TEXTURE_2D, m_texture_name);
110  static int32_t data[4] = { -1, -1, -1, -1 };
111  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0,
112 #ifdef USE_GLES2
113  GL_RGBA,
114 #else
115  GL_BGRA,
116 #endif
117  GL_UNSIGNED_BYTE, data);
118  glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0,
119 #ifdef USE_GLES2
120  GL_RGBA,
121 #else
122  GL_BGRA,
123 #endif
124  GL_UNSIGNED_BYTE, data);
125  glBindTexture(GL_TEXTURE_2D, 0);
126  if (private_init)
127  {
128  m_width.store(2);
129  m_height.store(2);
130  }
131  else
132  {
133  m_width.store(0);
134  m_height.store(0);
135  }
136 #endif
137  }
138  // ------------------------------------------------------------------------
139  SPTexture(bool white);
140  // ------------------------------------------------------------------------
141  bool texImage2d(std::shared_ptr<video::IImage> texture,
142  std::shared_ptr<video::IImage> mipmaps);
143  // ------------------------------------------------------------------------
144  bool compressedTexImage2d(std::shared_ptr<video::IImage> texture,
145  const std::vector<std::pair<core::dimension2du,
146  unsigned> >& mipmap_sizes);
147  // ------------------------------------------------------------------------
148  bool saveCompressedTexture(std::shared_ptr<video::IImage> texture,
149  const std::vector<std::pair<core::dimension2du,
150  unsigned> >& sizes,
151  const std::string& cache_location);
152  // ------------------------------------------------------------------------
153  std::vector<std::pair<core::dimension2du, unsigned> >
154  compressTexture(std::shared_ptr<video::IImage>& texture);
155  // ------------------------------------------------------------------------
156  bool useTextureCache(const std::string& full_path,
157  const std::string& cache_directory,
158  std::string* cache_loc);
159  // ------------------------------------------------------------------------
160  std::shared_ptr<video::IImage> getTextureCache(const std::string& path,
161  std::vector<std::pair<core::dimension2du, unsigned> >* sizes);
162 
163 public:
164  // ------------------------------------------------------------------------
165  static std::shared_ptr<SPTexture> getWhiteTexture()
166  {
167  SPTexture* tex = new SPTexture(true/*white*/);
168  tex->m_path = "unicolor_white";
169  return std::shared_ptr<SPTexture>(tex);
170  }
171  // ------------------------------------------------------------------------
172  static std::shared_ptr<SPTexture> getTransparentTexture()
173  {
174  SPTexture* tex = new SPTexture(false/*white*/);
175  return std::shared_ptr<SPTexture>(tex);
176  }
177  // ------------------------------------------------------------------------
178  SPTexture(const std::string& path, Material* m, bool undo_srgb,
179  const std::string& container_id);
180  // ------------------------------------------------------------------------
181  ~SPTexture();
182  // ------------------------------------------------------------------------
183  const std::string& getPath() const { return m_path; }
184  // ------------------------------------------------------------------------
185  std::shared_ptr<video::IImage> getTextureImage() const;
186  // ------------------------------------------------------------------------
187  GLuint getTextureHandler() const { return m_texture_name; }
188  // ------------------------------------------------------------------------
189  bool initialized() const
190  { return m_width.load() != 0 && m_height.load() != 0; }
191  // ------------------------------------------------------------------------
192  unsigned getWidth() const { return m_width.load(); }
193  // ------------------------------------------------------------------------
194  unsigned getHeight() const { return m_height.load(); }
195  // ------------------------------------------------------------------------
196  bool threadedLoad(const std::string& cache_directory);
197  // ------------------------------------------------------------------------
198  std::string getCacheDirectory();
199 
200 };
201 
202 }
203 
204 #endif
Definition: material.hpp:48
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:26
Definition: sp_texture.hpp:49