// Copyright (C) 2015 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 namespace Nz { /*! * \brief Constructs a Material object by default */ inline Material::Material() { Reset(); } /*! * \brief Constructs a Material object by assignation * * \param material Material to copy into this */ inline Material::Material(const Material& material) : RefCounted(), Resource(material) { Copy(material); } /*! * \brief Destructs the object and calls OnMaterialRelease * * \see OnMaterialRelease */ inline Material::~Material() { OnMaterialRelease(this); } /*! * \brief Enables a renderer parameter * * \param renderParameter Parameter for the rendering * \param enable Should the parameter be enabled * * \remark Produces a NazaraAssert if enumeration is invalid */ inline void Material::Enable(RendererParameter renderParameter, bool enable) { NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum"); m_states.parameters[renderParameter] = enable; } /*! * \brief Enables the alpha test * * \param alphaTest Should the parameter be enabled * * \remark Invalidates the shaders */ inline void Material::EnableAlphaTest(bool alphaTest) { m_alphaTestEnabled = alphaTest; InvalidateShaders(); } /*! * \brief Enables the depth sorting * * \param depthSorting Should the parameter be enabled */ inline void Material::EnableDepthSorting(bool depthSorting) { // Has no influence on shaders m_depthSortingEnabled = depthSorting; } /*! * \brief Enables the lighting * * \param lighting Should the parameter be enabled * * \remark Invalidates the shaders */ inline void Material::EnableLighting(bool lighting) { m_lightingEnabled = lighting; InvalidateShaders(); } /*! * \brief Enables the shadow casting * * \param castShadows Should shadow casting be enabled */ inline void Material::EnableShadowCasting(bool castShadows) { // Has no influence on shaders m_shadowCastingEnabled = castShadows; } /*! * \brief Enables the shadow on receiving object * * \param receiveShadow Should receiving object have shadows enabled * * \remark Invalidates the shaders */ inline void Material::EnableShadowReceive(bool receiveShadows) { m_shadowReceiveEnabled = receiveShadows; InvalidateShaders(); } /*! * \brief Enables the transformation * * \param transform Should the parameter be enabled * * \remark Invalidates the shaders */ inline void Material::EnableTransform(bool transform) { m_transformEnabled = transform; InvalidateShaders(); } /*! * \brief Gets the alpha map * \return Constant reference to the current texture */ inline const TextureRef& Material::GetAlphaMap() const { return m_alphaMap; } /*! * \brief Gets the alpha threshold * \return The threshold value for the alpha */ inline float Material::GetAlphaThreshold() const { return m_alphaThreshold; } /*! * \brief Gets the ambient color * \return Ambient color */ inline Color Material::GetAmbientColor() const { return m_ambientColor; } /*! * \brief Gets the function to compare depth * \return Function comparing the depth of two materials */ inline RendererComparison Material::GetDepthFunc() const { return m_states.depthFunc; } /*! * \brief Gets the depth material * \return Constant reference to the depth material */ inline const MaterialRef& Material::GetDepthMaterial() const { return m_depthMaterial; } /*! * \brief Gets the diffuse color * \return Diffuse color */ inline Color Material::GetDiffuseColor() const { return m_diffuseColor; } /*! * \brief Gets the diffuse sampler * \return Reference to the current texture sampler for the diffuse */ inline TextureSampler& Material::GetDiffuseSampler() { return m_diffuseSampler; } /*! * \brief Gets the diffuse sampler * \return Constant reference to the current texture sampler for the diffuse */ inline const TextureSampler& Material::GetDiffuseSampler() const { return m_diffuseSampler; } /*! * \brief Gets the diffuse map * \return Constant reference to the texture */ const TextureRef& Material::GetDiffuseMap() const { return m_diffuseMap; } /*! * \brief Gets the dst in blend * \return Function for dst blending */ inline BlendFunc Material::GetDstBlend() const { return m_states.dstBlend; } /*! * \brief Gets the emissive map * \return Constant reference to the texture */ inline const TextureRef& Material::GetEmissiveMap() const { return m_emissiveMap; } /*! * \brief Gets the face culling * \return Current face culling side */ inline FaceSide Material::GetFaceCulling() const { return m_states.faceCulling; } /*! * \brief Gets the face filling * \return Current face filling */ inline FaceFilling Material::GetFaceFilling() const { return m_states.faceFilling; } /*! * \brief Gets the height map * \return Constant reference to the texture */ inline const TextureRef& Material::GetHeightMap() const { return m_heightMap; } /*! * \brief Gets the normal map * \return Constant reference to the texture */ inline const TextureRef& Material::GetNormalMap() const { return m_normalMap; } /*! * \brief Gets the render states * \return Constant reference to the render states */ inline const RenderStates& Material::GetRenderStates() const { return m_states; } /*! * \brief Gets the shader of this material * \return Constant pointer to the ubershader used */ inline const UberShader* Material::GetShader() const { return m_uberShader; } /*! * \brief Gets the shader instance based on the flag * \return Constant pointer to the ubershader instance * * \param flags Flag of the shader */ inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const { const ShaderInstance& instance = m_shaders[flags]; if (!instance.uberInstance) GenerateShader(flags); return instance.uberInstance; } /*! * \brief Gets the shininess * \return Current shininess */ inline float Material::GetShininess() const { return m_shininess; } /*! * \brief Gets the specular color * \return Specular color */ inline Color Material::GetSpecularColor() const { return m_specularColor; } /*! * \brief Gets the specular map * \return Constant reference to the texture */ inline const TextureRef& Material::GetSpecularMap() const { return m_specularMap; } /*! * \brief Gets the specular sampler * \return Reference to the current texture sampler for the specular */ inline TextureSampler& Material::GetSpecularSampler() { return m_specularSampler; } /*! * \brief Gets the specular sampler * \return Constant reference to the current texture sampler for the specular */ inline const TextureSampler& Material::GetSpecularSampler() const { return m_specularSampler; } /*! * \brief Gets the src in blend * \return Function for src blending */ inline BlendFunc Material::GetSrcBlend() const { return m_states.srcBlend; } /*! * \brief Checks whether this material has an alpha map * \return true If it is the case */ inline bool Material::HasAlphaMap() const { return m_alphaMap.IsValid(); } /*! * \brief Checks whether this material has a depth material * \return true If it is the case */ inline bool Material::HasDepthMaterial() const { return m_depthMaterial.IsValid(); } /*! * \brief Checks whether this material has a diffuse map * \return true If it is the case */ inline bool Material::HasDiffuseMap() const { return m_diffuseMap.IsValid(); } /*! * \brief Checks whether this material has a emissive map * \return true If it is the case */ inline bool Material::HasEmissiveMap() const { return m_emissiveMap.IsValid(); } /*! * \brief Checks whether this material has a height map * \return true If it is the case */ inline bool Material::HasHeightMap() const { return m_heightMap.IsValid(); } /*! * \brief Checks whether this material has a normal map * \return true If it is the case */ inline bool Material::HasNormalMap() const { return m_normalMap.IsValid(); } /*! * \brief Checks whether this material has a specular map * \return true If it is the case */ inline bool Material::HasSpecularMap() const { return m_specularMap.IsValid(); } /*! * \brief Checks whether this material has alpha test enabled * \return true If it is the case */ inline bool Material::IsAlphaTestEnabled() const { return m_alphaTestEnabled; } /*! * \brief Checks whether this material has depth sorting enabled * \return true If it is the case */ inline bool Material::IsDepthSortingEnabled() const { return m_depthSortingEnabled; } /*! * \brief Checks whether this material has the render parameter enabled * \return true If it is the case * * \param parameter Parameter for the rendering * * \remark Produces a NazaraAssert if enumeration is invalid */ inline bool Material::IsEnabled(RendererParameter parameter) const { NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum"); return m_states.parameters[parameter]; } /*! * \brief Checks whether this material has lightning enabled * \return true If it is the case */ inline bool Material::IsLightingEnabled() const { return m_lightingEnabled; } /*! * \brief Checks whether this material cast shadow * \return true If it is the case */ inline bool Material::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; } /*! * \brief Checks whether this material receive shadow * \return true If it is the case */ inline bool Material::IsShadowReceiveEnabled() const { return m_shadowReceiveEnabled; } /*! * \brief Checks whether this material has transformation enabled * \return true If it is the case */ inline bool Material::IsTransformEnabled() const { return m_transformEnabled; } /*! * \brief Loads the material from file * \return true if loading is successful * * \param filePath Path to the file * \param params Parameters for the material */ inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) { return MaterialLoader::LoadFromFile(this, filePath, params); } /*! * \brief Loads the material from memory * \return true if loading is successful * * \param data Raw memory * \param size Size of the memory * \param params Parameters for the material */ inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) { return MaterialLoader::LoadFromMemory(this, data, size, params); } /*! * \brief Loads the material from stream * \return true if loading is successful * * \param stream Stream to the material * \param params Parameters for the material */ inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) { return MaterialLoader::LoadFromStream(this, stream, params); } /*! * \brief Sets the alpha map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetAlphaMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetAlphaMap(std::move(texture)); return true; } /*! * \brief Sets the alpha map with a reference to a texture * \return true If successful * * \param alphaMap Texture * * \remark Invalidates the shaders */ inline void Material::SetAlphaMap(TextureRef alphaMap) { m_alphaMap = std::move(alphaMap); InvalidateShaders(); } /*! * \brief Sets the alpha threshold * * \param alphaThreshold Threshold for the alpha */ inline void Material::SetAlphaThreshold(float alphaThreshold) { m_alphaThreshold = alphaThreshold; } /*! * \brief Sets the color for ambient * * \param ambient Color for ambient */ inline void Material::SetAmbientColor(const Color& ambient) { m_ambientColor = ambient; } /*! * \brief Sets the depth functor * * \param depthFunc */ inline void Material::SetDepthFunc(RendererComparison depthFunc) { m_states.depthFunc = depthFunc; } /*! * \brief Sets the depth material * \return true If successful * * \param depthMaterial Material for depth */ inline void Material::SetDepthMaterial(MaterialRef depthMaterial) { m_depthMaterial = std::move(depthMaterial); } /*! * \brief Sets the color for diffuse * * \param diffuse Color for diffuse */ inline void Material::SetDiffuseColor(const Color& diffuse) { m_diffuseColor = diffuse; } /*! * \brief Sets the diffuse map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetDiffuseMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetDiffuseMap(std::move(texture)); return true; } /*! * \brief Sets the diffuse map with a reference to a texture * \return true If successful * * \param diffuseMap Texture * * \remark Invalidates the shaders */ inline void Material::SetDiffuseMap(TextureRef diffuseMap) { m_diffuseMap = std::move(diffuseMap); InvalidateShaders(); } /*! * \brief Sets the diffuse sampler * * \param sampler Diffuse sample */ inline void Material::SetDiffuseSampler(const TextureSampler& sampler) { m_diffuseSampler = sampler; } /*! * \brief Sets the dst in blend * * \param func Function for dst blending */ inline void Material::SetDstBlend(BlendFunc func) { m_states.dstBlend = func; } /*! * \brief Sets the emissive map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetEmissiveMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetEmissiveMap(std::move(texture)); return true; } /*! * \brief Sets the emissive map with a reference to a texture * \return true If successful * * \param emissiveMap Texture * * \remark Invalidates the shaders */ inline void Material::SetEmissiveMap(TextureRef emissiveMap) { m_emissiveMap = std::move(emissiveMap); InvalidateShaders(); } /*! * \brief Sets the face culling * * \param faceSide Face to cull */ inline void Material::SetFaceCulling(FaceSide faceSide) { m_states.faceCulling = faceSide; } /*! * \brief Sets the face filling * * \param filling Face to fill */ inline void Material::SetFaceFilling(FaceFilling filling) { m_states.faceFilling = filling; } /*! * \brief Sets the height map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetHeightMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetHeightMap(std::move(texture)); return true; } /*! * \brief Sets the height map with a reference to a texture * \return true If successful * * \param heightMap Texture * * \remark Invalidates the shaders */ inline void Material::SetHeightMap(TextureRef heightMap) { m_heightMap = std::move(heightMap); InvalidateShaders(); } /*! * \brief Sets the normal map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetNormalMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetNormalMap(std::move(texture)); return true; } /*! * \brief Sets the normal map with a reference to a texture * \return true If successful * * \param normalMap Texture * * \remark Invalidates the shaders */ inline void Material::SetNormalMap(TextureRef normalMap) { m_normalMap = std::move(normalMap); InvalidateShaders(); } /*! * \brief Sets the render states * * \param states States for the rendering */ inline void Material::SetRenderStates(const RenderStates& states) { m_states = states; } /*! * \brief Sets the shader with a constant reference to a ubershader * * \param uberShader Uber shader to apply * * \remark Invalidates the shaders */ inline void Material::SetShader(UberShaderConstRef uberShader) { m_uberShader = std::move(uberShader); InvalidateShaders(); } /*! * \brief Sets the shader by name * \return true If successful * * \param uberShaderName Named shader */ inline bool Material::SetShader(const String& uberShaderName) { UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); if (!uberShader) return false; SetShader(std::move(uberShader)); return true; } /*! * \brief Sets the shininess of the material * * \param shininess Value of the shininess */ inline void Material::SetShininess(float shininess) { m_shininess = shininess; } /*! * \brief Sets the color for specular * * \param specular Color */ inline void Material::SetSpecularColor(const Color& specular) { m_specularColor = specular; } /*! * \brief Sets the specular map by name * \return true If successful * * \param textureName Named texture */ inline bool Material::SetSpecularMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); if (!texture) { texture = TextureManager::Get(textureName); if (!texture) return false; } SetSpecularMap(std::move(texture)); return true; } /*! * \brief Sets the specular map with a reference to a texture * \return true If successful * * \param specularMap Texture * * \remark Invalidates the shaders */ inline void Material::SetSpecularMap(TextureRef specularMap) { m_specularMap = std::move(specularMap); InvalidateShaders(); } /*! * \brief Sets the specular sampler * * \param sampler Specular sample */ inline void Material::SetSpecularSampler(const TextureSampler& sampler) { m_specularSampler = sampler; } /*! * \brief Sets the src in blend * * \param func Function for src blending */ inline void Material::SetSrcBlend(BlendFunc func) { m_states.srcBlend = func; } /*! * \brief Sets the current material with the content of the other one * \return A reference to this * * \param material The other Material */ inline Material& Material::operator=(const Material& material) { Resource::operator=(material); Copy(material); return *this; } /*! * \brief Gets the default material * \return Reference to the default material */ inline MaterialRef Material::GetDefault() { return s_defaultMaterial; } /*! * \brief Invalidates the shaders */ inline void Material::InvalidateShaders() { for (ShaderInstance& instance : m_shaders) instance.uberInstance = nullptr; } /*! * \brief Creates a new material from the arguments * \return A reference to the newly created material * * \param args Arguments for the material */ template MaterialRef Material::New(Args&&... args) { std::unique_ptr object(new Material(std::forward(args)...)); object->SetPersistent(false); return object.release(); } } #include