From 4aa31dc56e667e5ddf7243b90c5f4fd0b319a73e Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 25 Dec 2016 20:21:00 -0500 Subject: [PATCH 01/13] First attempt at #2316. WIP, issues remains --- src/graphics/material.cpp | 33 ++++++++++++++++++++++++++++++- src/graphics/material.hpp | 11 +++-------- src/graphics/material_manager.cpp | 12 +++++++++-- src/items/attachment_manager.hpp | 2 +- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 0d06343b4..8fe20bdb8 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -398,8 +398,30 @@ Material::Material(const XMLNode *node, bool deprecated) if(m_has_gravity) m_high_tire_adhesion = true; - install(/*is_full_path*/false); + //Log::info("Material", "setting for lazy load: '%s' '%s'", m_full_path.c_str(), m_texname.c_str()); + + //install(/*is_full_path*/false); + // now set the name to the basename, so that all tests work as expected + + //m_full_path = file_manager->searchTexture(m_texname); + //m_texname = StringUtils::getBasename(m_full_path); } // Material +//----------------------------------------------------------------------------- + +video::ITexture* Material::getTexture() +{ + // Note that dont load means that the textures are not loaded + // via the material. So getTexture should only get called for + // automatically loaded textures (used atm for font textures). + assert(!m_dont_load_texture); + if (!m_installed) + { + //m_texname = m_full_path; + Log::info("Material", "LazyLoading (getTexture) '%s'", m_texname.c_str()); + install(/*is_full_path*/true, true); + } + return m_texture; +} // getTexture //----------------------------------------------------------------------------- /** Create a standard material using the default settings for materials. @@ -476,6 +498,8 @@ void Material::install(bool is_full_path, bool complain_if_not_found) // Don't load a texture that are not supposed to be loaded automatically if(m_dont_load_texture) return; + m_installed = true; + const std::string &full_path = is_full_path ? m_texname : file_manager->searchTexture(m_texname); @@ -708,6 +732,13 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con */ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb) { + if (!m_installed) + { + //Log::info("Material", "LazyLoading (setMaterialProperties) '%s' : '%s'", m_texname.c_str(), m_full_path.c_str()); + install(/*is_full_path*/true, true); + } + //Log::info("Material", "setMaterialProperties '%s'", m_texname.c_str()); + if (m_deprecated || (m->getTexture(0) != NULL && ((core::stringc)m->getTexture(0)->getName()).find("deprecated") != -1)) diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index f45196fc3..5500d733d 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -268,6 +268,8 @@ private: bool m_deprecated; + bool m_installed = false; + void init (); void install (bool is_full_path=false, bool complain_if_not_found=true); void initCustomSFX(const XMLNode *sfx); @@ -290,14 +292,7 @@ public: void isInitiallyHidden(scene::IMeshBuffer* who); /** Returns the ITexture associated with this material. */ - video::ITexture *getTexture() const - { - // Note that dont load means that the textures are not loaded - // via the material. So getTexture should only get called for - // automatically loaded textures (used atm for font textures). - assert(!m_dont_load_texture); - return m_texture; - } // getTexture + video::ITexture *getTexture(); // ------------------------------------------------------------------------ bool isIgnore () const { return m_ignore; } // ------------------------------------------------------------------------ diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 1082f9677..49ee40483 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -86,13 +86,20 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, return getDefaultMaterial(material_type); core::stringc img_path = core::stringc(t->getName()); + img_path.make_lower(); + const std::string image = StringUtils::getBasename(img_path.c_str()); if (!img_path.empty() && (img_path.findFirst('/') != -1 || img_path.findFirst('\\') != -1)) { // Search backward so that temporary (track) textures are found first for (int i = (int)m_materials.size() - 1; i >= 0; i--) { - if (m_materials[i]->getTexFullPath() == img_path.c_str()) + //Log::info("DEBUG_TEX", "<%s> <%s>", m_materials[i]->getTexFullPath().c_str(), img_path.c_str()); + core::stringc fullpath = core::stringc(m_materials[i]->getTexFullPath().c_str()); + fullpath.make_lower(); + //if (fullpath.find("bumpy") > 0) + // Log::info("DEBUG_TEX", "<%s> <%s>", fullpath.c_str(), img_path.c_str()); + if (fullpath == img_path.c_str()) { return m_materials[i]; } @@ -102,6 +109,7 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, { for (int i = (int)m_materials.size() - 1; i >= 0; i--) { + //Log::info("DEBUG_TEX2", "<%s> <%s>", m_materials[i]->getTexFname().c_str(), image.c_str()); if (m_materials[i]->getTexFname() == image) { return m_materials[i]; @@ -139,7 +147,7 @@ Material* MaterialManager::getDefaultMaterial(video::E_MATERIAL_TYPE shader_type auto it = m_default_materials.find(shader_type); if (it == m_default_materials.end()) { - Material* default_material = new Material("", false, false, false); + Material* default_material = new Material("Default", false, false, false); // TODO: workaround, should not hardcode these material types here? // Try to find a cleaner way diff --git a/src/items/attachment_manager.hpp b/src/items/attachment_manager.hpp index ec4b4a296..cd99106a1 100644 --- a/src/items/attachment_manager.hpp +++ b/src/items/attachment_manager.hpp @@ -49,7 +49,7 @@ public: // ------------------------------------------------------------------------ /** Returns the icon to display in the race gui if a kart * has an attachment. */ - const Material* getIcon (int type) const {return m_all_icons [type]; } + Material* getIcon (int type) const { return m_all_icons [type]; } // ------------------------------------------------------------------------ }; From 059c2c8573869f2f31a9e3fd10e0a6191f892d48 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 25 Dec 2016 22:00:11 -0500 Subject: [PATCH 02/13] Bugfix delayed-loaded textures bug --- src/graphics/material_manager.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 49ee40483..8b739a7d0 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -88,7 +88,6 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, core::stringc img_path = core::stringc(t->getName()); img_path.make_lower(); - const std::string image = StringUtils::getBasename(img_path.c_str()); if (!img_path.empty() && (img_path.findFirst('/') != -1 || img_path.findFirst('\\') != -1)) { // Search backward so that temporary (track) textures are found first @@ -107,10 +106,15 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, } else { + core::stringc image(StringUtils::getBasename(img_path.c_str()).c_str()); + image.make_lower(); + for (int i = (int)m_materials.size() - 1; i >= 0; i--) { //Log::info("DEBUG_TEX2", "<%s> <%s>", m_materials[i]->getTexFname().c_str(), image.c_str()); - if (m_materials[i]->getTexFname() == image) + core::stringc texfname(m_materials[i]->getTexFname().c_str()); + texfname.make_lower(); + if (texfname == image) { return m_materials[i]; } @@ -347,10 +351,16 @@ Material *MaterialManager::getMaterial(const std::string& fname, else basename = fname; + core::stringc basename_lower(basename.c_str()); + basename_lower.make_lower(); + // Search backward so that temporary (track) textures are found first - for(int i = (int)m_materials.size()-1; i>=0; i-- ) + for (int i = (int)m_materials.size()-1; i>=0; i-- ) { - if(m_materials[i]->getTexFname()==basename) return m_materials[i]; + core::stringc fname(m_materials[i]->getTexFname().c_str()); + fname.make_lower(); + if (fname == basename_lower) + return m_materials[i]; } // Add the new material From 2b34dd841045c84da8fdf2d6892141f1a5ee9c34 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 25 Dec 2016 22:21:41 -0500 Subject: [PATCH 03/13] More cleanup and bugfixing related to #2316 --- src/graphics/material.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 8fe20bdb8..a0a510435 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -397,14 +397,6 @@ Material::Material(const XMLNode *node, bool deprecated) if(m_has_gravity) m_high_tire_adhesion = true; - - //Log::info("Material", "setting for lazy load: '%s' '%s'", m_full_path.c_str(), m_texname.c_str()); - - //install(/*is_full_path*/false); - // now set the name to the basename, so that all tests work as expected - - //m_full_path = file_manager->searchTexture(m_texname); - //m_texname = StringUtils::getBasename(m_full_path); } // Material //----------------------------------------------------------------------------- @@ -416,8 +408,6 @@ video::ITexture* Material::getTexture() assert(!m_dont_load_texture); if (!m_installed) { - //m_texname = m_full_path; - Log::info("Material", "LazyLoading (getTexture) '%s'", m_texname.c_str()); install(/*is_full_path*/true, true); } return m_texture; @@ -496,7 +486,8 @@ void Material::init() void Material::install(bool is_full_path, bool complain_if_not_found) { // Don't load a texture that are not supposed to be loaded automatically - if(m_dont_load_texture) return; + if (m_dont_load_texture) return; + if (m_installed) return; m_installed = true; @@ -525,9 +516,11 @@ void Material::install(bool is_full_path, bool complain_if_not_found) if (m_mask.size() > 0) { + m_texture->grab(); video::ITexture* tex = irr_driver->applyMask(m_texture, m_mask); if (tex) { + // TODO irr_driver->removeTexture(m_texture); m_texture = tex; } @@ -546,8 +539,11 @@ Material::~Material() if (m_texture != NULL) { m_texture->drop(); - if(m_texture->getReferenceCount()==1) + if (m_texture->getReferenceCount() == 1) + { irr_driver->removeTexture(m_texture); + m_texture = NULL; + } } // If a special sfx is installed (that isn't part of stk itself), the @@ -734,10 +730,8 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m { if (!m_installed) { - //Log::info("Material", "LazyLoading (setMaterialProperties) '%s' : '%s'", m_texname.c_str(), m_full_path.c_str()); install(/*is_full_path*/true, true); } - //Log::info("Material", "setMaterialProperties '%s'", m_texname.c_str()); if (m_deprecated || (m->getTexture(0) != NULL && From 46e7b5ac773fa0f89c77c99777cbf73bbea8cef3 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Sun, 25 Dec 2016 22:27:46 -0500 Subject: [PATCH 04/13] Try to fix build --- src/graphics/material.cpp | 3 ++- src/graphics/material.hpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index a0a510435..6484bb155 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -59,6 +59,7 @@ Material::Material(const XMLNode *node, bool deprecated) { m_shader_type = SHADERTYPE_SOLID; m_deprecated = deprecated; + m_installed = false; node->get("name", &m_texname); if (m_texname=="") @@ -422,7 +423,7 @@ Material::Material(const std::string& fname, bool is_full_path, bool complain_if_not_found, bool load_texture) { m_deprecated = false; - + m_installed = false; m_texname = fname; init(); m_full_path = file_manager->getFileSystem()->getAbsolutePath( diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 5500d733d..b15cbafee 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -268,7 +268,7 @@ private: bool m_deprecated; - bool m_installed = false; + bool m_installed; void init (); void install (bool is_full_path=false, bool complain_if_not_found=true); From 943373ea8ef0a28e3f394bf665cf6726115a71a6 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Mon, 26 Dec 2016 22:33:54 -0500 Subject: [PATCH 05/13] Try cleaning up textures when unloading tracks. Crashes at this time, more debugging is required --- src/graphics/material.cpp | 27 +++++++++++++++++---------- src/graphics/material.hpp | 2 ++ src/graphics/material_manager.cpp | 10 ++++++++++ src/graphics/material_manager.hpp | 2 ++ src/modes/world.cpp | 2 ++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 6484bb155..abf6d2937 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -521,7 +521,6 @@ void Material::install(bool is_full_path, bool complain_if_not_found) video::ITexture* tex = irr_driver->applyMask(m_texture, m_mask); if (tex) { - // TODO irr_driver->removeTexture(m_texture); m_texture = tex; } @@ -537,15 +536,7 @@ void Material::install(bool is_full_path, bool complain_if_not_found) //----------------------------------------------------------------------------- Material::~Material() { - if (m_texture != NULL) - { - m_texture->drop(); - if (m_texture->getReferenceCount() == 1) - { - irr_driver->removeTexture(m_texture); - m_texture = NULL; - } - } + unloadTexture(); // If a special sfx is installed (that isn't part of stk itself), the // entry needs to be removed from the sfx_manager's mapping, since other @@ -556,6 +547,22 @@ Material::~Material() } } // ~Material +//----------------------------------------------------------------------------- + +void Material::unloadTexture() +{ + if (m_texture != NULL) + { + m_texture->drop(); + if (m_texture->getReferenceCount() == 1) + { + irr_driver->removeTexture(m_texture); + } + m_texture = NULL; + m_installed = false; + } +} + //----------------------------------------------------------------------------- /** Initialise the data structures for a custom sfx to be played when a * kart is driving on that particular material. diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index b15cbafee..20c764918 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -283,6 +283,8 @@ public: bool load_texture = true); ~Material (); + void unloadTexture(); + void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const; void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb); void adjustForFog(scene::ISceneNode* parent, video::SMaterial *m, diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 8b739a7d0..dfb3db7f8 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -383,6 +383,16 @@ void MaterialManager::makeMaterialsPermanent() m_shared_material_index = (int) m_materials.size(); } // makeMaterialsPermanent +// ---------------------------------------------------------------------------- + +void MaterialManager::unloadAllTextures() +{ + for (int i = 0; i < m_shared_material_index; i++) + { + m_materials[i]->unloadTexture(); + } +} + // ---------------------------------------------------------------------------- bool MaterialManager::hasMaterial(const std::string& fname) { diff --git a/src/graphics/material_manager.hpp b/src/graphics/material_manager.hpp index 79cff15ad..6f3a7f0a3 100644 --- a/src/graphics/material_manager.hpp +++ b/src/graphics/material_manager.hpp @@ -83,6 +83,8 @@ public: void makeMaterialsPermanent(); bool hasMaterial(const std::string& fname); + void unloadAllTextures(); + Material* getLatestMaterial() { return m_materials[m_materials.size()-1]; } }; // MaterialManager diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 2522369dd..1d2798cfe 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -28,6 +28,7 @@ #include "graphics/camera.hpp" #include "graphics/irr_driver.hpp" #include "graphics/material.hpp" +#include "graphics/material_manager.hpp" #include "graphics/render_info.hpp" #include "io/file_manager.hpp" #include "input/device_manager.hpp" @@ -430,6 +431,7 @@ Controller* World::loadAIController(AbstractKart *kart) //----------------------------------------------------------------------------- World::~World() { + material_manager->unloadAllTextures(); RewindManager::destroy(); irr_driver->onUnloadWorld(); From 0be858f7f88c6015e9825fd030df7a6cb7b91808 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Mon, 26 Dec 2016 23:03:22 -0500 Subject: [PATCH 06/13] Fix crash in texture cleanup branch --- src/graphics/material_manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index dfb3db7f8..3b3cac772 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -387,9 +387,11 @@ void MaterialManager::makeMaterialsPermanent() void MaterialManager::unloadAllTextures() { + std::string texture_folder = file_manager->getAssetDirectory(FileManager::TEXTURE); for (int i = 0; i < m_shared_material_index; i++) { - m_materials[i]->unloadTexture(); + if (m_materials[i]->getTexFullPath().find(texture_folder) != std::string::npos) + m_materials[i]->unloadTexture(); } } From 5e415e333105497cc4810e7e3f60d6cf72605b10 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Tue, 27 Dec 2016 22:08:27 -0500 Subject: [PATCH 07/13] Install all materials before loading meshes --- src/graphics/material.cpp | 4 +++- src/graphics/material.hpp | 4 ++-- src/graphics/material_manager.cpp | 12 ++++++++++++ src/graphics/material_manager.hpp | 1 + src/tracks/track.cpp | 4 ++++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index abf6d2937..677d42d6b 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -518,10 +518,12 @@ void Material::install(bool is_full_path, bool complain_if_not_found) if (m_mask.size() > 0) { m_texture->grab(); + irr_driver->removeTexture(m_texture); video::ITexture* tex = irr_driver->applyMask(m_texture, m_mask); if (tex) { - irr_driver->removeTexture(m_texture); + // TODO: cleanup + //m_texture->drop(); m_texture = tex; } else diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 20c764918..746f8c435 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -271,7 +271,6 @@ private: bool m_installed; void init (); - void install (bool is_full_path=false, bool complain_if_not_found=true); void initCustomSFX(const XMLNode *sfx); void initParticlesEffect(const XMLNode *node); @@ -283,7 +282,8 @@ public: bool load_texture = true); ~Material (); - void unloadTexture(); + void install(bool is_full_path = false, bool complain_if_not_found = true); + void unloadTexture(); void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const; void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb); diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 3b3cac772..0b711c78a 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -395,6 +395,18 @@ void MaterialManager::unloadAllTextures() } } +// ---------------------------------------------------------------------------- + +void MaterialManager::installAllTextures() +{ + std::string texture_folder = file_manager->getAssetDirectory(FileManager::TEXTURE); + for (int i = 0; i < m_shared_material_index; i++) + { + if (m_materials[i]->getTexFullPath().find(texture_folder) != std::string::npos) + m_materials[i]->install(true, true); + } +} + // ---------------------------------------------------------------------------- bool MaterialManager::hasMaterial(const std::string& fname) { diff --git a/src/graphics/material_manager.hpp b/src/graphics/material_manager.hpp index 6f3a7f0a3..b8d2bb0e7 100644 --- a/src/graphics/material_manager.hpp +++ b/src/graphics/material_manager.hpp @@ -83,6 +83,7 @@ public: void makeMaterialsPermanent(); bool hasMaterial(const std::string& fname); + void installAllTextures(); void unloadAllTextures(); Material* getLatestMaterial() { return m_materials[m_materials.size()-1]; } diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 6218111b8..4b256479b 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1645,10 +1645,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) { if(!m_materials_loaded) material_manager->addSharedMaterial(materials_file); + material_manager->installAllTextures(); m_materials_loaded = true; } else + { material_manager->pushTempMaterial(materials_file); + material_manager->installAllTextures(); + } } catch (std::exception& e) { From ffe4dd88b4a681a62ff7797794cf26aa5f2940b5 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 28 Dec 2016 15:32:27 +0800 Subject: [PATCH 08/13] Apply mask directly on texture Avoiding the ref counting issues --- lib/irrlicht/source/Irrlicht/COGLES2Texture.h | 7 +++ lib/irrlicht/source/Irrlicht/COpenGLTexture.h | 7 +++ src/graphics/irr_driver.cpp | 47 ++++++++++++++----- src/graphics/irr_driver.hpp | 2 +- src/graphics/material.cpp | 15 +----- src/graphics/material.hpp | 4 +- src/graphics/material_manager.cpp | 12 ----- src/graphics/material_manager.hpp | 1 - src/items/attachment_manager.cpp | 1 + src/items/attachment_manager.hpp | 2 +- src/states_screens/race_gui.cpp | 1 + src/states_screens/race_gui_overworld.cpp | 1 + src/tracks/track.cpp | 4 -- 13 files changed, 56 insertions(+), 48 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/COGLES2Texture.h b/lib/irrlicht/source/Irrlicht/COGLES2Texture.h index 18be0d044..7782b361c 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2Texture.h +++ b/lib/irrlicht/source/Irrlicht/COGLES2Texture.h @@ -109,6 +109,13 @@ public: //! Get an access to texture states cache. SStatesCache& getStatesCache() const; + void setImage(IImage* new_image) + { + if (Image) + Image->drop(); + Image = new_image; + } + protected: //! protected constructor with basic setup, no GL texture name created, for derived classes diff --git a/lib/irrlicht/source/Irrlicht/COpenGLTexture.h b/lib/irrlicht/source/Irrlicht/COpenGLTexture.h index 5d3de4e90..8ec232ef7 100644 --- a/lib/irrlicht/source/Irrlicht/COpenGLTexture.h +++ b/lib/irrlicht/source/Irrlicht/COpenGLTexture.h @@ -103,6 +103,13 @@ public: //! sets whether this texture is intended to be used as a render target. void setIsRenderTarget(bool isTarget); + void setImage(IImage* new_image) + { + if (Image) + Image->drop(); + Image = new_image; + } + protected: //! protected constructor with basic setup, no GL texture name created, for derived classes diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 7b2013a7f..33e4269b3 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -65,6 +65,11 @@ #include "utils/vs.hpp" #include +#if defined(USE_GLES2) +#include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h" +#else +#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" +#endif /* Build-time check that the Irrlicht we're building against works for us. * Should help prevent distros building against an incompatible library. @@ -1818,8 +1823,8 @@ void IrrDriver::dropAllTextures(const scene::IMesh *mesh) } // dropAllTextures // ---------------------------------------------------------------------------- -video::ITexture* IrrDriver::applyMask(video::ITexture* texture, - const std::string& mask_path) +void IrrDriver::applyMask(video::ITexture* texture, + const std::string& mask_path) { video::IImage* img = m_video_driver->createImage(texture, core::position2d(0,0), @@ -1828,9 +1833,15 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture, video::IImage* mask = m_video_driver->createImageFromFile(mask_path.c_str()); - if (img == NULL || mask == NULL) return NULL; + if (img == NULL || mask == NULL) + { + Log::warn("irr_driver", "Applying mask failed for '%s'!", + core::stringc(texture->getName()).c_str()); + return; + } - if (img->lock() && mask->lock()) + void* dest = img->lock(); + if (dest != NULL && mask->lock()) { core::dimension2d dim = img->getDimension(); for (unsigned int x = 0; x < dim.Width; x++) @@ -1844,20 +1855,30 @@ video::ITexture* IrrDriver::applyMask(video::ITexture* texture, } // for y } // for x + if (!CVS->isGLSL()) + { + // For new graphical pipeline, it will be done in texture manager + // compressTexture + glBindTexture(GL_TEXTURE_2D, getTextureGLuint(texture)); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dim.Width, dim.Height, + GL_BGRA, GL_UNSIGNED_BYTE, dest); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } mask->unlock(); img->unlock(); +#if defined(USE_GLES2) + static_cast(texture)->setImage(img); +#else + static_cast(texture)->setImage(img); +#endif + mask->drop(); + return; } - else - { - return NULL; - } - - std::string base = - StringUtils::getBasename(texture->getName().getPath().c_str()); - video::ITexture *t = m_video_driver->addTexture(base.c_str(),img, NULL); + Log::warn("irr_driver", "Applying mask failed for '%s'!", + core::stringc(texture->getName()).c_str()); img->drop(); mask->drop(); - return t; } // applyMask // ---------------------------------------------------------------------------- diff --git a/src/graphics/irr_driver.hpp b/src/graphics/irr_driver.hpp index 4d40d8b46..2a36993f1 100644 --- a/src/graphics/irr_driver.hpp +++ b/src/graphics/irr_driver.hpp @@ -220,7 +220,7 @@ public: void setAllMaterialFlags(scene::IMesh *mesh) const; scene::IAnimatedMesh *getAnimatedMesh(const std::string &name); scene::IMesh *getMesh(const std::string &name); - video::ITexture *applyMask(video::ITexture* texture, + void applyMask(video::ITexture* texture, const std::string& mask_path); void displayFPS(); bool OnEvent(const irr::SEvent &event); diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 677d42d6b..81569a132 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -517,20 +517,7 @@ void Material::install(bool is_full_path, bool complain_if_not_found) if (m_mask.size() > 0) { - m_texture->grab(); - irr_driver->removeTexture(m_texture); - video::ITexture* tex = irr_driver->applyMask(m_texture, m_mask); - if (tex) - { - // TODO: cleanup - //m_texture->drop(); - m_texture = tex; - } - else - { - Log::warn("material", "Applying mask failed for '%s'!", - m_texname.c_str()); - } + irr_driver->applyMask(m_texture, m_mask); } m_texture->grab(); } // install diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 746f8c435..20c764918 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -271,6 +271,7 @@ private: bool m_installed; void init (); + void install (bool is_full_path=false, bool complain_if_not_found=true); void initCustomSFX(const XMLNode *sfx); void initParticlesEffect(const XMLNode *node); @@ -282,8 +283,7 @@ public: bool load_texture = true); ~Material (); - void install(bool is_full_path = false, bool complain_if_not_found = true); - void unloadTexture(); + void unloadTexture(); void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const; void setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb); diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 0b711c78a..3b3cac772 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -395,18 +395,6 @@ void MaterialManager::unloadAllTextures() } } -// ---------------------------------------------------------------------------- - -void MaterialManager::installAllTextures() -{ - std::string texture_folder = file_manager->getAssetDirectory(FileManager::TEXTURE); - for (int i = 0; i < m_shared_material_index; i++) - { - if (m_materials[i]->getTexFullPath().find(texture_folder) != std::string::npos) - m_materials[i]->install(true, true); - } -} - // ---------------------------------------------------------------------------- bool MaterialManager::hasMaterial(const std::string& fname) { diff --git a/src/graphics/material_manager.hpp b/src/graphics/material_manager.hpp index b8d2bb0e7..6f3a7f0a3 100644 --- a/src/graphics/material_manager.hpp +++ b/src/graphics/material_manager.hpp @@ -83,7 +83,6 @@ public: void makeMaterialsPermanent(); bool hasMaterial(const std::string& fname); - void installAllTextures(); void unloadAllTextures(); Material* getLatestMaterial() { return m_materials[m_materials.size()-1]; } diff --git a/src/items/attachment_manager.cpp b/src/items/attachment_manager.cpp index 8c3c54cc3..1238d36d7 100644 --- a/src/items/attachment_manager.cpp +++ b/src/items/attachment_manager.cpp @@ -19,6 +19,7 @@ #include "items/attachment_manager.hpp" #include "graphics/irr_driver.hpp" +#include "graphics/material.hpp" #include "graphics/material_manager.hpp" #include "io/file_manager.hpp" diff --git a/src/items/attachment_manager.hpp b/src/items/attachment_manager.hpp index cd99106a1..c5d827ed7 100644 --- a/src/items/attachment_manager.hpp +++ b/src/items/attachment_manager.hpp @@ -23,8 +23,8 @@ namespace irr { namespace scene { class IAnimatedMesh; } } +class Material; -#include "graphics/material.hpp" #include "items/attachment.hpp" #include "utils/no_copy.hpp" diff --git a/src/states_screens/race_gui.cpp b/src/states_screens/race_gui.cpp index 50153aa40..78cfc0fe9 100644 --- a/src/states_screens/race_gui.cpp +++ b/src/states_screens/race_gui.cpp @@ -31,6 +31,7 @@ using namespace irr; #include "graphics/glwrap.hpp" #endif #include "graphics/irr_driver.hpp" +#include "graphics/material.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/states_screens/race_gui_overworld.cpp b/src/states_screens/race_gui_overworld.cpp index e20452024..5ffb1f81f 100644 --- a/src/states_screens/race_gui_overworld.cpp +++ b/src/states_screens/race_gui_overworld.cpp @@ -29,6 +29,7 @@ #include "graphics/glwrap.hpp" #endif #include "graphics/irr_driver.hpp" +#include "graphics/material.hpp" #include "graphics/material_manager.hpp" #include "guiengine/engine.hpp" #include "guiengine/modaldialog.hpp" diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index 4b256479b..6218111b8 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1645,14 +1645,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id) { if(!m_materials_loaded) material_manager->addSharedMaterial(materials_file); - material_manager->installAllTextures(); m_materials_loaded = true; } else - { material_manager->pushTempMaterial(materials_file); - material_manager->installAllTextures(); - } } catch (std::exception& e) { From f43f76b7c9a6cf8ec23c2481ec83805c48cc0b42 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 28 Dec 2016 15:40:12 +0800 Subject: [PATCH 09/13] Fix server build --- src/graphics/irr_driver.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 33e4269b3..21b136ee9 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1826,6 +1826,7 @@ void IrrDriver::dropAllTextures(const scene::IMesh *mesh) void IrrDriver::applyMask(video::ITexture* texture, const std::string& mask_path) { +#ifndef SERVER_ONLY video::IImage* img = m_video_driver->createImage(texture, core::position2d(0,0), texture->getSize()); @@ -1879,6 +1880,7 @@ void IrrDriver::applyMask(video::ITexture* texture, core::stringc(texture->getName()).c_str()); img->drop(); mask->drop(); +#endif } // applyMask // ---------------------------------------------------------------------------- From 72963f4fb4326c549e9a9b2c0d9630da546791ea Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 28 Dec 2016 16:23:57 +0800 Subject: [PATCH 10/13] Fix GLES --- src/graphics/irr_driver.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 21b136ee9..61b2d76f5 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -66,6 +66,7 @@ #include #if defined(USE_GLES2) +#define _IRR_COMPILE_WITH_OGLES2_ #include "../../lib/irrlicht/source/Irrlicht/COGLES2Texture.h" #else #include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h" From 1597c2ad48858d448e70575a07d40d5f7486c310 Mon Sep 17 00:00:00 2001 From: Benau Date: Thu, 29 Dec 2016 00:36:13 +0800 Subject: [PATCH 11/13] Make scaled texture work with alpha mask --- src/graphics/irr_driver.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/graphics/irr_driver.cpp b/src/graphics/irr_driver.cpp index 61b2d76f5..b0bdde7d4 100644 --- a/src/graphics/irr_driver.cpp +++ b/src/graphics/irr_driver.cpp @@ -1828,9 +1828,9 @@ void IrrDriver::applyMask(video::ITexture* texture, const std::string& mask_path) { #ifndef SERVER_ONLY + const core::dimension2d size = texture->getSize(); video::IImage* img = - m_video_driver->createImage(texture, core::position2d(0,0), - texture->getSize()); + m_video_driver->createImage(texture, core::position2d(0,0), size); video::IImage* mask = m_video_driver->createImageFromFile(mask_path.c_str()); @@ -1842,6 +1842,15 @@ void IrrDriver::applyMask(video::ITexture* texture, return; } + if (mask->getDimension() != size) + { + video::IImage* mask_scaled = + m_video_driver->createImage(texture->getColorFormat(), size); + mask->copyToScaling(mask_scaled); + mask->drop(); + mask = mask_scaled; + } + void* dest = img->lock(); if (dest != NULL && mask->lock()) { From 33802d9f81d8babe6dfc42324f214185757a2436 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Wed, 28 Dec 2016 20:13:55 -0500 Subject: [PATCH 12/13] Materials optimisation : minor tweaks and cleanup --- src/graphics/material.cpp | 23 +++++++++-------------- src/graphics/material.hpp | 10 +++------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 81569a132..49d447c2a 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -75,7 +75,6 @@ Material::Material(const XMLNode *node, bool deprecated) m_full_path = file_manager->getFileSystem()->getAbsolutePath(relativePath.c_str()).c_str(); init(); - node->get("dont-load", &m_dont_load_texture); bool b = false; node->get("clampu", &b); if (b) m_clamp_tex |= UCLAMP; //blender 2.4 style @@ -403,13 +402,9 @@ Material::Material(const XMLNode *node, bool deprecated) video::ITexture* Material::getTexture() { - // Note that dont load means that the textures are not loaded - // via the material. So getTexture should only get called for - // automatically loaded textures (used atm for font textures). - assert(!m_dont_load_texture); if (!m_installed) { - install(/*is_full_path*/true, true); + install(/*is_full_path*/true); } return m_texture; } // getTexture @@ -429,8 +424,10 @@ Material::Material(const std::string& fname, bool is_full_path, m_full_path = file_manager->getFileSystem()->getAbsolutePath( file_manager->searchTexture(m_texname).c_str()).c_str(); + m_complain_if_not_found = complain_if_not_found; + if (load_texture) - install(is_full_path, complain_if_not_found); + install(is_full_path); } // Material //----------------------------------------------------------------------------- @@ -438,7 +435,6 @@ Material::Material(const std::string& fname, bool is_full_path, */ void Material::init() { - m_dont_load_texture = false; m_texture = NULL; m_clamp_tex = 0; m_shader_type = SHADERTYPE_SOLID; @@ -476,7 +472,7 @@ void Material::init() m_water_splash = false; m_is_jump_texture = false; m_has_gravity = false; - + m_complain_if_not_found = true; for (int n=0; nsearchTexture(m_texname); - if (complain_if_not_found && full_path.size() == 0) + if (m_complain_if_not_found && full_path.size() == 0) { Log::error("material", "Cannot find texture '%s'.", m_texname.c_str()); m_texture = NULL; @@ -507,7 +502,7 @@ void Material::install(bool is_full_path, bool complain_if_not_found) m_texture = irr_driver->getTexture(full_path, false, //isPreMul(), false, //isPreDiv(), - complain_if_not_found); + m_complain_if_not_found); } if (m_texture == NULL) return; @@ -727,7 +722,7 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m { if (!m_installed) { - install(/*is_full_path*/true, true); + install(/*is_full_path*/true); } if (m_deprecated || diff --git a/src/graphics/material.hpp b/src/graphics/material.hpp index 20c764918..810223328 100644 --- a/src/graphics/material.hpp +++ b/src/graphics/material.hpp @@ -92,12 +92,6 @@ private: std::string m_full_path; - /** If true, the texture will not automatically be loaded and bound - * at load time, it must be loaded elsewhere. This is used to store - * material settings for font textures, without loading fonts for - * languages that might not be needed at all. */ - bool m_dont_load_texture; - /** Name of a special sfx to play when a kart is on this terrain, or * "" if no special sfx exists. */ std::string m_sfx_name; @@ -266,12 +260,14 @@ private: std::string m_gloss_map; + bool m_complain_if_not_found; + bool m_deprecated; bool m_installed; void init (); - void install (bool is_full_path=false, bool complain_if_not_found=true); + void install (bool is_full_path=false); void initCustomSFX(const XMLNode *sfx); void initParticlesEffect(const XMLNode *node); From f0afba84c8878dd4ec705c11fa52164172dc5284 Mon Sep 17 00:00:00 2001 From: "auria.mg" Date: Wed, 28 Dec 2016 20:17:32 -0500 Subject: [PATCH 13/13] More cleanup --- src/graphics/material_manager.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index 3b3cac772..8666b125e 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -93,11 +93,8 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, // Search backward so that temporary (track) textures are found first for (int i = (int)m_materials.size() - 1; i >= 0; i--) { - //Log::info("DEBUG_TEX", "<%s> <%s>", m_materials[i]->getTexFullPath().c_str(), img_path.c_str()); - core::stringc fullpath = core::stringc(m_materials[i]->getTexFullPath().c_str()); - fullpath.make_lower(); - //if (fullpath.find("bumpy") > 0) - // Log::info("DEBUG_TEX", "<%s> <%s>", fullpath.c_str(), img_path.c_str()); + core::stringc fullpath = core::stringc(m_materials[i]->getTexFullPath().c_str()); + fullpath.make_lower(); if (fullpath == img_path.c_str()) { return m_materials[i]; @@ -111,7 +108,6 @@ Material* MaterialManager::getMaterialFor(video::ITexture* t, for (int i = (int)m_materials.size() - 1; i >= 0; i--) { - //Log::info("DEBUG_TEX2", "<%s> <%s>", m_materials[i]->getTexFname().c_str(), image.c_str()); core::stringc texfname(m_materials[i]->getTexFname().c_str()); texfname.make_lower(); if (texfname == image)