Load colorization data for vulkan
This commit is contained in:
parent
5252c78a05
commit
647988ad30
@ -1345,6 +1345,25 @@ void B3DMeshLoader::loadTextures(SB3dMaterial& material, scene::IMeshBuffer* mb)
|
||||
else
|
||||
full_path = fs->getFileBasename(B3dTexture->TextureName);
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
std::function<void(irr::video::IImage*)> image_mani;
|
||||
if (!CVS->isGLSL())
|
||||
{
|
||||
Material* m = material_manager->getMaterial(B3dTexture->TextureName.c_str(),
|
||||
/*is_full_path*/false,
|
||||
/*make_permanent*/false,
|
||||
/*complain_if_not_found*/true,
|
||||
/*strip_path*/true, /*install*/true,
|
||||
/*create_if_not_found*/false);
|
||||
if (m)
|
||||
{
|
||||
image_mani = m->getMaskImageMani();
|
||||
if (image_mani)
|
||||
STKTexManager::getInstance()->getTexture(full_path.c_str(), image_mani);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
bool convert_spm = CVS->isGLSL() || GE::getVKDriver() != NULL;
|
||||
if (convert_spm)
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
#include <ge_spm_buffer.hpp>
|
||||
#include <ge_texture.hpp>
|
||||
#endif
|
||||
|
||||
using namespace irr::video;
|
||||
@ -958,3 +959,121 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
#endif
|
||||
|
||||
} // setMaterialProperties
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
std::function<void(irr::video::IImage*)> Material::getMaskImageMani() const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
std::function<void(irr::video::IImage*)> image_mani;
|
||||
core::dimension2du max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
|
||||
// Material using alpha channel will be colorized as a whole
|
||||
if (irr_driver->getVideoDriver()->getDriverType() == EDT_VULKAN &&
|
||||
!useAlphaChannel() && (!m_colorization_mask.empty() ||
|
||||
m_colorization_factor > 0.0f || m_colorizable))
|
||||
{
|
||||
std::string colorization_mask;
|
||||
if (!m_colorization_mask.empty())
|
||||
{
|
||||
colorization_mask = StringUtils::getPath(m_sampler_path[0]) + "/" +
|
||||
m_colorization_mask;
|
||||
}
|
||||
float colorization_factor = m_colorization_factor;
|
||||
image_mani = [colorization_mask, colorization_factor, max_size]
|
||||
(video::IImage* img)->void
|
||||
{
|
||||
video::IImage* mask = NULL;
|
||||
core::dimension2du img_size = img->getDimension();
|
||||
const unsigned total_size = img_size.Width * img_size.Height;
|
||||
std::vector<uint8_t> empty_mask;
|
||||
uint8_t* mask_data = NULL;
|
||||
if (!colorization_mask.empty())
|
||||
{
|
||||
mask = GE::getResizedImage(colorization_mask, max_size);
|
||||
if (!mask)
|
||||
{
|
||||
Log::warn("Material",
|
||||
"Applying colorization mask failed for '%s'!",
|
||||
colorization_mask.c_str());
|
||||
return;
|
||||
}
|
||||
core::dimension2du mask_size = mask->getDimension();
|
||||
if (mask->getColorFormat() != video::ECF_A8R8G8B8 ||
|
||||
img_size != mask_size)
|
||||
{
|
||||
video::IImage* new_mask = irr_driver
|
||||
->getVideoDriver()->createImage(video::ECF_A8R8G8B8,
|
||||
img_size);
|
||||
if (img_size != mask_size)
|
||||
{
|
||||
mask->copyToScaling(new_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
mask->copyTo(new_mask);
|
||||
}
|
||||
mask->drop();
|
||||
mask = new_mask;
|
||||
}
|
||||
mask_data = (uint8_t*)mask->lock();
|
||||
}
|
||||
else
|
||||
{
|
||||
empty_mask.resize(total_size * 4, 0);
|
||||
mask_data = empty_mask.data();
|
||||
}
|
||||
uint8_t colorization_factor_encoded = uint8_t
|
||||
(irr::core::clamp(
|
||||
int(colorization_factor * 0.4f * 255.0f), 0, 255));
|
||||
for (unsigned int i = 0; i < total_size; i++)
|
||||
{
|
||||
if (!colorization_mask.empty() && mask_data[i * 4 + 3] > 127)
|
||||
continue;
|
||||
mask_data[i * 4 + 3] = colorization_factor_encoded;
|
||||
}
|
||||
uint8_t* img_data = (uint8_t*)img->lock();
|
||||
for (unsigned int i = 0; i < total_size; i++)
|
||||
img_data[i * 4 + 3] = mask_data[i * 4 + 3];
|
||||
if (mask)
|
||||
mask->drop();
|
||||
};
|
||||
return image_mani;
|
||||
}
|
||||
|
||||
std::string mask_full_path;
|
||||
if (!m_mask.empty())
|
||||
{
|
||||
mask_full_path = StringUtils::getPath(m_sampler_path[0]) + "/" +
|
||||
m_mask;
|
||||
}
|
||||
if (!mask_full_path.empty())
|
||||
{
|
||||
image_mani = [mask_full_path, max_size](video::IImage* img)->void
|
||||
{
|
||||
video::IImage* converted_mask =
|
||||
GE::getResizedImage(mask_full_path, max_size);
|
||||
if (converted_mask == NULL)
|
||||
{
|
||||
Log::warn("Material", "Applying alpha 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();
|
||||
};
|
||||
return image_mani;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
} // getMaskImageMani
|
||||
|
@ -284,6 +284,13 @@ public:
|
||||
m_shader_name == "displace";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool useAlphaChannel () const
|
||||
{
|
||||
return isTransparent() || m_shader_name == "alphatest" ||
|
||||
m_shader_name == "unlit" || m_shader_name == "grass";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the fraction of maximum speed on this material. */
|
||||
float getMaxSpeedFraction() const { return m_max_speed_fraction; }
|
||||
@ -382,6 +389,8 @@ public:
|
||||
return empty;
|
||||
return m_container_id;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
std::function<void(irr::video::IImage*)> getMaskImageMani() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,7 +40,6 @@ const uint8_t VERSION_NOW = 1;
|
||||
#include <ge_main.hpp>
|
||||
#include <ge_spm_buffer.hpp>
|
||||
#include <ge_spm.hpp>
|
||||
#include <ge_texture.hpp>
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -170,47 +169,14 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f)
|
||||
}
|
||||
std::function<void(irr::video::IImage*)> 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())
|
||||
{
|
||||
core::dimension2du max_size = irr_driver->getVideoDriver()
|
||||
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
|
||||
image_mani = [mask_full_path, max_size](video::IImage* img)->void
|
||||
{
|
||||
video::IImage* converted_mask =
|
||||
GE::getResizedImage(mask_full_path, max_size);
|
||||
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();
|
||||
};
|
||||
}
|
||||
if (m)
|
||||
image_mani = m->getMaskImageMani();
|
||||
#endif
|
||||
video::ITexture* tex = STKTexManager::getInstance()
|
||||
->getTexture(tex_name_1, image_mani);
|
||||
|
Loading…
Reference in New Issue
Block a user