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_SHADER_MANAGER_HPP 19 #define HEADER_SP_SHADER_MANAGER_HPP 20 21 #include <array> 22 #include <functional> 23 #include <memory> 24 #include <string> 25 #include <typeinfo> 26 #include <typeindex> 27 #include <unordered_map> 28 #include <vector> 29 30 #include "utils/no_copy.hpp" 31 32 class XMLNode; 33 namespace SP 34 { 35 class SPShader; 36 class SPUniformAssigner; 37 38 enum SamplerType: unsigned int; 39 enum RenderPass: unsigned int; 40 41 class SPShaderManager : public NoCopy 42 { 43 public: 44 struct PassInfo 45 { 46 std::function<void()> m_use_function; 47 48 std::function<void()> m_unuse_function; 49 50 std::string m_vertex_shader; 51 52 std::string m_fragment_shader; 53 54 std::string m_skinned_mesh_shader; 55 56 std::vector<std::tuple<std::string, std::string, bool, SamplerType> > 57 m_prefilled_textures; 58 }; 59 60 private: 61 typedef std::vector<std::pair< std::string, std::function<void 62 (SPUniformAssigner*)> > > UniformAssigners; 63 struct ShaderInfo 64 { 65 std::string m_shader_name, m_fallback_name; 66 67 int m_drawing_priority = 0; 68 69 bool m_transparent_shader = false; 70 71 bool m_use_alpha_channel = false; 72 73 bool m_use_tangents = false; 74 75 std::array<bool, 6> m_srgb = 76 {{ 77 true, true, false, false, false, false 78 }}; 79 }; 80 81 static SPShaderManager* m_spsm; 82 83 std::unordered_map<std::string, std::shared_ptr<SPShader> > m_shaders; 84 85 std::vector<std::shared_ptr<SPShader> > m_official_shaders; 86 87 std::unordered_map<std::string, SamplerType> m_official_sampler_types; 88 89 std::unordered_map<std::string, std::function<void(SPUniformAssigner*)> > 90 m_official_uniform_assigner_functions; 91 92 std::unordered_map<std::string, std::function<void()> > 93 m_official_use_functions; 94 95 std::unordered_map<std::string, std::function<void()> > 96 m_official_unuse_functions; 97 98 std::string m_shader_directory; 99 100 // ------------------------------------------------------------------------ 101 std::string getShaderFullPath(const std::string& name); 102 // ------------------------------------------------------------------------ 103 void loadPassInfo(const XMLNode* pass, PassInfo& pi); 104 // ------------------------------------------------------------------------ 105 void loadEachShader(const std::string& file_name); 106 // ------------------------------------------------------------------------ 107 std::shared_ptr<SPShader> buildSPShader(const ShaderInfo& si, 108 const std::array<PassInfo, 2>& pi, 109 const UniformAssigners& ua, 110 bool skinned); 111 112 public: 113 // ------------------------------------------------------------------------ get()114 static SPShaderManager* get() 115 { 116 if (m_spsm == NULL) 117 { 118 m_spsm = new SPShaderManager(); 119 } 120 return m_spsm; 121 } 122 // ------------------------------------------------------------------------ destroy()123 static void destroy() 124 { 125 delete m_spsm; 126 m_spsm = NULL; 127 } 128 // ------------------------------------------------------------------------ 129 static void addPrefilledTexturesToShader(SPShader* s, 130 const std::vector<std::tuple<std::string, std::string, bool, 131 SamplerType> >& t, RenderPass rp); 132 // ------------------------------------------------------------------------ 133 SPShaderManager(); 134 // ------------------------------------------------------------------------ 135 ~SPShaderManager(); 136 // ------------------------------------------------------------------------ getSPShader(const std::string & name)137 std::shared_ptr<SPShader> getSPShader(const std::string& name) 138 { 139 auto ret = m_shaders.find(name); 140 if (ret != m_shaders.end()) 141 { 142 return ret->second; 143 } 144 return NULL; 145 } 146 // ------------------------------------------------------------------------ 147 void loadSPShaders(const std::string& directory_name); 148 // ------------------------------------------------------------------------ addSPShader(const std::string & name,std::shared_ptr<SPShader> shader)149 void addSPShader(const std::string& name, 150 std::shared_ptr<SPShader> shader) 151 { 152 m_shaders[name] = shader; 153 } 154 // ------------------------------------------------------------------------ 155 void unloadAll(); 156 // ------------------------------------------------------------------------ 157 void initAll(); 158 // ------------------------------------------------------------------------ 159 void removeUnusedShaders(); 160 // ------------------------------------------------------------------------ setOfficialShaders()161 void setOfficialShaders() 162 { 163 for (auto& p : m_shaders) 164 { 165 m_official_shaders.push_back(p.second); 166 } 167 } 168 169 }; 170 171 } 172 173 #endif 174