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 namespace SP 42 { 43 44 class SPTexture : public NoCopy 45 { 46 private: 47 std::string m_path; 48 49 std::string m_cache_directory; 50 51 GLuint m_texture_name = 0; 52 53 std::atomic_uint m_width; 54 55 std::atomic_uint m_height; 56 57 Material* m_material; 58 59 const bool m_undo_srgb; 60 61 // ------------------------------------------------------------------------ 62 void squishCompressImage(uint8_t* rgba, int width, int height, int pitch, 63 void* blocks, unsigned flags); 64 // ------------------------------------------------------------------------ 65 void generateHQMipmap(void* in, 66 const std::vector<std::pair<core::dimension2du, 67 unsigned> >&, uint8_t* out); 68 // ------------------------------------------------------------------------ 69 void generateQuickMipmap(std::shared_ptr<video::IImage> first_image, 70 const std::vector<std::pair<core::dimension2du, 71 unsigned> >&, uint8_t* out); 72 // ------------------------------------------------------------------------ 73 std::shared_ptr<video::IImage> 74 getImageFromPath(const std::string& path) const; 75 // ------------------------------------------------------------------------ 76 std::shared_ptr<video::IImage> getMask(const core::dimension2du& s) const; 77 // ------------------------------------------------------------------------ 78 void applyMask(video::IImage* texture, video::IImage* mask); 79 // ------------------------------------------------------------------------ createTransparent()80 void createTransparent() 81 { 82 #ifndef SERVER_ONLY 83 glBindTexture(GL_TEXTURE_2D, m_texture_name); 84 static uint32_t data[4] = { 0, 0, 0, 0 }; 85 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, 86 #ifdef USE_GLES2 87 GL_RGBA, 88 #else 89 GL_BGRA, 90 #endif 91 GL_UNSIGNED_BYTE, data); 92 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, 93 #ifdef USE_GLES2 94 GL_RGBA, 95 #else 96 GL_BGRA, 97 #endif 98 GL_UNSIGNED_BYTE, data); 99 glBindTexture(GL_TEXTURE_2D, 0); 100 m_width.store(2); 101 m_height.store(2); 102 #endif 103 } 104 // ------------------------------------------------------------------------ createWhite(bool private_init=true)105 void createWhite(bool private_init = true) 106 { 107 #ifndef SERVER_ONLY 108 glBindTexture(GL_TEXTURE_2D, m_texture_name); 109 static int32_t data[4] = { -1, -1, -1, -1 }; 110 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, 111 #ifdef USE_GLES2 112 GL_RGBA, 113 #else 114 GL_BGRA, 115 #endif 116 GL_UNSIGNED_BYTE, data); 117 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, 118 #ifdef USE_GLES2 119 GL_RGBA, 120 #else 121 GL_BGRA, 122 #endif 123 GL_UNSIGNED_BYTE, data); 124 glBindTexture(GL_TEXTURE_2D, 0); 125 if (private_init) 126 { 127 m_width.store(2); 128 m_height.store(2); 129 } 130 else 131 { 132 m_width.store(0); 133 m_height.store(0); 134 } 135 #endif 136 } 137 // ------------------------------------------------------------------------ 138 SPTexture(bool white); 139 // ------------------------------------------------------------------------ 140 bool texImage2d(std::shared_ptr<video::IImage> texture, 141 std::shared_ptr<video::IImage> mipmaps); 142 // ------------------------------------------------------------------------ 143 bool compressedTexImage2d(std::shared_ptr<video::IImage> texture, 144 const std::vector<std::pair<core::dimension2du, 145 unsigned> >& mipmap_sizes); 146 // ------------------------------------------------------------------------ 147 bool saveCompressedTexture(std::shared_ptr<video::IImage> texture, 148 const std::vector<std::pair<core::dimension2du, 149 unsigned> >& sizes, 150 const std::string& cache_location); 151 // ------------------------------------------------------------------------ 152 std::vector<std::pair<core::dimension2du, unsigned> > 153 compressTexture(std::shared_ptr<video::IImage> texture); 154 // ------------------------------------------------------------------------ 155 bool useTextureCache(const std::string& full_path, std::string* cache_loc); 156 // ------------------------------------------------------------------------ 157 std::shared_ptr<video::IImage> getTextureCache(const std::string& path, 158 std::vector<std::pair<core::dimension2du, unsigned> >* sizes); 159 160 public: 161 // ------------------------------------------------------------------------ getWhiteTexture()162 static std::shared_ptr<SPTexture> getWhiteTexture() 163 { 164 SPTexture* tex = new SPTexture(true/*white*/); 165 tex->m_path = "unicolor_white"; 166 return std::shared_ptr<SPTexture>(tex); 167 } 168 // ------------------------------------------------------------------------ getTransparentTexture()169 static std::shared_ptr<SPTexture> getTransparentTexture() 170 { 171 SPTexture* tex = new SPTexture(false/*white*/); 172 return std::shared_ptr<SPTexture>(tex); 173 } 174 // ------------------------------------------------------------------------ 175 SPTexture(const std::string& path, Material* m, bool undo_srgb, 176 const std::string& container_id); 177 // ------------------------------------------------------------------------ 178 ~SPTexture(); 179 // ------------------------------------------------------------------------ getPath() const180 const std::string& getPath() const { return m_path; } 181 // ------------------------------------------------------------------------ 182 std::shared_ptr<video::IImage> getTextureImage() const; 183 // ------------------------------------------------------------------------ getOpenGLTextureName() const184 GLuint getOpenGLTextureName() const { return m_texture_name; } 185 // ------------------------------------------------------------------------ initialized() const186 bool initialized() const 187 { return m_width.load() != 0 && m_height.load() != 0; } 188 // ------------------------------------------------------------------------ getWidth() const189 unsigned getWidth() const { return m_width.load(); } 190 // ------------------------------------------------------------------------ getHeight() const191 unsigned getHeight() const { return m_height.load(); } 192 // ------------------------------------------------------------------------ 193 bool threadedLoad(); 194 195 196 }; 197 198 } 199 200 #endif 201