diff --git a/irr/include/SMaterial.h b/irr/include/SMaterial.h index 7a939317c..867557154 100644 --- a/irr/include/SMaterial.h +++ b/irr/include/SMaterial.h @@ -230,14 +230,14 @@ const c8 *const ZWriteNames[] = { /** SMaterial might ignore some textures in most function, like assignment and comparison, 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 // Note for implementors: Serialization is in CNullDriver class SMaterial { public: - //! Default constructor. Creates a solid, lit material with white colors + //! Default constructor. Creates a solid material SMaterial() : MaterialType(EMT_SOLID), ColorParam(0, 0, 0, 0), MaterialTypeParam(0.0f), Thickness(1.0f), ZBuffer(ECFN_LESSEQUAL), @@ -257,7 +257,7 @@ public: E_MATERIAL_TYPE MaterialType; //! Custom color parameter, can be used by custom shader materials. - // See MainShaderConstantSetter in Minetest. + // See MainShaderConstantSetter in Luanti. SColor ColorParam; //! Free parameter, dependent on the material type. @@ -427,10 +427,13 @@ public: PolygonOffsetDepthBias != b.PolygonOffsetDepthBias || PolygonOffsetSlopeScale != b.PolygonOffsetSlopeScale || UseMipMaps != b.UseMipMaps; - for (u32 i = 0; (i < MATERIAL_MAX_TEXTURES) && !different; ++i) { - different |= (TextureLayers[i] != b.TextureLayers[i]); + if (different) + 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 @@ -477,5 +480,19 @@ public: //! global const identity Material IRRLICHT_API extern SMaterial IdentityMaterial; + } // end namespace video } // end namespace irr + +template<> +struct std::hash +{ + /// @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{}(m.getTexture(0)); + auto h2 = std::hash{}(m.MaterialType); + return (h1 << 1) ^ h2; + } +}; diff --git a/irr/src/CSceneManager.cpp b/irr/src/CSceneManager.cpp index 04b3ec313..71ae7f962 100644 --- a/irr/src/CSceneManager.cpp +++ b/irr/src/CSceneManager.cpp @@ -469,14 +469,12 @@ void CSceneManager::drawAll() if (!Driver) return; - u32 i; // new ISO for scoping problem in some compilers - // reset all transforms Driver->setMaterial(video::SMaterial()); Driver->setTransform(video::ETS_PROJECTION, core::IdentityMatrix); Driver->setTransform(video::ETS_VIEW, 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); // TODO: This should not use an attribute here but a real parameter when necessary (too slow!) Driver->setAllowZWriteOnTransparent(Parameters->getAttributeAsBool(ALLOW_ZWRITE_ON_TRANSPARENT)); diff --git a/irr/src/CSceneManager.h b/irr/src/CSceneManager.h index 0f1b2c716..4362ba04d 100644 --- a/irr/src/CSceneManager.h +++ b/irr/src/CSceneManager.h @@ -193,21 +193,21 @@ private: } DefaultNodeEntry(ISceneNode *n) : - Node(n), TextureValue(0) + Node(n) { if (n->getMaterialCount()) - TextureValue = (n->getMaterial(0).getTexture(0)); + Hash = std::hash{}(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: - void *TextureValue; + size_t Hash = 0; }; //! sort on distance (center) to camera @@ -223,42 +223,15 @@ private: Distance = Node->getAbsoluteTransformation().getTranslation().getDistanceFromSQ(camera); } - bool operator<(const TransparentNodeEntry &other) const + bool operator<(const TransparentNodeEntry &other) const noexcept { return Distance > other.Distance; } - ISceneNode *Node; + ISceneNode *Node = nullptr; private: - f64 Distance; - }; - - //! 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; + f32 Distance = 0; }; //! video driver diff --git a/src/client/clientmap.cpp b/src/client/clientmap.cpp index c3207efd1..f57a04b60 100644 --- a/src/client/clientmap.cpp +++ b/src/client/clientmap.cpp @@ -25,19 +25,10 @@ namespace { // A helper struct struct MeshBufListMaps { - struct MaterialHash - { - size_t operator()(const video::SMaterial &m) const noexcept - { - // Only hash first texture. Simple and fast. - return std::hash{}(m.TextureLayers[0].Texture); - } - }; - using MeshBufListMap = std::unordered_map< video::SMaterial, - std::vector>, - MaterialHash>; + std::vector> + >; std::array maps;