Move SMaterial std::hash impl to its header

This commit is contained in:
sfan5 2024-11-25 21:56:12 +01:00
parent a799a54894
commit 810f39767c
4 changed files with 35 additions and 56 deletions

@ -230,14 +230,14 @@ const c8 *const ZWriteNames[] = {
/** SMaterial might ignore some textures in most function, like assignment and comparison, /** SMaterial might ignore some textures in most function, like assignment and comparison,
when SIrrlichtCreationParameters::MaxTextureUnits is set to a lower number. when SIrrlichtCreationParameters::MaxTextureUnits is set to a lower number.
*/ */
const u32 MATERIAL_MAX_TEXTURES = 4; constexpr static u32 MATERIAL_MAX_TEXTURES = 4;
//! Struct for holding parameters for a material renderer //! Struct for holding parameters for a material renderer
// Note for implementors: Serialization is in CNullDriver // Note for implementors: Serialization is in CNullDriver
class SMaterial class SMaterial
{ {
public: public:
//! Default constructor. Creates a solid, lit material with white colors //! Default constructor. Creates a solid material
SMaterial() : SMaterial() :
MaterialType(EMT_SOLID), ColorParam(0, 0, 0, 0), MaterialType(EMT_SOLID), ColorParam(0, 0, 0, 0),
MaterialTypeParam(0.0f), Thickness(1.0f), ZBuffer(ECFN_LESSEQUAL), MaterialTypeParam(0.0f), Thickness(1.0f), ZBuffer(ECFN_LESSEQUAL),
@ -257,7 +257,7 @@ public:
E_MATERIAL_TYPE MaterialType; E_MATERIAL_TYPE MaterialType;
//! Custom color parameter, can be used by custom shader materials. //! Custom color parameter, can be used by custom shader materials.
// See MainShaderConstantSetter in Minetest. // See MainShaderConstantSetter in Luanti.
SColor ColorParam; SColor ColorParam;
//! Free parameter, dependent on the material type. //! Free parameter, dependent on the material type.
@ -427,10 +427,13 @@ public:
PolygonOffsetDepthBias != b.PolygonOffsetDepthBias || PolygonOffsetDepthBias != b.PolygonOffsetDepthBias ||
PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale || PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale ||
UseMipMaps != b.UseMipMaps; UseMipMaps != b.UseMipMaps;
for (u32 i = 0; (i < MATERIAL_MAX_TEXTURES) && !different; ++i) { if (different)
different |= (TextureLayers[i] != b.TextureLayers[i]); return true;
for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i) {
if (TextureLayers[i] != b.TextureLayers[i])
return true;
} }
return different; return false;
} }
//! Equality operator //! Equality operator
@ -477,5 +480,19 @@ public:
//! global const identity Material //! global const identity Material
IRRLICHT_API extern SMaterial IdentityMaterial; IRRLICHT_API extern SMaterial IdentityMaterial;
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
template<>
struct std::hash<irr::video::SMaterial>
{
/// @brief std::hash specialization for video::SMaterial
std::size_t operator()(const irr::video::SMaterial &m) const noexcept
{
// basic implementation that hashes the two things most likely to differ
auto h1 = std::hash<irr::video::ITexture*>{}(m.getTexture(0));
auto h2 = std::hash<int>{}(m.MaterialType);
return (h1 << 1) ^ h2;
}
};

@ -469,14 +469,12 @@ void CSceneManager::drawAll()
if (!Driver) if (!Driver)
return; return;
u32 i; // new ISO for scoping problem in some compilers
// reset all transforms // reset all transforms
Driver->setMaterial(video::SMaterial()); Driver->setMaterial(video::SMaterial());
Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix); Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
Driver->setTransform(video::ETS_VIEW, core::IdentityMatrix); Driver->setTransform(video::ETS_VIEW, core::IdentityMatrix);
Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); Driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
for (i = video::ETS_COUNT - 1; i >= video::ETS_TEXTURE_0; --i) for (u32 i = video::ETS_COUNT - 1; i >= video::ETS_TEXTURE_0; --i)
Driver->setTransform((video::E_TRANSFORMATION_STATE)i, core::IdentityMatrix); Driver->setTransform((video::E_TRANSFORMATION_STATE)i, core::IdentityMatrix);
// TODO: This should not use an attribute here but a real parameter when necessary (too slow!) // TODO: This should not use an attribute here but a real parameter when necessary (too slow!)
Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT)); Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT));

@ -193,21 +193,21 @@ private:
} }
DefaultNodeEntry(ISceneNode *n) : DefaultNodeEntry(ISceneNode *n) :
Node(n), TextureValue(0) Node(n)
{ {
if (n->getMaterialCount()) if (n->getMaterialCount())
TextureValue = (n->getMaterial(0).getTexture(0)); Hash = std::hash<video::SMaterial>{}(n->getMaterial(0));
} }
bool operator<(const DefaultNodeEntry &other) const bool operator<(const DefaultNodeEntry &other) const noexcept
{ {
return (TextureValue < other.TextureValue); return Hash < other.Hash;
} }
ISceneNode *Node; ISceneNode *Node = nullptr;
private: private:
void *TextureValue; size_t Hash = 0;
}; };
//! sort on distance (center) to camera //! sort on distance (center) to camera
@ -223,42 +223,15 @@ private:
Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera);
} }
bool operator<(const TransparentNodeEntry &other) const bool operator<(const TransparentNodeEntry &other) const noexcept
{ {
return Distance > other.Distance; return Distance > other.Distance;
} }
ISceneNode *Node; ISceneNode *Node = nullptr;
private: private:
f64 Distance; f32 Distance = 0;
};
//! sort on distance (sphere) to camera
struct DistanceNodeEntry
{
DistanceNodeEntry(ISceneNode *n, const core::vector3df &cameraPos) :
Node(n)
{
setNodeAndDistanceFromPosition(n, cameraPos);
}
bool operator<(const DistanceNodeEntry &other) const
{
return Distance < other.Distance;
}
void setNodeAndDistanceFromPosition(ISceneNode *n, const core::vector3df &fromPosition)
{
Node = n;
Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(fromPosition);
Distance -= Node->getBoundingBox().getExtent().getLengthSQ() * 0.5;
}
ISceneNode *Node;
private:
f64 Distance;
}; };
//! video driver //! video driver

@ -25,19 +25,10 @@ namespace {
// A helper struct // A helper struct
struct MeshBufListMaps struct MeshBufListMaps
{ {
struct MaterialHash
{
size_t operator()(const video::SMaterial &m) const noexcept
{
// Only hash first texture. Simple and fast.
return std::hash<video::ITexture *>{}(m.TextureLayers[0].Texture);
}
};
using MeshBufListMap = std::unordered_map< using MeshBufListMap = std::unordered_map<
video::SMaterial, video::SMaterial,
std::vector<std::pair<v3s16, scene::IMeshBuffer *>>, std::vector<std::pair<v3s16, scene::IMeshBuffer *>>
MaterialHash>; >;
std::array<MeshBufListMap, MAX_TILE_LAYERS> maps; std::array<MeshBufListMap, MAX_TILE_LAYERS> maps;