diff --git a/.gitignore b/.gitignore index d671b209b..258594792 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Nazara build examples/bin/*.exe examples/bin/*.pdb +examples/bin/*.dll +examples/bin/*.so tests/*.exe tests/*.pdb lib/* diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 7ff31d623..d3bb9177e 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -2,9 +2,9 @@ // This file is part of the "Nazara Development Kit" // For conditions of distribution and use, see copyright notice in Prerequesites.hpp +#include #include #include -#include "CameraComponent.hpp" namespace Ndk { diff --git a/SDK/include/NDK/EntityOwner.hpp b/SDK/include/NDK/EntityOwner.hpp index c7cab901f..d0a4a4f59 100644 --- a/SDK/include/NDK/EntityOwner.hpp +++ b/SDK/include/NDK/EntityOwner.hpp @@ -17,7 +17,7 @@ namespace Ndk EntityOwner() = default; explicit EntityOwner(Entity* entity); EntityOwner(const EntityOwner& handle) = delete; - EntityOwner(EntityOwner&& handle); + EntityOwner(EntityOwner&& handle) noexcept = default; ~EntityOwner(); void Reset(Entity* entity = nullptr); @@ -25,7 +25,7 @@ namespace Ndk EntityOwner& operator=(Entity* entity); EntityOwner& operator=(const EntityOwner& handle) = delete; - EntityOwner& operator=(EntityOwner&& handle); + EntityOwner& operator=(EntityOwner&& handle) noexcept = default; }; } diff --git a/SDK/include/NDK/EntityOwner.inl b/SDK/include/NDK/EntityOwner.inl index 607f3229d..6efc2b30e 100644 --- a/SDK/include/NDK/EntityOwner.inl +++ b/SDK/include/NDK/EntityOwner.inl @@ -14,11 +14,6 @@ namespace Ndk Reset(entity); } - inline EntityOwner::EntityOwner(EntityOwner&& handle) : - EntityHandle(std::move(handle)) - { - } - inline EntityOwner::~EntityOwner() { Reset(nullptr); @@ -44,13 +39,6 @@ namespace Ndk return *this; } - - inline EntityOwner& EntityOwner::operator=(EntityOwner&& handle) - { - Reset(std::move(handle)); - - return *this; - } } namespace std diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index 903e76c05..cbd4e7c4a 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -170,7 +170,7 @@ namespace Nz return 1; default: - *address = *(*static_cast(instance.CheckUserdata(index, "IpAddress"))); + *address = *static_cast(instance.CheckUserdata(index, "IpAddress")); return 1; } } diff --git a/SDK/include/NDK/LuaBinding.hpp b/SDK/include/NDK/LuaBinding.hpp index 265e9e452..cb4fc24e5 100644 --- a/SDK/include/NDK/LuaBinding.hpp +++ b/SDK/include/NDK/LuaBinding.hpp @@ -37,29 +37,6 @@ namespace Ndk void RegisterClasses(Nz::LuaInstance& instance); - private: - void BindCore(); - void BindMath(); - void BindNetwork(); - void BindSDK(); - void BindUtility(); - - void RegisterCore(Nz::LuaInstance& instance); - void RegisterMath(Nz::LuaInstance& instance); - void RegisterNetwork(Nz::LuaInstance& instance); - void RegisterSDK(Nz::LuaInstance& instance); - void RegisterUtility(Nz::LuaInstance& instance); - - #ifndef NDK_SERVER - void BindAudio(); - void BindGraphics(); - void BindRenderer(); - - void RegisterAudio(Nz::LuaInstance& instance); - void RegisterGraphics(Nz::LuaInstance& instance); - void RegisterRenderer(Nz::LuaInstance& instance); - #endif - // Core Nz::LuaClass clockClass; Nz::LuaClass directoryClass; @@ -89,19 +66,6 @@ namespace Ndk Nz::LuaClass velocityComponent; Nz::LuaClass worldClass; - using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); - using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); - - struct ComponentBinding - { - AddComponentFunc adder; - ComponentIndex index; - GetComponentFunc getter; - Nz::String name; - }; - - std::vector m_componentBinding; - #ifndef NDK_SERVER // Audio Nz::LuaClass musicClass; @@ -117,6 +81,46 @@ namespace Ndk Nz::LuaClass consoleClass; Nz::LuaClass graphicsComponent; #endif + + private: + void BindCore(); + void BindMath(); + void BindNetwork(); + void BindSDK(); + void BindUtility(); + + void RegisterCore(Nz::LuaInstance& instance); + void RegisterMath(Nz::LuaInstance& instance); + void RegisterNetwork(Nz::LuaInstance& instance); + void RegisterSDK(Nz::LuaInstance& instance); + void RegisterUtility(Nz::LuaInstance& instance); + + #ifndef NDK_SERVER + void BindAudio(); + void BindGraphics(); + void BindRenderer(); + + void RegisterAudio(Nz::LuaInstance& instance); + void RegisterGraphics(Nz::LuaInstance& instance); + void RegisterRenderer(Nz::LuaInstance& instance); + #endif + + + using AddComponentFunc = int(*)(Nz::LuaInstance&, EntityHandle&); + using GetComponentFunc = int(*)(Nz::LuaInstance&, BaseComponent&); + + struct ComponentBinding + { + AddComponentFunc adder; + ComponentIndex index; + GetComponentFunc getter; + Nz::String name; + }; + + ComponentBinding* QueryComponentIndex(Nz::LuaInstance& lua, int argIndex = 1); + + std::vector m_componentBinding; + std::unordered_map m_componentBindingByName; }; template diff --git a/SDK/include/NDK/LuaBinding.inl b/SDK/include/NDK/LuaBinding.inl index 5ca290398..64e3eb453 100644 --- a/SDK/include/NDK/LuaBinding.inl +++ b/SDK/include/NDK/LuaBinding.inl @@ -21,6 +21,7 @@ namespace Ndk m_componentBinding.resize(T::componentIndex + 1); m_componentBinding[T::componentIndex] = std::move(binding); + m_componentBindingByName[name] = T::componentIndex; } template diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 4b65de11d..72aa1efb1 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -8,7 +8,9 @@ #define NDK_SYSTEMS_RENDERSYSTEM_HPP #include -#include +#include +#include +#include #include #include #include @@ -48,13 +50,19 @@ namespace Ndk void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; + void UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer); + void UpdatePointSpotShadowMaps(); std::unique_ptr m_renderTechnique; EntityList m_cameras; EntityList m_drawables; + EntityList m_directionalLights; EntityList m_lights; + EntityList m_pointSpotLights; Nz::BackgroundRef m_background; + Nz::DepthRenderTechnique m_shadowTechnique; Nz::Matrix4f m_coordinateSystemMatrix; + Nz::RenderTexture m_shadowRT; bool m_coordinateSystemInvalidated; }; } diff --git a/SDK/src/NDK/LuaBinding_SDK.cpp b/SDK/src/NDK/LuaBinding_SDK.cpp index 289e316a3..b371e76e3 100644 --- a/SDK/src/NDK/LuaBinding_SDK.cpp +++ b/SDK/src/NDK/LuaBinding_SDK.cpp @@ -59,56 +59,29 @@ namespace Ndk entityClass.BindMethod("Kill", &Entity::Kill); entityClass.BindMethod("IsEnabled", &Entity::IsEnabled); entityClass.BindMethod("IsValid", &Entity::IsValid); - entityClass.BindMethod("RemoveComponent", (void(Entity::*)(ComponentIndex)) &Entity::RemoveComponent); entityClass.BindMethod("RemoveAllComponents", &Entity::RemoveAllComponents); entityClass.BindMethod("__tostring", &EntityHandle::ToString); - entityClass.BindMethod("AddComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("AddComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); + ComponentBinding* binding = QueryComponentIndex(instance); - if (componentIndex > m_componentBinding.size()) - { - lua.Error("Invalid component index"); - return 0; - } - - ComponentBinding& binding = m_componentBinding[componentIndex]; - if (binding.name.IsEmpty()) - { - lua.Error("This component is not available to the LuaAPI"); - return 0; - } - - return binding.adder(lua, handle); + return binding->adder(instance, handle); }); - entityClass.BindMethod("GetComponent", [this] (Nz::LuaInstance& lua, EntityHandle& handle) -> int + entityClass.BindMethod("GetComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int { - int index = 1; - ComponentIndex componentIndex = lua.Check(&index); + ComponentBinding* binding = QueryComponentIndex(instance); - if (!handle->HasComponent(componentIndex)) - { - lua.PushNil(); - return 1; - } + return binding->getter(instance, handle->GetComponent(binding->index)); + }); - if (componentIndex > m_componentBinding.size()) - { - lua.Error("Invalid component index"); - return 0; - } + entityClass.BindMethod("RemoveComponent", [this] (Nz::LuaInstance& instance, EntityHandle& handle) -> int + { + ComponentBinding* binding = QueryComponentIndex(instance); - ComponentBinding& binding = m_componentBinding[componentIndex]; - if (binding.name.IsEmpty()) - { - lua.Error("This component is not available to the LuaAPI"); - return 0; - } - - return binding.getter(lua, handle->GetComponent(componentIndex)); + handle->RemoveComponent(binding->index); + return 0; }); /*********************************** Ndk::NodeComponent **********************************/ @@ -199,4 +172,45 @@ namespace Ndk } instance.SetGlobal("ComponentType"); } + + LuaBinding::ComponentBinding* LuaBinding::QueryComponentIndex(Nz::LuaInstance& instance, int argIndex) + { + switch (instance.GetType(argIndex)) + { + case Nz::LuaType_Number: + { + ComponentIndex componentIndex = instance.Check(&argIndex); + if (componentIndex > m_componentBinding.size()) + { + instance.Error("Invalid component index"); + return nullptr; + } + + ComponentBinding& binding = m_componentBinding[componentIndex]; + if (binding.name.IsEmpty()) + { + instance.Error("Invalid component index"); + return nullptr; + } + + return &binding; + } + + case Nz::LuaType_String: + { + const char* key = instance.CheckString(argIndex); + auto it = m_componentBindingByName.find(key); + if (it == m_componentBindingByName.end()) + { + instance.Error("Invalid component name"); + return nullptr; + } + + return &m_componentBinding[it->second]; + } + } + + instance.Error("Invalid component index at #" + Nz::String::Number(argIndex)); + return nullptr; + } } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 3237bbe52..7b90761b6 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include #include @@ -48,9 +50,27 @@ namespace Ndk m_drawables.Remove(entity); if (entity->HasComponent() && entity->HasComponent()) + { + LightComponent& lightComponent = entity->GetComponent(); + if (lightComponent.GetLightType() == Nz::LightType_Directional) + { + m_directionalLights.Insert(entity); + m_pointSpotLights.Remove(entity); + } + else + { + m_directionalLights.Remove(entity); + m_pointSpotLights.Insert(entity); + } + m_lights.Insert(entity); + } else + { + m_directionalLights.Remove(entity); m_lights.Remove(entity); + m_pointSpotLights.Remove(entity); + } } void RenderSystem::OnUpdate(float elapsedTime) @@ -69,10 +89,13 @@ namespace Ndk m_coordinateSystemInvalidated = false; } + UpdatePointSpotShadowMaps(); + for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); - camComponent.ApplyView(); + + //UpdateDirectionalShadowMaps(camComponent); Nz::AbstractRenderQueue* renderQueue = m_renderTechnique->GetRenderQueue(); renderQueue->Clear(); @@ -89,12 +112,14 @@ namespace Ndk for (const Ndk::EntityHandle& light : m_lights) { LightComponent& lightComponent = light->GetComponent(); - NodeComponent& drawableNode = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); ///TODO: Cache somehow? - lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); + lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, lightNode.GetTransformMatrix())); } + camComponent.ApplyView(); + Nz::SceneData sceneData; sceneData.ambientColor = Nz::Color(25, 25, 25); sceneData.background = m_background; @@ -105,5 +130,146 @@ namespace Ndk } } + void RenderSystem::UpdateDirectionalShadowMaps(const Nz::AbstractViewer& viewer) + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + Nz::SceneData dummySceneData; + dummySceneData.ambientColor = Nz::Color(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + + for (const Ndk::EntityHandle& light : m_directionalLights) + { + LightComponent& lightComponent = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); + + if (!lightComponent.IsShadowCastingEnabled()) + continue; + + Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + Nz::Renderer::SetTarget(&m_shadowRT); + Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + ///TODO: Cache the matrices in the light? + Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f)); + Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetRotation() * Nz::Vector3f::Forward() * 100.f, lightNode.GetRotation())); + + m_shadowTechnique.Clear(dummySceneData); + m_shadowTechnique.Draw(dummySceneData); + } + } + + void RenderSystem::UpdatePointSpotShadowMaps() + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + Nz::SceneData dummySceneData; + dummySceneData.ambientColor = Nz::Color(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + + for (const Ndk::EntityHandle& light : m_pointSpotLights) + { + LightComponent& lightComponent = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); + + if (!lightComponent.IsShadowCastingEnabled()) + continue; + + Nz::Vector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + switch (lightComponent.GetLightType()) + { + case Nz::LightType_Directional: + NazaraInternalError("Directional lights included in point/spot light list"); + break; + + case Nz::LightType_Point: + { + static Nz::Quaternionf rotations[6] = + { + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitX()), // nzCubemapFace_PositiveX + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitX()), // nzCubemapFace_NegativeX + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitY()), // nzCubemapFace_PositiveY + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitY()), // nzCubemapFace_NegativeY + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), -Nz::Vector3f::UnitZ()), // nzCubemapFace_PositiveZ + Nz::Quaternionf::RotationBetween(Nz::Vector3f::Forward(), Nz::Vector3f::UnitZ()) // nzCubemapFace_NegativeZ + }; + + for (unsigned int face = 0; face < 6; ++face) + { + m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face); + Nz::Renderer::SetTarget(&m_shadowRT); + Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(Nz::FromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius())); + Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face])); + + Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + m_shadowTechnique.Clear(dummySceneData); + m_shadowTechnique.Draw(dummySceneData); + } + break; + } + + case Nz::LightType_Spot: + { + m_shadowRT.AttachTexture(Nz::AttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + Nz::Renderer::SetTarget(&m_shadowRT); + Nz::Renderer::SetViewport(Nz::Recti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, Nz::Matrix4f::Perspective(lightComponent.GetOuterAngle()*2.f, 1.f, 0.1f, lightComponent.GetRadius())); + Nz::Renderer::SetMatrix(Nz::MatrixType_View, Nz::Matrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); + + Nz::AbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); + renderQueue->Clear(); + + ///TODO: Culling + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + m_shadowTechnique.Clear(dummySceneData); + m_shadowTechnique.Draw(dummySceneData); + break; + } + } + } + } + SystemIndex RenderSystem::systemIndex; } diff --git a/build/Build CodeBlocks (complete).bat b/build/Build_CodeBlocks.bat similarity index 100% rename from build/Build CodeBlocks (complete).bat rename to build/Build_CodeBlocks.bat diff --git a/build/Build CodeBlocks (complete, united).bat b/build/Build_CodeBlocks_OneLibrary.bat similarity index 100% rename from build/Build CodeBlocks (complete, united).bat rename to build/Build_CodeBlocks_OneLibrary.bat diff --git a/build/Build CodeLite (complete).bat b/build/Build_CodeLite.bat similarity index 100% rename from build/Build CodeLite (complete).bat rename to build/Build_CodeLite.bat diff --git a/build/Build CodeLite (complete, united).bat b/build/Build_CodeLite_OneLibrary.bat similarity index 100% rename from build/Build CodeLite (complete, united).bat rename to build/Build_CodeLite_OneLibrary.bat diff --git a/build/Build Visual Studio 2015 (complete).bat b/build/Build_VS2015.bat similarity index 100% rename from build/Build Visual Studio 2015 (complete).bat rename to build/Build_VS2015.bat diff --git a/build/Build Visual Studio 2015 (complete, united).bat b/build/Build_VS2015_OneLibrary.bat similarity index 100% rename from build/Build Visual Studio 2015 (complete, united).bat rename to build/Build_VS2015_OneLibrary.bat diff --git a/build/Encode Resources.bat b/build/EncodeResources.bat similarity index 100% rename from build/Encode Resources.bat rename to build/EncodeResources.bat diff --git a/build/Generate Headers.bat b/build/Generate_GlobalIncludes.bat similarity index 100% rename from build/Generate Headers.bat rename to build/Generate_GlobalIncludes.bat diff --git a/build/Parse Unicode.bat b/build/Generate_UnicodeData.bat similarity index 100% rename from build/Parse Unicode.bat rename to build/Generate_UnicodeData.bat diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 266b50f85..405b66b60 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -298,6 +298,14 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") end + -- Copy the module binaries to the example folder + if (toolTable.CopyTargetToExampleDir) then + if (os.is("windows")) then + configuration({}) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) + end + end + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") diff --git a/build/scripts/tools/assimp.lua b/build/scripts/tools/assimp.lua index 0eecbcd54..3a1ca093b 100644 --- a/build/scripts/tools/assimp.lua +++ b/build/scripts/tools/assimp.lua @@ -3,6 +3,8 @@ TOOL.Name = "Assimp" TOOL.Directory = "../SDK/lib" TOOL.Kind = "Plugin" +TOOL.CopyTargetToExampleDir = true + TOOL.Includes = { "../include", "../plugins/Assimp" diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index ba55d2686..73864abaa 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ int main() for (;;) { - Nz::Directory resourceDirectory("resources/"); + Nz::Directory resourceDirectory("resources"); if (!resourceDirectory.Open()) { std::cerr << "Failed to open resource directory" << std::endl; @@ -68,7 +69,7 @@ int main() break; Nz::Mesh mesh; - if (!mesh.LoadFromFile("resources/" + models[iChoice-1])) + if (!mesh.LoadFromFile(resourceDirectory.GetPath() + '/' + models[iChoice-1])) { std::cout << "Failed to load mesh" << std::endl; std::getchar(); @@ -168,8 +169,18 @@ int main() { for (unsigned int i = 0; i < materialCount; ++i) { - std::cout << "\t" << (i+1) << ": " << mesh.GetMaterial(i) << std::endl; - std::cin.ignore(std::numeric_limits::max(), '\n'); + const Nz::ParameterList& matData = mesh.GetMaterialData(i); + + Nz::String data; + if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data)) + { + if (matData.HasParameter(Nz::MaterialData::CustomDefined)) + data = ""; + else + data = ""; + } + + std::cout << "\t" << (i+1) << ": " << data << std::endl; } } diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index a9a93d45c..5f3c85c4c 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 03 Feb 2016 at 00:06:56 +// This file was automatically generated on 09 May 2016 at 17:07:09 /* Nazara Engine - Core module @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -72,8 +74,10 @@ #include #include #include +#include +#include #include -#include +#include #include #include #include diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 5f8b8aa7f..f031854c5 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index c45147d79..821a9069f 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -209,14 +209,8 @@ namespace Nz template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { - // Flush bits if a writing is in progress - if (context.currentBitPos != 8) - { - context.currentBitPos = 8; - - if (!Serialize(context, context.currentByte)) - NazaraWarning("Failed to flush bits"); - } + // Flush bits in case a writing is in progress + context.FlushBits(); if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) SwapBytes(&value, sizeof(T)); @@ -269,8 +263,7 @@ namespace Nz { NazaraAssert(value, "Invalid data pointer"); - // Reset bit position - context.currentBitPos = 8; + context.ResetBitPosition(); if (context.stream->Read(value, sizeof(T)) == sizeof(T)) { diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index a371212ab..3b440278c 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -31,7 +31,7 @@ namespace Nz Bitset(const char* bits, unsigned int bitCount); Bitset(const Bitset& bitset) = default; explicit Bitset(const String& bits); - template explicit Bitset(T value); + template Bitset(T value); Bitset(Bitset&& bitset) noexcept = default; ~Bitset() noexcept = default; diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index d689ff18a..568d4a815 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -120,19 +120,16 @@ namespace Nz { if (sizeof(T) <= sizeof(Block)) { - m_bitCount = CountBits(value); + m_bitCount = std::numeric_limits::digits; m_blocks.push_back(value); } else { // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits - unsigned int bitPos = 0; - for (T bit = 1; bit < std::numeric_limits::digits; bit <<= 1) + for (unsigned int bitPos = 0; bitPos < std::numeric_limits::digits; bitPos++) { - if (value & bit) + if (value & (T(1U) << bitPos)) UnboundedSet(bitPos, true); - - bitPos++; } } } @@ -838,7 +835,7 @@ namespace Nz Block block = m_blocks[i]; - // Compute the position of LSB in the block (and adjustement of the position) + // Compute the position of LSB in the block (and adjustment of the position) return IntegralLog2Pot(block & -block) + i*bitsPerBlock; } diff --git a/include/Nazara/Core/ByteStream.hpp b/include/Nazara/Core/ByteStream.hpp index e26382cf4..fe1516b06 100644 --- a/include/Nazara/Core/ByteStream.hpp +++ b/include/Nazara/Core/ByteStream.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 91a8cc43d..5fef4f854 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -25,6 +25,8 @@ namespace Nz inline Color(const Color& color) = default; inline ~Color() = default; + inline bool IsOpaque() const; + inline String ToString() const; inline Color operator+(const Color& angles) const; diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 4ac3a2246..5d71393df 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -72,6 +72,15 @@ namespace Nz { } + /*! + * \brief Return true is the color has no degree of transparency + * \return true if the color has an alpha value of 255 + */ + inline bool Color::IsOpaque() const + { + return a == 255; + } + /*! * \brief Converts this to string * \return String representation of the object "Color(r, g, b[, a])" diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 02039811b..7a5c161ab 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -93,6 +93,7 @@ namespace Nz enum ParameterType { ParameterType_Boolean, + ParameterType_Color, ParameterType_Float, ParameterType_Integer, ParameterType_None, diff --git a/include/Nazara/Core/HandledObject.hpp b/include/Nazara/Core/HandledObject.hpp index f1e096748..eeb9c4bfa 100644 --- a/include/Nazara/Core/HandledObject.hpp +++ b/include/Nazara/Core/HandledObject.hpp @@ -36,7 +36,8 @@ namespace Nz private: void RegisterHandle(ObjectHandle* handle); - void UnregisterHandle(ObjectHandle* handle); + void UnregisterHandle(ObjectHandle* handle) noexcept; + void UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* newHandle) noexcept; std::vector*> m_handles; }; diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl index 53a5065f4..738a5f7a5 100644 --- a/include/Nazara/Core/HandledObject.inl +++ b/include/Nazara/Core/HandledObject.inl @@ -71,14 +71,24 @@ namespace Nz } template - void HandledObject::UnregisterHandle(ObjectHandle* handle) + void HandledObject::UnregisterHandle(ObjectHandle* handle) noexcept { ///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash auto it = std::find(m_handles.begin(), m_handles.end(), handle); - NazaraAssert(it != m_handles.end(), "Handle not registred"); + NazaraAssert(it != m_handles.end(), "Handle not registered"); - // On échange cet élément avec le dernier, et on diminue la taille du vector de 1 + // Swap and pop idiom, more efficient than vector::erase std::swap(*it, m_handles.back()); m_handles.pop_back(); } + + template + void HandledObject::UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* newHandle) noexcept + { + auto it = std::find(m_handles.begin(), m_handles.end(), oldHandle); + NazaraAssert(it != m_handles.end(), "Handle not registered"); + + // Simply update the handle + *it = newHandle; + } } diff --git a/include/Nazara/Core/ObjectHandle.hpp b/include/Nazara/Core/ObjectHandle.hpp index d7a53e281..b3cc080dd 100644 --- a/include/Nazara/Core/ObjectHandle.hpp +++ b/include/Nazara/Core/ObjectHandle.hpp @@ -23,6 +23,7 @@ namespace Nz ObjectHandle(); explicit ObjectHandle(T* object); ObjectHandle(const ObjectHandle& handle); + ObjectHandle(ObjectHandle&& handle) noexcept; ~ObjectHandle(); T* GetObject() const; @@ -31,6 +32,7 @@ namespace Nz void Reset(T* object = nullptr); void Reset(const ObjectHandle& handle); + void Reset(ObjectHandle&& handle) noexcept; ObjectHandle& Swap(ObjectHandle& handle); @@ -42,6 +44,7 @@ namespace Nz ObjectHandle& operator=(T* object); ObjectHandle& operator=(const ObjectHandle& handle); + ObjectHandle& operator=(ObjectHandle&& handle) noexcept; static const ObjectHandle InvalidHandle; diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index 752cb96c0..cfcd6bc0d 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -24,11 +24,18 @@ namespace Nz template ObjectHandle::ObjectHandle(const ObjectHandle& handle) : - ObjectHandle() + ObjectHandle() { Reset(handle); } + template + ObjectHandle::ObjectHandle(ObjectHandle&& handle) noexcept : + ObjectHandle() + { + Reset(std::move(handle)); + } + template ObjectHandle::~ObjectHandle() { @@ -66,6 +73,20 @@ namespace Nz Reset(handle.GetObject()); } + template + void ObjectHandle::Reset(ObjectHandle&& handle) noexcept + { + if (m_object) + m_object->UnregisterHandle(this); + + if (T* object = handle.GetObject()) + { + m_object = handle.m_object; + handle.m_object = nullptr; + object->UpdateHandle(&handle, this); + } + } + template ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) { @@ -138,6 +159,14 @@ namespace Nz return *this; } + template + ObjectHandle& ObjectHandle::operator=(ObjectHandle&& handle) noexcept + { + Reset(std::move(handle)); + + return *this; + } + template void ObjectHandle::OnObjectDestroyed() { diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 8debb7d91..6f3ccab9a 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -17,8 +17,6 @@ namespace Nz template class ObjectRef { - static_assert(std::is_base_of::value, "ObjectRef shall only be used with RefCounted-derived type"); - public: ObjectRef(); ObjectRef(T* object); diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index 2475185d7..119d05cca 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -8,6 +8,7 @@ #define NAZARA_PARAMETERLIST_HPP #include +#include #include #include #include @@ -27,6 +28,7 @@ namespace Nz void Clear(); bool GetBooleanParameter(const String& name, bool* value) const; + bool GetColorParameter(const String& name, Color* value) const; bool GetFloatParameter(const String& name, float* value) const; bool GetIntegerParameter(const String& name, int* value) const; bool GetParameterType(const String& name, ParameterType* type) const; @@ -39,13 +41,14 @@ namespace Nz void RemoveParameter(const String& name); void SetParameter(const String& name); + void SetParameter(const String& name, const Color& value); void SetParameter(const String& name, const String& value); void SetParameter(const String& name, const char* value); - void SetParameter(const String& name, void* value); - void SetParameter(const String& name, void* value, Destructor destructor); void SetParameter(const String& name, bool value); void SetParameter(const String& name, float value); void SetParameter(const String& name, int value); + void SetParameter(const String& name, void* value); + void SetParameter(const String& name, void* value, Destructor destructor); ParameterList& operator=(const ParameterList& list); ParameterList& operator=(ParameterList&&) = default; @@ -79,6 +82,7 @@ namespace Nz float floatVal; int intVal; void* ptrVal; + Color colorVal; String stringVal; UserdataValue* userdataVal; }; diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/SerializationContext.hpp similarity index 79% rename from include/Nazara/Core/Serialization.hpp rename to include/Nazara/Core/SerializationContext.hpp index 47339b0a2..64c558a7b 100644 --- a/include/Nazara/Core/Serialization.hpp +++ b/include/Nazara/Core/SerializationContext.hpp @@ -8,6 +8,7 @@ #define NAZARA_SERIALIZATION_HPP #include +#include #include #include #include @@ -17,13 +18,18 @@ namespace Nz { class Stream; - struct SerializationContext + struct NAZARA_CORE_API SerializationContext { Stream* stream; Endianness endianness = Endianness_BigEndian; //< Default to Big Endian encoding UInt8 currentBitPos = 8; //< 8 means no bit is currently wrote UInt8 currentByte; //< Undefined value, will be initialized at the first bit write + + void FlushBits(); + inline void ResetBitPosition(); }; } +#include + #endif // NAZARA_SERIALIZATION_HPP diff --git a/include/Nazara/Core/SerializationContext.inl b/include/Nazara/Core/SerializationContext.inl new file mode 100644 index 000000000..47f56e5c2 --- /dev/null +++ b/include/Nazara/Core/SerializationContext.inl @@ -0,0 +1,24 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + /*! + * \brief Reset the current bit cursor + + * \remark This function only reset the cursor position, it doesn't do any writing + if you wish to write all bits and reset bit position, call FlushBits + + \see FlushBits + */ + inline void SerializationContext::ResetBitPosition() + { + currentBitPos = 8; + } +} + +#include diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 70673ae8a..765ef8b85 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 6c069e1d9..50c6e0832 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -62,7 +62,9 @@ namespace Nz struct DirectionalLight { Color color; + Matrix4f transformMatrix; Vector3f direction; + Texture* shadowMap; float ambientFactor; float diffuseFactor; }; @@ -71,6 +73,7 @@ namespace Nz { Color color; Vector3f position; + Texture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; @@ -81,8 +84,10 @@ namespace Nz struct SpotLight { Color color; + Matrix4f transformMatrix; Vector3f direction; Vector3f position; + Texture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp new file mode 100644 index 000000000..0b8a1fc5d --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -0,0 +1,53 @@ +// 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 + +#pragma once + +#ifndef NAZARA_DEPTHRENDERQUEUE_HPP +#define NAZARA_DEPTHRENDERQUEUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_GRAPHICS_API DepthRenderQueue : public ForwardRenderQueue + { + public: + DepthRenderQueue(); + ~DepthRenderQueue() = default; + + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDirectionalLight(const DirectionalLight& light) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddPointLight(const PointLight& light) override; + void AddSpotLight(const SpotLight& light) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + + private: + inline bool IsMaterialSuitable(const Material* material) const; + + MaterialRef m_baseMaterial; + }; +} + +#include + +#endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderQueue.inl b/include/Nazara/Graphics/DepthRenderQueue.inl new file mode 100644 index 000000000..7d6c9221f --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderQueue.inl @@ -0,0 +1,17 @@ +// 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 + +namespace Nz +{ + bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const + { + NazaraAssert(material, "Invalid material"); + + return material->HasDepthMaterial() || (material->IsEnabled(RendererParameter_DepthBuffer) && material->IsEnabled(RendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); + } +} + +#include diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp new file mode 100644 index 000000000..ac75f7e52 --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -0,0 +1,79 @@ +// 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 + +#pragma once + +#ifndef NAZARA_DEPTHRENDERTECHNIQUE_HPP +#define NAZARA_DEPTHRENDERTECHNIQUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_GRAPHICS_API DepthRenderTechnique : public AbstractRenderTechnique + { + public: + DepthRenderTechnique(); + ~DepthRenderTechnique() = default; + + void Clear(const SceneData& sceneData) const override; + bool Draw(const SceneData& sceneData) const override; + + AbstractRenderQueue* GetRenderQueue() override; + RenderTechniqueType GetType() const override; + + static bool Initialize(); + static void Uninitialize(); + + private: + struct ShaderUniforms; + + void DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; + void OnShaderInvalidated(const Shader* shader) const; + + struct LightIndex + { + LightType type; + float score; + unsigned int index; + }; + + struct ShaderUniforms + { + NazaraSlot(Shader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); + + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; + + mutable std::unordered_map m_shaderUniforms; + Buffer m_vertexBuffer; + mutable DepthRenderQueue m_renderQueue; + VertexBuffer m_billboardPointBuffer; + VertexBuffer m_spriteBuffer; + + static IndexBuffer s_quadIndexBuffer; + static VertexBuffer s_quadVertexBuffer; + static VertexDeclaration s_billboardInstanceDeclaration; + static VertexDeclaration s_billboardVertexDeclaration; + }; +} + + +#include + +#endif // NAZARA_DEPTHRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.inl b/include/Nazara/Graphics/DepthRenderTechnique.inl new file mode 100644 index 000000000..ac6b052d0 --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderTechnique.inl @@ -0,0 +1,3 @@ +// 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 diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 6cbbe0f03..6703f88a0 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -108,6 +108,7 @@ namespace Nz RenderTechniqueType_AdvancedForward, // AdvancedForwardRenderTechnique RenderTechniqueType_BasicForward, // BasicForwardRenderTechnique RenderTechniqueType_DeferredShading, // DeferredRenderTechnique + RenderTechniqueType_Depth, // DepthRenderTechnique RenderTechniqueType_LightPrePass, // LightPrePassRenderTechnique RenderTechniqueType_User, diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 6881ac2d7..447818958 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -36,7 +36,7 @@ namespace Nz static bool Initialize(); static void Uninitialize(); - private: + protected: struct ShaderUniforms; void ChooseLights(const Spheref& object, bool includeDirectionalLights = true) const; @@ -46,7 +46,7 @@ namespace Nz void DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; void OnShaderInvalidated(const Shader* shader) const; - void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; + void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const; static float ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light); static float ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light); @@ -89,6 +89,7 @@ namespace Nz unsigned int m_maxLightPassPerObject; static IndexBuffer s_quadIndexBuffer; + static TextureSampler s_shadowSampler; static VertexBuffer s_quadVertexBuffer; static VertexDeclaration s_billboardInstanceDeclaration; static VertexDeclaration s_billboardVertexDeclaration; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 69ae7614f..bf9e5674c 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -2,10 +2,16 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { - inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const + inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const { + // If anyone got a better idea.. + int dummyCubemap = Renderer::GetMaxTextureUnits() - 1; + int dummyTexture = Renderer::GetMaxTextureUnits() - 2; + if (index < m_lights.size()) { const LightIndex& lightIndex = m_lights[index]; @@ -21,6 +27,20 @@ namespace Nz shader->SendColor(uniforms.locations.color + uniformOffset, light.color); shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + Renderer::SetTexture(availableTextureUnit, light.shadowMap); + Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); break; } @@ -32,6 +52,19 @@ namespace Nz shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + Renderer::SetTexture(availableTextureUnit, light.shadowMap); + Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); break; } @@ -44,12 +77,31 @@ namespace Nz shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + Renderer::SetTexture(availableTextureUnit, light.shadowMap); + Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + break; } } } else + { shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + } } inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) @@ -78,7 +130,7 @@ namespace Nz NazaraUnused(object); NazaraUnused(light); - // Directional light are always suitables + // Directional light are always suitable return true; } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index efa468ba6..071b748c3 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include namespace Nz { @@ -21,7 +23,8 @@ namespace Nz { public: Light(LightType type = LightType_Point); - Light(const Light& light) = default; + inline Light(const Light& light); + Light(Light&& light) = default; ~Light() = default; void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const override; @@ -31,37 +34,56 @@ namespace Nz bool Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const override; - float GetAmbientFactor() const; - float GetAttenuation() const; - Color GetColor() const; - float GetDiffuseFactor() const; - float GetInnerAngle() const; - float GetInnerAngleCosine() const; - float GetInvRadius() const; - LightType GetLightType() const; - float GetOuterAngle() const; - float GetOuterAngleCosine() const; - float GetOuterAngleTangent() const; - float GetRadius() const; + inline void EnableShadowCasting(bool castShadows); - void SetAmbientFactor(float factor); - void SetAttenuation(float attenuation); - void SetColor(const Color& color); - void SetDiffuseFactor(float factor); - void SetInnerAngle(float innerAngle); - void SetLightType(LightType type); - void SetOuterAngle(float outerAngle); - void SetRadius(float radius); + inline void EnsureShadowMapUpdate() const; + + inline float GetAmbientFactor() const; + inline float GetAttenuation() const; + inline Color GetColor() const; + inline float GetDiffuseFactor() const; + inline float GetInnerAngle() const; + inline float GetInnerAngleCosine() const; + inline float GetInvRadius() const; + inline LightType GetLightType() const; + inline float GetOuterAngle() const; + inline float GetOuterAngleCosine() const; + inline float GetOuterAngleTangent() const; + inline float GetRadius() const; + inline TextureRef GetShadowMap() const; + inline PixelFormatType GetShadowMapFormat() const; + inline const Vector2ui& GetShadowMapSize() const; + + inline bool IsShadowCastingEnabled() const; + + inline void SetAmbientFactor(float factor); + inline void SetAttenuation(float attenuation); + inline void SetColor(const Color& color); + inline void SetDiffuseFactor(float factor); + inline void SetInnerAngle(float innerAngle); + inline void SetLightType(LightType type); + inline void SetOuterAngle(float outerAngle); + inline void SetRadius(float radius); + inline void SetShadowMapFormat(PixelFormatType shadowFormat); + inline void SetShadowMapSize(const Vector2ui& size); void UpdateBoundingVolume(const Matrix4f& transformMatrix) override; - Light& operator=(const Light& light) = default; + Light& operator=(const Light& light); + Light& operator=(Light&& light) = default; private: void MakeBoundingVolume() const override; + inline void InvalidateShadowMap(); + void UpdateShadowMap() const; - LightType m_type; Color m_color; + LightType m_type; + PixelFormatType m_shadowMapFormat; + Vector2ui m_shadowMapSize; + mutable TextureRef m_shadowMap; + bool m_shadowCastingEnabled; + mutable bool m_shadowMapUpdated; float m_ambientFactor; float m_attenuation; float m_diffuseFactor; @@ -80,10 +102,14 @@ namespace Nz { int type; int color; + int directionalSpotLightShadowMap; int factors; + int lightViewProjMatrix; int parameters1; int parameters2; int parameters3; + int pointLightShadowMap; + int shadowMapping; }; bool ubo; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index ad64e93dc..266f7939a 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -7,6 +7,42 @@ namespace Nz { + inline Light::Light(const Light& light) : + Renderable(light), + m_type(light.m_type), + m_shadowMapFormat(light.m_shadowMapFormat), + m_color(light.m_color), + m_shadowMapSize(light.m_shadowMapSize), + m_shadowCastingEnabled(light.m_shadowCastingEnabled), + m_shadowMapUpdated(false), + m_ambientFactor(light.m_ambientFactor), + m_attenuation(light.m_attenuation), + m_diffuseFactor(light.m_diffuseFactor), + m_innerAngle(light.m_innerAngle), + m_innerAngleCosine(light.m_innerAngleCosine), + m_invRadius(light.m_invRadius), + m_outerAngle(light.m_outerAngle), + m_outerAngleCosine(light.m_outerAngleCosine), + m_outerAngleTangent(light.m_outerAngleTangent), + m_radius(light.m_radius) + { + } + + inline void Light::EnableShadowCasting(bool castShadows) + { + if (m_shadowCastingEnabled != castShadows) + { + m_shadowCastingEnabled = castShadows; + m_shadowMapUpdated = false; + } + } + + inline void Light::EnsureShadowMapUpdate() const + { + if (!m_shadowMapUpdated) + UpdateShadowMap(); + } + inline float Light::GetAmbientFactor() const { return m_ambientFactor; @@ -67,6 +103,28 @@ namespace Nz return m_radius; } + inline TextureRef Light::GetShadowMap() const + { + EnsureShadowMapUpdate(); + + return m_shadowMap; + } + + inline PixelFormatType Light::GetShadowMapFormat() const + { + return m_shadowMapFormat; + } + + inline const Vector2ui& Light::GetShadowMapSize() const + { + return m_shadowMapSize; + } + + inline bool Light::IsShadowCastingEnabled() const + { + return m_shadowCastingEnabled; + } + inline void Light::SetAmbientFactor(float factor) { m_ambientFactor = factor; @@ -96,6 +154,8 @@ namespace Nz inline void Light::SetLightType(LightType type) { m_type = type; + + InvalidateShadowMap(); } inline void Light::SetOuterAngle(float outerAngle) @@ -115,6 +175,53 @@ namespace Nz InvalidateBoundingVolume(); } + + inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat) + { + NazaraAssert(PixelFormat::GetType(shadowFormat) == PixelFormatTypeType_Depth, "Shadow format type is not a depth format"); + + m_shadowMapFormat = shadowFormat; + + InvalidateShadowMap(); + } + + inline void Light::SetShadowMapSize(const Vector2ui& size) + { + NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size"); + + m_shadowMapSize = size; + + InvalidateShadowMap(); + } + + inline Light& Light::operator=(const Light& light) + { + Renderable::operator=(light); + + m_ambientFactor = light.m_ambientFactor; + m_attenuation = light.m_attenuation; + m_color = light.m_color; + m_diffuseFactor = light.m_diffuseFactor; + m_innerAngle = light.m_innerAngle; + m_innerAngleCosine = light.m_innerAngleCosine; + m_invRadius = light.m_invRadius; + m_outerAngle = light.m_outerAngle; + m_outerAngleCosine = light.m_outerAngleCosine; + m_outerAngleTangent = light.m_outerAngleTangent; + m_radius = light.m_radius; + m_shadowCastingEnabled = light.m_shadowCastingEnabled; + m_shadowMapFormat = light.m_shadowMapFormat; + m_shadowMapSize = light.m_shadowMapSize; + m_type = light.m_type; + + InvalidateShadowMap(); + return *this; + } + + inline void Light::InvalidateShadowMap() + { + m_shadowMapUpdated = false; + } } #include diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index a2d30b643..4a110c64f 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace Nz { @@ -56,90 +57,99 @@ namespace Nz friend class Graphics; public: - Material(); - Material(const Material& material); - ~Material(); + inline Material(); + inline Material(const Material& material); + inline ~Material(); const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; - void Enable(RendererParameter renderParameter, bool enable); - void EnableAlphaTest(bool alphaTest); - void EnableDepthSorting(bool depthSorting); - void EnableLighting(bool lighting); - void EnableTransform(bool transform); + void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams()); - Texture* GetAlphaMap() const; - float GetAlphaThreshold() const; - Color GetAmbientColor() const; - RendererComparison GetDepthFunc() const; - Color GetDiffuseColor() const; - Texture* GetDiffuseMap() const; - TextureSampler& GetDiffuseSampler(); - const TextureSampler& GetDiffuseSampler() const; - BlendFunc GetDstBlend() const; - Texture* GetEmissiveMap() const; - FaceSide GetFaceCulling() const; - FaceFilling GetFaceFilling() const; - Texture* GetHeightMap() const; - Texture* GetNormalMap() const; - const RenderStates& GetRenderStates() const; - const UberShader* GetShader() const; - const UberShaderInstance* GetShaderInstance(UInt32 flags = ShaderFlags_None) const; - float GetShininess() const; - Color GetSpecularColor() const; - Texture* GetSpecularMap() const; - TextureSampler& GetSpecularSampler(); - const TextureSampler& GetSpecularSampler() const; - BlendFunc GetSrcBlend() const; + inline void Enable(RendererParameter renderParameter, bool enable); + inline void EnableAlphaTest(bool alphaTest); + inline void EnableDepthSorting(bool depthSorting); + inline void EnableLighting(bool lighting); + inline void EnableShadowCasting(bool castShadows); + inline void EnableShadowReceive(bool receiveShadows); + inline void EnableTransform(bool transform); - bool HasAlphaMap() const; - bool HasDiffuseMap() const; - bool HasEmissiveMap() const; - bool HasHeightMap() const; - bool HasNormalMap() const; - bool HasSpecularMap() const; + inline const TextureRef& GetAlphaMap() const; + inline float GetAlphaThreshold() const; + inline Color GetAmbientColor() const; + inline RendererComparison GetDepthFunc() const; + inline const MaterialRef& GetDepthMaterial() const; + inline Color GetDiffuseColor() const; + inline const TextureRef& GetDiffuseMap() const; + inline TextureSampler& GetDiffuseSampler(); + inline const TextureSampler& GetDiffuseSampler() const; + inline BlendFunc GetDstBlend() const; + inline const TextureRef& GetEmissiveMap() const; + inline FaceSide GetFaceCulling() const; + inline FaceFilling GetFaceFilling() const; + inline const TextureRef& GetHeightMap() const; + inline const TextureRef& GetNormalMap() const; + inline const RenderStates& GetRenderStates() const; + inline const UberShader* GetShader() const; + inline const UberShaderInstance* GetShaderInstance(UInt32 flags = ShaderFlags_None) const; + inline float GetShininess() const; + inline Color GetSpecularColor() const; + inline const TextureRef& GetSpecularMap() const; + inline TextureSampler& GetSpecularSampler(); + inline const TextureSampler& GetSpecularSampler() const; + inline BlendFunc GetSrcBlend() const; - bool IsAlphaTestEnabled() const; - bool IsDepthSortingEnabled() const; - bool IsEnabled(RendererParameter renderParameter) const; - bool IsLightingEnabled() const; - bool IsTransformEnabled() const; + inline bool HasAlphaMap() const; + inline bool HasDepthMaterial() const; + inline bool HasDiffuseMap() const; + inline bool HasEmissiveMap() const; + inline bool HasHeightMap() const; + inline bool HasNormalMap() const; + inline bool HasSpecularMap() const; - bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); - bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); - bool LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); + inline bool IsAlphaTestEnabled() const; + inline bool IsDepthSortingEnabled() const; + inline bool IsEnabled(RendererParameter renderParameter) const; + inline bool IsLightingEnabled() const; + inline bool IsShadowCastingEnabled() const; + inline bool IsShadowReceiveEnabled() const; + inline bool IsTransformEnabled() const; + + inline bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); + inline bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); + inline bool LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); void Reset(); - bool SetAlphaMap(const String& textureName); - void SetAlphaMap(TextureRef alphaMap); - void SetAlphaThreshold(float alphaThreshold); - void SetAmbientColor(const Color& ambient); - void SetDepthFunc(RendererComparison depthFunc); - void SetDiffuseColor(const Color& diffuse); - bool SetDiffuseMap(const String& textureName); - void SetDiffuseMap(TextureRef diffuseMap); - void SetDiffuseSampler(const TextureSampler& sampler); - void SetDstBlend(BlendFunc func); - bool SetEmissiveMap(const String& textureName); - void SetEmissiveMap(TextureRef textureName); - void SetFaceCulling(FaceSide faceSide); - void SetFaceFilling(FaceFilling filling); - bool SetHeightMap(const String& textureName); - void SetHeightMap(TextureRef textureName); - bool SetNormalMap(const String& textureName); - void SetNormalMap(TextureRef textureName); - void SetRenderStates(const RenderStates& states); - void SetShader(UberShaderConstRef uberShader); - bool SetShader(const String& uberShaderName); - void SetShininess(float shininess); - void SetSpecularColor(const Color& specular); - bool SetSpecularMap(const String& textureName); - void SetSpecularMap(TextureRef specularMap); - void SetSpecularSampler(const TextureSampler& sampler); - void SetSrcBlend(BlendFunc func); + inline bool SetAlphaMap(const String& textureName); + inline void SetAlphaMap(TextureRef alphaMap); + inline void SetAlphaThreshold(float alphaThreshold); + inline void SetAmbientColor(const Color& ambient); + inline void SetDepthFunc(RendererComparison depthFunc); + inline void SetDepthMaterial(MaterialRef depthMaterial); + inline void SetDiffuseColor(const Color& diffuse); + inline bool SetDiffuseMap(const String& textureName); + inline void SetDiffuseMap(TextureRef diffuseMap); + inline void SetDiffuseSampler(const TextureSampler& sampler); + inline void SetDstBlend(BlendFunc func); + inline bool SetEmissiveMap(const String& textureName); + inline void SetEmissiveMap(TextureRef textureName); + inline void SetFaceCulling(FaceSide faceSide); + inline void SetFaceFilling(FaceFilling filling); + inline bool SetHeightMap(const String& textureName); + inline void SetHeightMap(TextureRef textureName); + inline bool SetNormalMap(const String& textureName); + inline void SetNormalMap(TextureRef textureName); + inline void SetRenderStates(const RenderStates& states); + inline void SetShader(UberShaderConstRef uberShader); + inline bool SetShader(const String& uberShaderName); + inline void SetShininess(float shininess); + inline void SetSpecularColor(const Color& specular); + inline bool SetSpecularMap(const String& textureName); + inline void SetSpecularMap(TextureRef specularMap); + inline void SetSpecularSampler(const TextureSampler& sampler); + inline void SetSrcBlend(BlendFunc func); - Material& operator=(const Material& material); + inline Material& operator=(const Material& material); static MaterialRef GetDefault(); template static MaterialRef New(Args&&... args); @@ -158,7 +168,7 @@ namespace Nz void Copy(const Material& material); void GenerateShader(UInt32 flags) const; - void InvalidateShaders(); + inline void InvalidateShaders(); static bool Initialize(); static void Uninitialize(); @@ -166,6 +176,7 @@ namespace Nz Color m_ambientColor; Color m_diffuseColor; Color m_specularColor; + MaterialRef m_depthMaterial; //< Materialception RenderStates m_states; TextureSampler m_diffuseSampler; TextureSampler m_specularSampler; @@ -180,6 +191,8 @@ namespace Nz bool m_alphaTestEnabled; bool m_depthSortingEnabled; bool m_lightingEnabled; + bool m_shadowCastingEnabled; + bool m_shadowReceiveEnabled; bool m_transformEnabled; float m_alphaThreshold; float m_shininess; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 177c8130b..c8559e11f 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -7,6 +7,513 @@ namespace Nz { + inline Material::Material() + { + Reset(); + } + + inline Material::Material(const Material& material) : + RefCounted(), + Resource(material) + { + Copy(material); + } + + inline Material::~Material() + { + OnMaterialRelease(this); + } + + inline void Material::Enable(RendererParameter renderParameter, bool enable) + { + NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum"); + + m_states.parameters[renderParameter] = enable; + } + + inline void Material::EnableAlphaTest(bool alphaTest) + { + m_alphaTestEnabled = alphaTest; + + InvalidateShaders(); + } + + inline void Material::EnableDepthSorting(bool depthSorting) + { + // Has no influence on shaders + m_depthSortingEnabled = depthSorting; + } + + inline void Material::EnableLighting(bool lighting) + { + m_lightingEnabled = lighting; + + InvalidateShaders(); + } + + inline void Material::EnableShadowCasting(bool castShadows) + { + // Has no influence on shaders + m_shadowCastingEnabled = castShadows; + } + + inline void Material::EnableShadowReceive(bool receiveShadows) + { + m_shadowReceiveEnabled = receiveShadows; + + InvalidateShaders(); + } + + inline void Material::EnableTransform(bool transform) + { + m_transformEnabled = transform; + + InvalidateShaders(); + } + + inline const TextureRef& Material::GetAlphaMap() const + { + return m_alphaMap; + } + + inline float Material::GetAlphaThreshold() const + { + return m_alphaThreshold; + } + + inline Color Material::GetAmbientColor() const + { + return m_ambientColor; + } + + inline RendererComparison Material::GetDepthFunc() const + { + return m_states.depthFunc; + } + + inline const MaterialRef& Material::GetDepthMaterial() const + { + return m_depthMaterial; + } + + inline Color Material::GetDiffuseColor() const + { + return m_diffuseColor; + } + + inline TextureSampler& Material::GetDiffuseSampler() + { + return m_diffuseSampler; + } + + inline const TextureSampler& Material::GetDiffuseSampler() const + { + return m_diffuseSampler; + } + + const TextureRef& Material::GetDiffuseMap() const + { + return m_diffuseMap; + } + + inline BlendFunc Material::GetDstBlend() const + { + return m_states.dstBlend; + } + + inline const TextureRef& Material::GetEmissiveMap() const + { + return m_emissiveMap; + } + + inline FaceSide Material::GetFaceCulling() const + { + return m_states.faceCulling; + } + + inline FaceFilling Material::GetFaceFilling() const + { + return m_states.faceFilling; + } + + inline const TextureRef& Material::GetHeightMap() const + { + return m_heightMap; + } + + inline const TextureRef& Material::GetNormalMap() const + { + return m_normalMap; + } + + inline const RenderStates& Material::GetRenderStates() const + { + return m_states; + } + + inline const UberShader* Material::GetShader() const + { + return m_uberShader; + } + + inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const + { + const ShaderInstance& instance = m_shaders[flags]; + if (!instance.uberInstance) + GenerateShader(flags); + + return instance.uberInstance; + } + + inline float Material::GetShininess() const + { + return m_shininess; + } + + inline Color Material::GetSpecularColor() const + { + return m_specularColor; + } + + inline const TextureRef& Material::GetSpecularMap() const + { + return m_specularMap; + } + + inline TextureSampler& Material::GetSpecularSampler() + { + return m_specularSampler; + } + + inline const TextureSampler& Material::GetSpecularSampler() const + { + return m_specularSampler; + } + + inline BlendFunc Material::GetSrcBlend() const + { + return m_states.srcBlend; + } + + inline bool Material::HasAlphaMap() const + { + return m_alphaMap.IsValid(); + } + + inline bool Material::HasDepthMaterial() const + { + return m_depthMaterial.IsValid(); + } + + inline bool Material::HasDiffuseMap() const + { + return m_diffuseMap.IsValid(); + } + + inline bool Material::HasEmissiveMap() const + { + return m_emissiveMap.IsValid(); + } + + inline bool Material::HasHeightMap() const + { + return m_heightMap.IsValid(); + } + + inline bool Material::HasNormalMap() const + { + return m_normalMap.IsValid(); + } + + inline bool Material::HasSpecularMap() const + { + return m_specularMap.IsValid(); + } + + inline bool Material::IsAlphaTestEnabled() const + { + return m_alphaTestEnabled; + } + + inline bool Material::IsDepthSortingEnabled() const + { + return m_depthSortingEnabled; + } + + inline bool Material::IsEnabled(RendererParameter parameter) const + { + NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum"); + + return m_states.parameters[parameter]; + } + + inline bool Material::IsLightingEnabled() const + { + return m_lightingEnabled; + } + + inline bool Material::IsShadowCastingEnabled() const + { + return m_shadowCastingEnabled; + } + + inline bool Material::IsShadowReceiveEnabled() const + { + return m_shadowReceiveEnabled; + } + + inline bool Material::IsTransformEnabled() const + { + return m_transformEnabled; + } + + inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) + { + return MaterialLoader::LoadFromFile(this, filePath, params); + } + + inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) + { + return MaterialLoader::LoadFromMemory(this, data, size, params); + } + + inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) + { + return MaterialLoader::LoadFromStream(this, stream, params); + } + + 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; + } + + inline void Material::SetAlphaMap(TextureRef alphaMap) + { + m_alphaMap = std::move(alphaMap); + + InvalidateShaders(); + } + + inline void Material::SetAlphaThreshold(float alphaThreshold) + { + m_alphaThreshold = alphaThreshold; + } + + inline void Material::SetAmbientColor(const Color& ambient) + { + m_ambientColor = ambient; + } + + inline void Material::SetDepthFunc(RendererComparison depthFunc) + { + m_states.depthFunc = depthFunc; + } + + inline void Material::SetDepthMaterial(MaterialRef depthMaterial) + { + m_depthMaterial = std::move(depthMaterial); + } + + inline void Material::SetDiffuseColor(const Color& diffuse) + { + m_diffuseColor = diffuse; + } + + 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; + } + + inline void Material::SetDiffuseMap(TextureRef diffuseMap) + { + m_diffuseMap = std::move(diffuseMap); + + InvalidateShaders(); + } + + inline void Material::SetDiffuseSampler(const TextureSampler& sampler) + { + m_diffuseSampler = sampler; + } + + inline void Material::SetDstBlend(BlendFunc func) + { + m_states.dstBlend = func; + } + + 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; + } + + inline void Material::SetEmissiveMap(TextureRef emissiveMap) + { + m_emissiveMap = std::move(emissiveMap); + + InvalidateShaders(); + } + + inline void Material::SetFaceCulling(FaceSide faceSide) + { + m_states.faceCulling = faceSide; + } + + inline void Material::SetFaceFilling(FaceFilling filling) + { + m_states.faceFilling = filling; + } + + 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; + } + + inline void Material::SetHeightMap(TextureRef heightMap) + { + m_heightMap = std::move(heightMap); + + InvalidateShaders(); + } + + 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; + } + + inline void Material::SetNormalMap(TextureRef normalMap) + { + m_normalMap = std::move(normalMap); + + InvalidateShaders(); + } + + inline void Material::SetRenderStates(const RenderStates& states) + { + m_states = states; + } + + inline void Material::SetShader(UberShaderConstRef uberShader) + { + m_uberShader = std::move(uberShader); + + InvalidateShaders(); + } + + inline bool Material::SetShader(const String& uberShaderName) + { + UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); + if (!uberShader) + return false; + + SetShader(std::move(uberShader)); + return true; + } + + inline void Material::SetShininess(float shininess) + { + m_shininess = shininess; + } + + inline void Material::SetSpecularColor(const Color& specular) + { + m_specularColor = specular; + } + + 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; + } + + inline void Material::SetSpecularMap(TextureRef specularMap) + { + m_specularMap = std::move(specularMap); + + InvalidateShaders(); + } + + inline void Material::SetSpecularSampler(const TextureSampler& sampler) + { + m_specularSampler = sampler; + } + + inline void Material::SetSrcBlend(BlendFunc func) + { + m_states.srcBlend = func; + } + + inline Material& Material::operator=(const Material& material) + { + Resource::operator=(material); + + Copy(material); + return *this; + } + + inline MaterialRef Material::GetDefault() + { + return s_defaultMaterial; + } + + inline void Material::InvalidateShaders() + { + for (ShaderInstance& instance : m_shaders) + instance.uberInstance = nullptr; + } + template MaterialRef Material::New(Args&&... args) { diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index db99077e2..8e0afa93e 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -77,7 +77,7 @@ namespace Nz mutable std::vector m_localVertices; Color m_color; MaterialRef m_material; - Rectui m_localBounds; + Recti m_localBounds; mutable bool m_verticesUpdated; float m_scale; diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 4d30c7ca3..b87bd51a7 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -132,7 +132,7 @@ namespace Nz } /*! - * \brief Returns the distance from the center of the sphere to the point + * \brief Returns the distance from the sphere to the point (is negative when the point is inside the sphere) * \return Distance to the point * * \param X X position of the point @@ -145,12 +145,11 @@ namespace Nz template T Sphere::Distance(T X, T Y, T Z) const { - Vector3 distance(X-x, Y-y, Z-z); - return distance.GetLength(); + return Distance({X, Y, Z}); } /*! - * \brief Returns the distance from the center of the sphere to the point + * \brief Returns the distance from the sphere to the point (is negative when the point is inside the sphere) * \return Distance to the point * * \param point Position of the point @@ -161,7 +160,7 @@ namespace Nz template T Sphere::Distance(const Vector3& point) const { - return Distance(point.x, point.y, point.z); + return Vector3f::Distance(point, GetPosition()) - radius; } /*! @@ -305,7 +304,7 @@ namespace Nz template bool Sphere::Intersect(const Sphere& sphere) const { - return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius * radius <= sphere.radius * sphere.radius; + return SquaredDistance(sphere.x, sphere.y, sphere.z) <= sphere.radius * sphere.radius; } /*! @@ -460,7 +459,7 @@ namespace Nz } /*! - * \brief Returns the squared distance from the center of the sphere to the point + * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) * \return Squared distance to the point * * \param X X position of the point @@ -469,27 +468,24 @@ namespace Nz * * \see Distance */ - template T Sphere::SquaredDistance(T X, T Y, T Z) const { - Vector3 distance(X - x, Y - y, Z - z); - return distance.GetSquaredLength(); + return SquaredDistance({X, Y, Z}); } /*! - * \brief Returns the squared distance from the center of the sphere to the point + * \brief Returns the squared distance from the sphere to the point (can be negative if the point is inside the sphere) * \return Squared distance to the point * * \param point Position of the point * * \see Distance */ - template T Sphere::SquaredDistance(const Vector3& point) const { - return SquaredDistance(point.x, point.y, point.z); + return Vector3f::Distance(point, GetPosition()) - radius * radius; } /*! diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index b9d16011c..7743e7a35 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -105,12 +105,15 @@ namespace Nz static Vector3 Backward(); static Vector3 CrossProduct(const Vector3& vec1, const Vector3& vec2); static T DotProduct(const Vector3& vec1, const Vector3& vec2); + static T Distance(const Vector3& vec1, const Vector3& vec2); + static float Distancef(const Vector3& vec1, const Vector3& vec2); static Vector3 Down(); static Vector3 Forward(); static Vector3 Left(); static Vector3 Lerp(const Vector3& from, const Vector3& to, T interpolation); static Vector3 Normalize(const Vector3& vec); static Vector3 Right(); + static T SquaredDistance(const Vector3& vec1, const Vector3& vec2); static Vector3 Unit(); static Vector3 UnitX(); static Vector3 UnitY(); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index fa48b7bef..c5a0155c7 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1011,6 +1011,40 @@ namespace Nz return vector; } + /*! + * \brief Measure the distance between two points + * Shorthand for vec1.Distance(vec2) + * + * param vec1 the first point + * param vec2 the second point + * + * \return The distance between the two vectors + * + * \see SquaredDistance + */ + template + T Vector3::Distance(const Vector3& vec1, const Vector3& vec2) + { + return vec1.Distance(vec2); + } + + /*! + * \brief Measure the distance between two points as a float + * Shorthand for vec1.Distancef(vec2) + * + * param vec1 the first point + * param vec2 the second point + * + * \return The distance between the two vectors as a float + * + * \see SquaredDistancef + */ + template + float Vector3::Distancef(const Vector3& vec1, const Vector3& vec2) + { + return vec1.Distancef(vec2); + } + /*! * \brief Shorthand for the vector (0, -1, 0) * \return A vector with components (0, -1, 0) @@ -1110,6 +1144,21 @@ namespace Nz return vector; } + /*! + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm + * + * \param vec1 The first point to measure the distance with + * \param vec2 The second point to measure the distance with + * + * \see Distance + */ + template + T Vector3::SquaredDistance(const Vector3& vec1, const Vector3& vec2) + { + return vec1.SquaredDistance(vec2); + } + /*! * \brief Shorthand for the vector (1, 1, 1) * \return A vector with components (1, 1, 1) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 30e0b5616..2d0e6d3a7 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -19,40 +19,6 @@ namespace Nz AttachmentPoint_Max = AttachmentPoint_Stencil }; - enum BlendFunc - { - BlendFunc_DestAlpha, - BlendFunc_DestColor, - BlendFunc_SrcAlpha, - BlendFunc_SrcColor, - BlendFunc_InvDestAlpha, - BlendFunc_InvDestColor, - BlendFunc_InvSrcAlpha, - BlendFunc_InvSrcColor, - BlendFunc_One, - BlendFunc_Zero, - - BlendFunc_Max = BlendFunc_Zero - }; - - enum FaceFilling - { - FaceFilling_Fill, - FaceFilling_Line, - FaceFilling_Point, - - FaceFilling_Max = FaceFilling_Point - }; - - enum FaceSide - { - FaceSide_Back, - FaceSide_Front, - FaceSide_FrontAndBack, - - FaceSide_Max = FaceSide_FrontAndBack - }; - enum GpuQueryCondition { GpuQueryCondition_Region_NoWait, @@ -124,59 +90,6 @@ namespace Nz RendererBuffer_Max = RendererBuffer_Stencil*2-1 }; - enum RendererComparison - { - RendererComparison_Always, - RendererComparison_Equal, - RendererComparison_Greater, - RendererComparison_GreaterOrEqual, - RendererComparison_Less, - RendererComparison_LessOrEqual, - RendererComparison_Never, - RendererComparison_NotEqual, - - RendererComparison_Max = RendererComparison_NotEqual - }; - - enum RendererParameter - { - RendererParameter_Blend, - RendererParameter_ColorWrite, - RendererParameter_DepthBuffer, - RendererParameter_DepthWrite, - RendererParameter_FaceCulling, - RendererParameter_ScissorTest, - RendererParameter_StencilTest, - - RendererParameter_Max = RendererParameter_StencilTest - }; - - enum SamplerFilter - { - SamplerFilter_Unknown = -1, - - SamplerFilter_Bilinear, - SamplerFilter_Nearest, - SamplerFilter_Trilinear, - - SamplerFilter_Default, - - SamplerFilter_Max = SamplerFilter_Default - }; - - enum SamplerWrap - { - SamplerWrap_Unknown = -1, - - SamplerWrap_Clamp, - SamplerWrap_MirroredRepeat, - SamplerWrap_Repeat, - - SamplerWrap_Default, - - SamplerWrap_Max = SamplerWrap_Repeat - }; - enum ShaderUniform { ShaderUniform_InvProjMatrix, @@ -205,20 +118,6 @@ namespace Nz ShaderStageType_Max = ShaderStageType_Vertex }; - - enum StencilOperation - { - StencilOperation_Decrement, - StencilOperation_DecrementNoClamp, - StencilOperation_Increment, - StencilOperation_IncrementNoClamp, - StencilOperation_Invert, - StencilOperation_Keep, - StencilOperation_Replace, - StencilOperation_Zero, - - StencilOperation_Max = StencilOperation_Zero - }; } #endif // NAZARA_ENUMS_RENDERER_HPP diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index b7691cd17..d008b52f4 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -319,6 +319,7 @@ NAZARA_RENDERER_API extern PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv; NAZARA_RENDERER_API extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; NAZARA_RENDERER_API extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; NAZARA_RENDERER_API extern PFNGLUSEPROGRAMPROC glUseProgram; +NAZARA_RENDERER_API extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; NAZARA_RENDERER_API extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index 9e9d455f4..4040bec55 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -7,7 +7,7 @@ #ifndef NAZARA_RENDERSTATES_HPP #define NAZARA_RENDERSTATES_HPP -#include +#include namespace Nz { diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 35789d09b..aa9dabba8 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -98,6 +98,8 @@ namespace Nz void SendVectorArray(int location, const Vector4f* vectors, unsigned int count) const; void SendVectorArray(int location, const Vector4i* vectors, unsigned int count) const; + bool Validate() const; + // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/include/Nazara/Renderer/TextureSampler.hpp b/include/Nazara/Renderer/TextureSampler.hpp index a461f57b2..21675e6c9 100644 --- a/include/Nazara/Renderer/TextureSampler.hpp +++ b/include/Nazara/Renderer/TextureSampler.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp index 20aac4db3..ffd704f6a 100644 --- a/include/Nazara/Utility/AbstractTextDrawer.hpp +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -26,7 +26,7 @@ namespace Nz AbstractTextDrawer() = default; virtual ~AbstractTextDrawer(); - virtual const Rectui& GetBounds() const = 0; + virtual const Recti& GetBounds() const = 0; virtual Font* GetFont(unsigned int index) const = 0; virtual unsigned int GetFontCount() const = 0; virtual const Glyph& GetGlyph(unsigned int index) const = 0; diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 096aa5fb6..143390906 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -17,6 +17,22 @@ namespace Nz AnimationType_Max = AnimationType_Static }; + enum BlendFunc + { + BlendFunc_DestAlpha, + BlendFunc_DestColor, + BlendFunc_SrcAlpha, + BlendFunc_SrcColor, + BlendFunc_InvDestAlpha, + BlendFunc_InvDestColor, + BlendFunc_InvSrcAlpha, + BlendFunc_InvSrcColor, + BlendFunc_One, + BlendFunc_Zero, + + BlendFunc_Max = BlendFunc_Zero + }; + enum BufferAccess { BufferAccess_DiscardAndWrite, @@ -87,6 +103,24 @@ namespace Nz DataStorage_Max = DataStorage_Software*2-1 }; + enum FaceFilling + { + FaceFilling_Fill, + FaceFilling_Line, + FaceFilling_Point, + + FaceFilling_Max = FaceFilling_Point + }; + + enum FaceSide + { + FaceSide_Back, + FaceSide_Front, + FaceSide_FrontAndBack, + + FaceSide_Max = FaceSide_FrontAndBack + }; + enum ImageType { ImageType_1D, @@ -211,6 +245,73 @@ namespace Nz PrimitiveMode_Max = PrimitiveMode_TriangleFan }; + enum RendererComparison + { + RendererComparison_Always, + RendererComparison_Equal, + RendererComparison_Greater, + RendererComparison_GreaterOrEqual, + RendererComparison_Less, + RendererComparison_LessOrEqual, + RendererComparison_Never, + RendererComparison_NotEqual, + + RendererComparison_Max = RendererComparison_NotEqual + }; + + enum RendererParameter + { + RendererParameter_Blend, + RendererParameter_ColorWrite, + RendererParameter_DepthBuffer, + RendererParameter_DepthWrite, + RendererParameter_FaceCulling, + RendererParameter_ScissorTest, + RendererParameter_StencilTest, + + RendererParameter_Max = RendererParameter_StencilTest + }; + + enum SamplerFilter + { + SamplerFilter_Unknown = -1, + + SamplerFilter_Bilinear, + SamplerFilter_Nearest, + SamplerFilter_Trilinear, + + SamplerFilter_Default, + + SamplerFilter_Max = SamplerFilter_Default + }; + + enum SamplerWrap + { + SamplerWrap_Unknown = -1, + + SamplerWrap_Clamp, + SamplerWrap_MirroredRepeat, + SamplerWrap_Repeat, + + SamplerWrap_Default, + + SamplerWrap_Max = SamplerWrap_Repeat + }; + + enum StencilOperation + { + StencilOperation_Decrement, + StencilOperation_DecrementNoClamp, + StencilOperation_Increment, + StencilOperation_IncrementNoClamp, + StencilOperation_Invert, + StencilOperation_Keep, + StencilOperation_Replace, + StencilOperation_Zero, + + StencilOperation_Max = StencilOperation_Zero + }; + enum TextAlign { TextAlign_Left, diff --git a/include/Nazara/Utility/Image.inl.save-failed b/include/Nazara/Utility/Image.inl.save-failed new file mode 100644 index 000000000..5cb8ef42f --- /dev/null +++ b/include/Nazara/Utility/Image.inl.save-failed @@ -0,0 +1,20 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + template + ImageRef Image::New(Args&&... args) + { + std::unique_ptr object(new Image(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp new file mode 100644 index 000000000..0f69c9846 --- /dev/null +++ b/include/Nazara/Utility/MaterialData.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MATERIALDATA_HPP +#define NAZARA_MATERIALDATA_HPP + +namespace Nz +{ + struct MaterialData + { + static constexpr const char* AlphaTest = "MatAlphaTest"; + static constexpr const char* AlphaTexturePath = "MatAlphaTexturePath"; + static constexpr const char* AlphaThreshold = "MatAlphaThreshold"; + static constexpr const char* AmbientColor = "MatAmbientColor"; + static constexpr const char* BackFaceStencilCompare = "MatBackFaceStencilCompare"; + static constexpr const char* BackFaceStencilFail = "MatBackFaceStencilFail"; + static constexpr const char* BackFaceStencilMask = "MatBackFaceStencilMask"; + static constexpr const char* BackFaceStencilPass = "MatBackFaceStencilPass"; + static constexpr const char* BackFaceStencilReference = "MatBackFaceStencilReference"; + static constexpr const char* BackFaceStencilZFail = "MatBackFaceStencilZFail"; + static constexpr const char* Blending = "MatBlending"; + static constexpr const char* CustomDefined = "MatCustomDefined"; + static constexpr const char* ColorWrite = "MatColorWrite"; + static constexpr const char* DepthBuffer = "MatDepthBuffer"; + static constexpr const char* DepthFunc = "MatDepthfunc"; + static constexpr const char* DepthSorting = "MatDepthSorting"; + static constexpr const char* DepthWrite = "MatDepthWrite"; + static constexpr const char* DiffuseAnisotropyLevel = "MatDiffuseAnisotropyLevel"; + static constexpr const char* DiffuseColor = "MatDiffuseColor"; + static constexpr const char* DiffuseFilter = "MatDiffuseFilter"; + static constexpr const char* DiffuseTexturePath = "MatDiffuseTexturePath"; + static constexpr const char* DiffuseWrap = "MatDiffuseWrap"; + static constexpr const char* DstBlend = "MatDstBlend"; + static constexpr const char* EmissiveTexturePath = "MatEmissiveTexturePath"; + static constexpr const char* FaceCulling = "MatFaceCulling"; + static constexpr const char* FaceFilling = "MatFaceFilling"; + static constexpr const char* FilePath = "MatFilePath"; + static constexpr const char* HeightTexturePath = "MatHeightTexturePath"; + static constexpr const char* Lighting = "MatLighting"; + static constexpr const char* LineWidth = "MatLineWidth"; + static constexpr const char* NormalTexturePath = "MatNormalTexturePath"; + static constexpr const char* PointSize = "MatPointSize"; + static constexpr const char* ScissorTest = "MatScissorTest"; + static constexpr const char* Shininess = "MatShininess"; + static constexpr const char* SpecularAnisotropyLevel = "MatSpecularAnisotropyLevel"; + static constexpr const char* SpecularColor = "MatSpecularColor"; + static constexpr const char* SpecularFilter = "MatSpecularFilter"; + static constexpr const char* SpecularTexturePath = "MatSpecularTexturePath"; + static constexpr const char* SpecularWrap = "MatSpecularWrap"; + static constexpr const char* SrcBlend = "MatSrcBlend"; + static constexpr const char* StencilCompare = "MatStencilCompare"; + static constexpr const char* StencilFail = "MatStencilFail"; + static constexpr const char* StencilMask = "MatStencilMask"; + static constexpr const char* StencilPass = "MatStencilPass"; + static constexpr const char* StencilReference = "MatStencilReference"; + static constexpr const char* StencilTest = "MatStencilTest"; + static constexpr const char* StencilZFail = "MatStencilZFail"; + static constexpr const char* Transform = "MatTransform"; + }; +} + +#endif // NAZARA_MATERIALDATA_HPP diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 433f50ab5..ff11b5d4d 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -93,7 +93,8 @@ namespace Nz String GetAnimation() const; AnimationType GetAnimationType() const; unsigned int GetJointCount() const; - String GetMaterial(unsigned int index) const; + ParameterList& GetMaterialData(unsigned int index); + const ParameterList& GetMaterialData(unsigned int index) const; unsigned int GetMaterialCount() const; Skeleton* GetSkeleton(); const Skeleton* GetSkeleton() const; @@ -124,8 +125,8 @@ namespace Nz void RemoveSubMesh(unsigned int index); void SetAnimation(const String& animationPath); - void SetMaterial(unsigned int matIndex, const String& materialPath); void SetMaterialCount(unsigned int matCount); + void SetMaterialData(unsigned int matIndex, ParameterList data); void Transform(const Matrix4f& matrix); diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 3f87bf3bb..f5532ca8f 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -28,7 +28,7 @@ namespace Nz void Clear(); - const Rectui& GetBounds() const override; + const Recti& GetBounds() const override; unsigned int GetCharacterSize() const; const Color& GetColor() const; Font* GetFont() const; @@ -71,7 +71,7 @@ namespace Nz Color m_color; FontRef m_font; mutable Rectf m_workingBounds; - mutable Rectui m_bounds; + mutable Recti m_bounds; String m_text; mutable UInt32 m_previousCharacter; UInt32 m_style; diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 0e754ea70..395ca6305 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -27,6 +27,7 @@ SOFTWARE. #include #include #include +#include #include #include #include @@ -165,6 +166,9 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { mesh->CreateStatic(); + // aiMaterial index in scene => Material index and data in Mesh + std::unordered_map> materials; + for (unsigned int i = 0; i < scene->mNumMeshes; ++i) { aiMesh* iMesh = scene->mMeshes[i]; @@ -222,8 +226,86 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) subMesh->GenerateAABB(); subMesh->SetMaterialIndex(iMesh->mMaterialIndex); + auto matIt = materials.find(iMesh->mMaterialIndex); + if (matIt == materials.end()) + { + ParameterList matData; + aiMaterial* aiMat = scene->mMaterials[iMesh->mMaterialIndex]; + + auto ConvertColor = [&] (const char* aiKey, unsigned int aiType, unsigned int aiIndex, const char* colorKey) + { + aiColor4D color; + if (aiGetMaterialColor(aiMat, aiKey, aiType, aiIndex, &color) == aiReturn_SUCCESS) + { + matData.SetParameter(MaterialData::CustomDefined); + + matData.SetParameter(colorKey, Color(static_cast(color.r * 255), static_cast(color.g * 255), static_cast(color.b * 255), static_cast(color.a * 255))); + } + }; + + auto ConvertTexture = [&] (aiTextureType aiType, const char* textureKey, const char* wrapKey = nullptr) + { + aiString path; + aiTextureMapMode mapMode; + if (aiGetMaterialTexture(aiMat, aiType, 0, &path, nullptr, nullptr, nullptr, nullptr, &mapMode, nullptr) == aiReturn_SUCCESS) + { + matData.SetParameter(MaterialData::CustomDefined); + matData.SetParameter(textureKey, stream.GetDirectory() + String(path.data, path.length)); + + if (wrapKey) + { + SamplerWrap wrap = SamplerWrap_Default; + switch (mapMode) + { + case aiTextureMapMode_Clamp: + case aiTextureMapMode_Decal: + wrap = SamplerWrap_Clamp; + break; + + case aiTextureMapMode_Mirror: + wrap = SamplerWrap_MirroredRepeat; + break; + + case aiTextureMapMode_Wrap: + wrap = SamplerWrap_Repeat; + break; + + default: + NazaraWarning("Assimp texture map mode 0x" + String::Number(mapMode, 16) + " not handled"); + break; + } + + matData.SetParameter(wrapKey, static_cast(wrap)); + } + } + }; + + ConvertColor(AI_MATKEY_COLOR_AMBIENT, MaterialData::AmbientColor); + ConvertColor(AI_MATKEY_COLOR_DIFFUSE, MaterialData::DiffuseColor); + ConvertColor(AI_MATKEY_COLOR_SPECULAR, MaterialData::SpecularColor); + + ConvertTexture(aiTextureType_DIFFUSE, MaterialData::DiffuseTexturePath, MaterialData::DiffuseWrap); + ConvertTexture(aiTextureType_EMISSIVE, MaterialData::EmissiveTexturePath); + ConvertTexture(aiTextureType_HEIGHT, MaterialData::HeightTexturePath); + ConvertTexture(aiTextureType_NORMALS, MaterialData::NormalTexturePath); + ConvertTexture(aiTextureType_OPACITY, MaterialData::AlphaTexturePath); + ConvertTexture(aiTextureType_SPECULAR, MaterialData::SpecularTexturePath, MaterialData::SpecularWrap); + + int iValue; + if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue)) + matData.SetParameter(MaterialData::FaceCulling, !iValue); + + matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first; + } + + subMesh->SetMaterialIndex(matIt->first); + mesh->AddSubMesh(subMesh); } + + mesh->SetMaterialCount(std::max(materials.size(), 1)); + for (const auto& pair : materials) + mesh->SetMaterialData(pair.second.first, pair.second.second); } if (parameters.center) diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 8505e42f9..97504b0ee 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -454,24 +454,24 @@ namespace Nz return true; } - /*! - * \brief Sets the size of the file - * \return true if the file size has correctly changed - * - * \param size The size the file should have after this call - * - * \remark The cursor position is not affected by this call - * \remark The file must be open in write mode - */ - bool File::SetSize(UInt64 size) - { - NazaraLock(m_mutex) + /*! + * \brief Sets the size of the file + * \return true if the file size has correctly changed + * + * \param size The size the file should have after this call + * + * \remark The cursor position is not affected by this call + * \remark The file must be open in write mode + */ + bool File::SetSize(UInt64 size) + { + NazaraLock(m_mutex) - NazaraAssert(IsOpen(), "File is not open"); - NazaraAssert(IsWritable(), "File is not writable"); + NazaraAssert(IsOpen(), "File is not open"); + NazaraAssert(IsWritable(), "File is not writable"); - return m_impl->SetSize(size); - } + return m_impl->SetSize(size); + } /*! * \brief Sets the file path diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index f9a24d4cc..91426a0b7 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -22,7 +22,6 @@ namespace Nz /*! * \brief Constructs a ParameterList object by copy */ - ParameterList::ParameterList(const ParameterList& list) { operator=(list); @@ -31,16 +30,14 @@ namespace Nz /*! * \brief Destructs the object and clears */ - ParameterList::~ParameterList() { Clear(); } /*! - * \brief Clears the list of parameters + * \brief Clears all the parameters */ - void ParameterList::Clear() { for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) @@ -50,17 +47,18 @@ namespace Nz } /*! - * \brief Gets a boolean parameter by name - * \return true if success + * \brief Gets a parameter as a boolean + * \return true if the parameter could be represented as a boolean * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a boolean to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a boolean, a conversion will be performed, compatibles types are: + Integer: 0 is interpreted as false, any other value is interpreted as true + String: Conversion obeys the rule as described by String::ToBool */ - bool ParameterList::GetBooleanParameter(const String& name, bool* value) const { NazaraAssert(value, "Invalid pointer"); @@ -85,17 +83,17 @@ namespace Nz return true; case ParameterType_String: + { + bool converted; + if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) { - bool converted; - if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) - { - *value = converted; - return true; - } - - break; + *value = converted; + return true; } + break; + } + case ParameterType_Float: case ParameterType_None: case ParameterType_Pointer: @@ -108,17 +106,62 @@ namespace Nz } /*! - * \brief Gets a float parameter by name - * \return true if success + * \brief Gets a parameter as a color + * \return true if the parameter could be represented as a color * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a color to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a color, the function fails */ + bool ParameterList::GetColorParameter(const String& name, Color* value) const + { + NazaraAssert(value, "Invalid pointer"); + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Color: + *value = it->second.value.colorVal; + return true; + + case ParameterType_Boolean: + case ParameterType_Integer: + case ParameterType_String: + case ParameterType_Float: + case ParameterType_None: + case ParameterType_Pointer: + case ParameterType_Userdata: + break; + } + + NazaraError("Parameter value is not representable as a color"); + return false; + } + + /*! + * \brief Gets a parameter as a float + * \return true if the parameter could be represented as a float + * + * \param name Name of the parameter + * \param value Pointer to a float to hold the retrieved value + * + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: + Integer: The integer value is converted to its float representation + String: Conversion obeys the rule as described by String::ToDouble + */ bool ParameterList::GetFloatParameter(const String& name, float* value) const { NazaraAssert(value, "Invalid pointer"); @@ -164,19 +207,21 @@ namespace Nz NazaraError("Parameter value is not representable as a float"); return false; } - + /*! - * \brief Gets a integer parameter by name - * \return true if success + * \brief Gets a parameter as an integer + * \return true if the parameter could be represented as an integer * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to an integer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a float, a conversion will be performed, compatibles types are: + Boolean: The boolean is represented as 1 if true and 0 if false + Float: The floating-point value is truncated and converted to a integer + String: Conversion obeys the rule as described by String::ToInteger but fails if the value could not be represented as a int */ - bool ParameterList::GetIntegerParameter(const String& name, int* value) const { NazaraAssert(value, "Invalid pointer"); @@ -229,15 +274,14 @@ namespace Nz } /*! - * \brief Gets a parameter type by name - * \return true if the parameter is present + * \brief Gets a parameter type + * \return true if the parameter is present, its type being written to type * * \param name Name of the variable - * \param type Pointer to a variable to hold result + * \param type Pointer to a variable to hold the result * - * \remark Produces a NazaraAssert if type is invalid + * \remark type must be a valid pointer to a ParameterType variable */ - bool ParameterList::GetParameterType(const String& name, ParameterType* type) const { NazaraAssert(type, "Invalid pointer"); @@ -252,17 +296,17 @@ namespace Nz } /*! - * \brief Gets a pointer parameter by name - * \return true if success + * \brief Gets a parameter as a pointer + * \return true if the parameter could be represented as a pointer * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a pointer, a conversion will be performed, compatibles types are: + Userdata: The pointer part of the userdata is returned */ - bool ParameterList::GetPointerParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); @@ -299,17 +343,23 @@ namespace Nz } /*! - * \brief Gets a string parameter by name - * \return true if success + * \brief Gets a parameter as a string + * \return true if the parameter could be represented as a string * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not a string, a conversion will be performed, all types are compatibles: + Boolean: Conversion obeys the rules of String::Boolean + Color: Conversion obeys the rules of Color::ToString + Float: Conversion obeys the rules of String::Number + Integer: Conversion obeys the rules of String::Number + None: An empty string is returned + Pointer: Conversion obeys the rules of String::Pointer + Userdata: Conversion obeys the rules of String::Pointer */ - bool ParameterList::GetStringParameter(const String& name, String* value) const { NazaraAssert(value, "Invalid pointer"); @@ -329,6 +379,10 @@ namespace Nz *value = String::Boolean(it->second.value.boolVal); return true; + case ParameterType_Color: + *value = it->second.value.colorVal.ToString(); + return true; + case ParameterType_Float: *value = String::Number(it->second.value.floatVal); return true; @@ -357,19 +411,20 @@ namespace Nz NazaraInternalError("Parameter value is not valid"); return false; } - + /*! - * \brief Gets a user parameter by name - * \return true if success + * \brief Gets a parameter as an userdata + * \return true if the parameter could be represented as a userdata * - * \param name Name of the variable - * \param value Value to set + * \param name Name of the parameter + * \param value Pointer to a pointer to hold the retrieved value * - * \remark Produces a NazaraAssert if pointer is invalid - * \remark Produces a silent NazaraError if name is not a variable - * \remark Produces a silent NazaraError if value could not be convertible + * \remark value must be a valid pointer + * \remark In case of failure, the variable pointed by value keep its value + * \remark If the parameter is not an userdata, the function fails + * + * \see GetPointerParameter */ - bool ParameterList::GetUserdataParameter(const String& name, void** value) const { NazaraAssert(value, "Invalid pointer"); @@ -396,25 +451,24 @@ namespace Nz } /*! - * \brief Checks whether the parameter list has a parameter with that name + * \brief Checks whether the parameter list contains a parameter named `name` * \return true if found * * \param name Name of the parameter */ - bool ParameterList::HasParameter(const String& name) const { return m_parameters.find(name) != m_parameters.end(); } /*! - * \brief Removes the parameter with that name + * \brief Removes the parameter named `name` * - * Removes the parameter with that name, if not found, nothing is done + * Search for a parameter named `name` and remove it from the parameter list, freeing up its memory + * Nothing is done if the parameter is not present in the parameter list * * \param name Name of the parameter */ - void ParameterList::RemoveParameter(const String& name) { auto it = m_parameters.find(name); @@ -426,11 +480,12 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to ParameterType_None + * \brief Sets a null parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter */ - void ParameterList::SetParameter(const String& name) { Parameter& parameter = CreateValue(name); @@ -438,12 +493,29 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a color parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The color value */ + void ParameterList::SetParameter(const String& name, const Color& value) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Color; + PlacementNew(¶meter.value.colorVal, value); + } + + /*! + * \brief Sets a string parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The string value + */ void ParameterList::SetParameter(const String& name, const String& value) { Parameter& parameter = CreateValue(name); @@ -453,12 +525,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a string parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The string value */ - void ParameterList::SetParameter(const String& name, const char* value) { Parameter& parameter = CreateValue(name); @@ -468,41 +541,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a boolean parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The boolean value */ - - void ParameterList::SetParameter(const String& name, void* value) - { - Parameter& parameter = CreateValue(name); - parameter.type = ParameterType_Pointer; - parameter.value.ptrVal = value; - } - - /*! - * \brief Sets the parameter with the name to the value - * - * \param name Name of the parameter - * \param value Value of the parameter - * \param destructor Destructor for dynamic variable - */ - - void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) - { - Parameter& parameter = CreateValue(name); - parameter.type = ParameterType_Userdata; - parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); - } - - /*! - * \brief Sets the parameter with the name to the value - * - * \param name Name of the parameter - * \param value Value of the parameter - */ - void ParameterList::SetParameter(const String& name, bool value) { Parameter& parameter = CreateValue(name); @@ -511,12 +556,13 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets a float parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The float value */ - void ParameterList::SetParameter(const String& name, float value) { Parameter& parameter = CreateValue(name); @@ -525,26 +571,63 @@ namespace Nz } /*! - * \brief Sets the parameter with the name to the value + * \brief Sets an integer parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call * * \param name Name of the parameter - * \param value Value of the parameter + * \param value The integer value */ - void ParameterList::SetParameter(const String& name, int value) { Parameter& parameter = CreateValue(name); parameter.type = ParameterType_Integer; parameter.value.intVal = value; } + + /*! + * \brief Sets a pointer parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The pointer value + * + * \remark This sets a raw pointer, this class takes no responsibility toward it, + if you wish to destroy the pointed variable along with the parameter list, you should set a userdata + */ + void ParameterList::SetParameter(const String& name, void* value) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Pointer; + parameter.value.ptrVal = value; + } /*! - * \brief Assigns the content of the other parameter list to this + * \brief Sets a userdata parameter named `name` + * + * If a parameter already exists with that name, it is destroyed and replaced by this call + * + * \param name Name of the parameter + * \param value The pointer value + * \param destructor The destructor function to be called upon parameter suppression + * + * \remark The destructor is called once when all copies of the userdata are destroyed, which means + you can safely copy the parameter list around. + */ + void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) + { + Parameter& parameter = CreateValue(name); + parameter.type = ParameterType_Userdata; + parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); + } + + /*! + * \brief Copies the content of the other parameter list to this * \return A reference to this * * \param list List to assign */ - ParameterList& ParameterList::operator=(const ParameterList& list) { Clear(); @@ -627,6 +710,7 @@ namespace Nz } case ParameterType_Boolean: + case ParameterType_Color: case ParameterType_Float: case ParameterType_Integer: case ParameterType_None: diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 31c1ace73..f6e8b3bcc 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -118,6 +118,11 @@ namespace Nz return lseek64(m_fileDescriptor, offset, moveMethod) != -1; } + bool FileImpl::SetSize(UInt64 size) + { + return ftruncate64(m_fileDescriptor, size) != 0; + } + std::size_t FileImpl::Write(const void* buffer, std::size_t size) { lockf64(m_fileDescriptor, F_LOCK, size); diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index 844bebd29..4981a832e 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -39,6 +39,7 @@ namespace Nz bool Open(const String& filePath, UInt32 mode); std::size_t Read(void* buffer, std::size_t size); bool SetCursorPos(CursorPosition pos, Int64 offset); + bool SetSize(UInt64 size); std::size_t Write(const void* buffer, std::size_t size); FileImpl& operator=(const FileImpl&) = delete; diff --git a/src/Nazara/Core/SerializationContext.cpp b/src/Nazara/Core/SerializationContext.cpp new file mode 100644 index 000000000..734b3b23d --- /dev/null +++ b/src/Nazara/Core/SerializationContext.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + + /*! + * \ingroup core + * \class Nz::SerializationContext + * \brief Structure containing a serialization/unserialization context states + */ + + /*! + * Write bits to the stream (if any) and reset the current bit cursor + + * \see ResetBitPosition + */ + void SerializationContext::FlushBits() + { + if (currentBitPos != 8) + { + ResetBitPosition(); + + // Serialize will reset the bit position + if (!Serialize(*this, currentByte)) + NazaraWarning("Failed to flush bits"); + } + } +} diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index b94715457..a57d89861 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4240,7 +4240,7 @@ namespace Nz utf8::unchecked::iterator it(m_sharedString->string.get()); do { - if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } while (*++it); @@ -4255,7 +4255,7 @@ namespace Nz utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); while ((it--).base() != m_sharedString->string.get()) { - if ((Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) break; } @@ -4271,7 +4271,8 @@ namespace Nz { for (; startPos < m_sharedString->size; ++startPos) { - if ((Unicode::GetCategory(m_sharedString->string[startPos]) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[startPos]; + if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) break; } } @@ -4281,7 +4282,8 @@ namespace Nz { for (; endPos > 0; --endPos) { - if ((Unicode::GetCategory(m_sharedString->string[endPos]) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[endPos]; + if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) break; } } diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp new file mode 100644 index 000000000..e6fc71ae0 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -0,0 +1,217 @@ +// 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 +#include +#include + +namespace Nz +{ + DepthRenderQueue::DepthRenderQueue() + { + // Material + m_baseMaterial = Material::New(); + m_baseMaterial->Enable(RendererParameter_ColorWrite, false); + m_baseMaterial->Enable(RendererParameter_FaceCulling, false); + //m_baseMaterial->SetFaceCulling(FaceSide_Front); + } + + void DepthRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboard(0, material, position, size, sinCos, color); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + NazaraUnused(meshAABB); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddMesh(0, material, meshData, meshAABB, transformMatrix); + } + + void DepthRenderQueue::AddPointLight(const PointLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddSpotLight(const SpotLight& light) + { + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); + } + + void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + { + NazaraAssert(material, "Invalid material"); + NazaraUnused(renderOrder); + NazaraUnused(overlay); + + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + ForwardRenderQueue::AddSprites(0, material, vertices, spriteCount, overlay); + } +} + diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp new file mode 100644 index 000000000..46e7fb043 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -0,0 +1,539 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace + { + struct BillboardPoint + { + Color color; + Vector3f position; + Vector2f size; + Vector2f sinCos; // must follow `size` (both will be sent as a Vector4f) + Vector2f uv; + }; + + unsigned int s_maxQuads = std::numeric_limits::max() / 6; + unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB + } + + DepthRenderTechnique::DepthRenderTechnique() : + m_vertexBuffer(BufferType_Vertex) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + m_vertexBuffer.Create(s_vertexBufferSize, DataStorage_Hardware, BufferUsage_Dynamic); + + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); + } + + void DepthRenderTechnique::Clear(const SceneData& sceneData) const + { + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_DepthWrite, true); + Renderer::Clear(RendererBuffer_Depth); + + // Just in case the background does render depth + //if (sceneData.background) + // sceneData.background->Draw(sceneData.viewer); + } + + bool DepthRenderTechnique::Draw(const SceneData& sceneData) const + { + for (auto& pair : m_renderQueue.layers) + { + ForwardRenderQueue::Layer& layer = pair.second; + + if (!layer.opaqueModels.empty()) + DrawOpaqueModels(sceneData, layer); + + if (!layer.basicSprites.empty()) + DrawBasicSprites(sceneData, layer); + + if (!layer.billboards.empty()) + DrawBillboards(sceneData, layer); + + for (const Drawable* drawable : layer.otherDrawables) + drawable->Draw(); + } + + return true; + } + + AbstractRenderQueue* DepthRenderTechnique::GetRenderQueue() + { + return &m_renderQueue; + } + + RenderTechniqueType DepthRenderTechnique::GetType() const + { + return RenderTechniqueType_Depth; + } + + bool DepthRenderTechnique::Initialize() + { + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, BufferUsage_Static); + + BufferMapper mapper(s_quadIndexBuffer, BufferAccess_WriteOnly); + UInt16* indices = static_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < s_maxQuads; ++i) + { + *indices++ = i * 4 + 0; + *indices++ = i * 4 + 2; + *indices++ = i * 4 + 1; + + *indices++ = i * 4 + 2; + *indices++ = i * 4 + 3; + *indices++ = i * 4 + 1; + } + + mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps + + // Quad buffer (utilisé pour l'instancing de billboard et de sprites) + //Note: Les UV sont calculés dans le shader + s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + + float vertices[2 * 4] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + + s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); + + // Déclaration lors du rendu des billboards par sommet + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(BillboardPoint, color)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(BillboardPoint, position)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(BillboardPoint, uv)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Englobe sincos + + // Declaration utilisée lors du rendu des billboards par instancing + // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center)); + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color)); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + String(e.what())); + return false; + } + + return true; + } + + void DepthRenderTechnique::Uninitialize() + { + s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); + } + + void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const + { + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); + Renderer::SetVertexBuffer(&m_spriteBuffer); + + for (auto& matIt : layer.basicSprites) + { + const Material* material = matIt.first; + auto& matEntry = matIt.second; + + if (matEntry.enabled) + { + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) + { + const Texture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; + + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + UInt32 flags = 0; + if (overlay) + flags |= ShaderFlags_TextureOverlay; + + UInt8 overlayUnit; + const Shader* shader = material->Apply(flags, 0, &overlayUnit); + + if (overlay) + { + overlayUnit++; + Renderer::SetTexture(overlayUnit, overlay); + Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); + + lastShader = shader; + } + + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + + do + { + // On ouvre le buffer en écriture + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + ForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(VertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } + } + while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } + } + + // On remet à zéro + matEntry.enabled = false; + } + } + } + + void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const + { + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + if (Renderer::HasCapability(RendererCap_Instancing)) + { + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); + + Renderer::SetVertexBuffer(&s_quadVertexBuffer); + + for (auto& matIt : layer.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); + + lastShader = shader; + } + + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + } + else + { + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetVertexBuffer(&m_billboardPointBuffer); + + for (auto& matIt : layer.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); + + lastShader = shader; + } + + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); + + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + for (unsigned int i = 0; i < renderedBillboardCount; ++i) + { + const ForwardRenderQueue::BillboardData& billboard = *data++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 0.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 0.f); + vertices++; + } + + vertexMapper.Unmap(); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + } + } + + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const + { + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + for (auto& matIt : layer.opaqueModels) + { + auto& matEntry = matIt.second; + + if (matEntry.enabled) + { + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + + if (!meshInstances.empty()) + { + const Material* material = matIt.first; + + bool instancing = m_instancingEnabled && matEntry.instancingEnabled; + + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + UInt8 freeTextureUnit; + const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + lastShader = shader; + } + + // Meshes + for (auto& meshIt : meshInstances) + { + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; + + if (!instances.empty()) + { + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (instancing) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + instances.clear(); + } + } + } + + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } + } + } + + const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const + { + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &DepthRenderTechnique::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DepthRenderTechnique::OnShaderInvalidated); + + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; + } + + void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const + { + m_shaderUniforms.erase(shader); + } + + IndexBuffer DepthRenderTechnique::s_quadIndexBuffer; + VertexBuffer DepthRenderTechnique::s_quadVertexBuffer; + VertexDeclaration DepthRenderTechnique::s_billboardInstanceDeclaration; + VertexDeclaration DepthRenderTechnique::s_billboardVertexDeclaration; +} \ No newline at end of file diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index b915c6f2e..ffd2b423e 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -3,9 +3,11 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include +#include #include #include #include @@ -14,6 +16,33 @@ namespace Nz { namespace { + void LoadMaterials(Model* model, const ModelParameters& parameters) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) + { + const ParameterList& matData = model->GetMesh()->GetMaterialData(i); + + String filePath; + if (matData.GetStringParameter(MaterialData::FilePath, &filePath)) + { + MaterialRef material = Material::New(); + if (material->LoadFromFile(filePath, parameters.material)) + model->SetMaterial(i, std::move(material)); + else + NazaraWarning("Failed to load material from file " + String::Number(i)); + } + else if (matData.HasParameter(MaterialData::CustomDefined)) + { + MaterialRef material = Material::New(); + material->BuildFromParameters(matData, parameters.material); + + model->SetMaterial(i, std::move(material)); + } + } + } + Ternary CheckStatic(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); @@ -46,22 +75,7 @@ namespace Nz model->SetMesh(mesh); if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) - { - String mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) - { - MaterialRef material = Material::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + String::Number(i)); - } - } - } + LoadMaterials(model, parameters); return true; } @@ -98,22 +112,7 @@ namespace Nz model->SetMesh(mesh); if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) - { - String mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) - { - MaterialRef material = Material::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + String::Number(i)); - } - } - } + LoadMaterials(model, parameters); return true; } diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index a4909e333..683230706 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -77,7 +77,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -120,7 +120,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -165,7 +165,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -212,7 +212,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -253,7 +253,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -296,7 +296,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) @@ -341,7 +341,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White float defaultRotation = 0.f; if (!anglePtr) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 21423fdc8..2ec95aee7 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -29,7 +29,7 @@ namespace Nz Color color; Vector3f position; Vector2f size; - Vector2f sinCos; // doit suivre size + Vector2f sinCos; // must follow `size` (both will be sent as a Vector4f) Vector2f uv; }; @@ -156,6 +156,9 @@ namespace Nz s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center)); s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color)); + + s_shadowSampler.SetFilterMode(SamplerFilter_Bilinear); + s_shadowSampler.SetWrapMode(SamplerWrap_Clamp); } catch (const std::exception& e) { @@ -487,7 +490,8 @@ namespace Nz bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0); + UInt8 freeTextureUnit; + const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -571,7 +575,10 @@ namespace Nz // Sends the uniforms for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, i*shaderUniforms->lightOffset); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); + + // Et on passe à l'affichage + drawFunc(meshData.primitiveMode, 0, indexCount); } const Matrix4f* instanceMatrices = &instances[0]; @@ -630,7 +637,7 @@ namespace Nz // Sends the light uniforms to the shader for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); // Et on passe à l'affichage drawFunc(meshData.primitiveMode, 0, indexCount); @@ -680,7 +687,8 @@ namespace Nz const Material* material = modelData.material; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const Shader* shader = material->Apply(); + UInt8 freeTextureUnit; + const Shader* shader = material->Apply(0, 0, &freeTextureUnit); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -699,7 +707,7 @@ namespace Nz lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); for (unsigned int i = 0; i < lightCount; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i, freeTextureUnit++); } lastShader = shader; @@ -738,7 +746,7 @@ namespace Nz ChooseLights(Spheref(position, radius), false); for (unsigned int i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i, freeTextureUnit++); } Renderer::SetMatrix(MatrixType_World, matrix); @@ -770,9 +778,13 @@ namespace Nz uniforms.lightUniforms.locations.type = type0Location; uniforms.lightUniforms.locations.color = shader->GetUniformLocation("Lights[0].color"); uniforms.lightUniforms.locations.factors = shader->GetUniformLocation("Lights[0].factors"); + uniforms.lightUniforms.locations.lightViewProjMatrix = shader->GetUniformLocation("LightViewProjMatrix[0]"); uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); + uniforms.lightUniforms.locations.pointLightShadowMap = shader->GetUniformLocation("PointLightShadowMap[0]"); + uniforms.lightUniforms.locations.shadowMapping = shader->GetUniformLocation("Lights[0].shadowMapping"); + uniforms.lightUniforms.locations.directionalSpotLightShadowMap = shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; @@ -789,6 +801,7 @@ namespace Nz } IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer; + TextureSampler ForwardRenderTechnique::s_shadowSampler; VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer; VertexDeclaration ForwardRenderTechnique::s_billboardInstanceDeclaration; VertexDeclaration ForwardRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index a96f2f4e7..b501682bc 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -96,14 +96,17 @@ namespace Nz return false; } - // Loaders - Loaders::RegisterOBJ(); - // Loaders génériques Loaders::RegisterMesh(); Loaders::RegisterTexture(); // RenderTechniques + if (!DepthRenderTechnique::Initialize()) + { + NazaraError("Failed to initialize Depth Rendering"); + return false; + } + if (!ForwardRenderTechnique::Initialize()) { NazaraError("Failed to initialize Forward Rendering"); @@ -176,10 +179,10 @@ namespace Nz // Loaders Loaders::UnregisterMesh(); - Loaders::UnregisterOBJ(); Loaders::UnregisterTexture(); DeferredRenderTechnique::Uninitialize(); + DepthRenderTechnique::Uninitialize(); ForwardRenderTechnique::Uninitialize(); SkinningManager::Uninitialize(); ParticleRenderer::Uninitialize(); diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 4e8822e02..14e33100b 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,11 @@ namespace Nz { Light::Light(LightType type) : - m_type(type) + m_type(type), + m_shadowMapFormat(PixelFormatType_Depth16), + m_shadowMapSize(512, 512), + m_shadowCastingEnabled(false), + m_shadowMapUpdated(false) { SetAmbientFactor((type == LightType_Directional) ? 0.2f : 0.f); SetAttenuation(0.9f); @@ -31,6 +36,11 @@ namespace Nz void Light::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const { + static Matrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f, + 0.f, 0.5f, 0.f, 0.f, + 0.f, 0.f, 0.5f, 0.f, + 0.5f, 0.5f, 0.5f, 1.f); + switch (m_type) { case LightType_Directional: @@ -40,6 +50,8 @@ namespace Nz light.color = m_color; light.diffuseFactor = m_diffuseFactor; light.direction = transformMatrix.Transform(Vector3f::Forward(), 0.f); + light.shadowMap = m_shadowMap.Get(); + light.transformMatrix = Matrix4f::ViewMatrix(transformMatrix.GetRotation() * Vector3f::Forward() * 100.f, transformMatrix.GetRotation()) * Matrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f) * biasMatrix; renderQueue->AddDirectionalLight(light); break; @@ -55,6 +67,7 @@ namespace Nz light.invRadius = m_invRadius; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); renderQueue->AddPointLight(light); break; @@ -74,6 +87,8 @@ namespace Nz light.outerAngleTangent = m_outerAngleTangent; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); + light.transformMatrix = Matrix4f::ViewMatrix(transformMatrix.GetTranslation(), transformMatrix.GetRotation()) * Matrix4f::Perspective(m_outerAngle*2.f, 1.f, 0.1f, m_radius) * biasMatrix; renderQueue->AddSpotLight(light); break; @@ -178,4 +193,19 @@ namespace Nz break; } } + + void Light::UpdateShadowMap() const + { + if (m_shadowCastingEnabled) + { + if (!m_shadowMap) + m_shadowMap = Texture::New(); + + m_shadowMap->Create((m_type == LightType_Point) ? ImageType_Cubemap : ImageType_2D, m_shadowMapFormat, m_shadowMapSize.x, m_shadowMapSize.y); + } + else + m_shadowMap.Reset(); + + m_shadowMapUpdated = true; + } } diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0a4755c03..44ec0310d 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -7,6 +7,7 @@ #endif #include +#include #include #include #include @@ -43,23 +44,6 @@ namespace Nz return true; } - Material::Material() - { - Reset(); - } - - Material::Material(const Material& material) : - RefCounted(), - Resource(material) - { - Copy(material); - } - - Material::~Material() - { - OnMaterialRelease(this); - } - const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const { const ShaderInstance& instance = m_shaders[shaderFlags]; @@ -139,240 +123,164 @@ namespace Nz return instance.shader; } - void Material::Enable(RendererParameter renderParameter, bool enable) + void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams) { - #ifdef NAZARA_DEBUG - if (renderParameter > RendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return; - } - #endif + Color color; + bool isEnabled; + float fValue; + int iValue; + String path; - m_states.parameters[renderParameter] = enable; - } + ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true); - void Material::EnableAlphaTest(bool alphaTest) - { - m_alphaTestEnabled = alphaTest; - InvalidateShaders(); - } + if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue)) + SetAlphaThreshold(fValue); - void Material::EnableDepthSorting(bool depthSorting) - { - m_depthSortingEnabled = depthSorting; - } + if (matData.GetBooleanParameter(MaterialData::AlphaTest, &isEnabled)) + EnableAlphaTest(isEnabled); - void Material::EnableLighting(bool lighting) - { - m_lightingEnabled = lighting; + if (matData.GetColorParameter(MaterialData::AmbientColor, &color)) + SetAmbientColor(color); - InvalidateShaders(); - } + if (matData.GetIntegerParameter(MaterialData::DepthFunc, &iValue)) + SetDepthFunc(static_cast(iValue)); - void Material::EnableTransform(bool transform) - { - m_transformEnabled = transform; + if (matData.GetBooleanParameter(MaterialData::DepthSorting, &isEnabled)) + EnableDepthSorting(isEnabled); - InvalidateShaders(); - } + if (matData.GetColorParameter(MaterialData::DiffuseColor, &color)) + SetDiffuseColor(color); - Texture* Material::GetAlphaMap() const - { - return m_alphaMap; - } + if (matData.GetIntegerParameter(MaterialData::DstBlend, &iValue)) + SetDstBlend(static_cast(iValue)); - float Material::GetAlphaThreshold() const - { - return m_alphaThreshold; - } + if (matData.GetIntegerParameter(MaterialData::FaceCulling, &iValue)) + SetFaceCulling(static_cast(iValue)); - Color Material::GetAmbientColor() const - { - return m_ambientColor; - } + if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue)) + SetFaceFilling(static_cast(iValue)); - RendererComparison Material::GetDepthFunc() const - { - return m_states.depthFunc; - } + if (matData.GetBooleanParameter(MaterialData::Lighting, &isEnabled)) + EnableLighting(isEnabled); - Color Material::GetDiffuseColor() const - { - return m_diffuseColor; - } + if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue)) + m_states.lineWidth = fValue; - TextureSampler& Material::GetDiffuseSampler() - { - return m_diffuseSampler; - } + if (matData.GetFloatParameter(MaterialData::PointSize, &fValue)) + m_states.pointSize = fValue; - const TextureSampler& Material::GetDiffuseSampler() const - { - return m_diffuseSampler; - } + if (matData.GetColorParameter(MaterialData::SpecularColor, &color)) + SetSpecularColor(color); - Texture* Material::GetDiffuseMap() const - { - return m_diffuseMap; - } + if (matData.GetFloatParameter(MaterialData::Shininess, &fValue)) + SetShininess(fValue); - BlendFunc Material::GetDstBlend() const - { - return m_states.dstBlend; - } + if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue)) + SetSrcBlend(static_cast(iValue)); - Texture* Material::GetEmissiveMap() const - { - return m_emissiveMap; - } + if (matData.GetBooleanParameter(MaterialData::Transform, &isEnabled)) + EnableTransform(isEnabled); - FaceSide Material::GetFaceCulling() const - { - return m_states.faceCulling; - } + // RendererParameter + if (matData.GetBooleanParameter(MaterialData::Blending, &isEnabled)) + Enable(RendererParameter_Blend, isEnabled); - FaceFilling Material::GetFaceFilling() const - { - return m_states.faceFilling; - } + if (matData.GetBooleanParameter(MaterialData::ColorWrite, &isEnabled)) + Enable(RendererParameter_ColorWrite, isEnabled); - Texture* Material::GetHeightMap() const - { - return m_heightMap; - } + if (matData.GetBooleanParameter(MaterialData::DepthBuffer, &isEnabled)) + Enable(RendererParameter_DepthBuffer, isEnabled); - Texture* Material::GetNormalMap() const - { - return m_normalMap; - } + if (matData.GetBooleanParameter(MaterialData::DepthWrite, &isEnabled)) + Enable(RendererParameter_DepthWrite, isEnabled); - const RenderStates& Material::GetRenderStates() const - { - return m_states; - } + if (matData.GetBooleanParameter(MaterialData::FaceCulling, &isEnabled)) + Enable(RendererParameter_FaceCulling, isEnabled); - const UberShader* Material::GetShader() const - { - return m_uberShader; - } + if (matData.GetBooleanParameter(MaterialData::ScissorTest, &isEnabled)) + Enable(RendererParameter_ScissorTest, isEnabled); - const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const - { - const ShaderInstance& instance = m_shaders[flags]; - if (!instance.uberInstance) - GenerateShader(flags); + if (matData.GetBooleanParameter(MaterialData::StencilTest, &isEnabled)) + Enable(RendererParameter_StencilTest, isEnabled); - return instance.uberInstance; - } + // Samplers + if (matData.GetIntegerParameter(MaterialData::DiffuseAnisotropyLevel, &iValue)) + m_diffuseSampler.SetAnisotropyLevel(static_cast(iValue)); - float Material::GetShininess() const - { - return m_shininess; - } + if (matData.GetIntegerParameter(MaterialData::DiffuseFilter, &iValue)) + m_diffuseSampler.SetFilterMode(static_cast(iValue)); - Color Material::GetSpecularColor() const - { - return m_specularColor; - } + if (matData.GetIntegerParameter(MaterialData::DiffuseWrap, &iValue)) + m_diffuseSampler.SetWrapMode(static_cast(iValue)); - Texture* Material::GetSpecularMap() const - { - return m_specularMap; - } + if (matData.GetIntegerParameter(MaterialData::SpecularAnisotropyLevel, &iValue)) + m_specularSampler.SetAnisotropyLevel(static_cast(iValue)); - TextureSampler& Material::GetSpecularSampler() - { - return m_specularSampler; - } + if (matData.GetIntegerParameter(MaterialData::SpecularFilter, &iValue)) + m_specularSampler.SetFilterMode(static_cast(iValue)); - const TextureSampler& Material::GetSpecularSampler() const - { - return m_specularSampler; - } + if (matData.GetIntegerParameter(MaterialData::SpecularWrap, &iValue)) + m_specularSampler.SetWrapMode(static_cast(iValue)); - BlendFunc Material::GetSrcBlend() const - { - return m_states.srcBlend; - } + // Stencil + if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue)) + m_states.frontFace.stencilCompare = static_cast(iValue); - bool Material::HasAlphaMap() const - { - return m_alphaMap.IsValid(); - } + if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue)) + m_states.frontFace.stencilFail = static_cast(iValue); - bool Material::HasDiffuseMap() const - { - return m_diffuseMap.IsValid(); - } + if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue)) + m_states.frontFace.stencilPass = static_cast(iValue); - bool Material::HasEmissiveMap() const - { - return m_emissiveMap.IsValid(); - } + if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue)) + m_states.frontFace.stencilZFail = static_cast(iValue); - bool Material::HasHeightMap() const - { - return m_heightMap.IsValid(); - } + if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue)) + m_states.frontFace.stencilMask = static_cast(iValue); - bool Material::HasNormalMap() const - { - return m_normalMap.IsValid(); - } + if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue)) + m_states.frontFace.stencilReference = static_cast(iValue); - bool Material::HasSpecularMap() const - { - return m_specularMap.IsValid(); - } + // Stencil (back) + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue)) + m_states.backFace.stencilCompare = static_cast(iValue); - bool Material::IsAlphaTestEnabled() const - { - return m_alphaTestEnabled; - } + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue)) + m_states.backFace.stencilFail = static_cast(iValue); - bool Material::IsDepthSortingEnabled() const - { - return m_depthSortingEnabled; - } + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue)) + m_states.backFace.stencilPass = static_cast(iValue); - bool Material::IsEnabled(RendererParameter parameter) const - { - #ifdef NAZARA_DEBUG - if (parameter > RendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return false; - } - #endif + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue)) + m_states.backFace.stencilZFail = static_cast(iValue); - return m_states.parameters[parameter]; - } + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue)) + m_states.backFace.stencilMask = static_cast(iValue); - bool Material::IsLightingEnabled() const - { - return m_lightingEnabled; - } + if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue)) + m_states.backFace.stencilReference = static_cast(iValue); - bool Material::IsTransformEnabled() const - { - return m_transformEnabled; - } + // Textures + if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path)) + SetAlphaMap(path); - bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) - { - return MaterialLoader::LoadFromFile(this, filePath, params); - } + if (matParams.loadDiffuseMap && matData.GetStringParameter(MaterialData::DiffuseTexturePath, &path)) + SetDiffuseMap(path); - bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) - { - return MaterialLoader::LoadFromMemory(this, data, size, params); - } + if (matParams.loadEmissiveMap && matData.GetStringParameter(MaterialData::EmissiveTexturePath, &path)) + SetEmissiveMap(path); - bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) - { - return MaterialLoader::LoadFromStream(this, stream, params); + if (matParams.loadHeightMap && matData.GetStringParameter(MaterialData::HeightTexturePath, &path)) + SetHeightMap(path); + + if (matParams.loadNormalMap && matData.GetStringParameter(MaterialData::NormalTexturePath, &path)) + SetNormalMap(path); + + if (matParams.loadSpecularMap && matData.GetStringParameter(MaterialData::SpecularTexturePath, &path)) + SetSpecularMap(path); + + SetShader(matParams.shaderName); } void Material::Reset() @@ -380,6 +288,7 @@ namespace Nz OnMaterialReset(this); m_alphaMap.Reset(); + m_depthMaterial.Reset(); m_diffuseMap.Reset(); m_emissiveMap.Reset(); m_heightMap.Reset(); @@ -397,6 +306,8 @@ namespace Nz m_diffuseColor = Color::White; m_diffuseSampler = TextureSampler(); m_lightingEnabled = true; + m_shadowCastingEnabled = true; + m_shadowReceiveEnabled = true; m_shininess = 50.f; m_specularColor = Color::White; m_specularSampler = TextureSampler(); @@ -408,252 +319,32 @@ namespace Nz SetShader("Basic"); } - 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; - } - - void Material::SetAlphaMap(TextureRef alphaMap) - { - m_alphaMap = std::move(alphaMap); - - InvalidateShaders(); - } - - void Material::SetAlphaThreshold(float alphaThreshold) - { - m_alphaThreshold = alphaThreshold; - } - - void Material::SetAmbientColor(const Color& ambient) - { - m_ambientColor = ambient; - } - - void Material::SetDepthFunc(RendererComparison depthFunc) - { - m_states.depthFunc = depthFunc; - } - - void Material::SetDiffuseColor(const Color& diffuse) - { - m_diffuseColor = diffuse; - } - - 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; - } - - void Material::SetDiffuseMap(TextureRef diffuseMap) - { - m_diffuseMap = std::move(diffuseMap); - - InvalidateShaders(); - } - - void Material::SetDiffuseSampler(const TextureSampler& sampler) - { - m_diffuseSampler = sampler; - } - - void Material::SetDstBlend(BlendFunc func) - { - m_states.dstBlend = func; - } - - 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; - } - - void Material::SetEmissiveMap(TextureRef emissiveMap) - { - m_emissiveMap = std::move(emissiveMap); - - InvalidateShaders(); - } - - void Material::SetFaceCulling(FaceSide faceSide) - { - m_states.faceCulling = faceSide; - } - - void Material::SetFaceFilling(FaceFilling filling) - { - m_states.faceFilling = filling; - } - - 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; - } - - void Material::SetHeightMap(TextureRef heightMap) - { - m_heightMap = std::move(heightMap); - - InvalidateShaders(); - } - - 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; - } - - void Material::SetNormalMap(TextureRef normalMap) - { - m_normalMap = std::move(normalMap); - - InvalidateShaders(); - } - - void Material::SetRenderStates(const RenderStates& states) - { - m_states = states; - } - - void Material::SetShader(UberShaderConstRef uberShader) - { - m_uberShader = std::move(uberShader); - - InvalidateShaders(); - } - - bool Material::SetShader(const String& uberShaderName) - { - UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); - if (!uberShader) - return false; - - SetShader(std::move(uberShader)); - return true; - } - - void Material::SetShininess(float shininess) - { - m_shininess = shininess; - } - - void Material::SetSpecularColor(const Color& specular) - { - m_specularColor = specular; - } - - 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; - } - - void Material::SetSpecularMap(TextureRef specularMap) - { - m_specularMap = std::move(specularMap); - - InvalidateShaders(); - } - - void Material::SetSpecularSampler(const TextureSampler& sampler) - { - m_specularSampler = sampler; - } - - void Material::SetSrcBlend(BlendFunc func) - { - m_states.srcBlend = func; - } - - Material& Material::operator=(const Material& material) - { - Resource::operator=(material); - - Copy(material); - return *this; - } - - MaterialRef Material::GetDefault() - { - return s_defaultMaterial; - } - void Material::Copy(const Material& material) { // Copie des états de base - m_alphaTestEnabled = material.m_alphaTestEnabled; - m_alphaThreshold = material.m_alphaThreshold; - m_ambientColor = material.m_ambientColor; - m_depthSortingEnabled = material.m_depthSortingEnabled; - m_diffuseColor = material.m_diffuseColor; - m_diffuseSampler = material.m_diffuseSampler; - m_lightingEnabled = material.m_lightingEnabled; - m_shininess = material.m_shininess; - m_specularColor = material.m_specularColor; - m_specularSampler = material.m_specularSampler; - m_states = material.m_states; - m_transformEnabled = material.m_transformEnabled; + m_alphaTestEnabled = material.m_alphaTestEnabled; + m_alphaThreshold = material.m_alphaThreshold; + m_ambientColor = material.m_ambientColor; + m_depthSortingEnabled = material.m_depthSortingEnabled; + m_diffuseColor = material.m_diffuseColor; + m_diffuseSampler = material.m_diffuseSampler; + m_lightingEnabled = material.m_lightingEnabled; + m_shininess = material.m_shininess; + m_shadowCastingEnabled = material.m_shadowCastingEnabled; + m_shadowReceiveEnabled = material.m_shadowReceiveEnabled; + m_specularColor = material.m_specularColor; + m_specularSampler = material.m_specularSampler; + m_states = material.m_states; + m_transformEnabled = material.m_transformEnabled; // Copie des références de texture - m_alphaMap = material.m_alphaMap; - m_diffuseMap = material.m_diffuseMap; - m_emissiveMap = material.m_emissiveMap; - m_heightMap = material.m_heightMap; - m_normalMap = material.m_normalMap; - m_specularMap = material.m_specularMap; - - // Copie de la référence vers l'Über-Shader + m_alphaMap = material.m_alphaMap; + m_depthMaterial = material.m_depthMaterial; + m_diffuseMap = material.m_diffuseMap; + m_emissiveMap = material.m_emissiveMap; + m_heightMap = material.m_heightMap; + m_normalMap = material.m_normalMap; + m_specularMap = material.m_specularMap; m_uberShader = material.m_uberShader; // On copie les instances de shader par la même occasion @@ -671,6 +362,7 @@ namespace Nz list.SetParameter("LIGHTING", m_lightingEnabled); list.SetParameter("NORMAL_MAPPING", m_normalMap.IsValid()); list.SetParameter("PARALLAX_MAPPING", m_heightMap.IsValid()); + list.SetParameter("SHADOW_MAPPING", m_shadowReceiveEnabled); list.SetParameter("SPECULAR_MAPPING", m_specularMap.IsValid()); list.SetParameter("TEXTURE_MAPPING", m_alphaMap.IsValid() || m_diffuseMap.IsValid() || m_emissiveMap.IsValid() || m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid() || @@ -704,12 +396,6 @@ namespace Nz #undef CacheUniform } - void Material::InvalidateShaders() - { - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; - } - bool Material::Initialize() { if (!MaterialLibrary::Initialize()) @@ -744,18 +430,35 @@ namespace Nz String fragmentShader(reinterpret_cast(r_phongLightingFragmentShader), sizeof(r_phongLightingFragmentShader)); String vertexShader(reinterpret_cast(r_phongLightingVertexShader), sizeof(r_phongLightingVertexShader)); - uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); - uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); UberShaderLibrary::Register("PhongLighting", uberShader); } - // Une fois les shaders de base enregistrés, on peut créer le matériau par défaut - s_defaultMaterial = Material::New(); + // Once the base shaders are registered, we can now set some default materials + s_defaultMaterial = New(); s_defaultMaterial->Enable(RendererParameter_FaceCulling, false); s_defaultMaterial->SetFaceFilling(FaceFilling_Line); MaterialLibrary::Register("Default", s_defaultMaterial); + MaterialRef mat; + + mat = New(); + mat->Enable(RendererParameter_DepthWrite, false); + mat->Enable(RendererParameter_FaceCulling, false); + mat->EnableLighting(false); + MaterialLibrary::Register("Basic2D", std::move(mat)); + + mat = New(); + mat->Enable(RendererParameter_Blend, true); + mat->Enable(RendererParameter_DepthWrite, false); + mat->Enable(RendererParameter_FaceCulling, false); + mat->EnableLighting(false); + mat->SetDstBlend(BlendFunc_InvSrcAlpha); + mat->SetSrcBlend(BlendFunc_SrcAlpha); + MaterialLibrary::Register("Translucent2D", std::move(mat)); + return true; } diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index b21c31218..df3eb5582 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -18,6 +18,7 @@ namespace Nz "Advanced Forward", "Basic Forward", "Deferred Shading", + "Depth Pass", "Light Pre-Pass", "User" }; diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h index 7c3081f31..993c7291b 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h @@ -1 +1 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file +47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,10,35,101,108,115,101,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,35,101,110,100,105,102,10,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,10,35,101,108,115,101,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,10,35,101,110,100,105,102,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,10,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,10,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,10,9,35,101,108,115,101,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,10,9,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,9,35,101,110,100,105,102,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,10,35,101,108,115,101,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,108,115,101,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,110,100,105,102,10,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,10,35,101,110,100,105,102,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 80ad84697..94184d6ab 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -8,6 +8,7 @@ layout(early_fragment_tests) in; /********************Entrant********************/ in vec4 vColor; +in vec4 vLightSpacePos[3]; in mat3 vLightToWorld; in vec3 vNormal; in vec2 vTexCoord; @@ -29,10 +30,13 @@ struct Light vec4 parameters1; vec4 parameters2; vec2 parameters3; + bool shadowMapping; }; // Lumières uniform Light Lights[3]; +uniform samplerCube PointLightShadowMap[3]; +uniform sampler2D DirectionalSpotLightShadowMap[3]; // Matériau uniform sampler2D MaterialAlphaMap; @@ -81,6 +85,41 @@ vec4 EncodeNormal(in vec3 normal) return vec4(vec2(atan(normal.y, normal.x)/kPI, normal.z), 0.0, 0.0); } +float VectorToDepthValue(vec3 vec, float zNear, float zFar) +{ + vec3 absVec = abs(vec); + float localZ = max(absVec.x, max(absVec.y, absVec.z)); + + float normZ = ((zFar + zNear) * localZ - (2.0*zFar*zNear)) / ((zFar - zNear)*localZ); + return (normZ + 1.0) * 0.5; +} + +float CalculateDirectionalShadowFactor(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0; +} + +float CalculatePointShadowFactor(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +{ + return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0; +} + +float CalculateSpotShadowFactor(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + + float visibility = 1.0; + float x,y; + for (y = -3.5; y <= 3.5; y+= 1.0) + for (x = -3.5; x <= 3.5; x+= 1.0) + visibility += (textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw + vec3(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.0)).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w) ? 1.0 : 0.0; + + visibility /= 64.0; + + return visibility; +} + void main() { vec4 diffuseColor = MaterialDiffuse * vColor; @@ -168,6 +207,10 @@ void main() for (int i = 0; i < 3; ++i) { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + switch (Lights[i].type) { case LIGHT_DIRECTIONAL: @@ -175,75 +218,120 @@ void main() vec3 lightDir = -Lights[i].parameters1.xyz; // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular vec3 reflection = reflect(-lightDir, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += specularFactor * Lights[i].color.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } case LIGHT_POINT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular vec3 reflection = reflect(-lightDir, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += att * specularFactor * Lights[i].color.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } case LIGHT_SPOT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); + float lambert = max(dot(normal, worldToLight), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; // Specular - vec3 reflection = reflect(-lightDir, normal); + vec3 reflection = reflect(-worldToLight, normal); float specularFactor = max(dot(reflection, eyeVec), 0.0); specularFactor = pow(specularFactor, MaterialShininess); - lightSpecular += att * specularFactor * Lights[i].color.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } @@ -256,61 +344,110 @@ void main() { for (int i = 0; i < 3; ++i) { + vec4 lightColor = Lights[i].color; + float lightAmbientFactor = Lights[i].factors.x; + float lightDiffuseFactor = Lights[i].factors.y; + switch (Lights[i].type) { case LIGHT_DIRECTIONAL: { - vec3 lightDir = normalize(-Lights[i].parameters1.xyz); + vec3 lightDir = -Lights[i].parameters1.xyz; // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + float att = 1.0; + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateDirectionalShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; break; } case LIGHT_POINT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + vec3 worldToLight = lightPos - vWorldPos; + float lightDirLength = length(worldToLight); + vec3 lightDir = worldToLight / lightDirLength; // Normalisation + + float att = max(lightAttenuation - lightInvRadius * lightDirLength, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; break; } case LIGHT_SPOT: { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation + vec3 lightPos = Lights[i].parameters1.xyz; + vec3 lightDir = Lights[i].parameters2.xyz; + float lightAttenuation = Lights[i].parameters1.w; + float lightInvRadius = Lights[i].parameters2.w; + float lightInnerAngle = Lights[i].parameters3.x; + float lightOuterAngle = Lights[i].parameters3.y; + + vec3 worldToLight = lightPos - vWorldPos; + float lightDistance = length(worldToLight); + worldToLight /= lightDistance; // Normalisation - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); + float att = max(lightAttenuation - lightInvRadius * lightDistance, 0.0); // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); + lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + + #if SHADOW_MAPPING + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculateSpotShadowFactor(i); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } + #endif // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); + float curAngle = dot(lightDir, -worldToLight); + float innerMinusOuterAngle = lightInnerAngle - lightOuterAngle; + att *= max((curAngle - lightOuterAngle) / innerMinusOuterAngle, 0.0); // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); + float lambert = max(dot(normal, worldToLight), 0.0); - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; } default: @@ -318,7 +455,7 @@ void main() } } } - + lightSpecular *= MaterialSpecular.rgb; #if SPECULAR_MAPPING lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens @@ -340,3 +477,4 @@ void main() #endif // LIGHTING #endif // FLAG_DEFERRED } + diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 29895eefa..b3c3f2c63 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h @@ -1 +1 @@ -35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,13,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,13,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,13,10,123,13,10,9,118,101,99,51,32,99,111,108,111,114,59,13,10,13,10,9,102,32,42,61,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,13,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,13,10,13,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,13,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,13,10,13,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,13,10,125,13,10,13,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,13,10,13,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,13,10,123,13,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,13,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,13,10,125,13,10,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,13,10,13,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,13,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,13,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,13,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,47,42,13,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,13,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,13,10,9,42,47,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,13,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,13,10,9,9,9,123,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,9,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,125,13,10,13,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,13,10,9,9,9,9,123,13,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,9,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,9,125,13,10,9,9,9,9,13,10,9,9,9,9,100,101,102,97,117,108,116,58,13,10,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,125,13,10, \ No newline at end of file +35,105,102,32,69,65,82,76,89,95,70,82,65,71,77,69,78,84,95,84,69,83,84,83,32,38,38,32,33,65,76,80,72,65,95,84,69,83,84,10,108,97,121,111,117,116,40,101,97,114,108,121,95,102,114,97,103,109,101,110,116,95,116,101,115,116,115,41,32,105,110,59,10,35,101,110,100,105,102,10,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,59,10,105,110,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,105,110,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,105,110,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,105,110,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,105,110,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,105,110,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,48,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,49,59,10,111,117,116,32,118,101,99,52,32,82,101,110,100,101,114,84,97,114,103,101,116,50,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,115,116,114,117,99,116,32,76,105,103,104,116,10,123,10,9,105,110,116,32,116,121,112,101,59,10,9,118,101,99,52,32,99,111,108,111,114,59,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,10,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,10,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,59,10,125,59,10,10,47,47,32,76,117,109,105,195,168,114,101,115,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,67,117,98,101,32,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,51,93,59,10,10,47,47,32,77,97,116,195,169,114,105,97,117,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,10,10,47,47,32,65,117,116,114,101,115,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,66,105,97,115,32,61,32,45,48,46,48,51,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,80,97,114,97,108,108,97,120,83,99,97,108,101,32,61,32,48,46,48,50,59,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,84,101,120,116,117,114,101,79,118,101,114,108,97,121,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,101,99,51,32,70,108,111,97,116,84,111,67,111,108,111,114,40,102,108,111,97,116,32,102,41,10,123,10,9,118,101,99,51,32,99,111,108,111,114,59,10,10,9,102,32,42,61,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,120,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,102,32,61,32,40,102,32,45,32,99,111,108,111,114,46,120,41,32,42,32,50,53,54,46,48,59,10,9,99,111,108,111,114,46,121,32,61,32,102,108,111,111,114,40,102,41,59,10,10,9,99,111,108,111,114,46,122,32,61,32,102,32,45,32,99,111,108,111,114,46,121,59,10,9,99,111,108,111,114,46,120,121,32,42,61,32,48,46,48,48,51,57,48,54,50,53,59,32,47,47,32,42,61,32,49,46,48,47,50,53,54,10,10,9,114,101,116,117,114,110,32,99,111,108,111,114,59,10,125,10,10,35,100,101,102,105,110,101,32,107,80,73,32,51,46,49,52,49,53,57,50,54,53,51,54,10,10,118,101,99,52,32,69,110,99,111,100,101,78,111,114,109,97,108,40,105,110,32,118,101,99,51,32,110,111,114,109,97,108,41,10,123,10,9,47,47,114,101,116,117,114,110,32,118,101,99,52,40,110,111,114,109,97,108,42,48,46,53,32,43,32,48,46,53,44,32,48,46,48,41,59,10,9,114,101,116,117,114,110,32,118,101,99,52,40,118,101,99,50,40,97,116,97,110,40,110,111,114,109,97,108,46,121,44,32,110,111,114,109,97,108,46,120,41,47,107,80,73,44,32,110,111,114,109,97,108,46,122,41,44,32,48,46,48,44,32,48,46,48,41,59,10,125,10,10,102,108,111,97,116,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,118,101,99,51,32,118,101,99,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,10,9,102,108,111,97,116,32,108,111,99,97,108,90,32,61,32,109,97,120,40,97,98,115,86,101,99,46,120,44,32,109,97,120,40,97,98,115,86,101,99,46,121,44,32,97,98,115,86,101,99,46,122,41,41,59,10,10,9,102,108,111,97,116,32,110,111,114,109,90,32,61,32,40,40,122,70,97,114,32,43,32,122,78,101,97,114,41,32,42,32,108,111,99,97,108,90,32,45,32,40,50,46,48,42,122,70,97,114,42,122,78,101,97,114,41,41,32,47,32,40,40,122,70,97,114,32,45,32,122,78,101,97,114,41,42,108,111,99,97,108,90,41,59,10,9,114,101,116,117,114,110,32,40,110,111,114,109,90,32,43,32,49,46,48,41,32,42,32,48,46,53,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,44,32,118,101,99,51,32,108,105,103,104,116,84,111,87,111,114,108,100,44,32,102,108,111,97,116,32,122,78,101,97,114,44,32,102,108,111,97,116,32,122,70,97,114,41,10,123,10,9,114,101,116,117,114,110,32,40,116,101,120,116,117,114,101,40,80,111,105,110,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,118,101,99,51,40,108,105,103,104,116,84,111,87,111,114,108,100,46,120,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,121,44,32,45,108,105,103,104,116,84,111,87,111,114,108,100,46,122,41,41,46,120,32,62,61,32,86,101,99,116,111,114,84,111,68,101,112,116,104,86,97,108,117,101,40,108,105,103,104,116,84,111,87,111,114,108,100,44,32,122,78,101,97,114,44,32,122,70,97,114,41,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,125,10,10,102,108,111,97,116,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,10,123,10,9,118,101,99,52,32,108,105,103,104,116,83,112,97,99,101,80,111,115,32,61,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,108,105,103,104,116,73,110,100,101,120,93,59,10,10,9,102,108,111,97,116,32,118,105,115,105,98,105,108,105,116,121,32,61,32,49,46,48,59,10,9,102,108,111,97,116,32,120,44,121,59,10,9,102,111,114,32,40,121,32,61,32,45,51,46,53,59,32,121,32,60,61,32,51,46,53,59,32,121,43,61,32,49,46,48,41,10,9,9,102,111,114,32,40,120,32,61,32,45,51,46,53,59,32,120,32,60,61,32,51,46,53,59,32,120,43,61,32,49,46,48,41,10,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,40,116,101,120,116,117,114,101,80,114,111,106,40,68,105,114,101,99,116,105,111,110,97,108,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,91,108,105,103,104,116,73,110,100,101,120,93,44,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,120,121,119,32,43,32,118,101,99,51,40,120,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,121,47,49,48,50,52,46,48,32,42,32,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,44,32,48,46,48,41,41,46,120,32,62,61,32,40,108,105,103,104,116,83,112,97,99,101,80,111,115,46,122,32,45,32,48,46,48,48,48,53,41,47,108,105,103,104,116,83,112,97,99,101,80,111,115,46,119,41,32,63,32,49,46,48,32,58,32,48,46,48,59,10,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,10,9,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,10,125,10,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,10,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,10,35,101,108,115,101,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,104,101,105,103,104,116,32,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,72,101,105,103,104,116,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,102,108,111,97,116,32,118,32,61,32,104,101,105,103,104,116,42,80,97,114,97,108,108,97,120,83,99,97,108,101,32,43,32,80,97,114,97,108,108,97,120,66,105,97,115,59,10,10,9,118,101,99,51,32,118,105,101,119,68,105,114,32,61,32,110,111,114,109,97,108,105,122,101,40,118,86,105,101,119,68,105,114,41,59,10,9,116,101,120,67,111,111,114,100,32,43,61,32,118,32,42,32,118,105,101,119,68,105,114,46,120,121,59,10,35,101,110,100,105,102,10,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,84,69,88,84,85,82,69,79,86,69,82,76,65,89,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,84,101,120,116,117,114,101,79,118,101,114,108,97,121,44,32,116,101,120,67,111,111,114,100,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,9,47,47,32,73,110,117,116,105,108,101,32,100,101,32,102,97,105,114,101,32,100,101,32,108,39,97,108,112,104,97,45,109,97,112,112,105,110,103,32,115,97,110,115,32,97,108,112,104,97,45,116,101,115,116,32,101,110,32,68,101,102,101,114,114,101,100,32,40,108,39,97,108,112,104,97,32,110,39,101,115,116,32,112,97,115,32,115,97,117,118,101,103,97,114,100,195,169,32,100,97,110,115,32,108,101,32,71,45,66,117,102,102,101,114,41,10,9,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,9,35,101,110,100,105,102,10,9,9,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,32,47,47,32,65,76,80,72,65,95,84,69,83,84,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,32,47,47,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,10,9,118,101,99,51,32,115,112,101,99,117,108,97,114,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,115,112,101,99,117,108,97,114,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,9,35,101,110,100,105,102,10,10,9,47,42,10,9,84,101,120,116,117,114,101,48,58,32,68,105,102,102,117,115,101,32,67,111,108,111,114,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,49,58,32,78,111,114,109,97,108,32,43,32,83,112,101,99,117,108,97,114,10,9,84,101,120,116,117,114,101,50,58,32,69,110,99,111,100,101,100,32,100,101,112,116,104,32,43,32,83,104,105,110,105,110,101,115,115,10,9,42,47,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,100,111,116,40,115,112,101,99,117,108,97,114,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,49,32,61,32,118,101,99,52,40,69,110,99,111,100,101,78,111,114,109,97,108,40,110,111,114,109,97,108,41,41,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,50,32,61,32,118,101,99,52,40,70,108,111,97,116,84,111,67,111,108,111,114,40,103,108,95,70,114,97,103,67,111,111,114,100,46,122,41,44,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,61,61,32,48,46,48,41,32,63,32,48,46,48,32,58,32,109,97,120,40,108,111,103,50,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,44,32,48,46,49,41,47,49,48,46,53,41,59,32,47,47,32,104,116,116,112,58,47,47,119,119,119,46,103,117,101,114,114,105,108,108,97,45,103,97,109,101,115,46,99,111,109,47,112,117,98,108,105,99,97,116,105,111,110,115,47,100,114,95,107,122,50,95,114,115,120,95,100,101,118,48,55,46,112,100,102,10,9,35,101,108,115,101,32,47,47,32,76,73,71,72,84,73,78,71,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,67,111,108,111,114,46,114,103,98,44,32,48,46,48,41,59,10,9,35,101,110,100,105,102,10,35,101,108,115,101,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,65,76,80,72,65,95,84,69,83,84,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,10,9,9,100,105,115,99,97,114,100,59,10,9,35,101,110,100,105,102,10,10,9,35,105,102,32,76,73,71,72,84,73,78,71,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,10,10,9,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,10,9,9,35,101,108,115,101,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,10,9,9,35,101,110,100,105,102,10,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,10,9,123,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,10,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,10,9,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,10,9,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,119,111,114,108,100,84,111,76,105,103,104,116,44,32,110,111,114,109,97,108,41,59,10,9,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,10,9,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,10,10,9,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,101,108,115,101,10,9,123,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,123,10,9,9,9,118,101,99,52,32,108,105,103,104,116,67,111,108,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,59,10,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,32,61,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,10,10,9,9,9,115,119,105,116,99,104,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,41,10,9,9,9,123,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,68,105,114,101,99,116,105,111,110,97,108,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,80,79,73,78,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,119,111,114,108,100,84,111,76,105,103,104,116,32,47,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,80,111,105,110,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,44,32,118,87,111,114,108,100,80,111,115,32,45,32,108,105,103,104,116,80,111,115,44,32,48,46,49,44,32,53,48,46,48,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,10,9,9,9,9,9,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,125,10,10,9,9,9,9,99,97,115,101,32,76,73,71,72,84,95,83,80,79,84,58,10,9,9,9,9,123,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,80,111,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,10,9,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,10,10,9,9,9,9,9,118,101,99,51,32,119,111,114,108,100,84,111,76,105,103,104,116,32,61,32,108,105,103,104,116,80,111,115,32,45,32,118,87,111,114,108,100,80,111,115,59,10,9,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,115,116,97,110,99,101,32,61,32,108,101,110,103,116,104,40,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,119,111,114,108,100,84,111,76,105,103,104,116,32,47,61,32,108,105,103,104,116,68,105,115,116,97,110,99,101,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,10,9,9,9,9,9,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,108,105,103,104,116,65,116,116,101,110,117,97,116,105,111,110,32,45,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,32,42,32,108,105,103,104,116,68,105,115,116,97,110,99,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,65,109,98,105,101,110,116,10,9,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,65,109,98,105,101,110,116,70,97,99,116,111,114,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,10,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,9,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,115,104,97,100,111,119,77,97,112,112,105,110,103,41,10,9,9,9,9,9,123,10,9,9,9,9,9,9,102,108,111,97,116,32,115,104,97,100,111,119,70,97,99,116,111,114,32,61,32,67,97,108,99,117,108,97,116,101,83,112,111,116,83,104,97,100,111,119,70,97,99,116,111,114,40,105,41,59,10,9,9,9,9,9,9,105,102,32,40,115,104,97,100,111,119,70,97,99,116,111,114,32,61,61,32,48,46,48,41,10,9,9,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,9,9,9,9,10,9,9,9,9,9,9,97,116,116,32,42,61,32,115,104,97,100,111,119,70,97,99,116,111,114,59,10,9,9,9,9,9,125,10,9,9,9,9,9,35,101,110,100,105,102,10,10,9,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,10,9,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,108,105,103,104,116,68,105,114,44,32,45,119,111,114,108,100,84,111,76,105,103,104,116,41,59,10,9,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,108,105,103,104,116,73,110,110,101,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,59,10,9,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,108,105,103,104,116,79,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,10,10,9,9,9,9,9,47,47,32,68,105,102,102,117,115,101,10,9,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,119,111,114,108,100,84,111,76,105,103,104,116,41,44,32,48,46,48,41,59,10,10,9,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,108,105,103,104,116,67,111,108,111,114,46,114,103,98,32,42,32,108,105,103,104,116,68,105,102,102,117,115,101,70,97,99,116,111,114,59,10,9,9,9,9,125,10,9,9,9,9,10,9,9,9,9,100,101,102,97,117,108,116,58,10,9,9,9,9,9,98,114,101,97,107,59,10,9,9,9,125,10,9,9,125,10,9,125,10,9,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,10,9,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,10,9,9,35,101,110,100,105,102,10,9,9,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,10,9,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,10,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,10,9,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,10,9,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,10,9,35,101,108,115,101,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,10,9,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,10,35,101,110,100,105,102,32,47,47,32,70,76,65,71,95,68,69,70,69,82,82,69,68,10,125,10,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert index 89f71e527..0f4c869a6 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -15,6 +15,7 @@ in vec2 VertexTexCoord; /********************Sortant********************/ out vec4 vColor; +out vec4 vLightSpacePos[3]; out mat3 vLightToWorld; out vec3 vNormal; out vec2 vTexCoord; @@ -23,6 +24,8 @@ out vec3 vWorldPos; /********************Uniformes********************/ uniform vec3 EyePosition; +uniform mat4 InvViewMatrix; +uniform mat4 LightViewProjMatrix[3]; uniform float VertexDepth; uniform mat4 ViewProjMatrix; uniform mat4 WorldMatrix; @@ -121,6 +124,11 @@ void main() #endif #endif +#if SHADOW_MAPPING + for (int i = 0; i < 3; ++i) + vLightSpacePos[i] = LightViewProjMatrix[i] * WorldMatrix * vec4(VertexPosition, 1.0); +#endif + #if TEXTURE_MAPPING vTexCoord = VertexTexCoord; #endif diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index d40070111..fbdd39607 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h @@ -1 +1 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,10,35,101,108,115,101,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,35,101,110,100,105,102,10,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,10,35,101,108,115,101,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,10,35,101,110,100,105,102,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,10,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,10,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,10,9,35,101,108,115,101,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,10,9,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,9,35,101,110,100,105,102,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,10,35,101,108,115,101,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,108,115,101,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,110,100,105,102,10,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,10,10,35,105,102,32,76,73,71,72,84,73,78,71,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,10,9,35,101,108,115,101,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,10,9,35,101,110,100,105,102,10,9,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,9,35,101,108,115,101,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,9,35,101,110,100,105,102,10,35,101,110,100,105,102,10,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,108,115,101,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,110,100,105,102,10,35,101,110,100,105,102,10,125,10, \ No newline at end of file +47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,105,110,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,10,105,110,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,10,35,101,108,115,101,10,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,35,101,110,100,105,102,10,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,10,105,110,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,59,10,111,117,116,32,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,10,111,117,116,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,73,110,118,86,105,101,119,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,10,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,10,118,111,105,100,32,109,97,105,110,40,41,10,123,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,10,35,101,108,115,101,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,10,35,101,110,100,105,102,10,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,10,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,10,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,48,46,53,59,10,9,35,101,108,115,101,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,48,46,53,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,10,9,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,10,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,10,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,9,35,101,110,100,105,102,10,9,116,101,120,67,111,111,114,100,115,46,121,32,61,32,49,46,48,32,45,32,116,101,120,67,111,111,114,100,115,46,121,59,10,35,101,108,115,101,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,108,115,101,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,35,101,108,115,101,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,10,9,9,9,35,101,108,115,101,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,9,9,9,35,101,110,100,105,102,10,9,9,35,101,110,100,105,102,10,9,35,101,110,100,105,102,10,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,10,10,35,105,102,32,76,73,71,72,84,73,78,71,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,41,59,10,9,35,101,108,115,101,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,41,59,10,9,35,101,110,100,105,102,10,9,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,9,35,101,108,115,101,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,10,9,35,101,110,100,105,102,10,35,101,110,100,105,102,10,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,10,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,10,9,9,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,105,93,32,61,32,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,105,93,32,42,32,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,10,35,101,110,100,105,102,10,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,10,9,118,84,101,120,67,111,111,114,100,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,10,35,101,110,100,105,102,10,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,108,115,101,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,10,9,35,101,110,100,105,102,10,35,101,110,100,105,102,10,125,10, \ No newline at end of file diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 3e1e43404..b77319997 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -995,6 +995,7 @@ namespace Nz glUniformMatrix4fv = reinterpret_cast(LoadEntry("glUniformMatrix4fv")); glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); + glValidateProgram = reinterpret_cast(LoadEntry("glValidateProgram")); glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisor")); glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); @@ -1684,24 +1685,44 @@ namespace Nz format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_SHORT; format->internalFormat = GL_DEPTH_COMPONENT16; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case PixelFormatType_Depth24: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_INT; format->internalFormat = GL_DEPTH_COMPONENT24; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case PixelFormatType_Depth24Stencil8: format->dataFormat = GL_DEPTH_STENCIL; format->dataType = GL_UNSIGNED_INT_24_8; format->internalFormat = GL_DEPTH24_STENCIL8; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_GREEN; return true; case PixelFormatType_Depth32: format->dataFormat = GL_DEPTH_COMPONENT; format->dataType = GL_UNSIGNED_BYTE; format->internalFormat = GL_DEPTH_COMPONENT32; + + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; return true; case PixelFormatType_Stencil1: @@ -2248,12 +2269,14 @@ PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr; PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr; PFNGLUSEPROGRAMPROC glUseProgram = nullptr; +PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr; PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr; PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr; PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = nullptr; PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer = nullptr; PFNGLVIEWPORTPROC glViewport = nullptr; + #if defined(NAZARA_PLATFORM_WINDOWS) PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat = nullptr; PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr; diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 2f2ba81c6..37b45c46a 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -156,9 +156,6 @@ namespace Nz InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == AttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -293,9 +290,6 @@ namespace Nz InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == AttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -819,6 +813,15 @@ namespace Nz void RenderTexture::UpdateTargets() const { + if (!m_impl->userDefinedTargets) + { + m_impl->colorTargets.clear(); + + unsigned int colorIndex = 0; + for (unsigned int index = attachmentIndex[AttachmentPoint_Color]; index < m_impl->attachments.size(); ++index) + m_impl->colorTargets.push_back(colorIndex++); + } + if (m_impl->colorTargets.empty()) { m_impl->drawBuffers.resize(1); diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 2017e2924..1093f1fd1 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1713,6 +1713,14 @@ namespace Nz // Et on termine par envoyer nos états au driver OpenGL::ApplyStates(s_states); + #ifdef NAZARA_DEBUG + if (!s_shader->Validate()) + { + NazaraError(Error::GetLastError()); + return false; + } + #endif + return true; } diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 9a4d15ca3..65deb8b3b 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -747,6 +747,31 @@ namespace Nz } } + bool Shader::Validate() const + { + #if NAZARA_RENDERER_SAFE + if (!m_program) + { + NazaraError("Shader is not initialized"); + return false; + } + #endif + + glValidateProgram(m_program); + + GLint success; + glGetProgramiv(m_program, GL_VALIDATE_STATUS, &success); + + if (success == GL_TRUE) + return true; + else + { + NazaraError("Failed to validate shader: " + GetLog()); + return false; + } + } + + unsigned int Shader::GetOpenGLID() const { return m_program; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 237553e9a..e4382cfc5 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1306,6 +1306,12 @@ namespace Nz glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); } + if (!proxy && PixelFormat::GetType(m_impl->format) == PixelFormatTypeType_Depth) + { + glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } + return true; } diff --git a/src/Nazara/Utility/Formats/DDSConstants.hpp b/src/Nazara/Utility/Formats/DDSConstants.hpp index 47a1766a4..4839df800 100644 --- a/src/Nazara/Utility/Formats/DDSConstants.hpp +++ b/src/Nazara/Utility/Formats/DDSConstants.hpp @@ -8,7 +8,7 @@ #define NAZARA_LOADERS_DDS_CONSTANTS_HPP #include -#include +#include #include namespace Nz diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index 15ed11f95..baa2657b3 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -65,7 +65,7 @@ namespace Nz headerDX10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; } - if (header.flags & DDSD_WIDTH == 0) + if ((header.flags & DDSD_WIDTH) == 0) NazaraWarning("Ill-formed DDS file, doesn't have a width flag"); unsigned int width = std::max(header.width, 1U); @@ -141,7 +141,7 @@ namespace Nz { if (header.ddsCaps[1] & DDSCAPS2_CUBEMAP) { - if (header.ddsCaps[1] & DDSCAPS2_CUBEMAP_ALLFACES != DDSCAPS2_CUBEMAP_ALLFACES) + if ((header.ddsCaps[1] & DDSCAPS2_CUBEMAP_ALLFACES) != DDSCAPS2_CUBEMAP_ALLFACES) { NazaraError("Partial cubemap are not yet supported, sorry"); return false; diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 184adfe17..eef4ac63d 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +100,11 @@ namespace Nz for (unsigned int i = 0; i < header.num_skins; ++i) { stream.Read(skin, 68*sizeof(char)); - mesh->SetMaterial(i, baseDir + skin); + + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + skin); + + mesh->SetMaterialData(i, std::move(matData)); } } } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 629452161..cda183313 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ namespace Nz // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) * - Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); + Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); String baseDir = stream.GetDirectory(); @@ -189,7 +190,10 @@ namespace Nz vertexMapper.Unmap(); // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader); + + mesh->SetMaterialData(i, std::move(matData)); // Submesh SkeletalMeshRef subMesh = SkeletalMesh::New(mesh); @@ -285,7 +289,10 @@ namespace Nz mesh->AddSubMesh(subMesh); // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); + ParameterList matData; + matData.SetParameter(MaterialData::FilePath, baseDir + md5Mesh.shader); + + mesh->SetMaterialData(i, std::move(matData)); } if (parameters.center) diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index d8dfcb304..56e384bf0 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -194,6 +194,7 @@ namespace Nz m_currentLine = m_stream.ReadLine(); m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires m_currentLine.Simplify(); // Pour un traitement plus simple + m_currentLine.Trim(); } while (m_currentLine.IsEmpty()); } diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp similarity index 67% rename from src/Nazara/Graphics/Formats/OBJLoader.cpp rename to src/Nazara/Utility/Formats/OBJLoader.cpp index 09ad743d7..75b5ba22f 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -1,14 +1,13 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Graphics module" +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp -#include +#include #include #include -#include -#include #include #include +#include #include #include #include @@ -17,7 +16,7 @@ #include #include #include -#include +#include ///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes @@ -30,7 +29,7 @@ namespace Nz return (extension == "obj"); } - Ternary Check(Stream& stream, const ModelParameters& parameters) + Ternary Check(Stream& stream, const MeshParams& parameters) { NazaraUnused(stream); @@ -41,7 +40,7 @@ namespace Nz return Ternary_Unknown; } - bool LoadMaterials(Model* model, const String& filePath, const MaterialParams& parameters, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount) + bool ParseMTL(Mesh* mesh, const String& filePath, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount) { File file(filePath); if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) @@ -57,7 +56,7 @@ namespace Nz return false; } - std::unordered_map materialCache; + std::unordered_map materialCache; String baseDir = file.GetDirectory(); for (unsigned int i = 0; i < meshCount; ++i) { @@ -72,8 +71,9 @@ namespace Nz auto it = materialCache.find(matName); if (it == materialCache.end()) { - MaterialRef material = Material::New(); - material->SetShader(parameters.shaderName); + ParameterList data; + + data.SetParameter(MaterialData::CustomDefined); UInt8 alphaValue = static_cast(mtlMat->alpha*255.f); @@ -84,54 +84,40 @@ namespace Nz diffuseColor.a = alphaValue; specularColor.a = alphaValue; - material->SetAmbientColor(ambientColor); - material->SetDiffuseColor(diffuseColor); - material->SetSpecularColor(specularColor); - material->SetShininess(mtlMat->shininess); + data.SetParameter(MaterialData::AmbientColor, ambientColor); + data.SetParameter(MaterialData::DiffuseColor, diffuseColor); + data.SetParameter(MaterialData::Shininess, mtlMat->shininess); + data.SetParameter(MaterialData::SpecularColor, specularColor); - bool isTranslucent = (alphaValue != 255); + if (!mtlMat->alphaMap.IsEmpty()) + data.SetParameter(MaterialData::AlphaTexturePath, baseDir + mtlMat->alphaMap); - if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty()) + if (!mtlMat->diffuseMap.IsEmpty()) + data.SetParameter(MaterialData::DiffuseTexturePath, baseDir + mtlMat->diffuseMap); + + if (!mtlMat->specularMap.IsEmpty()) + data.SetParameter(MaterialData::SpecularTexturePath, baseDir + mtlMat->specularMap); + + // If we either have an alpha value or an alpha map, let's configure the material for transparency + if (alphaValue != 255 || !mtlMat->alphaMap.IsEmpty()) { - if (material->SetAlphaMap(baseDir + mtlMat->alphaMap)) - isTranslucent = true; // Une alpha map indique de la transparence - else - NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')'); + // Some default settings + data.SetParameter(MaterialData::Blending, true); + data.SetParameter(MaterialData::DepthWrite, true); + data.SetParameter(MaterialData::DstBlend, static_cast(BlendFunc_InvSrcAlpha)); + data.SetParameter(MaterialData::SrcBlend, static_cast(BlendFunc_SrcAlpha)); } - if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty()) - { - if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap)) - NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')'); - } - - if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty()) - { - if (!material->SetSpecularMap(baseDir + mtlMat->specularMap)) - NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')'); - } - - // Si nous avons une alpha map ou des couleurs transparentes, - // nous devons configurer le matériau pour accepter la transparence au mieux - if (isTranslucent) - { - // On paramètre le matériau pour accepter la transparence au mieux - material->Enable(RendererParameter_Blend, true); - material->Enable(RendererParameter_DepthWrite, false); - material->SetDstBlend(BlendFunc_InvSrcAlpha); - material->SetSrcBlend(BlendFunc_SrcAlpha); - } - - it = materialCache.emplace(matName, std::move(material)).first; + it = materialCache.emplace(matName, std::move(data)).first; } - model->SetMaterial(meshes[i].material, it->second); + mesh->SetMaterialData(meshes[i].material, it->second); } return true; } - bool Load(Model* model, Stream& stream, const ModelParameters& parameters) + bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { int reservedVertexCount; if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) @@ -144,12 +130,7 @@ namespace Nz return false; } - MeshRef mesh = Mesh::New(); - if (!mesh->CreateStatic()) // Ne devrait jamais échouer - { - NazaraInternalError("Failed to create mesh"); - return false; - } + mesh->CreateStatic(); const String* materials = parser.GetMaterials(); const Vector4f* positions = parser.GetPositions(); @@ -160,8 +141,8 @@ namespace Nz unsigned int meshCount = parser.GetMeshCount(); NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr && - texCoords != nullptr && meshes != nullptr && meshCount > 0, - "Invalid OBJParser output"); + texCoords != nullptr && meshes != nullptr && meshCount > 0, + "Invalid OBJParser output"); // Un conteneur temporaire pour contenir les indices de face avant triangulation std::vector faceIndices(3); // Comme il y aura au moins trois sommets @@ -197,8 +178,8 @@ namespace Nz bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const { return lhs.normal == rhs.normal && - lhs.position == rhs.position && - lhs.texCoord == rhs.texCoord; + lhs.position == rhs.position && + lhs.texCoord == rhs.texCoord; } }; @@ -230,8 +211,8 @@ namespace Nz } // Création des buffers - IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.mesh.storage, BufferUsage_Static); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.storage, BufferUsage_Static); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, BufferUsage_Static); // Remplissage des indices IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); @@ -254,7 +235,7 @@ namespace Nz const Vector4f& vec = positions[vertexIndices.position]; vertex.position.Set(vec.x, vec.y, vec.z); - vertex.position *= parameters.mesh.scale/vec.w; + vertex.position *= parameters.scale/vec.w; if (vertexIndices.normal >= 0) vertex.normal = normals[vertexIndices.normal]; @@ -264,7 +245,7 @@ namespace Nz if (vertexIndices.texCoord >= 0) { const Vector3f& uvw = texCoords[vertexIndices.texCoord]; - vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé + vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé } else hasTexCoords = false; @@ -279,7 +260,7 @@ namespace Nz continue; } - if (parameters.mesh.optimizeIndexBuffers) + if (parameters.optimizeIndexBuffers) indexBuffer->Optimize(); subMesh->GenerateAABB(); @@ -299,17 +280,15 @@ namespace Nz } mesh->SetMaterialCount(parser.GetMaterialCount()); - if (parameters.mesh.center) + if (parameters.center) mesh->Recenter(); - model->SetMesh(mesh); - // On charge les matériaux si demandé String mtlLib = parser.GetMtlLib(); - if (parameters.loadMaterials && !mtlLib.IsEmpty()) + if (!mtlLib.IsEmpty()) { ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled); - LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount); + ParseMTL(mesh, stream.GetDirectory() + mtlLib, materials, meshes, meshCount); } return true; @@ -320,12 +299,12 @@ namespace Nz { void RegisterOBJ() { - ModelLoader::RegisterLoader(IsSupported, Check, Load); + MeshLoader::RegisterLoader(IsSupported, Check, Load); } void UnregisterOBJ() { - ModelLoader::UnregisterLoader(IsSupported, Check, Load); + MeshLoader::UnregisterLoader(IsSupported, Check, Load); } } } diff --git a/src/Nazara/Graphics/Formats/OBJLoader.hpp b/src/Nazara/Utility/Formats/OBJLoader.hpp similarity index 100% rename from src/Nazara/Graphics/Formats/OBJLoader.hpp rename to src/Nazara/Utility/Formats/OBJLoader.hpp diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 82c903cae..fca38e415 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -52,11 +52,11 @@ namespace Nz { MeshImpl() { - materials.resize(1); // Un matériau par défaut + materialData.resize(1); // Un matériau par défaut } std::unordered_map subMeshMap; - std::vector materials; + std::vector materialData; std::vector subMeshes; AnimationType animationType; Boxf aabb; @@ -75,93 +75,36 @@ namespace Nz void Mesh::AddSubMesh(SubMesh* subMesh) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(subMesh, "Invalid submesh"); + NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (subMesh->GetAnimationType() != m_impl->animationType) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif - - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); + + InvalidateAABB(); } void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (identifier.IsEmpty()) - { - NazaraError("Identifier is empty"); - return; - } - - auto it = m_impl->subMeshMap.find(identifier); - if (it != m_impl->subMeshMap.end()) - { - NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); - return; - } - - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (m_impl->animationType != subMesh->GetAnimationType()) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(!identifier.IsEmpty(), "Identifier is empty"); + NazaraAssert(m_impl->subMeshMap.find(identifier) == m_impl->subMeshMap.end(), "SubMesh identifier \"" + identifier + "\" is already in use"); + NazaraAssert(subMesh, "Invalid submesh"); + NazaraAssert(subMesh->GetAnimationType() == m_impl->animationType, "Submesh animation type doesn't match mesh animation type"); int index = m_impl->subMeshes.size(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); m_impl->subMeshMap[identifier] = index; + + InvalidateAABB(); } SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return nullptr; - } - - if (!params.IsValid()) - { - NazaraError("Parameters must be valid"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Submesh building only works for static meshes"); + NazaraAssert(params.IsValid(), "Invalid parameters"); Boxf aabb; IndexBufferRef indexBuffer; @@ -333,17 +276,7 @@ namespace Nz void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params) { - unsigned int primitiveCount = list.GetSize(); - - #if NAZARA_UTILITY_SAFE - if (primitiveCount == 0) - { - NazaraError("PrimitiveList must have at least one primitive"); - return; - } - #endif - - for (unsigned int i = 0; i < primitiveCount; ++i) + for (unsigned int i = 0; i < list.GetSize(); ++i) BuildSubMesh(list.GetPrimitive(i), params); } @@ -351,18 +284,17 @@ namespace Nz { Destroy(); - m_impl = new MeshImpl; - m_impl->animationType = AnimationType_Skeletal; - m_impl->jointCount = jointCount; - if (!m_impl->skeleton.Create(jointCount)) + std::unique_ptr impl(new MeshImpl); + impl->animationType = AnimationType_Skeletal; + impl->jointCount = jointCount; + if (!impl->skeleton.Create(jointCount)) { - delete m_impl; - m_impl = nullptr; - NazaraError("Failed to create skeleton"); return false; } + m_impl = impl.release(); + return true; } @@ -389,13 +321,7 @@ namespace Nz void Mesh::GenerateNormals() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateNormals(); @@ -403,13 +329,7 @@ namespace Nz void Mesh::GenerateNormalsAndTangents() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateNormalsAndTangents(); @@ -417,13 +337,7 @@ namespace Nz void Mesh::GenerateTangents() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); for (SubMesh* subMesh : m_impl->subMeshes) subMesh->GenerateTangents(); @@ -431,15 +345,7 @@ namespace Nz const Boxf& Mesh::GetAABB() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - - static Boxf dummy; - return dummy; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); if (!m_impl->aabbUpdated) { @@ -461,248 +367,121 @@ namespace Nz String Mesh::GetAnimation() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return String(); - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationPath; } AnimationType Mesh::GetAnimationType() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return AnimationType_Static; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationType; } unsigned int Mesh::GetJointCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return m_impl->jointCount; } - String Mesh::GetMaterial(unsigned int index) const + ParameterList& Mesh::GetMaterialData(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return String(); - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->materialData.size(), "Material index out of range"); - if (index >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->materials.size()) + ')'); - return String(); - } - #endif + return m_impl->materialData[index]; + } - return m_impl->materials[index]; + const ParameterList& Mesh::GetMaterialData(unsigned int index) const + { + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->materialData.size(), "Material index out of range"); + + return m_impl->materialData[index]; } unsigned int Mesh::GetMaterialCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); - return m_impl->materials.size(); + return m_impl->materialData.size(); } Skeleton* Mesh::GetSkeleton() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return &m_impl->skeleton; } const Skeleton* Mesh::GetSkeleton() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != AnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Skeletal, "Mesh is not skeletal"); return &m_impl->skeleton; } SubMesh* Mesh::GetSubMesh(const String& identifier) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return m_impl->subMeshes[it->second]; } SubMesh* Mesh::GetSubMesh(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); return m_impl->subMeshes[index]; } const SubMesh* Mesh::GetSubMesh(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return m_impl->subMeshes[it->second]; } const SubMesh* Mesh::GetSubMesh(unsigned int index) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); return m_impl->subMeshes[index]; } unsigned int Mesh::GetSubMeshCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->subMeshes.size(); } int Mesh::GetSubMeshIndex(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return -1; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return -1; - } - #endif + NazaraAssert(it != m_impl->subMeshMap.end(), "SubMesh " + identifier + " not found"); return it->second; } unsigned int Mesh::GetTriangleCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); unsigned int triangleCount = 0; for (SubMesh* subMesh : m_impl->subMeshes) @@ -713,13 +492,7 @@ namespace Nz unsigned int Mesh::GetVertexCount() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); unsigned int vertexCount = 0; for (SubMesh* subMesh : m_impl->subMeshes) @@ -730,52 +503,28 @@ namespace Nz void Mesh::InvalidateAABB() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); m_impl->aabbUpdated = false; } bool Mesh::HasSubMesh(const String& identifier) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end(); } bool Mesh::HasSubMesh(unsigned int index) const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return index < m_impl->subMeshes.size(); } bool Mesh::IsAnimable() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); return m_impl->animationType != AnimationType_Static; } @@ -802,21 +551,10 @@ namespace Nz void Mesh::Recenter() { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static"); - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return; - } - #endif - - // Le centre de notre mesh est le centre de l'AABB *globale* + // The center of our mesh is the center of our *global* AABB Vector3f center = GetAABB().GetCenter(); for (SubMesh* subMesh : m_impl->subMeshes) @@ -833,119 +571,62 @@ namespace Nz vertices++; } - // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé + // Our AABB doesn't change shape, only position Boxf aabb = staticMesh->GetAABB(); aabb.Translate(-center); staticMesh->SetAABB(aabb); } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; + InvalidateAABB(); } void Mesh::RemoveSubMesh(const String& identifier) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - auto it = m_impl->subMeshMap.find(identifier); - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return; - } - - unsigned int index = it->second; - #else - unsigned int index = m_impl->subMeshMap[identifier]; - #endif + unsigned int index = GetSubMeshIndex(identifier); // On déplace l'itérateur du début d'une distance de x auto it2 = m_impl->subMeshes.begin(); std::advance(it2, index); m_impl->subMeshes.erase(it2); - m_impl->aabbUpdated = false; // On invalide l'AABB + InvalidateAABB(); } void Mesh::RemoveSubMesh(unsigned int index) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(index < m_impl->subMeshes.size(), "Submesh index out of range"); // On déplace l'itérateur du début de x auto it = m_impl->subMeshes.begin(); std::advance(it, index); m_impl->subMeshes.erase(it); - m_impl->aabbUpdated = false; // On invalide l'AABB + InvalidateAABB(); } void Mesh::SetAnimation(const String& animationPath) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif + NazaraAssert(m_impl, "Mesh should be created first"); m_impl->animationPath = animationPath; } - void Mesh::SetMaterial(unsigned int matIndex, const String& materialPath) + void Mesh::SetMaterialData(unsigned int matIndex, ParameterList data) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(matIndex < m_impl->materialData.size(), "Material index out of range"); - if (matIndex >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_impl->materials.size()) + ')'); - return; - } - #endif - - m_impl->materials[matIndex] = materialPath; + m_impl->materialData[matIndex] = std::move(data); } void Mesh::SetMaterialCount(unsigned int matCount) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(matCount > 0, "A mesh should have at least a material"); - if (matCount == 0) - { - NazaraError("A mesh should have at least a material"); - return; - } - #endif - - m_impl->materials.resize(matCount); + m_impl->materialData.resize(matCount); #ifdef NAZARA_DEBUG for (SubMesh* subMesh : m_impl->subMeshes) @@ -953,7 +634,7 @@ namespace Nz unsigned int matIndex = subMesh->GetMaterialIndex(); if (matIndex >= matCount) { - subMesh->SetMaterialIndex(0); // Pour empêcher un crash + subMesh->SetMaterialIndex(0); // To prevent a crash NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material"); } } @@ -962,22 +643,8 @@ namespace Nz void Mesh::Transform(const Matrix4f& matrix) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (m_impl->animationType != AnimationType_Static) - { - NazaraError("Mesh must be static"); - return; - } - #endif - - if (matrix.IsIdentity()) - return; + NazaraAssert(m_impl, "Mesh should be created first"); + NazaraAssert(m_impl->animationType == AnimationType_Static, "Mesh is not static"); for (SubMesh* subMesh : m_impl->subMeshes) { @@ -1000,8 +667,7 @@ namespace Nz staticMesh->SetAABB(aabb); } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; + InvalidateAABB(); } bool Mesh::Initialize() diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index cc2130c05..ae2dc8762 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -49,7 +49,7 @@ namespace Nz ClearGlyphs(); } - const Rectui& SimpleTextDrawer::GetBounds() const + const Recti& SimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) UpdateGlyphs(); diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index ffe5a05f1..8b0589808 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -209,5 +209,5 @@ namespace Nz void SubMesh::SetMaterialIndex(unsigned int matIndex) { m_matIndex = matIndex; -} + } } diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 75084b8c0..78553ce54 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -114,7 +115,7 @@ namespace Nz Loaders::RegisterFreeType(); // Image - Loaders::RegisterDDSLoader(); // Generic loader (STB) + Loaders::RegisterDDSLoader(); // DDS Loader (DirectX format) Loaders::RegisterSTBLoader(); // Generic loader (STB) Loaders::RegisterSTBSaver(); // Generic saver (STB) @@ -122,6 +123,9 @@ namespace Nz // Animation Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10) + // Mesh (text) + Loaders::RegisterOBJ(); + // Mesh Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8) Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10) @@ -158,6 +162,7 @@ namespace Nz Loaders::UnregisterMD2(); Loaders::UnregisterMD5Anim(); Loaders::UnregisterMD5Mesh(); + Loaders::UnregisterOBJ(); Loaders::UnregisterPCX(); Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); diff --git a/tests/Engine/Core/Bitset.cpp b/tests/Engine/Core/Bitset.cpp index 76c35c886..cb870f7a4 100644 --- a/tests/Engine/Core/Bitset.cpp +++ b/tests/Engine/Core/Bitset.cpp @@ -7,7 +7,7 @@ SCENARIO("Bitset", "[CORE][BITSET]") { GIVEN("Allocate and constructor") { - Nz::Bitset<> bitset(3); + Nz::Bitset<> bitset(3, false); THEN("Capacity is 3 and size is 3") { diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index 2a87c8495..2ddbfebbf 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -78,9 +78,9 @@ SCENARIO("File", "[CORE][FILE]") THEN("The relative positioning should disappear") { - Nz::String containingNoMoreDot = "/resources/Spaceship/spaceship.mtl"; - REQUIRE(Nz::File::AbsolutePath(containingDot) == containingNoMoreDot); - REQUIRE(Nz::File::AbsolutePath(containingDoubleDot) == containingNoMoreDot); + Nz::String containingNoMoreDot = Nz::File::NormalizePath("/resources/Spaceship/spaceship.mtl"); + REQUIRE(Nz::File::AbsolutePath(containingDot).EndsWith(containingNoMoreDot)); + REQUIRE(Nz::File::AbsolutePath(containingDoubleDot).EndsWith(containingNoMoreDot)); } } } diff --git a/tests/Engine/Core/Serialization.cpp b/tests/Engine/Core/Serialization.cpp index a4d8ff75e..cc556dec8 100644 --- a/tests/Engine/Core/Serialization.cpp +++ b/tests/Engine/Core/Serialization.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -35,6 +35,7 @@ SCENARIO("Serialization", "[CORE][SERIALIZATION]") { context.stream->SetCursorPos(0); REQUIRE(Serialize(context, true)); + context.FlushBits(); //< Don't forget to flush bits (it is NOT done by the stream) context.stream->SetCursorPos(0); bool value = false; REQUIRE(Unserialize(context, &value));