// Copyright (C) 2020 Jérôme Leclercq // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include namespace Nz { inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo) : m_pipelineInfo(pipelineInfo) { } /*! * \brief Enable pipeline states for rendering * * \param flags Shader flags */ inline const MaterialPipeline::Instance& MaterialPipeline::Apply(UInt32 flags) const { const Instance& instance = GetInstance(flags); instance.uberInstance->Activate(); Renderer::SetRenderStates(m_pipelineInfo); return instance; } /*! * \brief Retrieve a MaterialPipelineInfo object describing this pipeline * * \return Pipeline informations */ const MaterialPipelineInfo& MaterialPipeline::GetInfo() const { return m_pipelineInfo; } /*! * \brief Retrieve (and generate if required) a pipeline instance using shader flags without applying it * * \param flags Shader flags * * \return Pipeline instance */ inline const MaterialPipeline::Instance& MaterialPipeline::GetInstance(UInt32 flags) const { const Instance& instance = m_instances[flags]; if (!instance.uberInstance) GenerateRenderPipeline(flags); return instance; } bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs) { if (!operator==(static_cast(lhs), static_cast(rhs))) return false; #define NazaraPipelineMember(field) if (lhs.field != rhs.field) return false #define NazaraPipelineBoolMember NazaraPipelineMember NazaraPipelineBoolMember(alphaTest); NazaraPipelineBoolMember(depthSorting); NazaraPipelineBoolMember(hasAlphaMap); NazaraPipelineBoolMember(hasDiffuseMap); NazaraPipelineBoolMember(hasEmissiveMap); NazaraPipelineBoolMember(hasHeightMap); NazaraPipelineBoolMember(hasNormalMap); NazaraPipelineBoolMember(hasSpecularMap); NazaraPipelineBoolMember(hasVertexColor); NazaraPipelineBoolMember(reflectionMapping); NazaraPipelineBoolMember(shadowReceive); NazaraPipelineMember(uberShader); #undef NazaraPipelineMember #undef NazaraPipelineBoolMember return true; } bool operator!=(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs) { return !operator==(lhs, rhs); } /*! * \brief Creates a new MaterialPipeline from the arguments * \return A reference to the newly created material pipeline * * \param args Arguments for the material pipeline */ template MaterialPipelineRef MaterialPipeline::New(Args&&... args) { std::unique_ptr object(new MaterialPipeline(std::forward(args)...)); object->SetPersistent(false); return object.release(); } } namespace std { template<> struct hash { size_t operator()(const Nz::MaterialPipelineInfo& pipelineInfo) const { hash parentHash; std::size_t seed = parentHash(pipelineInfo); Nz::UInt16 parameterHash = 0; Nz::UInt16 parameterIndex = 0; #define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.member) #define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++) NazaraPipelineBoolMember(alphaTest); NazaraPipelineBoolMember(depthSorting); NazaraPipelineBoolMember(hasAlphaMap); NazaraPipelineBoolMember(hasDiffuseMap); NazaraPipelineBoolMember(hasEmissiveMap); NazaraPipelineBoolMember(hasHeightMap); NazaraPipelineBoolMember(hasNormalMap); NazaraPipelineBoolMember(hasSpecularMap); NazaraPipelineBoolMember(hasVertexColor); NazaraPipelineBoolMember(reflectionMapping); NazaraPipelineBoolMember(shadowReceive); NazaraPipelineMember(uberShader); #undef NazaraPipelineMember #undef NazaraPipelineBoolMember Nz::HashCombine(seed, parameterHash); return seed; } }; } #include