From a1606f04d7caa0680a771778c1bae8fe6ad586e6 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 21 Apr 2021 09:04:39 +0800 Subject: [PATCH] Fix alpha mask for legacy device --- src/graphics/material_manager.cpp | 5 +++- src/graphics/material_manager.hpp | 2 +- src/graphics/sp_mesh_loader.cpp | 48 ++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/graphics/material_manager.cpp b/src/graphics/material_manager.cpp index f200a268f..d47d1b0fb 100644 --- a/src/graphics/material_manager.cpp +++ b/src/graphics/material_manager.cpp @@ -362,7 +362,8 @@ Material *MaterialManager::getMaterial(const std::string& fname, bool is_full_path, bool make_permanent, bool complain_if_not_found, - bool strip_path, bool install) + bool strip_path, bool install, + bool create_if_not_found) { if(fname=="") { @@ -392,6 +393,8 @@ Material *MaterialManager::getMaterial(const std::string& fname, return m_materials[i]; } + if (!create_if_not_found) + return NULL; // Add the new material Material* m = new Material(fname, is_full_path, complain_if_not_found, install); m_materials.push_back(m); diff --git a/src/graphics/material_manager.hpp b/src/graphics/material_manager.hpp index eaf8872d4..8ca39fd65 100644 --- a/src/graphics/material_manager.hpp +++ b/src/graphics/material_manager.hpp @@ -73,7 +73,7 @@ public: bool is_full_path=false, bool make_permanent=false, bool complain_if_not_found=true, - bool strip_path=true, bool install=true); + bool strip_path=true, bool install=true, bool create_if_not_found=true); void addSharedMaterial(const std::string& filename, bool deprecated = false); bool pushTempMaterial (const std::string& filename, bool deprecated = false); bool pushTempMaterial (const XMLNode *root, const std::string& filename, bool deprecated = false); diff --git a/src/graphics/sp_mesh_loader.cpp b/src/graphics/sp_mesh_loader.cpp index 5ebfa1f6c..e5f1f737b 100644 --- a/src/graphics/sp_mesh_loader.cpp +++ b/src/graphics/sp_mesh_loader.cpp @@ -20,11 +20,13 @@ #include "graphics/sp/sp_mesh.hpp" #include "graphics/sp/sp_mesh_buffer.hpp" #include "graphics/central_settings.hpp" +#include "graphics/material.hpp" #include "graphics/material_manager.hpp" #include "graphics/mesh_tools.hpp" #include "graphics/stk_tex_manager.hpp" #include "utils/constants.hpp" #include "utils/mini_glm.hpp" +#include "utils/string_utils.hpp" #include "../../lib/irrlicht/source/Irrlicht/CSkinnedMesh.h" const uint8_t VERSION_NOW = 1; @@ -33,6 +35,9 @@ const uint8_t VERSION_NOW = 1; #include #include #include +#ifndef SERVER_ONLY +#include +#endif // ---------------------------------------------------------------------------- bool SPMeshLoader::isALoadableFileExtension(const io::path& filename) const @@ -147,8 +152,49 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f) { tex_name_1 = full_path; } + std::function image_mani; +#ifndef SERVER_ONLY + std::string mask_full_path; + Material* m = material_manager->getMaterial(tex_name_1, + /*is_full_path*/false, + /*make_permanent*/false, + /*complain_if_not_found*/true, + /*strip_path*/true, /*install*/true, + /*create_if_not_found*/false); + if (m && !m->getAlphaMask().empty()) + { + mask_full_path = + StringUtils::getPath(m->getSamplerPath(0)) + + "/" + m->getAlphaMask(); + } + if (!mask_full_path.empty()) + { + image_mani = [mask_full_path](video::IImage* img)->void + { + video::IImage* converted_mask = GE::getResizedImage(mask_full_path); + if (converted_mask == NULL) + { + Log::warn("SPMeshLoader", "Applying mask failed for '%s'!", + mask_full_path.c_str()); + return; + } + const core::dimension2du& dim = img->getDimension(); + for (unsigned int x = 0; x < dim.Width; x++) + { + for (unsigned int y = 0; y < dim.Height; y++) + { + video::SColor col = img->getPixel(x, y); + video::SColor alpha = converted_mask->getPixel(x, y); + col.setAlpha(alpha.getRed()); + img->setPixel(x, y, col, false); + } // for y + } // for x + converted_mask->drop(); + }; + } +#endif video::ITexture* tex = STKTexManager::getInstance() - ->getTexture(tex_name_1); + ->getTexture(tex_name_1, image_mani); if (tex != NULL) { textures[0] = tex;