From fbdc1faf8c08f15e5c723ad16425f22e9b6f0802 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Wed, 7 Sep 2022 13:31:21 +0200 Subject: [PATCH] Graphics: Add TextureLoader --- include/Nazara/Graphics/Enums.hpp | 7 ++ include/Nazara/Graphics/Graphics.hpp | 4 + include/Nazara/Graphics/Graphics.inl | 10 +++ include/Nazara/Graphics/Material.hpp | 33 +++++-- include/Nazara/Graphics/Material.inl | 18 ---- src/Nazara/Graphics/Formats/TextureLoader.cpp | 88 +++++++++++++++++++ src/Nazara/Graphics/Formats/TextureLoader.hpp | 18 ++++ src/Nazara/Graphics/Material.cpp | 47 ++++++++++ 8 files changed, 202 insertions(+), 23 deletions(-) create mode 100644 src/Nazara/Graphics/Formats/TextureLoader.cpp create mode 100644 src/Nazara/Graphics/Formats/TextureLoader.hpp diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 2a796356b..06c744183 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -41,6 +41,13 @@ namespace Nz Volume }; + enum class MaterialLightingType + { + None, + Phong, + PhysicallyBased + }; + enum class MaterialPassFlag { SortByDistance, diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index 831a534ef..d8bbee43c 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,8 @@ namespace Nz inline const DefaultTextures& GetDefaultTextures() const; inline MaterialPassRegistry& GetMaterialPassRegistry(); inline const MaterialPassRegistry& GetMaterialPassRegistry() const; + MaterialLoader& GetMaterialLoader(); + const MaterialLoader& GetMaterialLoader() const; inline PixelFormat GetPreferredDepthStencilFormat() const; inline const std::shared_ptr& GetRenderDevice() const; inline const RenderPassCache& GetRenderPassCache() const; @@ -73,6 +76,7 @@ namespace Nz std::shared_ptr m_blitPipelineTransparent; std::shared_ptr m_blitPipelineLayout; DefaultTextures m_defaultTextures; + MaterialLoader m_materialLoader; MaterialPassRegistry m_materialPassRegistry; PixelFormat m_preferredDepthStencilFormat; diff --git a/include/Nazara/Graphics/Graphics.inl b/include/Nazara/Graphics/Graphics.inl index 93db349e5..21ade4b5b 100644 --- a/include/Nazara/Graphics/Graphics.inl +++ b/include/Nazara/Graphics/Graphics.inl @@ -32,6 +32,16 @@ namespace Nz return m_materialPassRegistry; } + inline MaterialLoader& Graphics::GetMaterialLoader() + { + return m_materialLoader; + } + + inline const MaterialLoader& Graphics::GetMaterialLoader() const + { + return m_materialLoader; + } + inline PixelFormat Graphics::GetPreferredDepthStencilFormat() const { return m_preferredDepthStencilFormat; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 7de4323d8..048900ec4 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -8,11 +8,30 @@ #define NAZARA_GRAPHICS_MATERIAL_HPP #include -#include -#include +#include +#include +#include +#include +#include +#include namespace Nz { + struct NAZARA_GRAPHICS_API MaterialParams : ResourceParameters + { + MaterialLightingType lightingType = MaterialLightingType::None; + + bool IsValid() const; + }; + + class Material; + class MaterialPass; + + using MaterialLibrary = ObjectLibrary; + using MaterialLoader = ResourceLoader; + using MaterialManager = ResourceManager; + using MaterialSaver = ResourceSaver; + class NAZARA_GRAPHICS_API Material : public Resource { public: @@ -20,9 +39,9 @@ namespace Nz ~Material() = default; inline void AddPass(std::size_t passIndex, std::shared_ptr pass); - inline void AddPass(std::string passName, std::shared_ptr pass); + void AddPass(std::string passName, std::shared_ptr pass); - inline const std::shared_ptr& FindPass(const std::string& passName) const; + const std::shared_ptr& FindPass(const std::string& passName) const; template void ForEachPass(F&& callback); @@ -31,7 +50,11 @@ namespace Nz inline bool HasPass(std::size_t passIndex) const; inline void RemovePass(std::size_t passIndex); - inline void RemovePass(const std::string& passName); + void RemovePass(const std::string& passName); + + static std::shared_ptr LoadFromFile(const std::filesystem::path& filePath, const MaterialParams& params = MaterialParams()); + static std::shared_ptr LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); + static std::shared_ptr LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); private: std::vector> m_passes; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index b7694d9de..76f3e1daf 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -15,18 +15,6 @@ namespace Nz m_passes[passIndex] = std::move(pass); } - inline void Material::AddPass(std::string passName, std::shared_ptr pass) - { - auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); - return AddPass(registry.GetPassIndex(passName), std::move(pass)); - } - - inline const std::shared_ptr& Material::FindPass(const std::string& passName) const - { - auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); - return GetPass(registry.GetPassIndex(passName)); - } - template void Material::ForEachPass(F&& callback) { @@ -63,12 +51,6 @@ namespace Nz m_passes[passIndex].reset(); } - - inline void Material::RemovePass(const std::string& passName) - { - auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); - return RemovePass(registry.GetPassIndex(passName)); - } } #include diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp new file mode 100644 index 000000000..b920fbed2 --- /dev/null +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -0,0 +1,88 @@ +// Copyright (C) 2017 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 +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace Loaders + { + MaterialLoader::Entry GetMaterialLoader_Texture() + { + MaterialLoader::Entry loaderEntry; + loaderEntry.extensionSupport = [](std::string_view extension) + { + return Utility::Instance()->GetImageLoader().IsExtensionSupported(extension); + }; + + loaderEntry.streamLoader = [](Stream& stream, const MaterialParams& parameters) -> Result, ResourceLoadingError> + { + TextureParams texParams; + texParams.renderDevice = Graphics::Instance()->GetRenderDevice(); + + std::shared_ptr texture = Texture::LoadFromStream(stream, {}); + if (!texture) + return Err(ResourceLoadingError::Unrecognized); + + std::shared_ptr material = std::make_shared(); + + // ForwardPass + { + std::shared_ptr matPass; + if (parameters.lightingType == MaterialLightingType::Phong) + matPass = std::make_shared(PhongLightingMaterial::GetSettings()); + else if (parameters.lightingType == MaterialLightingType::PhysicallyBased) + matPass = std::make_shared(PhysicallyBasedMaterial::GetSettings()); + else + matPass = std::make_shared(BasicMaterial::GetSettings()); + + matPass->EnableDepthBuffer(true); + + BasicMaterial forwardPass(*matPass); + forwardPass.SetBaseColorMap(texture); + + if (PixelFormatInfo::HasAlpha(texture->GetFormat())) + forwardPass.EnableAlphaTest(true); + + material->AddPass("ForwardPass", std::move(matPass)); + } + + // DepthPass + { + std::shared_ptr matPass = std::make_shared(DepthMaterial::GetSettings()); + + if (PixelFormatInfo::HasAlpha(texture->GetFormat())) + { + BasicMaterial depthPass(*matPass); + depthPass.SetBaseColorMap(texture); + depthPass.EnableAlphaTest(true); + } + + material->AddPass("DepthPass", std::move(matPass)); + } + + return material; + }; + + loaderEntry.parameterFilter = [](const MaterialParams& parameters) + { + bool skip; + if (parameters.custom.GetBooleanParameter("SkipNativeTextureLoader", &skip) && skip) + return false; + + return true; + }; + + return loaderEntry; + } + } +} diff --git a/src/Nazara/Graphics/Formats/TextureLoader.hpp b/src/Nazara/Graphics/Formats/TextureLoader.hpp new file mode 100644 index 000000000..de53c93b2 --- /dev/null +++ b/src/Nazara/Graphics/Formats/TextureLoader.hpp @@ -0,0 +1,18 @@ +// Copyright (C) 2017 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 + +#pragma once + +#ifndef NAZARA_LOADERS_TEXTURE_HPP +#define NAZARA_LOADERS_TEXTURE_HPP + +#include +#include + +namespace Nz::Loaders +{ + MaterialLoader::Entry GetMaterialLoader_Texture(); +} + +#endif // NAZARA_LOADERS_TEXTURE_HPP diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 2ba96b8ca..521c65520 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -3,8 +3,55 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz { + bool MaterialParams::IsValid() const + { + return true; + } + + void Material::AddPass(std::string passName, std::shared_ptr pass) + { + auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); + return AddPass(registry.GetPassIndex(passName), std::move(pass)); + } + + const std::shared_ptr& Material::FindPass(const std::string& passName) const + { + auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); + return GetPass(registry.GetPassIndex(passName)); + } + + void Material::RemovePass(const std::string& passName) + { + auto& registry = Graphics::Instance()->GetMaterialPassRegistry(); + return RemovePass(registry.GetPassIndex(passName)); + } + + std::shared_ptr Material::LoadFromFile(const std::filesystem::path& filePath, const MaterialParams& params) + { + Graphics* graphics = Graphics::Instance(); + NazaraAssert(graphics, "Utility module has not been initialized"); + + return graphics->GetMaterialLoader().LoadFromFile(filePath, params); + } + + std::shared_ptr Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) + { + Graphics* graphics = Graphics::Instance(); + NazaraAssert(graphics, "Utility module has not been initialized"); + + return graphics->GetMaterialLoader().LoadFromMemory(data, size, params); + } + + std::shared_ptr Material::LoadFromStream(Stream& stream, const MaterialParams& params) + { + Graphics* graphics = Graphics::Instance(); + NazaraAssert(graphics, "Utility module has not been initialized"); + + return graphics->GetMaterialLoader().LoadFromStream(stream, params); + } }