From 974df4288f97cc9e83c7823f10f8234ab96516fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 16 Jun 2015 14:21:20 +0200 Subject: [PATCH 001/224] First shadow mapping commit Former-commit-id: 7465a7c3297626f8db8c1ff48a20c0e0d9feb765 --- SDK/include/NDK/Systems/RenderSystem.hpp | 4 ++ SDK/src/NDK/Systems/RenderSystem.cpp | 64 ++++++++++++++++++++-- include/Nazara/Graphics/Light.hpp | 57 ++++++++++++-------- include/Nazara/Graphics/Light.inl | 68 ++++++++++++++++++++++++ src/Nazara/Graphics/Light.cpp | 19 ++++++- src/Nazara/Renderer/RenderTexture.cpp | 6 +++ 6 files changed, 190 insertions(+), 28 deletions(-) diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 522f1c775..0baae7684 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -8,6 +8,7 @@ #define NDK_SYSTEMS_RENDERSYSTEM_HPP #include +#include #include #include #include @@ -31,11 +32,14 @@ namespace Ndk private: void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; + void UpdateShadowMaps(); EntityList m_cameras; EntityList m_drawables; EntityList m_lights; NzForwardRenderTechnique m_renderTechnique; + NzForwardRenderTechnique m_shadowTechnique; + NzRenderTexture m_shadowRT; }; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 1f781e951..4f6f27f86 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -3,7 +3,9 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include #include +#include #include #include #include @@ -17,6 +19,8 @@ namespace Ndk void RenderSystem::Update(float elapsedTime) { + UpdateShadowMaps(); + for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); @@ -25,10 +29,10 @@ namespace Ndk NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); renderQueue->Clear(); - for (const Ndk::EntityHandle& light : m_drawables) + for (const Ndk::EntityHandle& drawable : m_drawables) { - GraphicsComponent& graphicsComponent = light->GetComponent(); - NodeComponent& drawableNode = light->GetComponent(); + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); graphicsComponent.AddToRenderQueue(renderQueue); } @@ -36,9 +40,9 @@ namespace Ndk for (const Ndk::EntityHandle& light : m_lights) { LightComponent& lightComponent = light->GetComponent(); - NodeComponent& drawableNode = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); - lightComponent.AddToRenderQueue(renderQueue, drawableNode.GetTransformMatrix()); + lightComponent.AddToRenderQueue(renderQueue, lightNode.GetTransformMatrix()); } NzColorBackground background; @@ -83,5 +87,55 @@ namespace Ndk m_lights.Remove(entity); } + void RenderSystem::UpdateShadowMaps() + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + for (const Ndk::EntityHandle& light : m_lights) + { + LightComponent& lightComponent = light->GetComponent(); + NodeComponent& lightNode = light->GetComponent(); + + if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) + continue; + + /// HACKY + NzCamera lightPOV; + lightPOV.SetPosition(lightNode.GetPosition()); + lightPOV.SetFOV(lightComponent.GetOuterAngle()); + lightPOV.SetRotation(lightNode.GetRotation()); + lightPOV.SetZFar(1000.f); + lightPOV.SetTarget(&m_shadowRT); + + NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + + NzRenderer::SetMatrix(nzMatrixType_Projection, lightPOV.GetProjectionMatrix()); + NzRenderer::SetMatrix(nzMatrixType_View, lightPOV.GetViewMatrix()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + renderQueue->Clear(); + + for (const Ndk::EntityHandle& drawable : m_drawables) + { + GraphicsComponent& graphicsComponent = drawable->GetComponent(); + NodeComponent& drawableNode = drawable->GetComponent(); + + graphicsComponent.AddToRenderQueue(renderQueue); + } + + NzSceneData sceneData; + sceneData.ambientColor = NzColor(0, 0, 0); + sceneData.background = nullptr; + sceneData.viewer = &lightPOV; + + m_renderTechnique.Draw(sceneData); + } + } + SystemIndex RenderSystem::systemIndex; } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 9a6a4235b..a28a86c17 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include class NzLight; struct NzLightUniforms; @@ -19,7 +21,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable { public: NzLight(nzLightType type = nzLightType_Point); - NzLight(const NzLight& light) = default; + inline NzLight(const NzLight& light); ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; @@ -29,37 +31,48 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const override; - float GetAmbientFactor() const; - float GetAttenuation() const; - NzColor GetColor() const; - float GetDiffuseFactor() const; - float GetInnerAngle() const; - float GetInnerAngleCosine() const; - float GetInvRadius() const; - nzLightType 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 NzColor& color); - void SetDiffuseFactor(float factor); - void SetInnerAngle(float innerAngle); - void SetLightType(nzLightType type); - void SetOuterAngle(float outerAngle); - void SetRadius(float radius); + inline void EnsureShadowMapUpdate() const; + + inline float GetAmbientFactor() const; + inline float GetAttenuation() const; + inline NzColor GetColor() const; + inline float GetDiffuseFactor() const; + inline float GetInnerAngle() const; + inline float GetInnerAngleCosine() const; + inline float GetInvRadius() const; + inline nzLightType GetLightType() const; + inline float GetOuterAngle() const; + inline float GetOuterAngleCosine() const; + inline float GetOuterAngleTangent() const; + inline float GetRadius() const; + inline NzTextureRef GetShadowMap() const; + + inline bool IsShadowCastingEnabled() const; + + inline void SetAmbientFactor(float factor); + inline void SetAttenuation(float attenuation); + inline void SetColor(const NzColor& color); + inline void SetDiffuseFactor(float factor); + inline void SetInnerAngle(float innerAngle); + inline void SetLightType(nzLightType type); + inline void SetOuterAngle(float outerAngle); + inline void SetRadius(float radius); void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; - NzLight& operator=(const NzLight& light) = default; + NzLight& operator=(const NzLight& light); private: void MakeBoundingVolume() const override; + void UpdateShadowMap() const; nzLightType m_type; NzColor m_color; + mutable NzTextureRef m_shadowMap; + bool m_shadowCastingEnabled; + mutable bool m_shadowMapUpdated; float m_ambientFactor; float m_attenuation; float m_diffuseFactor; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index ecda520a4..d981e95bb 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -5,6 +5,40 @@ #include #include +inline NzLight::NzLight(const NzLight& light) : +NzRenderable(light), +m_type(light.m_type), +m_color(light.m_color), +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 NzLight::EnableShadowCasting(bool castShadows) +{ + if (m_shadowCastingEnabled != castShadows) + { + m_shadowCastingEnabled = castShadows; + m_shadowMapUpdated = false; + } +} + +inline void NzLight::EnsureShadowMapUpdate() const +{ + if (!m_shadowMapUpdated) + UpdateShadowMap(); +} + inline float NzLight::GetAmbientFactor() const { return m_ambientFactor; @@ -45,6 +79,18 @@ inline float NzLight::GetRadius() const return m_radius; } +inline NzTextureRef NzLight::GetShadowMap() const +{ + EnsureShadowMapUpdate(); + + return m_shadowMap; +} + +inline bool NzLight::IsShadowCastingEnabled() const +{ + return m_shadowCastingEnabled; +} + inline void NzLight::SetAmbientFactor(float factor) { m_ambientFactor = factor; @@ -94,4 +140,26 @@ inline void NzLight::SetRadius(float radius) InvalidateBoundingVolume(); } +inline NzLight& NzLight::operator=(const NzLight& light) +{ + NzRenderable::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_shadowMapUpdated = false; + m_type = light.m_type; + + return *this; +} + #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 35717498f..0bc491511 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -17,7 +17,9 @@ ///TODO: Scale ? NzLight::NzLight(nzLightType type) : -m_type(type) +m_type(type), +m_shadowCastingEnabled(false), +m_shadowMapUpdated(false) { SetAmbientFactor((type == nzLightType_Directional) ? 0.2f : 0.f); SetAttenuation(0.9f); @@ -177,3 +179,18 @@ void NzLight::MakeBoundingVolume() const break; } } + +void NzLight::UpdateShadowMap() const +{ + if (m_shadowCastingEnabled) + { + if (!m_shadowMap) + m_shadowMap = NzTexture::New(); + + m_shadowMap->Create(nzImageType_2D, nzPixelFormat_Depth16, 256, 256); + } + else + m_shadowMap.Reset(); + + m_shadowMapUpdated = true; +} diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index f2dc61bfc..c9dc2d611 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -148,6 +148,9 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.buffer = buffer; @@ -286,6 +289,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.isBuffer = false; From 39779c059d2dbc48269cac651ae8c33803b97197 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 16 Jun 2015 23:35:52 +0200 Subject: [PATCH 002/224] Renderer/OpenGL: Apply swizzle on depth formats Too much red when debugging shadow maps Former-commit-id: 4445429fcae3208912fd509097403f3293a2ec7e --- src/Nazara/Renderer/OpenGL.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 5c8167ad8..5331e902c 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1803,24 +1803,44 @@ bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, Format 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 nzPixelFormat_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 nzPixelFormat_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 nzPixelFormat_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 nzPixelFormat_Stencil1: From ebbaaf7ff2b4b7fb69192ce9ec086e91ce22287f Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:05 +0200 Subject: [PATCH 003/224] Graphics: Add depth render technique/queue Former-commit-id: 711306ee5f84a9579068ce23240dc105cec15cde --- SDK/include/NDK/Systems/RenderSystem.hpp | 3 +- SDK/src/NDK/Systems/RenderSystem.cpp | 19 +- include/Nazara/Graphics/DepthRenderQueue.hpp | 76 ++++ .../Nazara/Graphics/DepthRenderTechnique.hpp | 53 +++ .../Nazara/Graphics/DepthRenderTechnique.inl | 3 + include/Nazara/Graphics/Enums.hpp | 1 + src/Nazara/Graphics/DepthRenderQueue.cpp | 377 ++++++++++++++++++ src/Nazara/Graphics/DepthRenderTechnique.cpp | 363 +++++++++++++++++ src/Nazara/Graphics/Graphics.cpp | 8 + src/Nazara/Graphics/RenderTechniques.cpp | 1 + 10 files changed, 890 insertions(+), 14 deletions(-) create mode 100644 include/Nazara/Graphics/DepthRenderQueue.hpp create mode 100644 include/Nazara/Graphics/DepthRenderTechnique.hpp create mode 100644 include/Nazara/Graphics/DepthRenderTechnique.inl create mode 100644 src/Nazara/Graphics/DepthRenderQueue.cpp create mode 100644 src/Nazara/Graphics/DepthRenderTechnique.cpp diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 0baae7684..b06fe7ddc 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -7,6 +7,7 @@ #ifndef NDK_SYSTEMS_RENDERSYSTEM_HPP #define NDK_SYSTEMS_RENDERSYSTEM_HPP +#include #include #include #include @@ -37,8 +38,8 @@ namespace Ndk EntityList m_cameras; EntityList m_drawables; EntityList m_lights; + NzDepthRenderTechnique m_shadowTechnique; NzForwardRenderTechnique m_renderTechnique; - NzForwardRenderTechnique m_shadowTechnique; NzRenderTexture m_shadowRT; }; } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 4f6f27f86..fa7ea650a 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -100,24 +100,17 @@ namespace Ndk if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) continue; - /// HACKY - NzCamera lightPOV; - lightPOV.SetPosition(lightNode.GetPosition()); - lightPOV.SetFOV(lightComponent.GetOuterAngle()); - lightPOV.SetRotation(lightNode.GetRotation()); - lightPOV.SetZFar(1000.f); - lightPOV.SetTarget(&m_shadowRT); - NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); - NzRenderer::SetMatrix(nzMatrixType_Projection, lightPOV.GetProjectionMatrix()); - NzRenderer::SetMatrix(nzMatrixType_View, lightPOV.GetViewMatrix()); + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle(), 1.f, 1.f, 1000.f)); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); NzRenderer::SetTarget(&m_shadowRT); NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); - NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); renderQueue->Clear(); for (const Ndk::EntityHandle& drawable : m_drawables) @@ -131,9 +124,9 @@ namespace Ndk NzSceneData sceneData; sceneData.ambientColor = NzColor(0, 0, 0); sceneData.background = nullptr; - sceneData.viewer = &lightPOV; + sceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - m_renderTechnique.Draw(sceneData); + m_shadowTechnique.Draw(sceneData); } } diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp new file mode 100644 index 000000000..ec6550494 --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -0,0 +1,76 @@ +// 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 + +class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue +{ + public: + NzDepthRenderQueue() = default; + ~NzDepthRenderQueue() = default; + + void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddDrawable(const NzDrawable* drawable) override; + void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + + void Clear(bool fully = false); + + struct BillboardData + { + NzColor color; + NzVector3f center; + NzVector2f size; + NzVector2f sinCos; + }; + + struct MeshInstanceEntry + { + NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); + NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); + + std::vector instances; + }; + + struct SpriteChain_XYZ_Color_UV + { + const NzVertexStruct_XYZ_Color_UV* vertices; + unsigned int spriteCount; + }; + + std::map meshes; + std::vector billboards; + std::vector otherDrawables; + std::vector basicSprites; + + private: + bool IsMaterialSuitable(const NzMaterial* material) const; + + void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); + void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); +}; + +#endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp new file mode 100644 index 000000000..b33a2b6cc --- /dev/null +++ b/include/Nazara/Graphics/DepthRenderTechnique.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_DEPTHRENDERTECHNIQUE_HPP +#define NAZARA_DEPTHRENDERTECHNIQUE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechnique +{ + public: + NzDepthRenderTechnique(); + ~NzDepthRenderTechnique() = default; + + bool Draw(const NzSceneData& sceneData) const override; + + NzAbstractRenderQueue* GetRenderQueue() override; + nzRenderTechniqueType GetType() const override; + + static bool Initialize(); + static void Uninitialize(); + + private: + void DrawBasicSprites(const NzSceneData& sceneData) const; + void DrawBillboards(const NzSceneData& sceneData) const; + void DrawOpaqueModels(const NzSceneData& sceneData) const; + + NzBuffer m_vertexBuffer; + mutable NzDepthRenderQueue m_renderQueue; + NzVertexBuffer m_billboardPointBuffer; + NzVertexBuffer m_spriteBuffer; + + static NzIndexBuffer s_quadIndexBuffer; + static NzMaterialRef s_material; + static NzVertexBuffer s_quadVertexBuffer; + static NzVertexDeclaration s_billboardInstanceDeclaration; + static NzVertexDeclaration 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 1e301ecb9..70002d7cf 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -98,6 +98,7 @@ enum nzRenderTechniqueType nzRenderTechniqueType_AdvancedForward, // NzAdvancedForwardRenderTechnique nzRenderTechniqueType_BasicForward, // NzBasicForwardRenderTechnique nzRenderTechniqueType_DeferredShading, // NzDeferredRenderTechnique + nzRenderTechniqueType_Depth, // NzDepthRenderTechnique nzRenderTechniqueType_LightPrePass, // NzLightPrePassRenderTechnique nzRenderTechniqueType_User, diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp new file mode 100644 index 000000000..613033015 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -0,0 +1,377 @@ +// 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 + +///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) + +void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) +{ + NazaraAssert(material, "Invalid material"); + + if (IsMaterialSuitable(material)) + billboards.push_back(BillboardData{color, position, size, sinCos}); +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + ///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) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + ///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) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + unsigned int prevSize = billboards.size(); + billboards.resize(prevSize + count); + + BillboardData* billboardData = &billboards[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) +{ + #if NAZARA_GRAPHICS_SAFE + if (!drawable) + { + NazaraError("Invalid drawable"); + return; + } + #endif + + otherDrawables.push_back(drawable); +} + +void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + auto it = meshes.find(meshData); + if (it == meshes.end()) + { + MeshInstanceEntry instanceEntry; + + if (meshData.indexBuffer) + instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDepthRenderQueue::OnIndexBufferInvalidation); + + instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDepthRenderQueue::OnVertexBufferInvalidation); + + it = meshes.insert(std::make_pair(meshData, std::move(instanceEntry))).first; + } + + std::vector& instances = it->second.instances; + instances.push_back(transformMatrix); + + // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + //if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) + // entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau +} + +void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) +{ + NazaraAssert(material, "Invalid material"); + + if (!IsMaterialSuitable(material)) + return; + + basicSprites.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); +} + +void NzDepthRenderQueue::Clear(bool fully) +{ + NzAbstractRenderQueue::Clear(fully); + + basicSprites.clear(); + billboards.clear(); + otherDrawables.clear(); + + if (fully) + meshes.clear(); +} + +bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const +{ + NazaraAssert(material, "Invalid material"); + + return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite); +} + +void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) +{ + for (auto it = meshes.begin(); it != meshes.end();) + { + const NzMeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } +} + +void NzDepthRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) +{ + for (auto it = meshes.begin(); it != meshes.end();) + { + const NzMeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } +} + diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp new file mode 100644 index 000000000..c6da59276 --- /dev/null +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -0,0 +1,363 @@ +// 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 +{ + struct BillboardPoint + { + NzColor color; + NzVector3f position; + NzVector2f size; + NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) + NzVector2f uv; + }; + + static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); + + unsigned int s_maxQuads = std::numeric_limits::max()/6; + unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB +} + +NzDepthRenderTechnique::NzDepthRenderTechnique() : +m_vertexBuffer(nzBufferType_Vertex) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + m_vertexBuffer.Create(s_vertexBufferSize, nzDataStorage_Hardware, nzBufferUsage_Dynamic); + + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), &m_vertexBuffer); +} + +bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const +{ + NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); + NzRenderer::Enable(nzRendererParameter_DepthWrite, true); + NzRenderer::Clear(nzRendererBuffer_Depth); + + // Just in case the background does render depth + if (sceneData.background) + sceneData.background->Draw(sceneData.viewer); + + if (!m_renderQueue.meshes.empty()) + DrawOpaqueModels(sceneData); + + if (!m_renderQueue.basicSprites.empty()) + DrawBasicSprites(sceneData); + + if (!m_renderQueue.billboards.empty()) + DrawBillboards(sceneData); + + // Other custom drawables + for (const NzDrawable* drawable : m_renderQueue.otherDrawables) + drawable->Draw(); + + return true; +} + +NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() +{ + return &m_renderQueue; +} + +nzRenderTechniqueType NzDepthRenderTechnique::GetType() const +{ + return nzRenderTechniqueType_BasicForward; +} + +bool NzDepthRenderTechnique::Initialize() +{ + try + { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxQuads*6, nzDataStorage_Hardware, nzBufferUsage_Static); + + NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); + nzUInt16* 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(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_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(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv)); + s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(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(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); + s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos + s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); + + // Material + s_material = NzMaterial::New(); + s_material->Enable(nzRendererParameter_ColorWrite, false); + s_material->Enable(nzRendererParameter_FaceCulling, false); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + NzString(e.what())); + return false; + } + + return true; +} + +void NzDepthRenderTechnique::Uninitialize() +{ + s_material.Reset(); + s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); +} + +void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const +{ + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); + NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); + NzRenderer::SetVertexBuffer(&m_spriteBuffer); + + auto& spriteChainVector = m_renderQueue.basicSprites; + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + s_material->Apply(); + + 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 + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + NzDepthRenderQueue::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(NzVertexStruct_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(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } +} + +void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const +{ + if (NzRenderer::HasCapability(nzRendererCap_Instancing)) + { + NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); + + NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); + + auto& billboardVector = m_renderQueue.billboards; + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + s_material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing); + + const NzDepthRenderQueue::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; + + NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + else + { + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); + NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + + auto& billboardVector = m_renderQueue.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + s_material->Apply(nzShaderFlags_Billboard); + + const NzDepthRenderQueue::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; + + NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + for (unsigned int i = 0; i < renderedBillboardCount; ++i) + { + const NzDepthRenderQueue::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(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } +} + +void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const +{ + s_material->Apply(); + + for (auto& meshIt : m_renderQueue.meshes) + { + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) + { + const NzIndexBuffer* indexBuffer = meshData.indexBuffer; + const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + // 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 NzMatrix4f& matrix : instances) + { + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + instances.clear(); + } + } +} + +NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; +NzMaterialRef NzDepthRenderTechnique::s_material; +NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; +NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; +NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 691423019..f81de8fce 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,12 @@ bool NzGraphics::Initialize() NzLoaders_Texture_Register(); // RenderTechniques + if (!NzDepthRenderTechnique::Initialize()) + { + NazaraError("Failed to initialize Depth Rendering"); + return false; + } + if (!NzForwardRenderTechnique::Initialize()) { NazaraError("Failed to initialize Forward Rendering"); @@ -164,6 +171,7 @@ void NzGraphics::Uninitialize() NzLoaders_Texture_Unregister(); NzDeferredRenderTechnique::Uninitialize(); + NzDepthRenderTechnique::Uninitialize(); NzForwardRenderTechnique::Uninitialize(); NzSkinningManager::Uninitialize(); NzParticleRenderer::Uninitialize(); diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index 820700451..9a96ac71e 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -15,6 +15,7 @@ namespace { "Advanced Forward", "Basic Forward", + "Depth Pass", "Deferred Shading", "Light Pre-Pass", "User" From b7c5283c4e85eca4cc605ded4d7c0fed0ac541eb Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:18 +0200 Subject: [PATCH 004/224] Graphics/Sprite: Fix compilation in debug Former-commit-id: 233f8ebe775e268b72808ecd0770956651e717f6 --- include/Nazara/Graphics/Sprite.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 7b7cb5b24..1ce1cf534 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -121,7 +121,7 @@ inline void NzSprite::SetTextureCoords(const NzRectf& coords) inline void NzSprite::SetTextureRect(const NzRectui& rect) { - NazaraAssert(material, "Sprite has no material"); + NazaraAssert(m_material, "Sprite has no material"); NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); NzTexture* diffuseMap = m_material->GetDiffuseMap(); From e89b87044d8b58069d5423948a2645b54cd0c3c0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 14:32:32 +0200 Subject: [PATCH 005/224] Graphics: Fix some comments Former-commit-id: df6d080b1ce251b7fe5707ddbb4e31773ba9035d --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 16 ++++++++-------- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 10469b1a5..fffd8372a 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -32,7 +32,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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 NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -71,7 +71,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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 NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -112,7 +112,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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) @@ -155,7 +155,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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) @@ -200,7 +200,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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 NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -239,7 +239,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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 NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) @@ -280,7 +280,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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) @@ -323,7 +323,7 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in { 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 ed36853d0..37e9efdde 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -27,10 +27,12 @@ namespace NzColor color; NzVector3f position; NzVector2f size; - NzVector2f sinCos; // doit suivre size + NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) NzVector2f uv; }; + static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); + unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } From 80208b0dc59dc17db96c60d8782f33977994462a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:32:48 +0200 Subject: [PATCH 006/224] Core/OffsetOf: Remove constexpr (cannot be used because of reinterpret_cast) Former-commit-id: 78142eb9033a1969f20055b2cecf1bc78152e896 --- include/Nazara/Core/OffsetOf.hpp | 3 ++- src/Nazara/Graphics/DepthRenderTechnique.cpp | 2 -- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index 4f13abacf..870481627 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -14,8 +14,9 @@ template T NzImplGetClassType(M T::*); template M NzImplGetMemberType(M T::*); template -constexpr std::size_t NzImplOffsetOf() +std::size_t NzImplOffsetOf() { + ///FIXME: reinterpret_cast is not allowed in constexpr functions return reinterpret_cast(&((static_cast(0))->*M)); } diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index c6da59276..9fe00be37 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -31,8 +31,6 @@ namespace NzVector2f uv; }; - static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); - unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 37e9efdde..656f34d5d 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -31,8 +31,6 @@ namespace NzVector2f uv; }; - static_assert(NzOffsetOf(BillboardPoint, sinCos) - NzOffsetOf(BillboardPoint, size) == sizeof(NzVector2f), "size and sinCos members should be packed"); - unsigned int s_maxQuads = std::numeric_limits::max()/6; unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } From 35066a3451bc972f79b3226fc937b03bf114fe4b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:35:06 +0200 Subject: [PATCH 007/224] Math/Sphere: Fix (Squared)Distance Former-commit-id: d91c0d6e8a193e47c3ed45babaf3b83bf1cbe7ee --- include/Nazara/Math/Sphere.inl | 10 ++++------ include/Nazara/Math/Vector3.hpp | 3 +++ include/Nazara/Math/Vector3.inl | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index f8ece724c..f617d28e2 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -68,14 +68,13 @@ bool NzSphere::Contains(const NzVector3& point) const template T NzSphere::Distance(T X, T Y, T Z) const { - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetLength(); + return Distance({X, Y, Z}); } template T NzSphere::Distance(const NzVector3& point) const { - return Distance(point.x, point.y, point.z); + return NzVector3f::Distance(point, GetPosition()) - radius; } template @@ -249,14 +248,13 @@ NzSphere& NzSphere::Set(const NzSphere& sphere) template T NzSphere::SquaredDistance(T X, T Y, T Z) const { - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetSquaredLength(); + return SquaredDistance({X, Y, Z}); } template T NzSphere::SquaredDistance(const NzVector3& point) const { - return SquaredDistance(point.x, point.y, point.z); + return NzVector3f::Distance(point, GetPosition()) - radius * radius; } template diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 14cd41b0a..f180816b2 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -103,12 +103,15 @@ class NzVector3 static NzVector3 Backward(); static NzVector3 CrossProduct(const NzVector3& vec1, const NzVector3& vec2); static T DotProduct(const NzVector3& vec1, const NzVector3& vec2); + static T Distance(const NzVector3& vec1, const NzVector3& vec2); + static float Distancef(const NzVector3& vec1, const NzVector3& vec2); static NzVector3 Down(); static NzVector3 Forward(); static NzVector3 Left(); static NzVector3 Lerp(const NzVector3& from, const NzVector3& to, T interpolation); static NzVector3 Normalize(const NzVector3& vec); static NzVector3 Right(); + static T SquaredDistance(const NzVector3& vec1, const NzVector3& vec2); static NzVector3 Unit(); static NzVector3 UnitX(); static NzVector3 UnitY(); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index a2f0ed35c..0d6d10cf5 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -567,6 +567,18 @@ NzVector3 NzVector3::Backward() return vector; } +template +T NzVector3::Distance(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.Distance(vec2); +} + +template +float NzVector3::Distancef(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.Distancef(vec2); +} + template NzVector3 NzVector3::Down() { @@ -615,6 +627,12 @@ NzVector3 NzVector3::Right() return vector; } +template +T NzVector3::SquaredDistance(const NzVector3& vec1, const NzVector3& vec2) +{ + return vec1.SquaredDistance(vec2); +} + template NzVector3 NzVector3::Unit() { From 763701df7fc09dcd4ff16c918101f0162812ef14 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Jun 2015 23:36:53 +0200 Subject: [PATCH 008/224] Graphics/Material: Inline class Former-commit-id: 7cd8b7a00c87adf087dae7d0fb8d955747cf82d1 --- include/Nazara/Graphics/Material.hpp | 148 ++++----- include/Nazara/Graphics/Material.inl | 468 ++++++++++++++++++++++++++ src/Nazara/Graphics/Material.cpp | 480 --------------------------- 3 files changed, 542 insertions(+), 554 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 59f8f800a..87f6ed615 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -53,90 +53,90 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource friend class NzGraphics; public: - NzMaterial(); - NzMaterial(const NzMaterial& material); - ~NzMaterial(); + inline NzMaterial(); + inline NzMaterial(const NzMaterial& material); + inline ~NzMaterial(); const NzShader* Apply(nzUInt32 shaderFlags = 0, nzUInt8 textureUnit = 0, nzUInt8* lastUsedUnit = nullptr) const; - void Enable(nzRendererParameter renderParameter, bool enable); - void EnableAlphaTest(bool alphaTest); - void EnableDepthSorting(bool depthSorting); - void EnableLighting(bool lighting); - void EnableTransform(bool transform); + inline void Enable(nzRendererParameter renderParameter, bool enable); + inline void EnableAlphaTest(bool alphaTest); + inline void EnableDepthSorting(bool depthSorting); + inline void EnableLighting(bool lighting); + inline void EnableTransform(bool transform); - NzTexture* GetAlphaMap() const; - float GetAlphaThreshold() const; - NzColor GetAmbientColor() const; - nzRendererComparison GetDepthFunc() const; - NzColor GetDiffuseColor() const; - NzTexture* GetDiffuseMap() const; - NzTextureSampler& GetDiffuseSampler(); - const NzTextureSampler& GetDiffuseSampler() const; - nzBlendFunc GetDstBlend() const; - NzTexture* GetEmissiveMap() const; - nzFaceSide GetFaceCulling() const; - nzFaceFilling GetFaceFilling() const; - NzTexture* GetHeightMap() const; - NzTexture* GetNormalMap() const; - const NzRenderStates& GetRenderStates() const; - const NzUberShader* GetShader() const; - const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; - float GetShininess() const; - NzColor GetSpecularColor() const; - NzTexture* GetSpecularMap() const; - NzTextureSampler& GetSpecularSampler(); - const NzTextureSampler& GetSpecularSampler() const; - nzBlendFunc GetSrcBlend() const; + inline NzTexture* GetAlphaMap() const; + inline float GetAlphaThreshold() const; + inline NzColor GetAmbientColor() const; + inline nzRendererComparison GetDepthFunc() const; + inline NzColor GetDiffuseColor() const; + inline NzTexture* GetDiffuseMap() const; + inline NzTextureSampler& GetDiffuseSampler(); + inline const NzTextureSampler& GetDiffuseSampler() const; + inline nzBlendFunc GetDstBlend() const; + inline NzTexture* GetEmissiveMap() const; + inline nzFaceSide GetFaceCulling() const; + inline nzFaceFilling GetFaceFilling() const; + inline NzTexture* GetHeightMap() const; + inline NzTexture* GetNormalMap() const; + inline const NzRenderStates& GetRenderStates() const; + inline const NzUberShader* GetShader() const; + inline const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; + inline float GetShininess() const; + inline NzColor GetSpecularColor() const; + inline NzTexture* GetSpecularMap() const; + inline NzTextureSampler& GetSpecularSampler(); + inline const NzTextureSampler& GetSpecularSampler() const; + inline nzBlendFunc GetSrcBlend() const; - bool HasAlphaMap() const; - bool HasDiffuseMap() const; - bool HasEmissiveMap() const; - bool HasHeightMap() const; - bool HasNormalMap() const; - bool HasSpecularMap() const; + inline bool HasAlphaMap() const; + inline bool HasDiffuseMap() const; + inline bool HasEmissiveMap() const; + inline bool HasHeightMap() const; + inline bool HasNormalMap() const; + inline bool HasSpecularMap() const; - bool IsAlphaTestEnabled() const; - bool IsDepthSortingEnabled() const; - bool IsEnabled(nzRendererParameter renderParameter) const; - bool IsLightingEnabled() const; - bool IsTransformEnabled() const; + inline bool IsAlphaTestEnabled() const; + inline bool IsDepthSortingEnabled() const; + inline bool IsEnabled(nzRendererParameter renderParameter) const; + inline bool IsLightingEnabled() const; + inline bool IsTransformEnabled() const; - bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams()); + inline bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams()); void Reset(); - bool SetAlphaMap(const NzString& textureName); - void SetAlphaMap(NzTextureRef alphaMap); - void SetAlphaThreshold(float alphaThreshold); - void SetAmbientColor(const NzColor& ambient); - void SetDepthFunc(nzRendererComparison depthFunc); - void SetDiffuseColor(const NzColor& diffuse); - bool SetDiffuseMap(const NzString& textureName); - void SetDiffuseMap(NzTextureRef diffuseMap); - void SetDiffuseSampler(const NzTextureSampler& sampler); - void SetDstBlend(nzBlendFunc func); - bool SetEmissiveMap(const NzString& textureName); - void SetEmissiveMap(NzTextureRef textureName); - void SetFaceCulling(nzFaceSide faceSide); - void SetFaceFilling(nzFaceFilling filling); - bool SetHeightMap(const NzString& textureName); - void SetHeightMap(NzTextureRef textureName); - bool SetNormalMap(const NzString& textureName); - void SetNormalMap(NzTextureRef textureName); - void SetRenderStates(const NzRenderStates& states); - void SetShader(NzUberShaderConstRef uberShader); - bool SetShader(const NzString& uberShaderName); - void SetShininess(float shininess); - void SetSpecularColor(const NzColor& specular); - bool SetSpecularMap(const NzString& textureName); - void SetSpecularMap(NzTextureRef specularMap); - void SetSpecularSampler(const NzTextureSampler& sampler); - void SetSrcBlend(nzBlendFunc func); + inline bool SetAlphaMap(const NzString& textureName); + inline void SetAlphaMap(NzTextureRef alphaMap); + inline void SetAlphaThreshold(float alphaThreshold); + inline void SetAmbientColor(const NzColor& ambient); + inline void SetDepthFunc(nzRendererComparison depthFunc); + inline void SetDiffuseColor(const NzColor& diffuse); + inline bool SetDiffuseMap(const NzString& textureName); + inline void SetDiffuseMap(NzTextureRef diffuseMap); + inline void SetDiffuseSampler(const NzTextureSampler& sampler); + inline void SetDstBlend(nzBlendFunc func); + inline bool SetEmissiveMap(const NzString& textureName); + inline void SetEmissiveMap(NzTextureRef textureName); + inline void SetFaceCulling(nzFaceSide faceSide); + inline void SetFaceFilling(nzFaceFilling filling); + inline bool SetHeightMap(const NzString& textureName); + inline void SetHeightMap(NzTextureRef textureName); + inline bool SetNormalMap(const NzString& textureName); + inline void SetNormalMap(NzTextureRef textureName); + inline void SetRenderStates(const NzRenderStates& states); + inline void SetShader(NzUberShaderConstRef uberShader); + inline bool SetShader(const NzString& uberShaderName); + inline void SetShininess(float shininess); + inline void SetSpecularColor(const NzColor& specular); + inline bool SetSpecularMap(const NzString& textureName); + inline void SetSpecularMap(NzTextureRef specularMap); + inline void SetSpecularSampler(const NzTextureSampler& sampler); + inline void SetSrcBlend(nzBlendFunc func); - NzMaterial& operator=(const NzMaterial& material); + inline NzMaterial& operator=(const NzMaterial& material); static NzMaterialRef GetDefault(); template static NzMaterialRef New(Args&&... args); @@ -155,7 +155,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource void Copy(const NzMaterial& material); void GenerateShader(nzUInt32 flags) const; - void InvalidateShaders(); + inline void InvalidateShaders(); static bool Initialize(); static void Uninitialize(); diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 08c3d9b2d..aed3f2ceb 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -5,6 +5,474 @@ #include #include +inline NzMaterial::NzMaterial() +{ + Reset(); +} + +inline NzMaterial::NzMaterial(const NzMaterial& material) : + NzRefCounted(), + NzResource(material) +{ + Copy(material); +} + +inline NzMaterial::~NzMaterial() +{ + OnMaterialRelease(this); +} + +inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) +{ + NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + + m_states.parameters[renderParameter] = enable; +} + +inline void NzMaterial::EnableAlphaTest(bool alphaTest) +{ + m_alphaTestEnabled = alphaTest; + + InvalidateShaders(); +} + +inline void NzMaterial::EnableDepthSorting(bool depthSorting) +{ + m_depthSortingEnabled = depthSorting; +} + +inline void NzMaterial::EnableLighting(bool lighting) +{ + m_lightingEnabled = lighting; + + InvalidateShaders(); +} + +inline void NzMaterial::EnableTransform(bool transform) +{ + m_transformEnabled = transform; + + InvalidateShaders(); +} + +inline NzTexture* NzMaterial::GetAlphaMap() const +{ + return m_alphaMap; +} + +inline float NzMaterial::GetAlphaThreshold() const +{ + return m_alphaThreshold; +} + +inline NzColor NzMaterial::GetAmbientColor() const +{ + return m_ambientColor; +} + +inline nzRendererComparison NzMaterial::GetDepthFunc() const +{ + return m_states.depthFunc; +} + +inline NzColor NzMaterial::GetDiffuseColor() const +{ + return m_diffuseColor; +} + +inline NzTextureSampler& NzMaterial::GetDiffuseSampler() +{ + return m_diffuseSampler; +} + +inline const NzTextureSampler& NzMaterial::GetDiffuseSampler() const +{ + return m_diffuseSampler; +} + +NzTexture* NzMaterial::GetDiffuseMap() const +{ + return m_diffuseMap; +} + +inline nzBlendFunc NzMaterial::GetDstBlend() const +{ + return m_states.dstBlend; +} + +inline NzTexture* NzMaterial::GetEmissiveMap() const +{ + return m_emissiveMap; +} + +inline nzFaceSide NzMaterial::GetFaceCulling() const +{ + return m_states.faceCulling; +} + +inline nzFaceFilling NzMaterial::GetFaceFilling() const +{ + return m_states.faceFilling; +} + +inline NzTexture* NzMaterial::GetHeightMap() const +{ + return m_heightMap; +} + +inline NzTexture* NzMaterial::GetNormalMap() const +{ + return m_normalMap; +} + +inline const NzRenderStates& NzMaterial::GetRenderStates() const +{ + return m_states; +} + +inline const NzUberShader* NzMaterial::GetShader() const +{ + return m_uberShader; +} + +inline const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const +{ + const ShaderInstance& instance = m_shaders[flags]; + if (!instance.uberInstance) + GenerateShader(flags); + + return instance.uberInstance; +} + +inline float NzMaterial::GetShininess() const +{ + return m_shininess; +} + +inline NzColor NzMaterial::GetSpecularColor() const +{ + return m_specularColor; +} + +inline NzTexture* NzMaterial::GetSpecularMap() const +{ + return m_specularMap; +} + +inline NzTextureSampler& NzMaterial::GetSpecularSampler() +{ + return m_specularSampler; +} + +inline const NzTextureSampler& NzMaterial::GetSpecularSampler() const +{ + return m_specularSampler; +} + +inline nzBlendFunc NzMaterial::GetSrcBlend() const +{ + return m_states.srcBlend; +} + +inline bool NzMaterial::HasAlphaMap() const +{ + return m_alphaMap.IsValid(); +} + +inline bool NzMaterial::HasDiffuseMap() const +{ + return m_diffuseMap.IsValid(); +} + +inline bool NzMaterial::HasEmissiveMap() const +{ + return m_emissiveMap.IsValid(); +} + +inline bool NzMaterial::HasHeightMap() const +{ + return m_heightMap.IsValid(); +} + +inline bool NzMaterial::HasNormalMap() const +{ + return m_normalMap.IsValid(); +} + +inline bool NzMaterial::HasSpecularMap() const +{ + return m_specularMap.IsValid(); +} + +inline bool NzMaterial::IsAlphaTestEnabled() const +{ + return m_alphaTestEnabled; +} + +inline bool NzMaterial::IsDepthSortingEnabled() const +{ + return m_depthSortingEnabled; +} + +inline bool NzMaterial::IsEnabled(nzRendererParameter parameter) const +{ + NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + + return m_states.parameters[parameter]; +} + +inline bool NzMaterial::IsLightingEnabled() const +{ + return m_lightingEnabled; +} + +inline bool NzMaterial::IsTransformEnabled() const +{ + return m_transformEnabled; +} + +inline bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromFile(this, filePath, params); +} + +inline bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromMemory(this, data, size, params); +} + +inline bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params) +{ + return NzMaterialLoader::LoadFromStream(this, stream, params); +} + +inline bool NzMaterial::SetAlphaMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetAlphaMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetAlphaMap(NzTextureRef alphaMap) +{ + m_alphaMap = std::move(alphaMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetAlphaThreshold(float alphaThreshold) +{ + m_alphaThreshold = alphaThreshold; +} + +inline void NzMaterial::SetAmbientColor(const NzColor& ambient) +{ + m_ambientColor = ambient; +} + +inline void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) +{ + m_states.depthFunc = depthFunc; +} + +inline void NzMaterial::SetDiffuseColor(const NzColor& diffuse) +{ + m_diffuseColor = diffuse; +} + +inline bool NzMaterial::SetDiffuseMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetDiffuseMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap) +{ + m_diffuseMap = std::move(diffuseMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) +{ + m_diffuseSampler = sampler; +} + +inline void NzMaterial::SetDstBlend(nzBlendFunc func) +{ + m_states.dstBlend = func; +} + +inline bool NzMaterial::SetEmissiveMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetEmissiveMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap) +{ + m_emissiveMap = std::move(emissiveMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetFaceCulling(nzFaceSide faceSide) +{ + m_states.faceCulling = faceSide; +} + +inline void NzMaterial::SetFaceFilling(nzFaceFilling filling) +{ + m_states.faceFilling = filling; +} + +inline bool NzMaterial::SetHeightMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetHeightMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetHeightMap(NzTextureRef heightMap) +{ + m_heightMap = std::move(heightMap); + + InvalidateShaders(); +} + +inline bool NzMaterial::SetNormalMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetNormalMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetNormalMap(NzTextureRef normalMap) +{ + m_normalMap = std::move(normalMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetRenderStates(const NzRenderStates& states) +{ + m_states = states; +} + +inline void NzMaterial::SetShader(NzUberShaderConstRef uberShader) +{ + m_uberShader = std::move(uberShader); + + InvalidateShaders(); +} + +inline bool NzMaterial::SetShader(const NzString& uberShaderName) +{ + NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName); + if (!uberShader) + return false; + + SetShader(std::move(uberShader)); + return true; +} + +inline void NzMaterial::SetShininess(float shininess) +{ + m_shininess = shininess; +} + +inline void NzMaterial::SetSpecularColor(const NzColor& specular) +{ + m_specularColor = specular; +} + +inline bool NzMaterial::SetSpecularMap(const NzString& textureName) +{ + NzTextureRef texture = NzTextureLibrary::Query(textureName); + if (!texture) + { + texture = NzTextureManager::Get(textureName); + if (!texture) + return false; + } + + SetSpecularMap(std::move(texture)); + return true; +} + +inline void NzMaterial::SetSpecularMap(NzTextureRef specularMap) +{ + m_specularMap = std::move(specularMap); + + InvalidateShaders(); +} + +inline void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) +{ + m_specularSampler = sampler; +} + +inline void NzMaterial::SetSrcBlend(nzBlendFunc func) +{ + m_states.srcBlend = func; +} + +inline NzMaterial& NzMaterial::operator=(const NzMaterial& material) +{ + NzResource::operator=(material); + + Copy(material); + return *this; +} + +inline NzMaterialRef NzMaterial::GetDefault() +{ + return s_defaultMaterial; +} + +inline void NzMaterial::InvalidateShaders() +{ + for (ShaderInstance& instance : m_shaders) + instance.uberInstance = nullptr; +} + template NzMaterialRef NzMaterial::New(Args&&... args) { diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index ce569a127..382cf4d2c 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -41,23 +41,6 @@ bool NzMaterialParams::IsValid() const return true; } -NzMaterial::NzMaterial() -{ - Reset(); -} - -NzMaterial::NzMaterial(const NzMaterial& material) : -NzRefCounted(), -NzResource(material) -{ - Copy(material); -} - -NzMaterial::~NzMaterial() -{ - OnMaterialRelease(this); -} - const NzShader* NzMaterial::Apply(nzUInt32 shaderFlags, nzUInt8 textureUnit, nzUInt8* lastUsedUnit) const { const ShaderInstance& instance = m_shaders[shaderFlags]; @@ -137,242 +120,6 @@ const NzShader* NzMaterial::Apply(nzUInt32 shaderFlags, nzUInt8 textureUnit, nzU return instance.shader; } -void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) -{ - #ifdef NAZARA_DEBUG - if (renderParameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return; - } - #endif - - m_states.parameters[renderParameter] = enable; -} - -void NzMaterial::EnableAlphaTest(bool alphaTest) -{ - m_alphaTestEnabled = alphaTest; - - InvalidateShaders(); -} - -void NzMaterial::EnableDepthSorting(bool depthSorting) -{ - m_depthSortingEnabled = depthSorting; -} - -void NzMaterial::EnableLighting(bool lighting) -{ - m_lightingEnabled = lighting; - - InvalidateShaders(); -} - -void NzMaterial::EnableTransform(bool transform) -{ - m_transformEnabled = transform; - - InvalidateShaders(); -} - -NzTexture* NzMaterial::GetAlphaMap() const -{ - return m_alphaMap; -} - -float NzMaterial::GetAlphaThreshold() const -{ - return m_alphaThreshold; -} - -NzColor NzMaterial::GetAmbientColor() const -{ - return m_ambientColor; -} - -nzRendererComparison NzMaterial::GetDepthFunc() const -{ - return m_states.depthFunc; -} - -NzColor NzMaterial::GetDiffuseColor() const -{ - return m_diffuseColor; -} - -NzTextureSampler& NzMaterial::GetDiffuseSampler() -{ - return m_diffuseSampler; -} - -const NzTextureSampler& NzMaterial::GetDiffuseSampler() const -{ - return m_diffuseSampler; -} - -NzTexture* NzMaterial::GetDiffuseMap() const -{ - return m_diffuseMap; -} - -nzBlendFunc NzMaterial::GetDstBlend() const -{ - return m_states.dstBlend; -} - -NzTexture* NzMaterial::GetEmissiveMap() const -{ - return m_emissiveMap; -} - -nzFaceSide NzMaterial::GetFaceCulling() const -{ - return m_states.faceCulling; -} - -nzFaceFilling NzMaterial::GetFaceFilling() const -{ - return m_states.faceFilling; -} - -NzTexture* NzMaterial::GetHeightMap() const -{ - return m_heightMap; -} - -NzTexture* NzMaterial::GetNormalMap() const -{ - return m_normalMap; -} - -const NzRenderStates& NzMaterial::GetRenderStates() const -{ - return m_states; -} - -const NzUberShader* NzMaterial::GetShader() const -{ - return m_uberShader; -} - -const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const -{ - const ShaderInstance& instance = m_shaders[flags]; - if (!instance.uberInstance) - GenerateShader(flags); - - return instance.uberInstance; -} - -float NzMaterial::GetShininess() const -{ - return m_shininess; -} - -NzColor NzMaterial::GetSpecularColor() const -{ - return m_specularColor; -} - -NzTexture* NzMaterial::GetSpecularMap() const -{ - return m_specularMap; -} - -NzTextureSampler& NzMaterial::GetSpecularSampler() -{ - return m_specularSampler; -} - -const NzTextureSampler& NzMaterial::GetSpecularSampler() const -{ - return m_specularSampler; -} - -nzBlendFunc NzMaterial::GetSrcBlend() const -{ - return m_states.srcBlend; -} - -bool NzMaterial::HasAlphaMap() const -{ - return m_alphaMap.IsValid(); -} - -bool NzMaterial::HasDiffuseMap() const -{ - return m_diffuseMap.IsValid(); -} - -bool NzMaterial::HasEmissiveMap() const -{ - return m_emissiveMap.IsValid(); -} - -bool NzMaterial::HasHeightMap() const -{ - return m_heightMap.IsValid(); -} - -bool NzMaterial::HasNormalMap() const -{ - return m_normalMap.IsValid(); -} - -bool NzMaterial::HasSpecularMap() const -{ - return m_specularMap.IsValid(); -} - -bool NzMaterial::IsAlphaTestEnabled() const -{ - return m_alphaTestEnabled; -} - -bool NzMaterial::IsDepthSortingEnabled() const -{ - return m_depthSortingEnabled; -} - -bool NzMaterial::IsEnabled(nzRendererParameter parameter) const -{ - #ifdef NAZARA_DEBUG - if (parameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return false; - } - #endif - - return m_states.parameters[parameter]; -} - -bool NzMaterial::IsLightingEnabled() const -{ - return m_lightingEnabled; -} - -bool NzMaterial::IsTransformEnabled() const -{ - return m_transformEnabled; -} - -bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromFile(this, filePath, params); -} - -bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromMemory(this, data, size, params); -} - -bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromStream(this, stream, params); -} - void NzMaterial::Reset() { OnMaterialReset(this); @@ -406,227 +153,6 @@ void NzMaterial::Reset() SetShader("Basic"); } -bool NzMaterial::SetAlphaMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetAlphaMap(std::move(texture)); - return true; -} - -void NzMaterial::SetAlphaMap(NzTextureRef alphaMap) -{ - m_alphaMap = std::move(alphaMap); - - InvalidateShaders(); -} - -void NzMaterial::SetAlphaThreshold(float alphaThreshold) -{ - m_alphaThreshold = alphaThreshold; -} - -void NzMaterial::SetAmbientColor(const NzColor& ambient) -{ - m_ambientColor = ambient; -} - -void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) -{ - m_states.depthFunc = depthFunc; -} - -void NzMaterial::SetDiffuseColor(const NzColor& diffuse) -{ - m_diffuseColor = diffuse; -} - -bool NzMaterial::SetDiffuseMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetDiffuseMap(std::move(texture)); - return true; -} - -void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap) -{ - m_diffuseMap = std::move(diffuseMap); - - InvalidateShaders(); -} - -void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) -{ - m_diffuseSampler = sampler; -} - -void NzMaterial::SetDstBlend(nzBlendFunc func) -{ - m_states.dstBlend = func; -} - -bool NzMaterial::SetEmissiveMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetEmissiveMap(std::move(texture)); - return true; -} - -void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap) -{ - m_emissiveMap = std::move(emissiveMap); - - InvalidateShaders(); -} - -void NzMaterial::SetFaceCulling(nzFaceSide faceSide) -{ - m_states.faceCulling = faceSide; -} - -void NzMaterial::SetFaceFilling(nzFaceFilling filling) -{ - m_states.faceFilling = filling; -} - -bool NzMaterial::SetHeightMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetHeightMap(std::move(texture)); - return true; -} - -void NzMaterial::SetHeightMap(NzTextureRef heightMap) -{ - m_heightMap = std::move(heightMap); - - InvalidateShaders(); -} - -bool NzMaterial::SetNormalMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetNormalMap(std::move(texture)); - return true; -} - -void NzMaterial::SetNormalMap(NzTextureRef normalMap) -{ - m_normalMap = std::move(normalMap); - - InvalidateShaders(); -} - -void NzMaterial::SetRenderStates(const NzRenderStates& states) -{ - m_states = states; -} - -void NzMaterial::SetShader(NzUberShaderConstRef uberShader) -{ - m_uberShader = std::move(uberShader); - - InvalidateShaders(); -} - -bool NzMaterial::SetShader(const NzString& uberShaderName) -{ - NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName); - if (!uberShader) - return false; - - SetShader(std::move(uberShader)); - return true; -} - -void NzMaterial::SetShininess(float shininess) -{ - m_shininess = shininess; -} - -void NzMaterial::SetSpecularColor(const NzColor& specular) -{ - m_specularColor = specular; -} - -bool NzMaterial::SetSpecularMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetSpecularMap(std::move(texture)); - return true; -} - -void NzMaterial::SetSpecularMap(NzTextureRef specularMap) -{ - m_specularMap = std::move(specularMap); - - InvalidateShaders(); -} - -void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) -{ - m_specularSampler = sampler; -} - -void NzMaterial::SetSrcBlend(nzBlendFunc func) -{ - m_states.srcBlend = func; -} - -NzMaterial& NzMaterial::operator=(const NzMaterial& material) -{ - NzResource::operator=(material); - - Copy(material); - return *this; -} - -NzMaterialRef NzMaterial::GetDefault() -{ - return s_defaultMaterial; -} - void NzMaterial::Copy(const NzMaterial& material) { // Copie des états de base @@ -702,12 +228,6 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const #undef CacheUniform } -void NzMaterial::InvalidateShaders() -{ - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; -} - bool NzMaterial::Initialize() { if (!NzMaterialLibrary::Initialize()) From ac8578c510c54cb5edcc82888bfe96ab165ca5fe Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 18 Jun 2015 00:03:38 +0200 Subject: [PATCH 009/224] Graphics/Material: Add shadow support The real fun will be in the shader Former-commit-id: e29e98cbf3c35e4cf14c68852e03dc9da1df0ff1 --- include/Nazara/Graphics/Material.hpp | 6 ++++++ include/Nazara/Graphics/Material.inl | 24 ++++++++++++++++++++++++ src/Nazara/Graphics/Material.cpp | 1 + 3 files changed, 31 insertions(+) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 87f6ed615..2d09c2f35 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -63,6 +63,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource 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); inline NzTexture* GetAlphaMap() const; @@ -100,6 +102,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline bool IsDepthSortingEnabled() const; inline bool IsEnabled(nzRendererParameter renderParameter) const; inline bool IsLightingEnabled() const; + inline bool IsShadowCastingEnabled() const; + inline bool IsShadowReceiveEnabled() const; inline bool IsTransformEnabled() const; inline bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); @@ -177,6 +181,8 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource 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 aed3f2ceb..93cca4bb0 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -38,6 +38,7 @@ inline void NzMaterial::EnableAlphaTest(bool alphaTest) inline void NzMaterial::EnableDepthSorting(bool depthSorting) { + // Has no influence on shaders m_depthSortingEnabled = depthSorting; } @@ -48,6 +49,19 @@ inline void NzMaterial::EnableLighting(bool lighting) InvalidateShaders(); } +inline void NzMaterial::EnableShadowCasting(bool castShadows) +{ + // Has no influence on shaders + m_shadowCastingEnabled = castShadows; +} + +inline void NzMaterial::EnableShadowReceive(bool receiveShadows) +{ + m_shadowReceiveEnabled = receiveShadows; + + InvalidateShaders(); +} + inline void NzMaterial::EnableTransform(bool transform) { m_transformEnabled = transform; @@ -226,6 +240,16 @@ inline bool NzMaterial::IsLightingEnabled() const return m_lightingEnabled; } +inline bool NzMaterial::IsShadowCastingEnabled() const +{ + return m_shadowCastingEnabled; +} + +inline bool NzMaterial::IsShadowReceiveEnabled() const +{ + return m_shadowReceiveEnabled; +} + inline bool NzMaterial::IsTransformEnabled() const { return m_transformEnabled; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 382cf4d2c..e6cd9ff1b 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -195,6 +195,7 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const 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() || From 8472578e422eb4218b843463f7912c83dedcf0a9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 18 Jun 2015 12:09:51 +0200 Subject: [PATCH 010/224] Graphics/Material: Fix compilation error Former-commit-id: 1cb87781afd8de0f6aaf4f6cbac861d5a1f8f717 --- include/Nazara/Graphics/Material.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 93cca4bb0..23a9433f5 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -24,7 +24,7 @@ inline NzMaterial::~NzMaterial() inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) { - NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + NazaraAssert(renderParameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); m_states.parameters[renderParameter] = enable; } From 286de8b5382a5a3c5ae76135e26f45893f7764b3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 21 Jun 2015 13:10:03 +0200 Subject: [PATCH 011/224] Graphics/Material: Fix debug build Former-commit-id: eccbb4c2a0d9ab1a5d9d942087809c0079a422c1 --- include/Nazara/Graphics/Material.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 93cca4bb0..23a9433f5 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -24,7 +24,7 @@ inline NzMaterial::~NzMaterial() inline void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) { - NazaraAssert(parameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); + NazaraAssert(renderParameter <= nzRendererParameter_Max, "Renderer parameter out of enum"); m_states.parameters[renderParameter] = enable; } From 1593b7969fc50cb320b9037235c94e9b0a18b787 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 21 Jun 2015 13:11:03 +0200 Subject: [PATCH 012/224] Graphics/Material: Fix shadow states initialize/copy/parameter Former-commit-id: efe926baa3a5f00e04e7443b3463730e0d16edf7 --- src/Nazara/Graphics/Material.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index e6cd9ff1b..bc8b5a002 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -142,6 +142,8 @@ void NzMaterial::Reset() m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); m_lightingEnabled = true; + m_shadowCastingEnabled = true; + m_shadowReceiveEnabled = true; m_shininess = 50.f; m_specularColor = NzColor::White; m_specularSampler = NzTextureSampler(); @@ -156,18 +158,20 @@ void NzMaterial::Reset() void NzMaterial::Copy(const NzMaterial& 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; @@ -301,8 +305,8 @@ bool NzMaterial::Initialize() vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); } - uberShader->SetShader(nzShaderStage_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(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_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(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("PhongLighting", uberShader); } From 685f8c99da15814b423894fa1e684521a0db4f7f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 22 Jun 2015 13:36:34 +0200 Subject: [PATCH 013/224] Sdk/RenderSystem: Fix code duplication (merge fail) Former-commit-id: ac552375a50d333b53b11c435c88e647a7cd0817 --- SDK/src/NDK/Systems/RenderSystem.cpp | 31 ---------------------------- 1 file changed, 31 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index e5ef93907..03da11d8d 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -48,37 +48,6 @@ namespace Ndk m_lights.Remove(entity); } - void RenderSystem::OnEntityRemoved(Entity* entity) - { - m_cameras.Remove(entity); - m_drawables.Remove(entity); - m_lights.Remove(entity); - } - - void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) - { - if (entity->HasComponent() && entity->HasComponent()) - { - m_cameras.Insert(entity); - std::sort(m_cameras.begin(), m_cameras.end(), [](const EntityHandle& handle1, const EntityHandle& handle2) - { - return handle1->GetComponent().GetLayer() < handle2->GetComponent().GetLayer(); - }); - } - else - m_cameras.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_drawables.Insert(entity); - else - m_drawables.Remove(entity); - - if (entity->HasComponent() && entity->HasComponent()) - m_lights.Insert(entity); - else - m_lights.Remove(entity); - } - void RenderSystem::OnUpdate(float elapsedTime) { UpdateShadowMaps(); From 7dd4965f9a0cc66a710b66658477f6c3ffe8879e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 26 Jun 2015 14:05:50 +0200 Subject: [PATCH 014/224] Math/Matrix4: Fix cotangent in projection matrix Former-commit-id: 57ccfc4fd2a1a8245272328204afa6590a5cb3fb --- include/Nazara/Math/Algorithm.hpp | 4 ++++ include/Nazara/Math/Matrix4.inl | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 070d048aa..0d0776746 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -16,6 +16,10 @@ #define M_PI 3.141592653589793238462643 #endif +#ifndef M_PI_2 +#define M_PI_2 1.5707963267948966192313217 +#endif + #ifndef M_SQRT2 #define M_SQRT2 1.4142135623730950488016887 #endif diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 694ef446a..6816bbd72 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -623,7 +623,7 @@ NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) angle = NzDegreeToRadian(angle/F(2.0)); #endif - T yScale = F(1.0) / std::tan(angle); + T yScale = std::tan(M_PI_2 - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), F(0.0), yScale, F(0.0), F(0.0), From d93229a9acd942a96347693c6dbd13b26e08dcd9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:44:01 +0200 Subject: [PATCH 015/224] Fix compilation error Former-commit-id: 5f264fc941898921da408b836c385d4073ebe3ae --- SDK/src/NDK/Systems/RenderSystem.cpp | 1 - src/Nazara/Graphics/DepthRenderTechnique.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index dfeb04928..e5057dc66 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include -#include #include #include #include diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 9fe00be37..e76b0c981 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include From 34e8271d24ecf20527281ec66b317098d9239916 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:44:37 +0200 Subject: [PATCH 016/224] Fix warnings Former-commit-id: 42f2d38f7bf5143d91da6a0fa7dc7d3b88ce56ea --- include/Nazara/Math/Matrix4.inl | 2 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 2 ++ src/Nazara/Graphics/DepthRenderTechnique.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 6816bbd72..ac140fe9a 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -623,7 +623,7 @@ NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) angle = NzDegreeToRadian(angle/F(2.0)); #endif - T yScale = std::tan(M_PI_2 - angle); + T yScale = std::tan(T(M_PI_2) - angle); Set(yScale / ratio, F(0.0), F(0.0), F(0.0), F(0.0), yScale, F(0.0), F(0.0), diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 613033015..e038c3bbd 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -297,6 +297,7 @@ void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) { NazaraAssert(material, "Invalid material"); + NazaraUnused(meshAABB); if (!IsMaterialSuitable(material)) return; @@ -325,6 +326,7 @@ void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& m void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { NazaraAssert(material, "Invalid material"); + NazaraUnused(overlay); if (!IsMaterialSuitable(material)) return; diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index e76b0c981..6ec9dfaf3 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -153,6 +153,8 @@ void NzDepthRenderTechnique::Uninitialize() void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); NzRenderer::SetVertexBuffer(&m_spriteBuffer); @@ -207,6 +209,8 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + if (NzRenderer::HasCapability(nzRendererCap_Instancing)) { NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); @@ -306,6 +310,8 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const { + NazaraUnused(sceneData); + s_material->Apply(); for (auto& meshIt : m_renderQueue.meshes) From bdb6554bc8cd24cebfdc586b25d72523002087d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:47:08 +0200 Subject: [PATCH 017/224] Graphics/DepthRenderQueue: Make use of shadow casting parameter Former-commit-id: cf15775c67a5d4245d344d001847b9fb1ffe7432 --- src/Nazara/Graphics/DepthRenderQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index e038c3bbd..9b5a2c170 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -350,7 +350,7 @@ bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const { NazaraAssert(material, "Invalid material"); - return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite); + return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled(); } void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) From 2c4a35b2d1d1ec6ebd94803c59ed1fa8530bc865 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:47:39 +0200 Subject: [PATCH 018/224] Graphics/Light: Add move constructor/operator Former-commit-id: d2823b5bae913fc0d218f6aaf067ee29812a6cbf --- include/Nazara/Graphics/Light.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a28a86c17..a473b031d 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -22,6 +22,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable public: NzLight(nzLightType type = nzLightType_Point); inline NzLight(const NzLight& light); + NzLight(NzLight&& light) = default; ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; @@ -63,6 +64,7 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; NzLight& operator=(const NzLight& light); + NzLight& operator=(NzLight&& light) = default; private: void MakeBoundingVolume() const override; From 529673ebc1b7215db2b016131e226d2890c0d501 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 30 Jun 2015 20:48:46 +0200 Subject: [PATCH 019/224] Graphics/Light: Make shadow map format/size parametrable Former-commit-id: 8151d71d58ab760584c0ace1e0686c44bab9d3b2 --- include/Nazara/Graphics/Light.hpp | 7 ++++++ include/Nazara/Graphics/Light.inl | 41 ++++++++++++++++++++++++++++++- src/Nazara/Graphics/Light.cpp | 4 ++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a473b031d..5d42c0961 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -49,6 +49,8 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable inline float GetOuterAngleTangent() const; inline float GetRadius() const; inline NzTextureRef GetShadowMap() const; + inline nzPixelFormat GetShadowMapFormat() const; + inline const NzVector2ui& GetShadowMapSize() const; inline bool IsShadowCastingEnabled() const; @@ -60,6 +62,8 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable inline void SetLightType(nzLightType type); inline void SetOuterAngle(float outerAngle); inline void SetRadius(float radius); + inline void SetShadowMapFormat(nzPixelFormat shadowFormat); + inline void SetShadowMapSize(const NzVector2ui& size); void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; @@ -68,10 +72,13 @@ class NAZARA_GRAPHICS_API NzLight : public NzRenderable private: void MakeBoundingVolume() const override; + inline void InvalidateShadowMap(); void UpdateShadowMap() const; nzLightType m_type; + nzPixelFormat m_shadowMapFormat; NzColor m_color; + NzVector2ui m_shadowMapSize; mutable NzTextureRef m_shadowMap; bool m_shadowCastingEnabled; mutable bool m_shadowMapUpdated; diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index f0f7600ff..b5408ce43 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -8,7 +8,9 @@ inline NzLight::NzLight(const NzLight& light) : NzRenderable(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), @@ -96,6 +98,16 @@ inline NzTextureRef NzLight::GetShadowMap() const return m_shadowMap; } +inline nzPixelFormat NzLight::GetShadowMapFormat() const +{ + return m_shadowMapFormat; +} + +inline const NzVector2ui& NzLight::GetShadowMapSize() const +{ + return m_shadowMapSize; +} + inline bool NzLight::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; @@ -130,6 +142,8 @@ inline void NzLight::SetInnerAngle(float innerAngle) inline void NzLight::SetLightType(nzLightType type) { m_type = type; + + InvalidateShadowMap(); } inline void NzLight::SetOuterAngle(float outerAngle) @@ -150,6 +164,24 @@ inline void NzLight::SetRadius(float radius) InvalidateBoundingVolume(); } +inline void NzLight::SetShadowMapFormat(nzPixelFormat shadowFormat) +{ + NazaraAssert(NzPixelFormat::GetType(shadowFormat) == nzPixelFormatType_Depth, "Shadow format type is not a depth format"); + + m_shadowMapFormat = shadowFormat; + + InvalidateShadowMap(); +} + +inline void NzLight::SetShadowMapSize(const NzVector2ui& size) +{ + NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size"); + + m_shadowMapSize = size; + + InvalidateShadowMap(); +} + inline NzLight& NzLight::operator=(const NzLight& light) { NzRenderable::operator=(light); @@ -166,10 +198,17 @@ inline NzLight& NzLight::operator=(const NzLight& light) m_outerAngleTangent = light.m_outerAngleTangent; m_radius = light.m_radius; m_shadowCastingEnabled = light.m_shadowCastingEnabled; - m_shadowMapUpdated = false; + m_shadowMapFormat = light.m_shadowMapFormat; + m_shadowMapSize = light.m_shadowMapSize; m_type = light.m_type; + InvalidateShadowMap(); return *this; } +inline void NzLight::InvalidateShadowMap() +{ + m_shadowMapUpdated = false; +} + #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index ee0e233ca..be93fd055 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -17,6 +17,8 @@ NzLight::NzLight(nzLightType type) : m_type(type), +m_shadowMapFormat(nzPixelFormat_Depth16), +m_shadowMapSize(512, 512), m_shadowCastingEnabled(false), m_shadowMapUpdated(false) { @@ -186,7 +188,7 @@ void NzLight::UpdateShadowMap() const if (!m_shadowMap) m_shadowMap = NzTexture::New(); - m_shadowMap->Create(nzImageType_2D, nzPixelFormat_Depth16, 256, 256); + m_shadowMap->Create((m_type == nzLightType_Point) ? nzImageType_Cubemap : nzImageType_2D, m_shadowMapFormat, m_shadowMapSize.x, m_shadowMapSize.y); } else m_shadowMap.Reset(); From 9a7c356f75b7c00c1b9cd576082b7a2b2c22d143 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jul 2015 12:24:04 +0200 Subject: [PATCH 020/224] Graphics/Material: Fix texture getters Former-commit-id: 00799529501c489498c4afd7e42195157b74ba22 --- include/Nazara/Graphics/Material.hpp | 12 ++++++------ include/Nazara/Graphics/Material.inl | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 2d09c2f35..e199d2439 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -67,26 +67,26 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline void EnableShadowReceive(bool receiveShadows); inline void EnableTransform(bool transform); - inline NzTexture* GetAlphaMap() const; + inline const NzTextureRef& GetAlphaMap() const; inline float GetAlphaThreshold() const; inline NzColor GetAmbientColor() const; inline nzRendererComparison GetDepthFunc() const; inline NzColor GetDiffuseColor() const; - inline NzTexture* GetDiffuseMap() const; + inline const NzTextureRef& GetDiffuseMap() const; inline NzTextureSampler& GetDiffuseSampler(); inline const NzTextureSampler& GetDiffuseSampler() const; inline nzBlendFunc GetDstBlend() const; - inline NzTexture* GetEmissiveMap() const; + inline const NzTextureRef& GetEmissiveMap() const; inline nzFaceSide GetFaceCulling() const; inline nzFaceFilling GetFaceFilling() const; - inline NzTexture* GetHeightMap() const; - inline NzTexture* GetNormalMap() const; + inline const NzTextureRef& GetHeightMap() const; + inline const NzTextureRef& GetNormalMap() const; inline const NzRenderStates& GetRenderStates() const; inline const NzUberShader* GetShader() const; inline const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; inline float GetShininess() const; inline NzColor GetSpecularColor() const; - inline NzTexture* GetSpecularMap() const; + inline const NzTextureRef& GetSpecularMap() const; inline NzTextureSampler& GetSpecularSampler(); inline const NzTextureSampler& GetSpecularSampler() const; inline nzBlendFunc GetSrcBlend() const; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 23a9433f5..9fb3851de 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -69,7 +69,7 @@ inline void NzMaterial::EnableTransform(bool transform) InvalidateShaders(); } -inline NzTexture* NzMaterial::GetAlphaMap() const +inline const NzTextureRef& NzMaterial::GetAlphaMap() const { return m_alphaMap; } @@ -104,7 +104,7 @@ inline const NzTextureSampler& NzMaterial::GetDiffuseSampler() const return m_diffuseSampler; } -NzTexture* NzMaterial::GetDiffuseMap() const +const NzTextureRef& NzMaterial::GetDiffuseMap() const { return m_diffuseMap; } @@ -114,7 +114,7 @@ inline nzBlendFunc NzMaterial::GetDstBlend() const return m_states.dstBlend; } -inline NzTexture* NzMaterial::GetEmissiveMap() const +inline const NzTextureRef& NzMaterial::GetEmissiveMap() const { return m_emissiveMap; } @@ -129,12 +129,12 @@ inline nzFaceFilling NzMaterial::GetFaceFilling() const return m_states.faceFilling; } -inline NzTexture* NzMaterial::GetHeightMap() const +inline const NzTextureRef& NzMaterial::GetHeightMap() const { return m_heightMap; } -inline NzTexture* NzMaterial::GetNormalMap() const +inline const NzTextureRef& NzMaterial::GetNormalMap() const { return m_normalMap; } @@ -168,7 +168,7 @@ inline NzColor NzMaterial::GetSpecularColor() const return m_specularColor; } -inline NzTexture* NzMaterial::GetSpecularMap() const +inline const NzTextureRef& NzMaterial::GetSpecularMap() const { return m_specularMap; } From 1398ed7ebc4c0f6a7b44b7e924587efb6fa0d441 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jul 2015 13:01:23 +0200 Subject: [PATCH 021/224] Core/ObjectRef: Remove static_assert Former-commit-id: 5050ce7a786053725d7e18fcc943bfb2ce3fee69 --- include/Nazara/Core/ObjectRef.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 35d016f90..7137eb7ee 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -14,8 +14,6 @@ template class NzObjectRef { - static_assert(std::is_base_of::value, "ObjectRef shall only be used with RefCounted-derived type"); - public: NzObjectRef(); NzObjectRef(T* object); From c0ee9d04b5f9ca2763022c24797ad3c5090599d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:23:17 +0200 Subject: [PATCH 022/224] Graphics/Material: Add depth material parameter Former-commit-id: 980888e12e5d8c8cf280c6a62592068cfab49d2e --- include/Nazara/Graphics/Material.hpp | 4 ++++ include/Nazara/Graphics/Material.inl | 15 +++++++++++++++ src/Nazara/Graphics/Material.cpp | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index e199d2439..bdd6e8fcc 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -71,6 +71,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline float GetAlphaThreshold() const; inline NzColor GetAmbientColor() const; inline nzRendererComparison GetDepthFunc() const; + inline const NzMaterialRef& GetDepthMaterial() const; inline NzColor GetDiffuseColor() const; inline const NzTextureRef& GetDiffuseMap() const; inline NzTextureSampler& GetDiffuseSampler(); @@ -92,6 +93,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline nzBlendFunc GetSrcBlend() const; inline bool HasAlphaMap() const; + inline bool HasDepthMaterial() const; inline bool HasDiffuseMap() const; inline bool HasEmissiveMap() const; inline bool HasHeightMap() const; @@ -117,6 +119,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource inline void SetAlphaThreshold(float alphaThreshold); inline void SetAmbientColor(const NzColor& ambient); inline void SetDepthFunc(nzRendererComparison depthFunc); + inline void SetDepthMaterial(NzMaterialRef depthMaterial); inline void SetDiffuseColor(const NzColor& diffuse); inline bool SetDiffuseMap(const NzString& textureName); inline void SetDiffuseMap(NzTextureRef diffuseMap); @@ -167,6 +170,7 @@ class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource NzColor m_ambientColor; NzColor m_diffuseColor; NzColor m_specularColor; + NzMaterialRef m_depthMaterial; //< Materialception NzRenderStates m_states; NzTextureSampler m_diffuseSampler; NzTextureSampler m_specularSampler; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 9fb3851de..7bfb4d196 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -89,6 +89,11 @@ inline nzRendererComparison NzMaterial::GetDepthFunc() const return m_states.depthFunc; } +inline const NzMaterialRef& NzMaterial::GetDepthMaterial() const +{ + return m_depthMaterial; +} + inline NzColor NzMaterial::GetDiffuseColor() const { return m_diffuseColor; @@ -193,6 +198,11 @@ inline bool NzMaterial::HasAlphaMap() const return m_alphaMap.IsValid(); } +inline bool NzMaterial::HasDepthMaterial() const +{ + return m_depthMaterial.IsValid(); +} + inline bool NzMaterial::HasDiffuseMap() const { return m_diffuseMap.IsValid(); @@ -306,6 +316,11 @@ inline void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) m_states.depthFunc = depthFunc; } +inline void NzMaterial::SetDepthMaterial(NzMaterialRef depthMaterial) +{ + m_depthMaterial = std::move(depthMaterial); +} + inline void NzMaterial::SetDiffuseColor(const NzColor& diffuse) { m_diffuseColor = diffuse; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index bc8b5a002..b4a64dc11 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -125,6 +125,7 @@ void NzMaterial::Reset() OnMaterialReset(this); m_alphaMap.Reset(); + m_depthMaterial.Reset(); m_diffuseMap.Reset(); m_emissiveMap.Reset(); m_heightMap.Reset(); @@ -173,16 +174,15 @@ void NzMaterial::Copy(const NzMaterial& material) 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_uberShader = material.m_uberShader; + // Copying resources refs + 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 std::memcpy(&m_shaders[0], &material.m_shaders[0], (nzShaderFlags_Max+1)*sizeof(ShaderInstance)); From 5556c3890102b03d3e9b4b61fc84d02beeb40cb2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:25:12 +0200 Subject: [PATCH 023/224] Renderer/RenderTexture: Fix Detach() not removing color targets Former-commit-id: 058d95e1952f2316333be380cb6418c121db4a32 --- src/Nazara/Renderer/RenderTexture.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index b574de8d9..75d4de01d 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -154,9 +154,6 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -291,9 +288,6 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i InvalidateSize(); InvalidateTargets(); - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - return true; } @@ -828,6 +822,15 @@ void NzRenderTexture::UpdateSize() const void NzRenderTexture::UpdateTargets() const { + if (!m_impl->userDefinedTargets) + { + m_impl->colorTargets.clear(); + + unsigned int colorIndex = 0; + for (unsigned int index = attachmentIndex[nzAttachmentPoint_Color]; index < m_impl->attachments.size(); ++index) + m_impl->colorTargets.push_back(colorIndex++); + } + if (m_impl->colorTargets.empty()) { m_impl->drawBuffers.resize(1); From 68701483148bf855640d39a1ccee6566f8fcf8c4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:26:09 +0200 Subject: [PATCH 024/224] Renderer: Add shader validation Former-commit-id: fa9225b87e6ec2217c3838535531075dfcaaf433 --- include/Nazara/Renderer/OpenGL.hpp | 1 + include/Nazara/Renderer/Shader.hpp | 2 ++ src/Nazara/Renderer/OpenGL.cpp | 2 ++ src/Nazara/Renderer/Renderer.cpp | 8 ++++++++ src/Nazara/Renderer/Shader.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 021252677..64578dae8 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -318,6 +318,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/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 951f01a51..3057943ac 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -95,6 +95,8 @@ class NAZARA_RENDERER_API NzShader : public NzRefCounted, NzNonCopyable void SendVectorArray(int location, const NzVector4f* vectors, unsigned int count) const; void SendVectorArray(int location, const NzVector4i* vectors, unsigned int count) const; + bool Validate() const; + // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 5331e902c..cd13021e2 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -945,6 +945,7 @@ bool NzOpenGL::Initialize() 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")); glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); glViewport = reinterpret_cast(LoadEntry("glViewport")); @@ -2384,6 +2385,7 @@ PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr; PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr; PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr; PFNGLUSEPROGRAMPROC glUseProgram = nullptr; +PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr; PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr; PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr; diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index ab252a1f1..e9f5d4c60 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1857,6 +1857,14 @@ bool NzRenderer::EnsureStateUpdate() // Et on termine par envoyer nos états au driver NzOpenGL::ApplyStates(s_states); + #ifdef NAZARA_DEBUG + if (!s_shader->Validate()) + { + NazaraError(NzError::GetLastError()); + return false; + } + #endif + return true; } diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 1b45b9789..91dea1192 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -748,6 +748,30 @@ void NzShader::SendVectorArray(int location, const NzVector4i* vectors, unsigned } } +bool NzShader::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 NzShader::GetOpenGLID() const { return m_program; From 1f2e81092741091a72df8bc7bdfabf7f99695133 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:43:35 +0200 Subject: [PATCH 025/224] Graphics: Remake DepthRender[Queue|Technique] Former-commit-id: c4d8d4d28d02822273ebe7dca3e468ea156af674 --- include/Nazara/Graphics/DepthRenderQueue.hpp | 40 +- .../Nazara/Graphics/DepthRenderTechnique.hpp | 34 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 332 ++++---------- src/Nazara/Graphics/DepthRenderTechnique.cpp | 409 ++++++++++++------ 4 files changed, 387 insertions(+), 428 deletions(-) diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index ec6550494..ed96b7d6b 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -18,10 +18,10 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue +class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzForwardRenderQueue { public: - NzDepthRenderQueue() = default; + NzDepthRenderQueue(); ~NzDepthRenderQueue() = default; void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; @@ -33,44 +33,16 @@ class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzAbstractRenderQueue void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddDrawable(const NzDrawable* drawable) override; + void AddDirectionalLight(const DirectionalLight& light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; + void AddPointLight(const PointLight& light) override; + void AddSpotLight(const SpotLight& light) override; void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; - void Clear(bool fully = false); - - struct BillboardData - { - NzColor color; - NzVector3f center; - NzVector2f size; - NzVector2f sinCos; - }; - - struct MeshInstanceEntry - { - NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); - NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); - - std::vector instances; - }; - - struct SpriteChain_XYZ_Color_UV - { - const NzVertexStruct_XYZ_Color_UV* vertices; - unsigned int spriteCount; - }; - - std::map meshes; - std::vector billboards; - std::vector otherDrawables; - std::vector basicSprites; - private: bool IsMaterialSuitable(const NzMaterial* material) const; - void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); - void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); + NzMaterialRef m_baseMaterial; }; #endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index b33a2b6cc..9da641c3b 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -32,22 +31,51 @@ class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechni static void Uninitialize(); private: + struct ShaderUniforms; + void DrawBasicSprites(const NzSceneData& sceneData) const; void DrawBillboards(const NzSceneData& sceneData) const; void DrawOpaqueModels(const NzSceneData& sceneData) const; + const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; + void OnShaderInvalidated(const NzShader* shader) const; + struct LightIndex + { + nzLightType type; + float score; + unsigned int index; + }; + + struct ShaderUniforms + { + NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + + NzLightUniforms lightUniforms; + bool hasLightUniforms; + + /// Moins coûteux en mémoire que de stocker un NzLightUniforms par index de lumière, + /// à voir si ça fonctionne chez tout le monde + int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; + + mutable std::unordered_map m_shaderUniforms; NzBuffer m_vertexBuffer; mutable NzDepthRenderQueue m_renderQueue; NzVertexBuffer m_billboardPointBuffer; NzVertexBuffer m_spriteBuffer; static NzIndexBuffer s_quadIndexBuffer; - static NzMaterialRef s_material; static NzVertexBuffer s_quadVertexBuffer; static NzVertexDeclaration s_billboardInstanceDeclaration; static NzVertexDeclaration s_billboardVertexDeclaration; }; -#include +#include #endif // NAZARA_DEPTHRENDERTECHNIQUE_HPP diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 9b5a2c170..9ff02dcbd 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -7,76 +7,58 @@ #include #include -///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) +NzDepthRenderQueue::NzDepthRenderQueue() +{ + // Material + m_baseMaterial = NzMaterial::New(); + m_baseMaterial->Enable(nzRendererParameter_ColorWrite, false); + m_baseMaterial->Enable(nzRendererParameter_FaceCulling, false); + //m_baseMaterial->SetFaceCulling(nzFaceSide_Front); +} void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) { NazaraAssert(material, "Invalid material"); - if (IsMaterialSuitable(material)) - billboards.push_back(BillboardData{color, position, size, sinCos}); + if (!IsMaterialSuitable(material)) + return; + + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; + + NzForwardRenderQueue::AddBillboard(material, position, size, sinCos, color); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos = *sinCosPtr++; - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos = *sinCosPtr++; - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) @@ -86,129 +68,57 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int if (!IsMaterialSuitable(material)) return; - ///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 (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos.Set(sin, cos); - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos.Set(sin, cos); - billboardData->size = *sizePtr++; - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos = *sinCosPtr++; - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos = *sinCosPtr++; - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) @@ -218,80 +128,33 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int if (!IsMaterialSuitable(material)) return; - ///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 (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - if (!colorPtr) - colorPtr.Reset(&NzColor::White, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos.Set(sin, cos); - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); } void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) { - ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White NazaraAssert(material, "Invalid material"); if (!IsMaterialSuitable(material)) return; - float defaultRotation = 0.f; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (!anglePtr) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile - - float defaultAlpha = 1.f; - - if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil - - unsigned int prevSize = billboards.size(); - billboards.resize(prevSize + count); - - BillboardData* billboardData = &billboards[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - float sin = std::sin(NzToRadians(*anglePtr)); - float cos = std::cos(NzToRadians(*anglePtr)); - anglePtr++; - - billboardData->center = *positionPtr++; - billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); - billboardData->sinCos.Set(sin, cos); - billboardData->size.Set(*sizePtr++); - billboardData++; - } + NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } -void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable) +void NzDepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) { - #if NAZARA_GRAPHICS_SAFE - if (!drawable) - { - NazaraError("Invalid drawable"); - return; - } - #endif - - otherDrawables.push_back(drawable); + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); } void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) @@ -302,25 +165,24 @@ void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& m if (!IsMaterialSuitable(material)) return; - auto it = meshes.find(meshData); - if (it == meshes.end()) - { - MeshInstanceEntry instanceEntry; + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; - if (meshData.indexBuffer) - instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDepthRenderQueue::OnIndexBufferInvalidation); + NzForwardRenderQueue::AddMesh(material, meshData, meshAABB, transformMatrix); +} - instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDepthRenderQueue::OnVertexBufferInvalidation); +void NzDepthRenderQueue::AddPointLight(const PointLight& light) +{ + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); +} - it = meshes.insert(std::make_pair(meshData, std::move(instanceEntry))).first; - } - - std::vector& instances = it->second.instances; - instances.push_back(transformMatrix); - - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? - //if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - // entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau +void NzDepthRenderQueue::AddSpotLight(const SpotLight& light) +{ + NazaraAssert(false, "Depth render queue doesn't handle lights"); + NazaraUnused(light); } void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) @@ -331,49 +193,17 @@ void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexSt if (!IsMaterialSuitable(material)) return; - basicSprites.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); -} + if (material->HasDepthMaterial()) + material = material->GetDepthMaterial(); + else + material = m_baseMaterial; -void NzDepthRenderQueue::Clear(bool fully) -{ - NzAbstractRenderQueue::Clear(fully); - - basicSprites.clear(); - billboards.clear(); - otherDrawables.clear(); - - if (fully) - meshes.clear(); + NzForwardRenderQueue::AddSprites(material, vertices, spriteCount, overlay); } bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const { NazaraAssert(material, "Invalid material"); - return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled(); + return material->HasDepthMaterial() || (material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); } - -void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) -{ - for (auto it = meshes.begin(); it != meshes.end();) - { - const NzMeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; - } -} - -void NzDepthRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) -{ - for (auto it = meshes.begin(); it != meshes.end();) - { - const NzMeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; - } -} - diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 6ec9dfaf3..31d63d56a 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const if (sceneData.background) sceneData.background->Draw(sceneData.viewer); - if (!m_renderQueue.meshes.empty()) + if (!m_renderQueue.opaqueModels.empty()) DrawOpaqueModels(sceneData); if (!m_renderQueue.basicSprites.empty()) @@ -78,7 +79,7 @@ NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() nzRenderTechniqueType NzDepthRenderTechnique::GetType() const { - return nzRenderTechniqueType_BasicForward; + return nzRenderTechniqueType_Depth; } bool NzDepthRenderTechnique::Initialize() @@ -129,11 +130,6 @@ bool NzDepthRenderTechnique::Initialize() s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); - - // Material - s_material = NzMaterial::New(); - s_material->Enable(nzRendererParameter_ColorWrite, false); - s_material->Enable(nzRendererParameter_FaceCulling, false); } catch (const std::exception& e) { @@ -146,7 +142,6 @@ bool NzDepthRenderTechnique::Initialize() void NzDepthRenderTechnique::Uninitialize() { - s_material.Reset(); s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } @@ -155,55 +150,101 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons { NazaraUnused(sceneData); + const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); NzRenderer::SetVertexBuffer(&m_spriteBuffer); - auto& spriteChainVector = m_renderQueue.basicSprites; - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + for (auto& matIt : m_renderQueue.basicSprites) { - s_material->Apply(); + const NzMaterial* material = matIt.first; + auto& matEntry = matIt.second; - 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 + if (matEntry.enabled) { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); - - unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); - - do + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) { - NzDepthRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + const NzTexture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; - - spriteCount += count; - spriteChainOffset += count; - - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) { - spriteChain++; - spriteChainOffset = 0; + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + nzUInt32 flags = nzShaderFlags_VertexColor; + if (overlay) + flags |= nzShaderFlags_TextureOverlay; + + nzUInt8 overlayUnit; + const NzShader* shader = material->Apply(flags, 0, &overlayUnit); + + if (overlay) + { + overlayUnit++; + NzRenderer::SetTexture(overlayUnit, overlay); + NzRenderer::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); + + 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 + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + NzForwardRenderQueue::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(NzVertexStruct_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(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); } } - while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + // On remet à zéro + matEntry.enabled = false; } - while (spriteChain < spriteChainCount); - - spriteChainVector.clear(); } } @@ -218,27 +259,34 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); - auto& billboardVector = m_renderQueue.billboards; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + for (auto& matIt : m_renderQueue.billboards) { - s_material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing); + const NzMaterial* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + // On commence par appliquer du matériau + material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; + const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } else @@ -246,64 +294,70 @@ void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); - auto& billboardVector = m_renderQueue.billboards; - - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + for (auto& matIt : m_renderQueue.billboards) { - s_material->Apply(nzShaderFlags_Billboard); + const NzMaterial* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - const NzDepthRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + // On commence par appliquer du matériau + material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); - NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + do { - const NzDepthRenderQueue::BillboardData& billboard = *data++; + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; + NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; + for (unsigned int i = 0; i < renderedBillboardCount; ++i) + { + const NzForwardRenderQueue::BillboardData& billboard = *data++; - 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(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, 0.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(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); } + while (billboardCount > 0); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -312,55 +366,130 @@ void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) cons { NazaraUnused(sceneData); - s_material->Apply(); - - for (auto& meshIt : m_renderQueue.meshes) + for (auto& matIt : m_renderQueue.opaqueModels) { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + auto& matEntry = matIt.second; - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + if (matEntry.enabled) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + if (!meshInstances.empty()) + { + const NzMaterial* material = matIt.first; - if (indexBuffer) - { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); + // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active + // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches + // (Le deferred shading n'a pas ce problème) + bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); + bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; + + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + material->Apply((instancing) ? nzShaderFlags_Instancing : 0); + + // Meshes + for (auto& meshIt : meshInstances) + { + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) + { + const NzIndexBuffer* indexBuffer = meshData.indexBuffer; + const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::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) + NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); + + const NzMatrix4f* 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 NzMatrix4f& matrix : instances) + { + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + instances.clear(); + } + } } - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); - - // 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 NzMatrix4f& matrix : instances) - { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); - } - instances.clear(); + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } } +const NzDepthRenderTechnique::ShaderUniforms* NzDepthRenderTechnique::GetShaderUniforms(const NzShader* shader) const +{ + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzDepthRenderTechnique::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzDepthRenderTechnique::OnShaderInvalidated); + + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; +} + +void NzDepthRenderTechnique::OnShaderInvalidated(const NzShader* shader) const +{ + m_shaderUniforms.erase(shader); +} + NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; -NzMaterialRef NzDepthRenderTechnique::s_material; NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; From 4d07735b85f1f89a88efcfebaf03e8740bc04801 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:56:30 +0200 Subject: [PATCH 026/224] Ndk/Rendersystem: Add point-light shadows generation Former-commit-id: ecf1fb1c83bafddba9e91f31f018e72180893e5c --- SDK/src/NDK/Systems/RenderSystem.cpp | 91 +++++++++++++++++++++------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index e5057dc66..f4c8fe82c 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -95,41 +95,86 @@ namespace Ndk if (!m_shadowRT.IsValid()) m_shadowRT.Create(); + NzSceneData dummySceneData; + dummySceneData.ambientColor = NzColor(0, 0, 0); + dummySceneData.background = nullptr; + dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer + for (const Ndk::EntityHandle& light : m_lights) { LightComponent& lightComponent = light->GetComponent(); NodeComponent& lightNode = light->GetComponent(); - if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() != nzLightType_Spot) + if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() == nzLightType_Directional) continue; NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); - m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); - - ///TODO: Cache the matrices in the light? - NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle(), 1.f, 1.f, 1000.f)); - NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); - NzRenderer::SetTarget(&m_shadowRT); - NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); - - NzAbstractRenderQueue* renderQueue = m_shadowTechnique.GetRenderQueue(); - renderQueue->Clear(); - - for (const Ndk::EntityHandle& drawable : m_drawables) + switch (lightComponent.GetLightType()) { - GraphicsComponent& graphicsComponent = drawable->GetComponent(); - NodeComponent& drawableNode = drawable->GetComponent(); + case nzLightType_Point: + { + static NzQuaternionf rotations[6] = + { + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitX()), // nzCubemapFace_PositiveX + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitX()), // nzCubemapFace_NegativeX + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitY()), // nzCubemapFace_PositiveY + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitY()), // nzCubemapFace_NegativeY + NzQuaternionf::RotationBetween(NzVector3f::Forward(), -NzVector3f::UnitZ()), // nzCubemapFace_PositiveZ + NzQuaternionf::RotationBetween(NzVector3f::Forward(), NzVector3f::UnitZ()) // nzCubemapFace_NegativeZ + }; - graphicsComponent.AddToRenderQueue(renderQueue); + for (unsigned int face = 0; face < 6; ++face) + { + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap(), face); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(NzFromDegrees(90.f), 1.f, 0.1f, lightComponent.GetRadius())); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), rotations[face])); + + NzAbstractRenderQueue* 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.Draw(dummySceneData); + } + break; + } + + case nzLightType_Spot: + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + ///TODO: Cache the matrices in the light? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Perspective(lightComponent.GetOuterAngle()*2.f, 1.f, 0.1f, lightComponent.GetRadius())); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetPosition(), lightNode.GetRotation())); + + NzAbstractRenderQueue* 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.Draw(dummySceneData); + break; } - - NzSceneData sceneData; - sceneData.ambientColor = NzColor(0, 0, 0); - sceneData.background = nullptr; - sceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - - m_shadowTechnique.Draw(sceneData); } } From 75972fec36c16f08dd916dd64908b31c1d70b0b0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 5 Jul 2015 23:57:54 +0200 Subject: [PATCH 027/224] Graphics: Add shadow mapping Former-commit-id: ca404bee246991eab98df35396e3010ec5165c43 --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 3 + .../Graphics/ForwardRenderTechnique.hpp | 5 +- .../Graphics/ForwardRenderTechnique.inl | 39 +++- include/Nazara/Graphics/Light.hpp | 7 +- .../Graphics/ForwardRenderTechnique.cpp | 22 ++- src/Nazara/Graphics/Light.cpp | 9 + .../Resources/Shaders/PhongLighting/core.frag | 167 +++++++++++++----- .../Shaders/PhongLighting/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.vert | 8 + .../Shaders/PhongLighting/core.vert.h | 2 +- 10 files changed, 206 insertions(+), 58 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index e641dcca0..f7e0ad79d 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -68,6 +68,7 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue { NzColor color; NzVector3f position; + NzTexture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; @@ -78,8 +79,10 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct SpotLight { NzColor color; + NzMatrix4f transformMatrix; NzVector3f direction; NzVector3f position; + NzTexture* shadowMap; float ambientFactor; float attenuation; float diffuseFactor; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 766fd6fc9..50f8a43c0 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -33,7 +33,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech static bool Initialize(); static void Uninitialize(); - private: + protected: struct ShaderUniforms; void ChooseLights(const NzSpheref& object, bool includeDirectionalLights = true) const; @@ -43,7 +43,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech void DrawTransparentModels(const NzSceneData& sceneData) const; const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; void OnShaderInvalidated(const NzShader* shader) const; - void SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; + void SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, nzUInt8 availableTextureUnit) const; static float ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light); static float ComputePointLightScore(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light); @@ -86,6 +86,7 @@ class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTech unsigned int m_maxLightPassPerObject; static NzIndexBuffer s_quadIndexBuffer; + static NzTextureSampler s_shadowSampler; static NzVertexBuffer s_quadVertexBuffer; static NzVertexDeclaration s_billboardInstanceDeclaration; static NzVertexDeclaration s_billboardVertexDeclaration; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 8d4d8736b..2e9f46dd4 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -2,8 +2,14 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const +#include + +inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, nzUInt8 availableTextureUnit) const { + // If anyone got a better idea.. + int dummyCubemap = NzRenderer::GetMaxTextureUnits() - 1; + int dummyTexture = NzRenderer::GetMaxTextureUnits() - 2; + if (index < m_lights.size()) { const LightIndex& lightIndex = m_lights[index]; @@ -30,6 +36,19 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(0.f, 0.f, 0.f, light.invRadius)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); + + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); break; } @@ -42,12 +61,30 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(light.direction, light.invRadius)); shader->SendVector(uniforms.locations.parameters3 + uniformOffset, NzVector2f(light.innerAngleCosine, light.outerAngleCosine)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); + + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, availableTextureUnit); + } + else + shader->SendInteger(uniforms.locations.spotLightShadowMap + 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.pointLightShadowMap + index, dummyCubemap); + shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + } } inline float NzForwardRenderTechnique::ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 5d42c0961..a8cdaf191 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -14,9 +14,6 @@ #include #include -class NzLight; -struct NzLightUniforms; - class NAZARA_GRAPHICS_API NzLight : public NzRenderable { public: @@ -101,9 +98,13 @@ struct NzLightUniforms int type; int color; int factors; + int lightViewProjMatrix; int parameters1; int parameters2; int parameters3; + int pointLightShadowMap; + int shadowMapping; + int spotLightShadowMap; }; bool ubo; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 440ad7a5b..b8611feaa 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -147,6 +147,9 @@ bool NzForwardRenderTechnique::Initialize() s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); + + s_shadowSampler.SetFilterMode(nzSamplerFilter_Bilinear); + s_shadowSampler.SetWrapMode(nzSamplerWrap_Clamp); } catch (const std::exception& e) { @@ -475,7 +478,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co 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 NzShader* shader = material->Apply((instancing) ? nzShaderFlags_Instancing : 0); + nzUInt8 freeTextureUnit; + const NzShader* shader = material->Apply((instancing) ? nzShaderFlags_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) @@ -559,7 +563,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co // 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++, i*shaderUniforms->lightOffset, freeTextureUnit + i); } const NzMatrix4f* instanceMatrices = &instances[0]; @@ -618,7 +622,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co // 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); @@ -668,7 +672,8 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat const NzMaterial* material = modelData.material; // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(); + nzUInt8 freeTextureUnit; + const NzShader* 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) @@ -687,7 +692,7 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat lightCount = std::min(m_renderQueue.directionalLights.size(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); 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; @@ -726,7 +731,7 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneDat ChooseLights(NzSpheref(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++); } NzRenderer::SetMatrix(nzMatrixType_World, matrix); @@ -758,9 +763,13 @@ const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetSha 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.spotLightShadowMap = shader->GetUniformLocation("SpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; @@ -777,6 +786,7 @@ void NzForwardRenderTechnique::OnShaderInvalidated(const NzShader* shader) const } NzIndexBuffer NzForwardRenderTechnique::s_quadIndexBuffer; +NzTextureSampler NzForwardRenderTechnique::s_shadowSampler; NzVertexBuffer NzForwardRenderTechnique::s_quadVertexBuffer; NzVertexDeclaration NzForwardRenderTechnique::s_billboardInstanceDeclaration; NzVertexDeclaration NzForwardRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index be93fd055..4fc4506e7 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -57,6 +57,7 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.invRadius = m_invRadius; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); renderQueue->AddPointLight(light); break; @@ -76,6 +77,14 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.outerAngleTangent = m_outerAngleTangent; light.position = transformMatrix.GetTranslation(); light.radius = m_radius; + light.shadowMap = m_shadowMap.Get(); + + static NzMatrix4f 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); + + light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetTranslation(), transformMatrix.GetRotation()) * NzMatrix4f::Perspective(m_outerAngle*2.f, 1.f, 0.1f, m_radius) * biasMatrix; renderQueue->AddSpotLight(light); break; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 80ad84697..e80279b7d 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 SpotLightShadowMap[3]; // Matériau uniform sampler2D MaterialAlphaMap; @@ -81,6 +85,32 @@ 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; +} + +bool TestShadowDirectional() +{ + ///TODO + return true; +} + +bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +{ + return texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar); +} + +bool TestShadowSpot(int lightIndex) +{ + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return textureProj(SpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; +} + void main() { vec4 diffuseColor = MaterialDiffuse * vColor; @@ -168,6 +198,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 +209,95 @@ 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); // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += 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 += 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 && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 50.0)) + break; + #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 && !TestShadowSpot(i)) + break; + #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 +310,85 @@ 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); // Diffuse float lambert = max(dot(normal, lightDir), 0.0); - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; + lightDiffuse += 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 && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 1.0 / lightInvRadius)) + break; + #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 && !TestShadowSpot(i)) + break; + #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 +396,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 +418,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..ca82b7284 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,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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,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,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,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,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,13,10,13,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,13,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,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,41,13,10,123,13,10,9,47,47,47,84,79,68,79,13,10,9,114,101,116,117,114,110,32,116,114,117,101,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,13,10,123,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,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,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,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,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,13,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,13,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,13,10,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,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,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,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 5c1d95fef..06f7b7bd2 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; @@ -120,6 +123,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 3c23c60a3..45e30d30e 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,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,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,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,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,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,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,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,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,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,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,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,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,13,10,35,105,102,32,76,73,71,72,84,73,78,71,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,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,13,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,13,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,13,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,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,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,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,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,13,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,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,33,70,76,65,71,95,68,69,70,69,82,82,69,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,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,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,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,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,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,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,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,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,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,109,97,116,52,32,73,110,118,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,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,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,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,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,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,13,10,35,105,102,32,76,73,71,72,84,73,78,71,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,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,13,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,13,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,13,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,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,13,10,35,101,110,100,105,102,13,10,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,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,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,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,13,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,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,33,70,76,65,71,95,68,69,70,69,82,82,69,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file From 835da411c780971d48309bb189aac0161d532342 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:54:34 +0200 Subject: [PATCH 028/224] Graphics/Shadows: Add directional shadow mapping (WIP) It still needs some debug Former-commit-id: 029872debc1a784712a33802ddd70a2b61e55623 --- SDK/include/NDK/Systems/RenderSystem.hpp | 5 +- SDK/src/NDK/Systems/RenderSystem.cpp | 79 +++++++++++++++++-- .../Nazara/Graphics/AbstractRenderQueue.hpp | 2 + .../Graphics/ForwardRenderTechnique.inl | 22 +++++- include/Nazara/Graphics/Light.hpp | 2 +- .../Graphics/ForwardRenderTechnique.cpp | 2 +- src/Nazara/Graphics/Light.cpp | 13 +-- .../Resources/Shaders/PhongLighting/core.frag | 15 ++-- .../Shaders/PhongLighting/core.frag.h | 2 +- 9 files changed, 118 insertions(+), 24 deletions(-) diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 91f63f8ed..9df56bc49 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -37,11 +37,14 @@ namespace Ndk void OnEntityRemoved(Entity* entity) override; void OnEntityValidation(Entity* entity, bool justAdded) override; void OnUpdate(float elapsedTime) override; - void UpdateShadowMaps(); + void UpdateDirectionalShadowMaps(const NzAbstractViewer& viewer); + void UpdatePointSpotShadowMaps(); EntityList m_cameras; EntityList m_drawables; + EntityList m_directionalLights; EntityList m_lights; + EntityList m_pointSpotLights; NzBackgroundRef m_background; NzDepthRenderTechnique m_shadowTechnique; NzForwardRenderTechnique m_renderTechnique; diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index f4c8fe82c..742dcd363 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -46,21 +46,40 @@ namespace Ndk m_drawables.Remove(entity); if (entity->HasComponent() && entity->HasComponent()) + { + LightComponent& lightComponent = entity->GetComponent(); + if (lightComponent.GetLightType() == nzLightType_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) { NazaraUnused(elapsedTime); - UpdateShadowMaps(); + UpdatePointSpotShadowMaps(); for (const Ndk::EntityHandle& camera : m_cameras) { CameraComponent& camComponent = camera->GetComponent(); - camComponent.ApplyView(); + + //UpdateDirectionalShadowMaps(camComponent); NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); renderQueue->Clear(); @@ -81,6 +100,8 @@ namespace Ndk lightComponent.AddToRenderQueue(renderQueue, lightNode.GetTransformMatrix()); } + camComponent.ApplyView(); + NzSceneData sceneData; sceneData.ambientColor = NzColor(25, 25, 25); sceneData.background = m_background; @@ -90,7 +111,7 @@ namespace Ndk } } - void RenderSystem::UpdateShadowMaps() + void RenderSystem::UpdateDirectionalShadowMaps(const NzAbstractViewer& viewer) { if (!m_shadowRT.IsValid()) m_shadowRT.Create(); @@ -100,18 +121,66 @@ namespace Ndk dummySceneData.background = nullptr; dummySceneData.viewer = nullptr; //< Depth technique doesn't require any viewer - for (const Ndk::EntityHandle& light : m_lights) + for (const Ndk::EntityHandle& light : m_directionalLights) { LightComponent& lightComponent = light->GetComponent(); NodeComponent& lightNode = light->GetComponent(); - if (!lightComponent.IsShadowCastingEnabled() || lightComponent.GetLightType() == nzLightType_Directional) + if (!lightComponent.IsShadowCastingEnabled()) + continue; + + NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); + + m_shadowRT.AttachTexture(nzAttachmentPoint_Depth, 0, lightComponent.GetShadowMap()); + NzRenderer::SetTarget(&m_shadowRT); + NzRenderer::SetViewport(NzRecti(0, 0, shadowMapSize.x, shadowMapSize.y)); + + NzAbstractRenderQueue* 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? + NzRenderer::SetMatrix(nzMatrixType_Projection, NzMatrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f)); + NzRenderer::SetMatrix(nzMatrixType_View, NzMatrix4f::ViewMatrix(lightNode.GetRotation() * NzVector3f::Forward() * 100.f, lightNode.GetRotation())); + + m_shadowTechnique.Draw(dummySceneData); + } + } + + void RenderSystem::UpdatePointSpotShadowMaps() + { + if (!m_shadowRT.IsValid()) + m_shadowRT.Create(); + + NzSceneData dummySceneData; + dummySceneData.ambientColor = NzColor(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; NzVector2ui shadowMapSize(lightComponent.GetShadowMap()->GetSize()); switch (lightComponent.GetLightType()) { + case nzLightType_Directional: + NazaraInternalError("Directional lights included in point/spot light list"); + break; + case nzLightType_Point: { static NzQuaternionf rotations[6] = diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index f7e0ad79d..fceabf47f 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -59,7 +59,9 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct DirectionalLight { NzColor color; + NzMatrix4f transformMatrix; NzVector3f direction; + NzTexture* shadowMap; float ambientFactor; float diffuseFactor; }; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 2e9f46dd4..a04fab511 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -25,6 +25,20 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, shader->SendColor(uniforms.locations.color + uniformOffset, light.color); shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.direction)); + + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + if (light.shadowMap) + { + NzRenderer::SetTexture(availableTextureUnit, light.shadowMap); + NzRenderer::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; } @@ -48,7 +62,7 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, else shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); break; } @@ -69,10 +83,10 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, NzRenderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, availableTextureUnit); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); } else - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); + shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); break; @@ -82,8 +96,8 @@ inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, 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); - shader->SendInteger(uniforms.locations.spotLightShadowMap + index, dummyTexture); } } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index a8cdaf191..a9a4a781f 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -97,6 +97,7 @@ struct NzLightUniforms { int type; int color; + int directionalSpotLightShadowMap; int factors; int lightViewProjMatrix; int parameters1; @@ -104,7 +105,6 @@ struct NzLightUniforms int parameters3; int pointLightShadowMap; int shadowMapping; - int spotLightShadowMap; }; bool ubo; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index b8611feaa..5c3b29bca 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -769,7 +769,7 @@ const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetSha 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.spotLightShadowMap = shader->GetUniformLocation("SpotLightShadowMap[0]"); + uniforms.lightUniforms.locations.directionalSpotLightShadowMap = shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 4fc4506e7..43bbf9b0e 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -33,6 +33,11 @@ m_shadowMapUpdated(false) void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const { + static NzMatrix4f 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 nzLightType_Directional: @@ -42,6 +47,8 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.color = m_color; light.diffuseFactor = m_diffuseFactor; light.direction = transformMatrix.Transform(NzVector3f::Forward(), 0.f); + light.shadowMap = m_shadowMap.Get(); + light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetRotation() * NzVector3f::Forward() * 100.f, transformMatrix.GetRotation()) * NzMatrix4f::Ortho(0.f, 100.f, 100.f, 0.f, 1.f, 100.f) * biasMatrix; renderQueue->AddDirectionalLight(light); break; @@ -78,12 +85,6 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatri light.position = transformMatrix.GetTranslation(); light.radius = m_radius; light.shadowMap = m_shadowMap.Get(); - - static NzMatrix4f 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); - light.transformMatrix = NzMatrix4f::ViewMatrix(transformMatrix.GetTranslation(), transformMatrix.GetRotation()) * NzMatrix4f::Perspective(m_outerAngle*2.f, 1.f, 0.1f, m_radius) * biasMatrix; renderQueue->AddSpotLight(light); diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index e80279b7d..6f4b1e3aa 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -36,7 +36,7 @@ struct Light // Lumières uniform Light Lights[3]; uniform samplerCube PointLightShadowMap[3]; -uniform sampler2D SpotLightShadowMap[3]; +uniform sampler2D DirectionalSpotLightShadowMap[3]; // Matériau uniform sampler2D MaterialAlphaMap; @@ -94,10 +94,10 @@ float VectorToDepthValue(vec3 vec, float zNear, float zFar) return (normZ + 1.0) * 0.5; } -bool TestShadowDirectional() +bool TestShadowDirectional(int lightIndex) { - ///TODO - return true; + vec4 lightSpacePos = vLightSpacePos[lightIndex]; + return texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005); } bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) @@ -108,7 +108,7 @@ bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) bool TestShadowSpot(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return textureProj(SpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; + return textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; } void main() @@ -211,6 +211,11 @@ void main() // Ambient lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + #if SHADOW_MAPPING + if (Lights[i].shadowMapping && !TestShadowDirectional(i)) + break; + #endif + // Diffuse float lambert = max(dot(normal, lightDir), 0.0); diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index ca82b7284..d617f915b 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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,83,112,111,116,76,105,103,104,116,83,104,97,100,111,119,77,97,112,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,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,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,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,13,10,13,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,13,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,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,41,13,10,123,13,10,9,47,47,47,84,79,68,79,13,10,9,114,101,116,117,114,110,32,116,114,117,101,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,13,10,123,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,116,101,120,116,117,114,101,80,114,111,106,40,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,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,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,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,13,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,13,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,13,10,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,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,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,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,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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,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,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,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,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,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,13,10,13,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,13,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,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,13,10,123,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,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,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,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,13,10, \ No newline at end of file From 6a2e0da88f1bd7b89f96a92ea45c926ca197036e Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:54:57 +0200 Subject: [PATCH 029/224] SDK/Entity: Fix destruction Former-commit-id: 045e771bc67f6141b4bd8d5a32d151fb09526857 --- SDK/src/NDK/Entity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 9d05a504d..d26a8f953 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -119,8 +119,6 @@ namespace Ndk void Entity::Destroy() { - m_valid = false; - // On informe chaque système for (SystemIndex index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) { @@ -137,5 +135,7 @@ namespace Ndk handle->OnEntityDestroyed(); m_handles.clear(); + + m_valid = false; } } From fabe42dc3abd5e4980941b824cc2a71295b45c36 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 13 Aug 2015 13:55:14 +0200 Subject: [PATCH 030/224] Renderer/Texture: Set up compare mode Former-commit-id: 6f85b6956530ea27b5bb96eb9b51a3ddc702f71b --- src/Nazara/Renderer/Texture.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 303b983fa..2db286640 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1269,6 +1269,12 @@ bool NzTexture::CreateTexture(bool proxy) glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); } + if (!proxy && NzPixelFormat::GetType(m_impl->format) == nzPixelFormatType_Depth) + { + glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } + return true; } From 5cad63c21bf0dc6914a6614281cba157dbdb343e Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 14 Aug 2015 14:13:53 +0200 Subject: [PATCH 031/224] Graphics/Shadow: Implement PCF for spot lights Former-commit-id: 0045af26b612a5c41268fcf3e3d03893e01c0448 --- .../Resources/Shaders/PhongLighting/core.frag | 96 +++++++++++++++---- .../Shaders/PhongLighting/core.frag.h | 2 +- 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 6f4b1e3aa..9e446aefd 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -87,28 +87,37 @@ vec4 EncodeNormal(in vec3 normal) float VectorToDepthValue(vec3 vec, float zNear, float zFar) { - vec3 absVec = abs(vec); - float localZ = max(absVec.x, max(absVec.y, absVec.z)); + 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; } -bool TestShadowDirectional(int lightIndex) +float CalculateDirectionalShadowFactor(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005); + return (texture(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xy).x >= (lightSpacePos.z - 0.0005)) ? 1.0 : 0.0; } -bool TestShadowPoint(int lightIndex, vec3 lightToWorld, float zNear, float zFar) +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); + return (texture(PointLightShadowMap[lightIndex], vec3(lightToWorld.x, -lightToWorld.y, -lightToWorld.z)).x >= VectorToDepthValue(lightToWorld, zNear, zFar)) ? 1.0 : 0.0; } -bool TestShadowSpot(int lightIndex) +float CalculateSpotShadowFactor(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; - return textureProj(DirectionalSpotLightShadowMap[lightIndex], lightSpacePos.xyw).x >= (lightSpacePos.z - 0.0005)/lightSpacePos.w; + + 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 + vec4(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.05, 0.0)); + + visibility /= 64.0; + + return visibility; } void main() @@ -211,22 +220,30 @@ void main() // Ambient lightAmbient += lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); + float att = 1.0; + #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowDirectional(i)) - break; + 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 * lightColor.rgb * lightDiffuseFactor; + 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 * lightColor.rgb; + lightSpecular += att * specularFactor * lightColor.rgb; break; } @@ -246,8 +263,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 50.0)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Diffuse @@ -283,8 +306,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowSpot(i)) - break; + 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 @@ -328,10 +357,23 @@ void main() // Ambient 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 * lightColor.rgb * lightDiffuseFactor; + lightDiffuse += att * lambert * lightColor.rgb * lightDiffuseFactor; break; } @@ -351,8 +393,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowPoint(i, vWorldPos - lightPos, 0.1, 1.0 / lightInvRadius)) - break; + if (Lights[i].shadowMapping) + { + float shadowFactor = CalculatePointShadowFactor(i, vWorldPos - lightPos, 0.1, 50.0); + if (shadowFactor == 0.0) + break; + + att *= shadowFactor; + } #endif // Diffuse @@ -381,8 +429,14 @@ void main() lightAmbient += att * lightColor.rgb * lightAmbientFactor * (MaterialAmbient.rgb + SceneAmbient.rgb); #if SHADOW_MAPPING - if (Lights[i].shadowMapping && !TestShadowSpot(i)) - break; + 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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index d617f915b..2fdfa2e06 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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,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,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,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,13,10,123,13,10,32,32,32,32,118,101,99,51,32,97,98,115,86,101,99,32,61,32,97,98,115,40,118,101,99,41,59,13,10,32,32,32,32,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,13,10,13,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,13,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,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,13,10,123,13,10,9,114,101,116,117,114,110,32,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,59,13,10,125,13,10,13,10,98,111,111,108,32,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,110,116,32,108,105,103,104,116,73,110,100,101,120,41,13,10,123,13,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,13,10,9,114,101,116,117,114,110,32,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,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,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,68,105,114,101,99,116,105,111,110,97,108,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,80,111,105,110,116,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,49,46,48,32,47,32,108,105,103,104,116,73,110,118,82,97,100,105,117,115,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,32,38,38,32,33,84,101,115,116,83,104,97,100,111,119,83,112,111,116,40,105,41,41,13,10,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,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,83,104,97,100,111,119,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,47,47,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,32,32,32,32,114,101,116,117,114,110,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,47,47,9,9,9,32,32,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,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,9,9,9,118,105,115,105,98,105,108,105,116,121,32,43,61,32,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,32,43,32,118,101,99,52,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,53,44,32,48,46,48,41,41,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 From cd3b19ca799564b2facf04a01b53dbc3ecb51f47 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 19 Aug 2015 13:46:11 +0200 Subject: [PATCH 032/224] Graphics/Shader: Fix shadowing Former-commit-id: 54fc9a019217eef85281c33a8a7becb6fec4f851 --- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag | 2 +- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 9e446aefd..94184d6ab 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -113,7 +113,7 @@ float CalculateSpotShadowFactor(int lightIndex) 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 + vec4(x/1024.0 * lightSpacePos.w, y/1024.0 * lightSpacePos.w, 0.05, 0.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; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 441a300c1..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,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,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,32,43,32,118,101,99,52,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,53,44,32,48,46,48,41,41,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 +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 From 831b9358ef8ba6af6e5053e04e5cbaaf9eb3c8e1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 19 Aug 2015 23:23:19 +0200 Subject: [PATCH 033/224] Utility/SimpleTextDrawer: Fix movement Former-commit-id: f5086d1ca281f31a3b89d5cd535f9aeaa9b2a929 --- include/Nazara/Utility/SimpleTextDrawer.hpp | 7 ++- src/Nazara/Utility/SimpleTextDrawer.cpp | 56 ++++++++++++++++----- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index c69cc1a25..200031c7c 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -19,7 +19,7 @@ class NAZARA_UTILITY_API NzSimpleTextDrawer : public NzAbstractTextDrawer public: NzSimpleTextDrawer(); NzSimpleTextDrawer(const NzSimpleTextDrawer& drawer); - NzSimpleTextDrawer(NzSimpleTextDrawer&&) = default; + NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer); virtual ~NzSimpleTextDrawer(); const NzRectui& GetBounds() const; @@ -39,10 +39,15 @@ class NAZARA_UTILITY_API NzSimpleTextDrawer : public NzAbstractTextDrawer void SetStyle(nzUInt32 style); void SetText(const NzString& str); + NzSimpleTextDrawer& operator=(const NzSimpleTextDrawer& drawer) = default; + NzSimpleTextDrawer& operator=(NzSimpleTextDrawer&& drawer); + static NzSimpleTextDrawer Draw(const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); static NzSimpleTextDrawer Draw(NzFont* font, const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); private: + void ConnectFontSlots(); + void DisconnectFontSlots(); void OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); void OnFontInvalidated(const NzFont* font); void OnFontRelease(const NzFont* object); diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 2373f722a..45cd8a5b5 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -24,6 +24,12 @@ m_characterSize(drawer.m_characterSize) SetFont(drawer.m_font); } +NzSimpleTextDrawer::NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer) +{ + operator=(std::move(drawer)); +} + + NzSimpleTextDrawer::~NzSimpleTextDrawer() = default; const NzRectui& NzSimpleTextDrawer::GetBounds() const @@ -112,20 +118,11 @@ void NzSimpleTextDrawer::SetFont(NzFont* font) if (m_font != font) { m_font = font; + if (m_font) - { - m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &NzSimpleTextDrawer::OnFontInvalidated); - m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &NzSimpleTextDrawer::OnFontAtlasLayerChanged); - m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &NzSimpleTextDrawer::OnFontRelease); - m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &NzSimpleTextDrawer::OnFontInvalidated); - } + ConnectFontSlots(); else - { - m_atlasChangedSlot.Disconnect(); - m_atlasLayerChangedSlot.Disconnect(); - m_fontReleaseSlot.Disconnect(); - m_glyphCacheClearedSlot.Disconnect(); - } + DisconnectFontSlots(); m_glyphUpdated = false; } @@ -145,6 +142,25 @@ void NzSimpleTextDrawer::SetText(const NzString& str) m_glyphUpdated = false; } +NzSimpleTextDrawer& NzSimpleTextDrawer::operator=(NzSimpleTextDrawer&& drawer) +{ + DisconnectFontSlots(); + + m_bounds = std::move(drawer.m_bounds); + m_characterSize = std::move(drawer.m_characterSize); + m_color = std::move(drawer.m_color); + m_glyphs = std::move(drawer.m_glyphs); + m_glyphUpdated = std::move(drawer.m_glyphUpdated); + m_font = std::move(drawer.m_font); + m_style = std::move(drawer.m_style); + m_text = std::move(drawer.m_text); + + // Update slot pointers (TODO: Improve the way of doing this) + ConnectFontSlots(); + + return *this; +} + NzSimpleTextDrawer NzSimpleTextDrawer::Draw(const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) { NzSimpleTextDrawer drawer; @@ -168,6 +184,22 @@ NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, const NzString& str, u return drawer; } +void NzSimpleTextDrawer::ConnectFontSlots() +{ + m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &NzSimpleTextDrawer::OnFontInvalidated); + m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &NzSimpleTextDrawer::OnFontAtlasLayerChanged); + m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &NzSimpleTextDrawer::OnFontRelease); + m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &NzSimpleTextDrawer::OnFontInvalidated); +} + +void NzSimpleTextDrawer::DisconnectFontSlots() +{ + m_atlasChangedSlot.Disconnect(); + m_atlasLayerChangedSlot.Disconnect(); + m_fontReleaseSlot.Disconnect(); + m_glyphCacheClearedSlot.Disconnect(); +} + void NzSimpleTextDrawer::OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer) { NazaraUnused(font); From 6ed8abafc6da77fdeb5ba042981c829fd3b5c20b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 19 Sep 2015 15:31:39 +0200 Subject: [PATCH 034/224] Ndk/RenderSystem: Fix compilation Former-commit-id: 25907facf61c77d64c1206ce4abe3e8018931ba7 --- SDK/src/NDK/Systems/RenderSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 7face4a5a..d242e6ce2 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -113,7 +113,7 @@ namespace Ndk NodeComponent& lightNode = light->GetComponent(); ///TODO: Cache somehow? - lightComponent.AddToRenderQueue(renderQueue, NzMatrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); + lightComponent.AddToRenderQueue(renderQueue, NzMatrix4f::ConcatenateAffine(m_coordinateSystemMatrix, lightNode.GetTransformMatrix())); } camComponent.ApplyView(); From 9e7452ab68860b53c29e0cd28267897adaf99cc2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 9 Dec 2015 01:11:27 +0100 Subject: [PATCH 035/224] Graphics/DepthRender: Fix compilation Former-commit-id: 749e3b67038cba20c46bd5570e616608200733f5 --- include/Nazara/Graphics/DepthRenderQueue.hpp | 49 +- .../Nazara/Graphics/DepthRenderTechnique.hpp | 91 +- src/Nazara/Graphics/DepthRenderQueue.cpp | 402 ++++----- src/Nazara/Graphics/DepthRenderTechnique.cpp | 834 ++++++++++-------- 4 files changed, 720 insertions(+), 656 deletions(-) diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index ed96b7d6b..0b8a1fc5d 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -18,31 +18,36 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderQueue : public NzForwardRenderQueue +namespace Nz { - public: - NzDepthRenderQueue(); - ~NzDepthRenderQueue() = default; + class NAZARA_GRAPHICS_API DepthRenderQueue : public ForwardRenderQueue + { + public: + DepthRenderQueue(); + ~DepthRenderQueue() = default; - void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; - void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; - void AddDirectionalLight(const DirectionalLight& light) override; - void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddPointLight(const PointLight& light) override; - void AddSpotLight(const SpotLight& light) override; - void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + 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: - bool IsMaterialSuitable(const NzMaterial* material) const; + private: + inline bool IsMaterialSuitable(const Material* material) const; - NzMaterialRef m_baseMaterial; -}; + MaterialRef m_baseMaterial; + }; +} + +#include #endif // NAZARA_DEPTHRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 9da641c3b..0b265ccc3 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -16,65 +16,62 @@ #include #include -class NAZARA_GRAPHICS_API NzDepthRenderTechnique : public NzAbstractRenderTechnique +namespace Nz { - public: - NzDepthRenderTechnique(); - ~NzDepthRenderTechnique() = default; + class NAZARA_GRAPHICS_API DepthRenderTechnique : public AbstractRenderTechnique + { + public: + DepthRenderTechnique(); + ~DepthRenderTechnique() = default; - bool Draw(const NzSceneData& sceneData) const override; + bool Draw(const SceneData& sceneData) const override; - NzAbstractRenderQueue* GetRenderQueue() override; - nzRenderTechniqueType GetType() const override; + AbstractRenderQueue* GetRenderQueue() override; + RenderTechniqueType GetType() const override; - static bool Initialize(); - static void Uninitialize(); + static bool Initialize(); + static void Uninitialize(); - private: - struct ShaderUniforms; + private: + struct ShaderUniforms; - void DrawBasicSprites(const NzSceneData& sceneData) const; - void DrawBillboards(const NzSceneData& sceneData) const; - void DrawOpaqueModels(const NzSceneData& sceneData) const; - const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; - void OnShaderInvalidated(const NzShader* shader) const; + 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 - { - nzLightType type; - float score; - unsigned int index; - }; + struct LightIndex + { + LightType type; + float score; + unsigned int index; + }; - struct ShaderUniforms - { - NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); - NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + struct ShaderUniforms + { + NazaraSlot(Shader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); - NzLightUniforms lightUniforms; - bool hasLightUniforms; + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; - /// Moins coûteux en mémoire que de stocker un NzLightUniforms par index de lumière, - /// à voir si ça fonctionne chez tout le monde - int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + mutable std::unordered_map m_shaderUniforms; + Buffer m_vertexBuffer; + mutable DepthRenderQueue m_renderQueue; + VertexBuffer m_billboardPointBuffer; + VertexBuffer m_spriteBuffer; - // Autre uniformes - int eyePosition; - int sceneAmbient; - int textureOverlay; - }; + static IndexBuffer s_quadIndexBuffer; + static VertexBuffer s_quadVertexBuffer; + static VertexDeclaration s_billboardInstanceDeclaration; + static VertexDeclaration s_billboardVertexDeclaration; + }; +} - mutable std::unordered_map m_shaderUniforms; - NzBuffer m_vertexBuffer; - mutable NzDepthRenderQueue m_renderQueue; - NzVertexBuffer m_billboardPointBuffer; - NzVertexBuffer m_spriteBuffer; - - static NzIndexBuffer s_quadIndexBuffer; - static NzVertexBuffer s_quadVertexBuffer; - static NzVertexDeclaration s_billboardInstanceDeclaration; - static NzVertexDeclaration s_billboardVertexDeclaration; -}; #include diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index 9ff02dcbd..e6fc71ae0 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -7,203 +7,211 @@ #include #include -NzDepthRenderQueue::NzDepthRenderQueue() +namespace Nz { - // Material - m_baseMaterial = NzMaterial::New(); - m_baseMaterial->Enable(nzRendererParameter_ColorWrite, false); - m_baseMaterial->Enable(nzRendererParameter_FaceCulling, false); - //m_baseMaterial->SetFaceCulling(nzFaceSide_Front); + 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); + } } -void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboard(material, position, size, sinCos, color); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); -} - -void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); -} - -void NzDepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) -{ - NazaraAssert(material, "Invalid material"); - NazaraUnused(meshAABB); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddMesh(material, meshData, meshAABB, transformMatrix); -} - -void NzDepthRenderQueue::AddPointLight(const PointLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddSpotLight(const SpotLight& light) -{ - NazaraAssert(false, "Depth render queue doesn't handle lights"); - NazaraUnused(light); -} - -void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) -{ - NazaraAssert(material, "Invalid material"); - NazaraUnused(overlay); - - if (!IsMaterialSuitable(material)) - return; - - if (material->HasDepthMaterial()) - material = material->GetDepthMaterial(); - else - material = m_baseMaterial; - - NzForwardRenderQueue::AddSprites(material, vertices, spriteCount, overlay); -} - -bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const -{ - NazaraAssert(material, "Invalid material"); - - return material->HasDepthMaterial() || (material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); -} diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 31d63d56a..107043bce 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -20,173 +20,269 @@ #include #include -namespace +namespace Nz { - struct BillboardPoint + namespace { - NzColor color; - NzVector3f position; - NzVector2f size; - NzVector2f sinCos; // must follow `size` (both will be sent as a Vector4f) - NzVector2f uv; - }; - - unsigned int s_maxQuads = std::numeric_limits::max()/6; - unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB -} - -NzDepthRenderTechnique::NzDepthRenderTechnique() : -m_vertexBuffer(nzBufferType_Vertex) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - m_vertexBuffer.Create(s_vertexBufferSize, nzDataStorage_Hardware, nzBufferUsage_Dynamic); - - m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); - m_spriteBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), &m_vertexBuffer); -} - -bool NzDepthRenderTechnique::Draw(const NzSceneData& sceneData) const -{ - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_DepthWrite, true); - NzRenderer::Clear(nzRendererBuffer_Depth); - - // Just in case the background does render depth - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); - - if (!m_renderQueue.opaqueModels.empty()) - DrawOpaqueModels(sceneData); - - if (!m_renderQueue.basicSprites.empty()) - DrawBasicSprites(sceneData); - - if (!m_renderQueue.billboards.empty()) - DrawBillboards(sceneData); - - // Other custom drawables - for (const NzDrawable* drawable : m_renderQueue.otherDrawables) - drawable->Draw(); - - return true; -} - -NzAbstractRenderQueue* NzDepthRenderTechnique::GetRenderQueue() -{ - return &m_renderQueue; -} - -nzRenderTechniqueType NzDepthRenderTechnique::GetType() const -{ - return nzRenderTechniqueType_Depth; -} - -bool NzDepthRenderTechnique::Initialize() -{ - try - { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - s_quadIndexBuffer.Reset(false, s_maxQuads*6, nzDataStorage_Hardware, nzBufferUsage_Static); - - NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); - nzUInt16* indices = static_cast(mapper.GetPointer()); - - for (unsigned int i = 0; i < s_maxQuads; ++i) + struct BillboardPoint { - *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(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); - - float vertices[2*4] = { - -0.5f, -0.5f, - 0.5f, -0.5f, - -0.5f, 0.5f, - 0.5f, 0.5f, + Color color; + Vector3f position; + Vector2f size; + Vector2f sinCos; // must follow `size` (both will be sent as a Vector4f) + Vector2f uv; }; - s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); - - // Déclaration lors du rendu des billboards par sommet - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(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(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialise: " + NzString(e.what())); - return false; + unsigned int s_maxQuads = std::numeric_limits::max() / 6; + unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB } - return true; -} - -void NzDepthRenderTechnique::Uninitialize() -{ - s_quadIndexBuffer.Reset(); - s_quadVertexBuffer.Reset(); -} - -void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); - NzRenderer::SetVertexBuffer(&m_spriteBuffer); - - for (auto& matIt : m_renderQueue.basicSprites) + DepthRenderTechnique::DepthRenderTechnique() : + m_vertexBuffer(BufferType_Vertex) { - const NzMaterial* material = matIt.first; - auto& matEntry = matIt.second; + ErrorFlags flags(ErrorFlag_ThrowException, true); - if (matEntry.enabled) + 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); + } + + bool DepthRenderTechnique::Draw(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); + + for (auto& pair : m_renderQueue.layers) { - auto& overlayMap = matEntry.overlayMap; - for (auto& overlayIt : overlayMap) - { - const NzTexture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second.spriteChains; + ForwardRenderQueue::Layer& layer = pair.second; - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + 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 + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + 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 = ShaderFlags_VertexColor; + 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); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + 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 + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + 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é) - nzUInt32 flags = nzShaderFlags_VertexColor; - if (overlay) - flags |= nzShaderFlags_TextureOverlay; - - nzUInt8 overlayUnit; - const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) - { - overlayUnit++; - NzRenderer::SetTexture(overlayUnit, overlay); - NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } + 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) @@ -194,302 +290,260 @@ void NzDepthRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) cons // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); 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 + 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); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + lastShader = shader; + } + + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); do { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - do + for (unsigned int i = 0; i < renderedBillboardCount; ++i) { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + const ForwardRenderQueue::BillboardData& billboard = *data++; - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; - spriteCount += count; - spriteChainOffset += count; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) - { - spriteChain++; - spriteChainOffset = 0; - } + 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++; } - while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); vertexMapper.Unmap(); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); } - while (spriteChain < spriteChainCount); + while (billboardCount > 0); - spriteChainVector.clear(); + billboardVector.clear(); } } - - // On remet à zéro - matEntry.enabled = false; - } - } -} - -void NzDepthRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - { - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); - - NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); - - for (auto& matIt : m_renderQueue.billboards) - { - const NzMaterial* 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 - material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); - - const NzForwardRenderQueue::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; - - NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); - } - while (billboardCount > 0); - - billboardVector.clear(); - } } } - else + + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + NazaraAssert(sceneData.viewer, "Invalid viewer"); - for (auto& matIt : m_renderQueue.billboards) + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + for (auto& matIt : layer.opaqueModels) { - const NzMaterial* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + auto& matEntry = matIt.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (matEntry.enabled) { - // On commence par appliquer du matériau - material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do + if (!meshInstances.empty()) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; - NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + bool instancing = m_instancingEnabled && matEntry.instancingEnabled; - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + // 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) { - const NzForwardRenderQueue::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++; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + lastShader = shader; } - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); - } - while (billboardCount > 0); - - billboardVector.clear(); - } - } - } -} - -void NzDepthRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const -{ - NazaraUnused(sceneData); - - for (auto& matIt : m_renderQueue.opaqueModels) - { - auto& matEntry = matIt.second; - - if (matEntry.enabled) - { - NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - - if (!meshInstances.empty()) - { - const NzMaterial* material = matIt.first; - - // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active - // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches - // (Le deferred shading n'a pas ce problème) - bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); - bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; - - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - material->Apply((instancing) ? nzShaderFlags_Instancing : 0); - - // Meshes - for (auto& meshIt : meshInstances) - { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; - - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + // Meshes + for (auto& meshIt : meshInstances) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; - if (indexBuffer) + if (!instances.empty()) { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (instancing) - { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); + if (indexBuffer) + { + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } - const NzMatrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); - while (instanceCount > 0) + if (instancing) { // 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; + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + 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 NzMatrix4f& matrix : instances) + else { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + // 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(); } - instances.clear(); } } - } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } } } -} -const NzDepthRenderTechnique::ShaderUniforms* NzDepthRenderTechnique::GetShaderUniforms(const NzShader* shader) const -{ - auto it = m_shaderUniforms.find(shader); - if (it == m_shaderUniforms.end()) + const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const { - ShaderUniforms uniforms; - uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzDepthRenderTechnique::OnShaderInvalidated); - uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzDepthRenderTechnique::OnShaderInvalidated); + 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.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); - it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; } - return &it->second; -} + void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const + { + m_shaderUniforms.erase(shader); + } -void NzDepthRenderTechnique::OnShaderInvalidated(const NzShader* shader) const -{ - m_shaderUniforms.erase(shader); -} - -NzIndexBuffer NzDepthRenderTechnique::s_quadIndexBuffer; -NzVertexBuffer NzDepthRenderTechnique::s_quadVertexBuffer; -NzVertexDeclaration NzDepthRenderTechnique::s_billboardInstanceDeclaration; -NzVertexDeclaration NzDepthRenderTechnique::s_billboardVertexDeclaration; + IndexBuffer DepthRenderTechnique::s_quadIndexBuffer; + VertexBuffer DepthRenderTechnique::s_quadVertexBuffer; + VertexDeclaration DepthRenderTechnique::s_billboardInstanceDeclaration; + VertexDeclaration DepthRenderTechnique::s_billboardVertexDeclaration; +} \ No newline at end of file From b3455e88ca18e8f16ac163b50c1c41b71a15e513 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 19:58:15 +0200 Subject: [PATCH 036/224] Graphics/DepthRenderTechnique: Add Clear method Former-commit-id: 70e7cb5b59f0407c73766687b6a95e09b7eca589 --- SDK/src/NDK/Systems/RenderSystem.cpp | 4 ++++ include/Nazara/Graphics/DepthRenderTechnique.hpp | 1 + src/Nazara/Graphics/DepthRenderTechnique.cpp | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 829d2b398..7b90761b6 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -169,6 +170,7 @@ namespace Ndk 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); } } @@ -233,6 +235,7 @@ namespace Ndk graphicsComponent.AddToRenderQueue(renderQueue); } + m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); } break; @@ -260,6 +263,7 @@ namespace Ndk graphicsComponent.AddToRenderQueue(renderQueue); } + m_shadowTechnique.Clear(dummySceneData); m_shadowTechnique.Draw(dummySceneData); break; } diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 0b265ccc3..ac75f7e52 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -24,6 +24,7 @@ namespace Nz DepthRenderTechnique(); ~DepthRenderTechnique() = default; + void Clear(const SceneData& sceneData) const override; bool Draw(const SceneData& sceneData) const override; AbstractRenderQueue* GetRenderQueue() override; diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 107043bce..1b2dc03f1 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -48,7 +48,7 @@ namespace Nz m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); } - bool DepthRenderTechnique::Draw(const SceneData& sceneData) const + void DepthRenderTechnique::Clear(const SceneData& sceneData) const { Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_DepthWrite, true); @@ -57,7 +57,10 @@ namespace Nz // 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; From 43c1243b750a50877b631c4c78a78640b5ea48a1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Apr 2016 20:22:29 +0200 Subject: [PATCH 037/224] Fix merge problems Former-commit-id: 899b541adea1719f558c52abfab51458249b6aaf --- include/Nazara/Math/Sphere.inl | 17 ++++---- include/Nazara/Math/Vector2.hpp | 10 ++--- include/Nazara/Math/Vector3.hpp | 10 ++--- include/Nazara/Math/Vector3.inl | 45 +++++++++++++++++--- include/Nazara/Math/Vector4.hpp | 10 ++--- include/Nazara/Math/Vector4.inl | 2 + src/Nazara/Graphics/DepthRenderTechnique.cpp | 29 ++++--------- 7 files changed, 72 insertions(+), 51 deletions(-) diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 3438b5080..b87bd51a7 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -124,6 +124,7 @@ namespace Nz * * \param point Position of the point */ + template bool Sphere::Contains(const Vector3& point) const { @@ -131,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 @@ -148,7 +149,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 point Position of the point @@ -303,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; } /*! @@ -392,7 +393,6 @@ namespace Nz return *this; } - /* template Sphere& Sphere::Set(const Circle& circle) @@ -407,11 +407,12 @@ namespace Nz */ /*! - * \brief Sets the components of the sphere with center and radius from another sphere + * \brief Sets the components of the sphere with center and radius from another * \return A reference to this sphere * * \param sphere The other sphere */ + template Sphere& Sphere::Set(const Sphere& sphere) { @@ -458,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 @@ -467,7 +468,6 @@ namespace Nz * * \see Distance */ - template T Sphere::SquaredDistance(T X, T Y, T Z) const { @@ -475,14 +475,13 @@ 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 point Position of the point * * \see Distance */ - template T Sphere::SquaredDistance(const Vector3& point) const { diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 4a6a83c16..b275d0544 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -102,11 +102,6 @@ namespace Nz T x, y; }; - template std::ostream& operator<<(std::ostream& out, const Vector2& vec); - - template Vector2 operator*(T scale, const Vector2& vec); - template Vector2 operator/(T scale, const Vector2& vec); - typedef Vector2 Vector2d; typedef Vector2 Vector2f; typedef Vector2 Vector2i; @@ -118,6 +113,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector2* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec); + +template Nz::Vector2 operator*(T scale, const Nz::Vector2& vec); +template Nz::Vector2 operator/(T scale, const Nz::Vector2& vec); + #include #endif // NAZARA_VECTOR2_HPP diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index a5fbad035..7743e7a35 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -124,11 +124,6 @@ namespace Nz T x, y, z; }; - template std::ostream& operator<<(std::ostream& out, const Vector3& vec); - - template Vector3 operator*(T scale, const Vector3& vec); - template Vector3 operator/(T scale, const Vector3& vec); - typedef Vector3 Vector3d; typedef Vector3 Vector3f; typedef Vector3 Vector3i; @@ -140,6 +135,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector3* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec); + +template Nz::Vector3 operator*(T scale, const Nz::Vector3& vec); +template Nz::Vector3 operator/(T scale, const Nz::Vector3& vec); + #include #endif // NAZARA_VECTOR3_HPP diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 96f70f9b1..c5a0155c7 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1012,10 +1012,15 @@ namespace Nz } /*! - * \brief Shorthand for the vector (0, -1, 0) - * \return A vector with components (0, -1, 0) + * \brief Measure the distance between two points + * Shorthand for vec1.Distance(vec2) * - * \see MakeDown + * 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) @@ -1023,12 +1028,29 @@ namespace Nz 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) + * + * \see MakeDown + */ template Vector3 Vector3::Down() { @@ -1123,10 +1145,13 @@ namespace Nz } /*! - * \brief Shorthand for the vector (1, 1, 1) - * \return A vector with components (1, 1, 1) + * \brief Calculates the squared distance between two vectors + * \return The metric distance between two vectors with the squared euclidean norm * - * \see MakeUnit + * \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) @@ -1134,6 +1159,12 @@ namespace Nz return vec1.SquaredDistance(vec2); } + /*! + * \brief Shorthand for the vector (1, 1, 1) + * \return A vector with components (1, 1, 1) + * + * \see MakeUnit + */ template Vector3 Vector3::Unit() { @@ -1312,6 +1343,8 @@ Nz::Vector3 operator/(T scale, const Nz::Vector3& vec) throw std::domain_error(error); } #endif + + return Nz::Vector3(scale / vec.x, scale / vec.y, scale / vec.z); } #undef F diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index daedcad0b..d1e51433a 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -100,11 +100,6 @@ namespace Nz T x, y, z, w; }; - template std::ostream& operator<<(std::ostream& out, const Vector4& vec); - - template Vector4 operator*(T scale, const Vector4& vec); - template Vector4 operator/(T scale, const Vector4& vec); - typedef Vector4 Vector4d; typedef Vector4 Vector4f; typedef Vector4 Vector4i; @@ -116,6 +111,11 @@ namespace Nz template bool Unserialize(SerializationContext& context, Vector4* vector); } +template std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec); + +template Nz::Vector4 operator*(T scale, const Nz::Vector4& vec); +template Nz::Vector4 operator/(T scale, const Nz::Vector4& vec); + #include #endif // NAZARA_VECTOR4_HPP diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index f0220ec4e..73a9a0802 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1116,6 +1116,8 @@ Nz::Vector4 operator/(T scale, const Nz::Vector4& vec) throw std::domain_error(error); } #endif + + return Nz::Vector4(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w); } #undef F diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 1b2dc03f1..46e7fb043 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -55,8 +55,8 @@ namespace Nz Renderer::Clear(RendererBuffer_Depth); // Just in case the background does render depth - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); + //if (sceneData.background) + // sceneData.background->Draw(sceneData.viewer); } bool DepthRenderTechnique::Draw(const SceneData& sceneData) const @@ -121,9 +121,9 @@ namespace Nz float vertices[2 * 4] = { -0.5f, -0.5f, - 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, 0.5f, - 0.5f, 0.5f, + 0.5f, 0.5f, }; s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); @@ -157,8 +157,6 @@ namespace Nz void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -183,7 +181,7 @@ namespace Nz if (spriteChainCount > 0) { // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - UInt32 flags = ShaderFlags_VertexColor; + UInt32 flags = 0; if (overlay) flags |= ShaderFlags_TextureOverlay; @@ -203,12 +201,10 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Overlay shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -263,8 +259,6 @@ namespace Nz void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -293,10 +287,8 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -342,10 +334,8 @@ namespace Nz // Index des uniformes dans le shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; } @@ -408,8 +398,6 @@ namespace Nz void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { - NazaraAssert(sceneData.viewer, "Invalid viewer"); - const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -531,7 +519,6 @@ namespace Nz uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DepthRenderTechnique::OnShaderInvalidated); uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); - uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; From ddf75e852a42e8a46f6c600754ee7bd9738babff Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Apr 2016 13:38:58 +0200 Subject: [PATCH 038/224] Vulkan: Add empty module Former-commit-id: 89e01819b36aeda5bfadac35d8a4190256461eca --- build/scripts/modules/vulkan.lua | 11 ++++ include/Nazara/Vulkan/Config.hpp | 53 +++++++++++++++++++ include/Nazara/Vulkan/ConfigCheck.hpp | 22 ++++++++ include/Nazara/Vulkan/Debug.hpp | 8 +++ include/Nazara/Vulkan/DebugOff.hpp | 9 ++++ include/Nazara/Vulkan/VkLoader.hpp | 20 +++++++ include/Nazara/Vulkan/Vulkan.hpp | 33 ++++++++++++ src/Nazara/Vulkan/Debug/NewOverload.cpp | 31 +++++++++++ src/Nazara/Vulkan/VkLoader.cpp | 11 ++++ src/Nazara/Vulkan/Vulkan.cpp | 70 +++++++++++++++++++++++++ 10 files changed, 268 insertions(+) create mode 100644 build/scripts/modules/vulkan.lua create mode 100644 include/Nazara/Vulkan/Config.hpp create mode 100644 include/Nazara/Vulkan/ConfigCheck.hpp create mode 100644 include/Nazara/Vulkan/Debug.hpp create mode 100644 include/Nazara/Vulkan/DebugOff.hpp create mode 100644 include/Nazara/Vulkan/VkLoader.hpp create mode 100644 include/Nazara/Vulkan/Vulkan.hpp create mode 100644 src/Nazara/Vulkan/Debug/NewOverload.cpp create mode 100644 src/Nazara/Vulkan/VkLoader.cpp create mode 100644 src/Nazara/Vulkan/Vulkan.cpp diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua new file mode 100644 index 000000000..687a542c5 --- /dev/null +++ b/build/scripts/modules/vulkan.lua @@ -0,0 +1,11 @@ +MODULE.Name = "Vulkan" + +MODULE.Libraries = { + "NazaraCore", + "NazaraUtility" +} + +MODULE.OsFiles.Windows = { + "../src/Nazara/Vulkan/Win32/**.hpp", + "../src/Nazara/Vulkan/Win32/**.cpp" +} diff --git a/include/Nazara/Vulkan/Config.hpp b/include/Nazara/Vulkan/Config.hpp new file mode 100644 index 000000000..28a98edfd --- /dev/null +++ b/include/Nazara/Vulkan/Config.hpp @@ -0,0 +1,53 @@ +/* + Nazara Engine - Module name + + Copyright (C) YEAR AUTHORS (EMAIL) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_CONFIG_VULKAN_HPP +#define NAZARA_CONFIG_VULKAN_HPP + +/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci + +// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +#define NAZARA_VULKAN_MANAGE_MEMORY 0 + +// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +#define NAZARA_VULKAN_SAFE 1 + +/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code + +/// Vérification des valeurs et types de certaines constantes +#include + +#if !defined(NAZARA_STATIC) + #ifdef NAZARA_VULKAN_BUILD + #define NAZARA_VULKAN_API NAZARA_EXPORT + #else + #define NAZARA_VULKAN_API NAZARA_IMPORT + #endif +#else + #define NAZARA_VULKAN_API +#endif + +#endif // NAZARA_CONFIG_MODULENAME_HPP diff --git a/include/Nazara/Vulkan/ConfigCheck.hpp b/include/Nazara/Vulkan/ConfigCheck.hpp new file mode 100644 index 000000000..22f334c6f --- /dev/null +++ b/include/Nazara/Vulkan/ConfigCheck.hpp @@ -0,0 +1,22 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CONFIG_CHECK_VULKANE_HPP +#define NAZARA_CONFIG_CHECK_VULKANE_HPP + +/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp + +#include +#define CheckType(name, type, err) static_assert(std::is_ ##type ::value, #type err) +#define CheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) + +// On force la valeur de MANAGE_MEMORY en mode debug +#if defined(NAZARA_DEBUG) && !NAZARA_VULKAN_MANAGE_MEMORY + #undef NAZARA_MODULENAME_MANAGE_MEMORY + #define NAZARA_MODULENAME_MANAGE_MEMORY 0 +#endif + +#endif // NAZARA_CONFIG_CHECK_VULKAN_HPP diff --git a/include/Nazara/Vulkan/Debug.hpp b/include/Nazara/Vulkan/Debug.hpp new file mode 100644 index 000000000..a744946ef --- /dev/null +++ b/include/Nazara/Vulkan/Debug.hpp @@ -0,0 +1,8 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_MODULENAME_MANAGE_MEMORY + #include +#endif diff --git a/include/Nazara/Vulkan/DebugOff.hpp b/include/Nazara/Vulkan/DebugOff.hpp new file mode 100644 index 000000000..e57a2b946 --- /dev/null +++ b/include/Nazara/Vulkan/DebugOff.hpp @@ -0,0 +1,9 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +#if NAZARA_MODULENAME_MANAGE_MEMORY + #undef delete + #undef new +#endif diff --git a/include/Nazara/Vulkan/VkLoader.hpp b/include/Nazara/Vulkan/VkLoader.hpp new file mode 100644 index 000000000..0aaa24da1 --- /dev/null +++ b/include/Nazara/Vulkan/VkLoader.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_LOADER_HPP +#define NAZARA_VULKAN_LOADER_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_VULKAN_API VkLoader + { + }; +} + +#endif // NAZARA_VULKAN_LOADER_HPP diff --git a/include/Nazara/Vulkan/Vulkan.hpp b/include/Nazara/Vulkan/Vulkan.hpp new file mode 100644 index 000000000..aabb87aea --- /dev/null +++ b/include/Nazara/Vulkan/Vulkan.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_HPP +#define NAZARA_VULKAN_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_VULKAN_API Vulkan + { + public: + Vulkan() = delete; + ~Vulkan() = delete; + + static bool Initialize(); + + static bool IsInitialized(); + + static void Uninitialize(); + + private: + static unsigned int s_moduleReferenceCounter; + }; +} + +#endif // NAZARA_VULKAN_HPP diff --git a/src/Nazara/Vulkan/Debug/NewOverload.cpp b/src/Nazara/Vulkan/Debug/NewOverload.cpp new file mode 100644 index 000000000..410a53c76 --- /dev/null +++ b/src/Nazara/Vulkan/Debug/NewOverload.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2014 AUTHORS +// This file is part of the "Nazara Engine - Module name" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_VULKAN_MANAGE_MEMORY + +#include +#include // Nécessaire ? + +void* operator new(std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, false); +} + +void* operator new[](std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, true); +} + +void operator delete(void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, false); +} + +void operator delete[](void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, true); +} + +#endif // NAZARA_VULKAN_MANAGE_MEMORY diff --git a/src/Nazara/Vulkan/VkLoader.cpp b/src/Nazara/Vulkan/VkLoader.cpp new file mode 100644 index 000000000..04d9cb8dc --- /dev/null +++ b/src/Nazara/Vulkan/VkLoader.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ +} + diff --git a/src/Nazara/Vulkan/Vulkan.cpp b/src/Nazara/Vulkan/Vulkan.cpp new file mode 100644 index 000000000..5c41e0034 --- /dev/null +++ b/src/Nazara/Vulkan/Vulkan.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + bool Vulkan::Initialize() + { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Already initialized + } + + // Initialize module dependencies + if (!Utility::Initialize()) + { + NazaraError("Failed to initialize utility module"); + return false; + } + + s_moduleReferenceCounter++; + + CallOnExit onExit(Vulkan::Uninitialize); + + // Initialize module here + + onExit.Reset(); + + NazaraNotice("Initialized: Vulkan module"); + return true; + } + + bool Vulkan::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } + + void Vulkan::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Either the module is not initialized, either it was initialized multiple times + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + s_moduleReferenceCounter = 0; + + // Uninitialize module here + + NazaraNotice("Uninitialized: Vulkan module"); + + // Free module dependencies + Utility::Uninitialize(); + } + + unsigned int Vulkan::s_moduleReferenceCounter = 0; +} + From 16d1b83edb12807eac9fc2039acf8e6238803347 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Apr 2016 17:27:16 +0200 Subject: [PATCH 039/224] Extlibs: Add Vulkan headers Former-commit-id: 09fcbdfd488b2ba203245a1579f6665d2f0f9497 --- include/Nazara/Vulkan/VkLoader.hpp | 14 ++++++++++++++ src/Nazara/Vulkan/VkLoader.cpp | 3 +++ 2 files changed, 17 insertions(+) diff --git a/include/Nazara/Vulkan/VkLoader.hpp b/include/Nazara/Vulkan/VkLoader.hpp index 0aaa24da1..8e973b0bb 100644 --- a/include/Nazara/Vulkan/VkLoader.hpp +++ b/include/Nazara/Vulkan/VkLoader.hpp @@ -8,13 +8,27 @@ #define NAZARA_VULKAN_LOADER_HPP #include +#include #include +#include namespace Nz { class NAZARA_VULKAN_API VkLoader { + public: + VkLoader() = delete; + ~VkLoader() = delete; + + static bool Initialize(); + + private: + static DynLib s_vulkanLib; }; } +#define NAZARA_VULKAN_EXPORTED_FUNCTION(func) extern PFN_##func func; + +NAZARA_VULKAN_EXPORTED_FUNCTION(vkGetInstanceProcAddr); + #endif // NAZARA_VULKAN_LOADER_HPP diff --git a/src/Nazara/Vulkan/VkLoader.cpp b/src/Nazara/Vulkan/VkLoader.cpp index 04d9cb8dc..b261778df 100644 --- a/src/Nazara/Vulkan/VkLoader.cpp +++ b/src/Nazara/Vulkan/VkLoader.cpp @@ -9,3 +9,6 @@ namespace Nz { } +#define NAZARA_VULKAN_EXPORTED_FUNCTION_IMPL(func) PFN_##func func = nullptr; + +NAZARA_VULKAN_EXPORTED_FUNCTION_IMPL(vkGetInstanceProcAddr) \ No newline at end of file From 22a31c72ed84b685cd25e20c942682fe6f92233c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Apr 2016 02:28:26 +0200 Subject: [PATCH 040/224] Vulkan: Add loading of Instance/Device Former-commit-id: 0184f78824900bd46cff94dbfe829b126b8c984d --- build/scripts/modules/vulkan.lua | 4 ++ include/Nazara/Vulkan.hpp | 38 ++++++++++ include/Nazara/Vulkan/Config.hpp | 4 +- include/Nazara/Vulkan/Debug.hpp | 2 +- include/Nazara/Vulkan/VkDevice.hpp | 62 ++++++++++++++++ include/Nazara/Vulkan/VkDevice.inl | 67 +++++++++++++++++ include/Nazara/Vulkan/VkInstance.hpp | 74 +++++++++++++++++++ include/Nazara/Vulkan/VkInstance.inl | 86 ++++++++++++++++++++++ include/Nazara/Vulkan/VkLoader.hpp | 44 ++++++++---- include/Nazara/Vulkan/VkLoader.inl | 19 +++++ include/Nazara/Vulkan/Vulkan.hpp | 2 +- src/Nazara/Vulkan/VkDevice.cpp | 50 +++++++++++++ src/Nazara/Vulkan/VkInstance.cpp | 103 +++++++++++++++++++++++++++ src/Nazara/Vulkan/VkLoader.cpp | 60 ++++++++++++++-- src/Nazara/Vulkan/Vulkan.cpp | 2 +- 15 files changed, 592 insertions(+), 25 deletions(-) create mode 100644 include/Nazara/Vulkan.hpp create mode 100644 include/Nazara/Vulkan/VkDevice.hpp create mode 100644 include/Nazara/Vulkan/VkDevice.inl create mode 100644 include/Nazara/Vulkan/VkInstance.hpp create mode 100644 include/Nazara/Vulkan/VkInstance.inl create mode 100644 include/Nazara/Vulkan/VkLoader.inl create mode 100644 src/Nazara/Vulkan/VkDevice.cpp create mode 100644 src/Nazara/Vulkan/VkInstance.cpp diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua index 687a542c5..876e5e75e 100644 --- a/build/scripts/modules/vulkan.lua +++ b/build/scripts/modules/vulkan.lua @@ -1,5 +1,9 @@ MODULE.Name = "Vulkan" +MODULE.Defines = { + "VK_NO_PROTOTYPES" +} + MODULE.Libraries = { "NazaraCore", "NazaraUtility" diff --git a/include/Nazara/Vulkan.hpp b/include/Nazara/Vulkan.hpp new file mode 100644 index 000000000..a935674e9 --- /dev/null +++ b/include/Nazara/Vulkan.hpp @@ -0,0 +1,38 @@ +// This file was automatically generated on 24 Apr 2016 at 02:26:55 + +/* + Nazara Engine - Vulkan + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_GLOBAL_VULKAN_HPP +#define NAZARA_GLOBAL_VULKAN_HPP + +#include +#include +#include +#include +#include + +#endif // NAZARA_GLOBAL_VULKAN_HPP diff --git a/include/Nazara/Vulkan/Config.hpp b/include/Nazara/Vulkan/Config.hpp index 28a98edfd..d5f616214 100644 --- a/include/Nazara/Vulkan/Config.hpp +++ b/include/Nazara/Vulkan/Config.hpp @@ -1,7 +1,7 @@ /* - Nazara Engine - Module name + Nazara Engine - Vulkan - Copyright (C) YEAR AUTHORS (EMAIL) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Vulkan/Debug.hpp b/include/Nazara/Vulkan/Debug.hpp index a744946ef..b5e44efae 100644 --- a/include/Nazara/Vulkan/Debug.hpp +++ b/include/Nazara/Vulkan/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2016 Jérôme Leclercq // This file is part of the "Nazara Engine - Vulkan" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp new file mode 100644 index 000000000..0779cdcd8 --- /dev/null +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -0,0 +1,62 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKDEVICE_HPP +#define NAZARA_VULKAN_VKDEVICE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Instance; + + class NAZARA_VULKAN_API Device + { + public: + inline Device(Instance& instance); + Device(const Device&) = delete; + Device(Device&&) = delete; + inline ~Device(); + + bool Create(VkPhysicalDevice device, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline void Destroy(); + + inline void GetDeviceQueue(UInt32 queueFamilyIndex, UInt32 queueIndex, VkQueue* queue); + inline VkResult GetLastErrorCode() const; + + inline bool WaitForIdle(); + + Device& operator=(const Device&) = delete; + Device& operator=(Device&&) = delete; + + // Vulkan functions + #define NAZARA_VULKAN_DEVICE_FUNCTION(func) PFN_##func func + + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyDevice); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue); + + #undef NAZARA_VULKAN_DEVICE_FUNCTION + + private: + inline PFN_vkVoidFunction GetProcAddr(const char* name); + + Instance& m_instance; + VkAllocationCallbacks m_allocator; + VkDevice m_device; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKDEVICE_HPP diff --git a/include/Nazara/Vulkan/VkDevice.inl b/include/Nazara/Vulkan/VkDevice.inl new file mode 100644 index 000000000..75a3a6e8b --- /dev/null +++ b/include/Nazara/Vulkan/VkDevice.inl @@ -0,0 +1,67 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Device::Device(Instance& instance) : + m_instance(instance), + m_device(nullptr) + { + } + + inline Device::~Device() + { + Destroy(); + } + + inline void Device::Destroy() + { + if (m_device) + { + vkDeviceWaitIdle(m_device); + vkDestroyDevice(m_device, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + } + + inline void Device::GetDeviceQueue(UInt32 queueFamilyIndex, UInt32 queueIndex, VkQueue* queue) + { + return vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, queue); + } + + inline VkResult Device::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline bool Device::WaitForIdle() + { + m_lastErrorCode = vkDeviceWaitIdle(m_device); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to wait for device idle"); + return false; + } + + return true; + } + + inline PFN_vkVoidFunction Device::GetProcAddr(const char* name) + { + PFN_vkVoidFunction func = m_instance.GetDeviceProcAddr(m_device, name); + if (!func) + NazaraError("Failed to get " + String(name) + " address"); + + return func; + } + } +} + +#include diff --git a/include/Nazara/Vulkan/VkInstance.hpp b/include/Nazara/Vulkan/VkInstance.hpp new file mode 100644 index 000000000..b3b0b62eb --- /dev/null +++ b/include/Nazara/Vulkan/VkInstance.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKINSTANCE_HPP +#define NAZARA_VULKAN_VKINSTANCE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class NAZARA_VULKAN_API Instance + { + public: + inline Instance(); + Instance(const Instance&) = delete; + Instance(Instance&&) = delete; + inline ~Instance(); + + bool Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline void Destroy(); + + bool EnumeratePhysicalDevices(std::vector* physicalDevices); + + inline PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name); + + inline void GetPhysicalDeviceFeatures(VkPhysicalDevice device, VkPhysicalDeviceFeatures* features); + inline void GetPhysicalDeviceFormatProperties(VkPhysicalDevice device, VkFormat format, VkFormatProperties* formatProperties); + inline bool GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* imageFormatProperties); + inline void GetPhysicalDeviceMemoryProperties(VkPhysicalDevice device, VkPhysicalDeviceMemoryProperties* properties); + inline void GetPhysicalDeviceProperties(VkPhysicalDevice device, VkPhysicalDeviceProperties* properties); + bool GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice device, std::vector* queueFamilyProperties); + + inline VkResult GetLastErrorCode() const; + + Instance& operator=(const Instance&) = delete; + Instance& operator=(Instance&&) = delete; + + // Vulkan functions + #define NAZARA_VULKAN_INSTANCE_FUNCTION(func) PFN_##func func + + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDevice); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyInstance); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFormatProperties); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceImageFormatProperties); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMemoryProperties); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties); + + #undef NAZARA_VULKAN_INSTANCE_FUNCTION + + private: + inline PFN_vkVoidFunction GetProcAddr(const char* name); + + VkAllocationCallbacks m_allocator; + VkInstance m_instance; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKINSTANCE_HPP diff --git a/include/Nazara/Vulkan/VkInstance.inl b/include/Nazara/Vulkan/VkInstance.inl new file mode 100644 index 000000000..1aaa508ef --- /dev/null +++ b/include/Nazara/Vulkan/VkInstance.inl @@ -0,0 +1,86 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Instance::Instance() : + m_instance(nullptr) + { + } + + inline Instance::~Instance() + { + Destroy(); + } + + inline void Instance::Destroy() + { + if (m_instance) + vkDestroyInstance(m_instance, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + inline PFN_vkVoidFunction Instance::GetDeviceProcAddr(VkDevice device, const char* name) + { + PFN_vkVoidFunction func = vkGetDeviceProcAddr(device, name); + if (!func) + NazaraError("Failed to get " + String(name) + " address"); + + return func; + } + + inline VkResult Instance::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline void Instance::GetPhysicalDeviceFeatures(VkPhysicalDevice device, VkPhysicalDeviceFeatures* features) + { + return vkGetPhysicalDeviceFeatures(device, features); + } + + inline void Instance::GetPhysicalDeviceFormatProperties(VkPhysicalDevice device, VkFormat format, VkFormatProperties* formatProperties) + { + return vkGetPhysicalDeviceFormatProperties(device, format, formatProperties); + } + + inline bool Instance::GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* imageFormatProperties) + { + m_lastErrorCode = vkGetPhysicalDeviceImageFormatProperties(physicalDevice, format, type, tiling, usage, flags, imageFormatProperties); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to get physical device image format properties"); + return false; + } + + return true; + } + + inline void Instance::GetPhysicalDeviceMemoryProperties(VkPhysicalDevice device, VkPhysicalDeviceMemoryProperties* memoryProperties) + { + return vkGetPhysicalDeviceMemoryProperties(device, memoryProperties); + } + + inline void Instance::GetPhysicalDeviceProperties(VkPhysicalDevice device, VkPhysicalDeviceProperties* properties) + { + return vkGetPhysicalDeviceProperties(device, properties); + } + + inline PFN_vkVoidFunction Instance::GetProcAddr(const char* name) + { + PFN_vkVoidFunction func = Loader::GetInstanceProcAddr(m_instance, name); + if (!func) + NazaraError("Failed to get " + String(name) + " address"); + + return func; + } + } +} + +#include diff --git a/include/Nazara/Vulkan/VkLoader.hpp b/include/Nazara/Vulkan/VkLoader.hpp index 8e973b0bb..c700451c5 100644 --- a/include/Nazara/Vulkan/VkLoader.hpp +++ b/include/Nazara/Vulkan/VkLoader.hpp @@ -1,11 +1,11 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2016 Jérôme Leclercq // This file is part of the "Nazara Engine - Vulkan" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once -#ifndef NAZARA_VULKAN_LOADER_HPP -#define NAZARA_VULKAN_LOADER_HPP +#ifndef NAZARA_VULKAN_VKLOADER_HPP +#define NAZARA_VULKAN_VKLOADER_HPP #include #include @@ -14,21 +14,35 @@ namespace Nz { - class NAZARA_VULKAN_API VkLoader + namespace Vk { - public: - VkLoader() = delete; - ~VkLoader() = delete; + class NAZARA_VULKAN_API Loader + { + public: + Loader() = delete; + ~Loader() = delete; + + static inline PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name); - static bool Initialize(); + static bool Initialize(); + static void Uninitialize(); - private: - static DynLib s_vulkanLib; - }; + // Vulkan functions + #define NAZARA_VULKAN_GLOBAL_FUNCTION(func) static PFN_##func func + + NAZARA_VULKAN_GLOBAL_FUNCTION(vkCreateInstance); + NAZARA_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties); + NAZARA_VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties); + NAZARA_VULKAN_GLOBAL_FUNCTION(vkGetInstanceProcAddr); + + #undef NAZARA_VULKAN_GLOBAL_FUNCTION + + private: + static DynLib s_vulkanLib; + }; + } } -#define NAZARA_VULKAN_EXPORTED_FUNCTION(func) extern PFN_##func func; +#include -NAZARA_VULKAN_EXPORTED_FUNCTION(vkGetInstanceProcAddr); - -#endif // NAZARA_VULKAN_LOADER_HPP +#endif // NAZARA_VULKAN_VKLOADER_HPP diff --git a/include/Nazara/Vulkan/VkLoader.inl b/include/Nazara/Vulkan/VkLoader.inl new file mode 100644 index 000000000..49467366d --- /dev/null +++ b/include/Nazara/Vulkan/VkLoader.inl @@ -0,0 +1,19 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + namespace Vk + { + inline PFN_vkVoidFunction Loader::GetInstanceProcAddr(VkInstance instance, const char* name) + { + return vkGetInstanceProcAddr(instance, name); + } + } +} + +#include diff --git a/include/Nazara/Vulkan/Vulkan.hpp b/include/Nazara/Vulkan/Vulkan.hpp index aabb87aea..9d90202c2 100644 --- a/include/Nazara/Vulkan/Vulkan.hpp +++ b/include/Nazara/Vulkan/Vulkan.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2016 Jérôme Leclercq // This file is part of the "Nazara Engine - Vulkan" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Vulkan/VkDevice.cpp b/src/Nazara/Vulkan/VkDevice.cpp new file mode 100644 index 000000000..ef28af223 --- /dev/null +++ b/src/Nazara/Vulkan/VkDevice.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + bool Device::Create(VkPhysicalDevice device, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateDevice(device, &createInfo, allocator, &m_device); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan device"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + #define NAZARA_VULKAN_LOAD_DEVICE(func) func = reinterpret_cast(GetProcAddr(#func)) + + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyDevice); + NAZARA_VULKAN_LOAD_DEVICE(vkDeviceWaitIdle); + NAZARA_VULKAN_LOAD_DEVICE(vkGetDeviceQueue); + } + catch (const std::exception& e) + { + NazaraError(String("Failed to query device function: ") + e.what()); + return false; + } + + #undef NAZARA_VULKAN_LOAD_DEVICE + + return true; + } + } +} diff --git a/src/Nazara/Vulkan/VkInstance.cpp b/src/Nazara/Vulkan/VkInstance.cpp new file mode 100644 index 000000000..304bbc277 --- /dev/null +++ b/src/Nazara/Vulkan/VkInstance.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + bool Instance::Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = Loader::vkCreateInstance(&createInfo, allocator, &m_instance); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan instance"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + #define NAZARA_VULKAN_LOAD_INSTANCE(func) func = reinterpret_cast(GetProcAddr(#func)) + + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDevice); + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroyInstance); + NAZARA_VULKAN_LOAD_INSTANCE(vkEnumeratePhysicalDevices); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDeviceProcAddr); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceFeatures); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceFormatProperties); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceImageFormatProperties); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceMemoryProperties); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceProperties); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties); + } + catch (const std::exception& e) + { + NazaraError(String("Failed to query instance function: ") + e.what()); + return false; + } + + #undef NAZARA_VULKAN_LOAD_INSTANCE + + return true; + } + + bool Instance::EnumeratePhysicalDevices(std::vector* devices) + { + NazaraAssert(devices, "Invalid device vector"); + + // First, query physical device count + UInt32 deviceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + m_lastErrorCode = vkEnumeratePhysicalDevices(m_instance, &deviceCount, nullptr); + if (m_lastErrorCode != VkResult::VK_SUCCESS || deviceCount == 0) + { + NazaraError("Failed to query physical device count"); + return false; + } + + // Now we can get the list of the available physical device + devices->resize(deviceCount); + m_lastErrorCode = vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices->data()); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query physical devices"); + return false; + } + + return true; + } + + bool Instance::GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice device, std::vector* queueFamilyProperties) + { + NazaraAssert(queueFamilyProperties, "Invalid device vector"); + + // First, query physical device count + UInt32 queueFamiliesCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamiliesCount, nullptr); + if (queueFamiliesCount == 0) + { + NazaraError("Failed to query physical device count"); + return false; + } + + // Now we can get the list of the available physical device + queueFamilyProperties->resize(queueFamiliesCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamiliesCount, queueFamilyProperties->data()); + + return true; + } + + } +} diff --git a/src/Nazara/Vulkan/VkLoader.cpp b/src/Nazara/Vulkan/VkLoader.cpp index b261778df..c4a6f08b5 100644 --- a/src/Nazara/Vulkan/VkLoader.cpp +++ b/src/Nazara/Vulkan/VkLoader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2016 Jérôme Leclercq // This file is part of the "Nazara Engine - Vulkan" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -7,8 +7,58 @@ namespace Nz { + namespace Vk + { + bool Loader::Initialize() + { + #ifdef NAZARA_PLATFORM_WINDOWS + s_vulkanLib.Load("vulkan-1.dll"); + #elif defined(NAZARA_PLATFORM_LINUX) + s_vulkanLib.Load("libvulkan.so"); + #else + #error Unhandled platform + #endif + + if (!s_vulkanLib.IsLoaded()) + { + NazaraError("Failed to open vulkan library: " + s_vulkanLib.GetLastError()); + return false; + } + + // vkGetInstanceProcAddr is the only function that's garantee to be exported + vkGetInstanceProcAddr = reinterpret_cast(s_vulkanLib.GetSymbol("vkGetInstanceProcAddr")); + if (!vkGetInstanceProcAddr) + { + NazaraError("Failed to get symbol \"vkGetInstanceProcAddr\": " + s_vulkanLib.GetLastError()); + return false; + } + + // all other functions should be loaded using vkGetInstanceProcAddr + #define NAZARA_VULKAN_LOAD_GLOBAL(func) func = reinterpret_cast(vkGetInstanceProcAddr(nullptr, #func)) + + NAZARA_VULKAN_LOAD_GLOBAL(vkCreateInstance); + NAZARA_VULKAN_LOAD_GLOBAL(vkEnumerateInstanceExtensionProperties); + NAZARA_VULKAN_LOAD_GLOBAL(vkEnumerateInstanceLayerProperties); + + #undef NAZARA_VULKAN_LOAD_GLOBAL + + return true; + } + + #define NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(func) PFN_##func Loader::func = nullptr + + NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkCreateInstance); + NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkEnumerateInstanceExtensionProperties); + NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkEnumerateInstanceLayerProperties); + NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkGetInstanceProcAddr); + + #undef NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL + + DynLib Loader::s_vulkanLib; + + void Loader::Uninitialize() + { + s_vulkanLib.Unload(); + } + } } - -#define NAZARA_VULKAN_EXPORTED_FUNCTION_IMPL(func) PFN_##func func = nullptr; - -NAZARA_VULKAN_EXPORTED_FUNCTION_IMPL(vkGetInstanceProcAddr) \ No newline at end of file diff --git a/src/Nazara/Vulkan/Vulkan.cpp b/src/Nazara/Vulkan/Vulkan.cpp index 5c41e0034..00bb55337 100644 --- a/src/Nazara/Vulkan/Vulkan.cpp +++ b/src/Nazara/Vulkan/Vulkan.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016 Jérôme Leclercq +// Copyright (C) 2016 Jérôme Leclercq // This file is part of the "Nazara Engine - Vulkan" // For conditions of distribution and use, see copyright notice in Config.hpp From da401af52c2c82a5f0f85bad486f868f8807e745 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 24 Apr 2016 04:37:31 +0200 Subject: [PATCH 041/224] Vulkan/VkLoader: Add EnumerateInstance[Extension|Layer]Properties helper Former-commit-id: a7cfc73816266cef944f7cb3c668be0b86bbfcbf --- include/Nazara/Vulkan/VkLoader.hpp | 4 +++ src/Nazara/Vulkan/VkLoader.cpp | 53 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/include/Nazara/Vulkan/VkLoader.hpp b/include/Nazara/Vulkan/VkLoader.hpp index c700451c5..f12429b28 100644 --- a/include/Nazara/Vulkan/VkLoader.hpp +++ b/include/Nazara/Vulkan/VkLoader.hpp @@ -22,6 +22,9 @@ namespace Nz Loader() = delete; ~Loader() = delete; + static bool EnumerateInstanceExtensionProperties(std::vector* properties, const char* layerName = nullptr); + static bool EnumerateInstanceLayerProperties(std::vector* properties); + static inline PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* name); static bool Initialize(); @@ -39,6 +42,7 @@ namespace Nz private: static DynLib s_vulkanLib; + static VkResult s_lastErrorCode; }; } } diff --git a/src/Nazara/Vulkan/VkLoader.cpp b/src/Nazara/Vulkan/VkLoader.cpp index c4a6f08b5..c9d2a360d 100644 --- a/src/Nazara/Vulkan/VkLoader.cpp +++ b/src/Nazara/Vulkan/VkLoader.cpp @@ -9,6 +9,56 @@ namespace Nz { namespace Vk { + bool Loader::EnumerateInstanceExtensionProperties(std::vector* properties, const char* layerName) + { + NazaraAssert(properties, "Invalid device vector"); + + // First, query physical device count + UInt32 propertyCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + s_lastErrorCode = vkEnumerateInstanceExtensionProperties(layerName, &propertyCount, properties->data()); + if (s_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to get instance extension properties count"); + return false; + } + + // Now we can get the list of the available physical device + properties->resize(propertyCount); + s_lastErrorCode = vkEnumerateInstanceExtensionProperties(layerName, &propertyCount, properties->data()); + if (s_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to enumerate instance extension properties"); + return false; + } + + return true; + } + + bool Loader::EnumerateInstanceLayerProperties(std::vector* properties) + { + NazaraAssert(properties, "Invalid device vector"); + + // First, query physical device count + UInt32 propertyCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + s_lastErrorCode = vkEnumerateInstanceLayerProperties(&propertyCount, properties->data()); + if (s_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to get instance layer properties count"); + return false; + } + + // Now we can get the list of the available physical device + properties->resize(propertyCount); + s_lastErrorCode = vkEnumerateInstanceLayerProperties(&propertyCount, properties->data()); + if (s_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to enumerate instance layer properties"); + return false; + } + + return true; + } + bool Loader::Initialize() { #ifdef NAZARA_PLATFORM_WINDOWS @@ -42,6 +92,8 @@ namespace Nz #undef NAZARA_VULKAN_LOAD_GLOBAL + s_lastErrorCode = VkResult::VK_SUCCESS; + return true; } @@ -55,6 +107,7 @@ namespace Nz #undef NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL DynLib Loader::s_vulkanLib; + VkResult Loader::s_lastErrorCode; void Loader::Uninitialize() { From e1d424e5f90967c62f1ed62913f7941a06093af7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 28 Apr 2016 20:37:30 +0200 Subject: [PATCH 042/224] Vulkan: Add support for extensions Former-commit-id: ab5742edc79815dd75473bf467c7b1dd46e2fecb --- include/Nazara/Vulkan/VkInstance.hpp | 77 ++++++++++++++++++++ include/Nazara/Vulkan/VkInstance.inl | 42 +++++++++++ src/Nazara/Vulkan/VkInstance.cpp | 104 +++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) diff --git a/include/Nazara/Vulkan/VkInstance.hpp b/include/Nazara/Vulkan/VkInstance.hpp index b3b0b62eb..4581b9cf1 100644 --- a/include/Nazara/Vulkan/VkInstance.hpp +++ b/include/Nazara/Vulkan/VkInstance.hpp @@ -8,9 +8,11 @@ #define NAZARA_VULKAN_VKINSTANCE_HPP #include +#include #include #include #include +#include namespace Nz { @@ -25,6 +27,7 @@ namespace Nz inline ~Instance(); bool Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const String& appName, UInt32 appVersion, const String& engineName, UInt32 engineVersion, const std::vector& layers, const std::vector& extensions, const VkAllocationCallbacks* allocator = nullptr); inline void Destroy(); bool EnumeratePhysicalDevices(std::vector* physicalDevices); @@ -40,12 +43,18 @@ namespace Nz inline VkResult GetLastErrorCode() const; + inline bool IsExtensionLoaded(const String& extensionName); + inline bool IsLayerLoaded(const String& layerName); + Instance& operator=(const Instance&) = delete; Instance& operator=(Instance&&) = delete; + inline operator VkInstance(); + // Vulkan functions #define NAZARA_VULKAN_INSTANCE_FUNCTION(func) PFN_##func func + // Vulkan core NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDevice); NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyInstance); NAZARA_VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices); @@ -57,6 +66,72 @@ namespace Nz NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties); NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties); + // VK_KHR_display + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDisplayModeKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDisplayPlaneSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayModePropertiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayPlaneCapabilitiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayPlaneSupportedDisplaysKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPropertiesKHR); + + // VK_KHR_display_swapchain + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSharedSwapchainsKHR); + + // VK_KHR_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); + + // VK_KHR_swapchain + NAZARA_VULKAN_INSTANCE_FUNCTION(vkAcquireNextImageKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSwapchainKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySwapchainKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkQueuePresentKHR); + + // VK_EXT_debug_report + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDebugReportCallbackEXT); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyDebugReportCallbackEXT); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDebugReportMessageEXT); + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateAndroidSurfaceKHR); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateMirSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMirPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateXcbSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceXcbPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateXlibSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceXlibPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateWaylandSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceWaylandPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateWin32SurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceWin32PresentationSupportKHR); + #endif + #undef NAZARA_VULKAN_INSTANCE_FUNCTION private: @@ -65,6 +140,8 @@ namespace Nz VkAllocationCallbacks m_allocator; VkInstance m_instance; VkResult m_lastErrorCode; + std::unordered_set m_loadedExtensions; + std::unordered_set m_loadedLayers; }; } } diff --git a/include/Nazara/Vulkan/VkInstance.inl b/include/Nazara/Vulkan/VkInstance.inl index 1aaa508ef..8f0f6d2af 100644 --- a/include/Nazara/Vulkan/VkInstance.inl +++ b/include/Nazara/Vulkan/VkInstance.inl @@ -20,6 +20,33 @@ namespace Nz Destroy(); } + inline bool Instance::Create(const String& appName, UInt32 appVersion, const String& engineName, UInt32 engineVersion, const std::vector& layers, const std::vector& extensions, const VkAllocationCallbacks* allocator) + { + VkApplicationInfo appInfo = + { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + nullptr, + appName.GetConstBuffer(), + appVersion, + engineName.GetConstBuffer(), + engineVersion + }; + + VkInstanceCreateInfo instanceInfo = + { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + nullptr, + 0, + &appInfo, + static_cast(layers.size()), + &layers[0], + static_cast(extensions.size()), + &extensions[0] + }; + + return Create(instanceInfo, allocator); + } + inline void Instance::Destroy() { if (m_instance) @@ -40,6 +67,21 @@ namespace Nz return m_lastErrorCode; } + inline bool Instance::IsExtensionLoaded(const String& extensionName) + { + return m_loadedExtensions.count(extensionName) != 0; + } + + inline bool Instance::IsLayerLoaded(const String& layerName) + { + return m_loadedLayers.count(layerName) != 0; + } + + inline Instance::operator VkInstance() + { + return m_instance; + } + inline void Instance::GetPhysicalDeviceFeatures(VkPhysicalDevice device, VkPhysicalDeviceFeatures* features) { return vkGetPhysicalDeviceFeatures(device, features); diff --git a/src/Nazara/Vulkan/VkInstance.cpp b/src/Nazara/Vulkan/VkInstance.cpp index 304bbc277..5533798a5 100644 --- a/src/Nazara/Vulkan/VkInstance.cpp +++ b/src/Nazara/Vulkan/VkInstance.cpp @@ -26,12 +26,21 @@ namespace Nz else m_allocator.pfnAllocation = nullptr; + // Parse extensions and layers + for (UInt32 i = 0; i < createInfo.enabledExtensionCount; ++i) + m_loadedExtensions.insert(createInfo.ppEnabledExtensionNames[i]); + + for (UInt32 i = 0; i < createInfo.enabledLayerCount; ++i) + m_loadedLayers.insert(createInfo.ppEnabledLayerNames[i]); + + // And now load everything #define NAZARA_VULKAN_LOAD_INSTANCE(func) func = reinterpret_cast(GetProcAddr(#func)) try { ErrorFlags flags(ErrorFlag_ThrowException, true); + // Vulkan core NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDevice); NAZARA_VULKAN_LOAD_INSTANCE(vkDestroyInstance); NAZARA_VULKAN_LOAD_INSTANCE(vkEnumeratePhysicalDevices); @@ -42,6 +51,101 @@ namespace Nz NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceMemoryProperties); NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceProperties); NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties); + + // VK_KHR_display + if (IsExtensionLoaded("VK_KHR_display")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDisplayModeKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDisplayPlaneSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayModePropertiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayPlaneCapabilitiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayPlaneSupportedDisplaysKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceDisplayPropertiesKHR); + } + + // VK_KHR_display_swapchain + if (IsExtensionLoaded("VK_KHR_display_swapchain")) + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSharedSwapchainsKHR); + + // VK_KHR_surface + if (IsExtensionLoaded("VK_KHR_display")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceFormatsKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfacePresentModesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceSupportKHR); + } + + // VK_KHR_swapchain + if (IsExtensionLoaded("VK_KHR_swapchain")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkAcquireNextImageKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSwapchainKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySwapchainKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkQueuePresentKHR); + } + + // VK_EXT_debug_report + if (IsExtensionLoaded("VK_EXT_debug_report")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDebugReportCallbackEXT); + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroyDebugReportCallbackEXT); + NAZARA_VULKAN_LOAD_INSTANCE(vkDebugReportMessageEXT); + } + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + if (IsExtensionLoaded("VK_KHR_android_surface")) + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateAndroidSurfaceKHR); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + if (IsExtensionLoaded("VK_KHR_mir_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateMirSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceMirPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + if (IsExtensionLoaded("VK_KHR_xcb_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateXcbSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceXcbPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + if (IsExtensionLoaded("VK_KHR_xlib_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateXlibSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceXlibPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + if (IsExtensionLoaded("VK_KHR_wayland_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateWaylandSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceWaylandPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + if (IsExtensionLoaded("VK_KHR_win32_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateWin32SurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceWin32PresentationSupportKHR); + } + #endif } catch (const std::exception& e) { From a3cc866bbd165aed19625b0f6a3c2746c17f5e15 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 28 Apr 2016 20:37:41 +0200 Subject: [PATCH 043/224] Vulkan: Add support for surfaces Former-commit-id: c4599c430add1bc54e9665d5bb0e0ca5071bcf41 --- include/Nazara/Vulkan/VkSurface.hpp | 87 +++++++++++++++ include/Nazara/Vulkan/VkSurface.inl | 166 ++++++++++++++++++++++++++++ src/Nazara/Vulkan/VkSurface.cpp | 78 +++++++++++++ 3 files changed, 331 insertions(+) create mode 100644 include/Nazara/Vulkan/VkSurface.hpp create mode 100644 include/Nazara/Vulkan/VkSurface.inl create mode 100644 src/Nazara/Vulkan/VkSurface.cpp diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp new file mode 100644 index 000000000..ff7ac0002 --- /dev/null +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -0,0 +1,87 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKSURFACE_HPP +#define NAZARA_VULKAN_VKSURFACE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Instance; + + class NAZARA_VULKAN_API Surface + { + public: + inline Surface(Instance& instance); + Surface(const Surface&) = delete; + Surface(Surface&&) = delete; + inline ~Surface(); + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + bool Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + inline void Destroy(); + + inline bool IsSupported() const; + + inline VkResult GetLastErrorCode() const; + + Surface& operator=(const Surface&) = delete; + Surface& operator=(Surface&&) = delete; + + private: + bool Create(const VkAllocationCallbacks* allocator); + + Instance& m_instance; + VkAllocationCallbacks m_allocator; + VkSurfaceKHR m_surface; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // Surface diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl new file mode 100644 index 000000000..daab26d1e --- /dev/null +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -0,0 +1,166 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Surface::Surface(Instance& instance) : + m_instance(instance), + m_surface(0) + { + } + + inline Surface::~Surface() + { + Destroy(); + } + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkAndroidSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + inline bool Surface::Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkMirSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + connection, + surface + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkXcbSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + connection, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkXlibSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + display, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkWaylandSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + display, + surface + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkWin32SurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + instance, + handle + }; + + return Create(createInfo, allocator); + } + #endif + + inline void Surface::Destroy() + { + if (m_surface) + m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + inline bool Surface::IsSupported() const + { + if (!m_instance.IsExtensionLoaded("VK_KHR_surface")) + return false; + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_android_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_mir_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_xcb_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_xlib_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_wayland_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_win32_surface")) + return true; + #endif + + return false; + } + } +} + +#include diff --git a/src/Nazara/Vulkan/VkSurface.cpp b/src/Nazara/Vulkan/VkSurface.cpp new file mode 100644 index 000000000..87b8657a9 --- /dev/null +++ b/src/Nazara/Vulkan/VkSurface.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + #ifdef VK_USE_PLATFORM_ANDROID_KHR + bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + bool Surface::Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + bool Surface::Create(const VkAllocationCallbacks* allocator) + { + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan surface"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } + } +} From 432022c5b7000be9d496a12c0d5175a44b6296fc Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 09:02:24 +0200 Subject: [PATCH 044/224] Build/Vulkan: Add Win32 define Former-commit-id: d1bd3db4f8e89c3a8ea3544fb6dab744781b76bb --- build/scripts/modules/vulkan.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua index 876e5e75e..03c774cd5 100644 --- a/build/scripts/modules/vulkan.lua +++ b/build/scripts/modules/vulkan.lua @@ -9,6 +9,10 @@ MODULE.Libraries = { "NazaraUtility" } +MODULE.OsDefines.Windows = { + "VK_USE_PLATFORM_WIN32_KHR" +} + MODULE.OsFiles.Windows = { "../src/Nazara/Vulkan/Win32/**.hpp", "../src/Nazara/Vulkan/Win32/**.cpp" From 81e2c3817acaea392af21c8b868c9c431106438c Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 20:54:42 +0200 Subject: [PATCH 045/224] Build: Add support for Linux, BSD and Solaris Former-commit-id: 2f7f1e74fd101d688977ceb5129027cb1fa4a67b --- build/scripts/modules/vulkan.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua index 03c774cd5..a8e674d03 100644 --- a/build/scripts/modules/vulkan.lua +++ b/build/scripts/modules/vulkan.lua @@ -9,6 +9,16 @@ MODULE.Libraries = { "NazaraUtility" } +MODULE.OsDefines.Linux = { + "VK_USE_PLATFORM_MIR_KHR", + "VK_USE_PLATFORM_XCB_KHR", + "VK_USE_PLATFORM_XLIB_KHR", + "VK_USE_PLATFORM_WAYLAND_KHR" +} + +MODULE.OsDefines.BSD = MODULE.OsDefines.Linux +MODULE.OsDefines.Solaris = MODULE.OsDefines.Linux + MODULE.OsDefines.Windows = { "VK_USE_PLATFORM_WIN32_KHR" } From da3682149cb35e826133725b521c9b96ffb6a570 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 22:45:54 +0200 Subject: [PATCH 046/224] Vulkan: Move device-level extension to Vk::Device Former-commit-id: a73c8cd9744517baea7a5fbd440ccb4d90e9bfc7 --- include/Nazara/Vulkan/VkDevice.hpp | 18 ++++++++++++++++++ include/Nazara/Vulkan/VkInstance.hpp | 10 ---------- src/Nazara/Vulkan/VkDevice.cpp | 14 ++++++++++++++ src/Nazara/Vulkan/VkInstance.cpp | 14 -------------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 0779cdcd8..547253fd9 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -40,10 +40,28 @@ namespace Nz // Vulkan functions #define NAZARA_VULKAN_DEVICE_FUNCTION(func) PFN_##func func + // Vulkan core NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyDevice); NAZARA_VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle); NAZARA_VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue); + // VK_KHR_display_swapchain + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateSharedSwapchainsKHR); + + // VK_KHR_surface + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroySurfaceKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); + + // VK_KHR_swapchain + NAZARA_VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR); + #undef NAZARA_VULKAN_DEVICE_FUNCTION private: diff --git a/include/Nazara/Vulkan/VkInstance.hpp b/include/Nazara/Vulkan/VkInstance.hpp index 4581b9cf1..ded2b0ef7 100644 --- a/include/Nazara/Vulkan/VkInstance.hpp +++ b/include/Nazara/Vulkan/VkInstance.hpp @@ -75,9 +75,6 @@ namespace Nz NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPropertiesKHR); - // VK_KHR_display_swapchain - NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSharedSwapchainsKHR); - // VK_KHR_surface NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR); NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); @@ -85,13 +82,6 @@ namespace Nz NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); - // VK_KHR_swapchain - NAZARA_VULKAN_INSTANCE_FUNCTION(vkAcquireNextImageKHR); - NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSwapchainKHR); - NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySwapchainKHR); - NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetSwapchainImagesKHR); - NAZARA_VULKAN_INSTANCE_FUNCTION(vkQueuePresentKHR); - // VK_EXT_debug_report NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDebugReportCallbackEXT); NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyDebugReportCallbackEXT); diff --git a/src/Nazara/Vulkan/VkDevice.cpp b/src/Nazara/Vulkan/VkDevice.cpp index ef28af223..1c3eafa3c 100644 --- a/src/Nazara/Vulkan/VkDevice.cpp +++ b/src/Nazara/Vulkan/VkDevice.cpp @@ -35,6 +35,20 @@ namespace Nz NAZARA_VULKAN_LOAD_DEVICE(vkDestroyDevice); NAZARA_VULKAN_LOAD_DEVICE(vkDeviceWaitIdle); NAZARA_VULKAN_LOAD_DEVICE(vkGetDeviceQueue); + + // VK_KHR_display_swapchain + if (m_instance.IsExtensionLoaded("VK_KHR_display_swapchain")) + NAZARA_VULKAN_LOAD_DEVICE(vkCreateSharedSwapchainsKHR); + + // VK_KHR_swapchain + if (m_instance.IsExtensionLoaded("VK_KHR_swapchain")) + { + NAZARA_VULKAN_LOAD_DEVICE(vkAcquireNextImageKHR); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateSwapchainKHR); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroySwapchainKHR); + NAZARA_VULKAN_LOAD_DEVICE(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_LOAD_DEVICE(vkQueuePresentKHR); + } } catch (const std::exception& e) { diff --git a/src/Nazara/Vulkan/VkInstance.cpp b/src/Nazara/Vulkan/VkInstance.cpp index 5533798a5..e66189b7c 100644 --- a/src/Nazara/Vulkan/VkInstance.cpp +++ b/src/Nazara/Vulkan/VkInstance.cpp @@ -64,10 +64,6 @@ namespace Nz NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceDisplayPropertiesKHR); } - // VK_KHR_display_swapchain - if (IsExtensionLoaded("VK_KHR_display_swapchain")) - NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSharedSwapchainsKHR); - // VK_KHR_surface if (IsExtensionLoaded("VK_KHR_display")) { @@ -78,16 +74,6 @@ namespace Nz NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceSupportKHR); } - // VK_KHR_swapchain - if (IsExtensionLoaded("VK_KHR_swapchain")) - { - NAZARA_VULKAN_LOAD_INSTANCE(vkAcquireNextImageKHR); - NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSwapchainKHR); - NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySwapchainKHR); - NAZARA_VULKAN_LOAD_INSTANCE(vkGetSwapchainImagesKHR); - NAZARA_VULKAN_LOAD_INSTANCE(vkQueuePresentKHR); - } - // VK_EXT_debug_report if (IsExtensionLoaded("VK_EXT_debug_report")) { From 3d09177795f8a5b5d8c9d2b69ef699bf8f6bcb09 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 22:46:25 +0200 Subject: [PATCH 047/224] Vulkan/Device: Add useful accessors Former-commit-id: b2b6378b2b9a8de2ad1c47b72f2acd6dd86a087a --- include/Nazara/Vulkan/VkDevice.hpp | 4 ++++ include/Nazara/Vulkan/VkDevice.inl | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 547253fd9..0df3ec68d 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -30,6 +30,8 @@ namespace Nz inline void Destroy(); inline void GetDeviceQueue(UInt32 queueFamilyIndex, UInt32 queueIndex, VkQueue* queue); + inline Instance& GetInstance(); + inline const Instance& GetInstance() const; inline VkResult GetLastErrorCode() const; inline bool WaitForIdle(); @@ -37,6 +39,8 @@ namespace Nz Device& operator=(const Device&) = delete; Device& operator=(Device&&) = delete; + inline operator VkDevice(); + // Vulkan functions #define NAZARA_VULKAN_DEVICE_FUNCTION(func) PFN_##func func diff --git a/include/Nazara/Vulkan/VkDevice.inl b/include/Nazara/Vulkan/VkDevice.inl index 75a3a6e8b..4eddb4abf 100644 --- a/include/Nazara/Vulkan/VkDevice.inl +++ b/include/Nazara/Vulkan/VkDevice.inl @@ -36,6 +36,16 @@ namespace Nz return vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, queue); } + inline Instance& Device::GetInstance() + { + return m_instance; + } + + inline const Instance& Device::GetInstance() const + { + return m_instance; + } + inline VkResult Device::GetLastErrorCode() const { return m_lastErrorCode; @@ -53,6 +63,11 @@ namespace Nz return true; } + inline Device::operator VkDevice() + { + return m_device; + } + inline PFN_vkVoidFunction Device::GetProcAddr(const char* name) { PFN_vkVoidFunction func = m_instance.GetDeviceProcAddr(m_device, name); From 5bd08501e97dd61886008019d5b5431c4b114bbe Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 22:46:43 +0200 Subject: [PATCH 048/224] Vulkan/Surface: Add missing implementation Former-commit-id: ca6008f2c717aee8cea80805f9f5f0c6ed950c32 --- include/Nazara/Vulkan/VkSurface.inl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index daab26d1e..9e8d4afac 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -13,7 +13,7 @@ namespace Nz { inline Surface::Surface(Instance& instance) : m_instance(instance), - m_surface(0) + m_surface(VK_NULL_HANDLE) { } @@ -119,9 +119,14 @@ namespace Nz inline void Surface::Destroy() { - if (m_surface) + if (m_surface != VK_NULL_HANDLE) m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); } + + inline VkResult Surface::GetLastErrorCode() const + { + return m_lastErrorCode; + } inline bool Surface::IsSupported() const { From 72e849fa8531bbca1c3afd9905fa0c2e93679016 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Apr 2016 23:20:44 +0200 Subject: [PATCH 049/224] Vulkan/Surface: Move all of .cpp code to .inl There's no point to have .cpp file of this class and others (swapchain, fence, semaphore, etc.) Former-commit-id: 82472312ac31bbe60683cf7e3c4b8f40bb5cd984 --- include/Nazara/Vulkan/VkSurface.hpp | 14 +++--- include/Nazara/Vulkan/VkSurface.inl | 53 ++++++++++++++++++++ src/Nazara/Vulkan/VkSurface.cpp | 78 ----------------------------- 3 files changed, 60 insertions(+), 85 deletions(-) delete mode 100644 src/Nazara/Vulkan/VkSurface.cpp diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp index ff7ac0002..57893b61e 100644 --- a/include/Nazara/Vulkan/VkSurface.hpp +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -28,37 +28,37 @@ namespace Nz #ifdef VK_USE_PLATFORM_ANDROID_KHR // VK_KHR_android_surface - bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif #ifdef VK_USE_PLATFORM_MIR_KHR // VK_KHR_mir_surface - bool Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif #ifdef VK_USE_PLATFORM_XCB_KHR // VK_KHR_xcb_surface - bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif #ifdef VK_USE_PLATFORM_XLIB_KHR // VK_KHR_xlib_surface - bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR // VK_KHR_wayland_surface - bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif #ifdef VK_USE_PLATFORM_WIN32_KHR // VK_KHR_win32_surface - bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); #endif @@ -72,7 +72,7 @@ namespace Nz Surface& operator=(Surface&&) = delete; private: - bool Create(const VkAllocationCallbacks* allocator); + inline bool Create(const VkAllocationCallbacks* allocator); Instance& m_instance; VkAllocationCallbacks m_allocator; diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index 9e8d4afac..69c2f89d2 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -23,6 +23,12 @@ namespace Nz } #ifdef VK_USE_PLATFORM_ANDROID_KHR + inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkAndroidSurfaceCreateInfoKHR createInfo = @@ -38,6 +44,12 @@ namespace Nz #endif #ifdef VK_USE_PLATFORM_MIR_KHR + inline bool Surface::Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkMirSurfaceCreateInfoKHR createInfo = @@ -54,6 +66,12 @@ namespace Nz #endif #ifdef VK_USE_PLATFORM_XCB_KHR + inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkXcbSurfaceCreateInfoKHR createInfo = @@ -70,6 +88,12 @@ namespace Nz #endif #ifdef VK_USE_PLATFORM_XLIB_KHR + inline bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkXlibSurfaceCreateInfoKHR createInfo = @@ -86,6 +110,12 @@ namespace Nz #endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR + inline bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkWaylandSurfaceCreateInfoKHR createInfo = @@ -102,6 +132,12 @@ namespace Nz #endif #ifdef VK_USE_PLATFORM_WIN32_KHR + inline bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) { VkWin32SurfaceCreateInfoKHR createInfo = @@ -165,6 +201,23 @@ namespace Nz return false; } + + inline bool Surface::Create(const VkAllocationCallbacks* allocator) + { + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan surface"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } } } diff --git a/src/Nazara/Vulkan/VkSurface.cpp b/src/Nazara/Vulkan/VkSurface.cpp deleted file mode 100644 index 87b8657a9..000000000 --- a/src/Nazara/Vulkan/VkSurface.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2016 Jérôme Leclercq -// This file is part of the "Nazara Engine - Vulkan" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include - -namespace Nz -{ - namespace Vk - { - #ifdef VK_USE_PLATFORM_ANDROID_KHR - bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.PFN_vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - #ifdef VK_USE_PLATFORM_MIR_KHR - bool Surface::Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.PFN_vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - #ifdef VK_USE_PLATFORM_XCB_KHR - bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.PFN_vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - #ifdef VK_USE_PLATFORM_XLIB_KHR - bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.PFN_vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - #ifdef VK_USE_PLATFORM_WAYLAND_KHR - bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - #ifdef VK_USE_PLATFORM_WIN32_KHR - bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface); - return Create(allocator); - } - #endif - - bool Surface::Create(const VkAllocationCallbacks* allocator) - { - if (m_lastErrorCode != VkResult::VK_SUCCESS) - { - NazaraError("Failed to create Vulkan surface"); - return false; - } - - // Store the allocator to access them when needed - if (allocator) - m_allocator = *allocator; - else - m_allocator.pfnAllocation = nullptr; - - return true; - } - } -} From 3bcde868efa83f8e2f5a35dd7daaaa848bd7afc3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 11:41:36 +0200 Subject: [PATCH 050/224] Vulkan/Instance: Fix possible crash when not using layers or extensions Former-commit-id: a429d0f1032f1a39ee50075b366d83cf4cba0823 --- include/Nazara/Vulkan/VkInstance.inl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Vulkan/VkInstance.inl b/include/Nazara/Vulkan/VkInstance.inl index 8f0f6d2af..801691855 100644 --- a/include/Nazara/Vulkan/VkInstance.inl +++ b/include/Nazara/Vulkan/VkInstance.inl @@ -39,9 +39,9 @@ namespace Nz 0, &appInfo, static_cast(layers.size()), - &layers[0], + (!layers.empty()) ? layers.data() : nullptr, static_cast(extensions.size()), - &extensions[0] + (!extensions.empty()) ? extensions.data() : nullptr }; return Create(instanceInfo, allocator); @@ -69,12 +69,12 @@ namespace Nz inline bool Instance::IsExtensionLoaded(const String& extensionName) { - return m_loadedExtensions.count(extensionName) != 0; + return m_loadedExtensions.count(extensionName) > 0; } inline bool Instance::IsLayerLoaded(const String& layerName) { - return m_loadedLayers.count(layerName) != 0; + return m_loadedLayers.count(layerName) > 0; } inline Instance::operator VkInstance() From 0b725e1090fbf189de99c3542deccc75b3d58f69 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 11:42:24 +0200 Subject: [PATCH 051/224] Vulkan/Surface: Add implicit conversion to VkSurfaceKHR Former-commit-id: 83bd6ba118a3d5c3c2ea136b6cc0a0011d1d4c3d --- include/Nazara/Vulkan/VkSurface.hpp | 4 +++- include/Nazara/Vulkan/VkSurface.inl | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp index 57893b61e..84f8459a2 100644 --- a/include/Nazara/Vulkan/VkSurface.hpp +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -71,6 +71,8 @@ namespace Nz Surface& operator=(const Surface&) = delete; Surface& operator=(Surface&&) = delete; + inline operator VkSurfaceKHR(); + private: inline bool Create(const VkAllocationCallbacks* allocator); @@ -84,4 +86,4 @@ namespace Nz #include -#endif // Surface +#endif // NAZARA_VULKAN_VKSURFACE_HPP diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index 69c2f89d2..d045a1f06 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -202,6 +202,11 @@ namespace Nz return false; } + inline Surface::operator VkSurfaceKHR() + { + return m_surface; + } + inline bool Surface::Create(const VkAllocationCallbacks* allocator) { if (m_lastErrorCode != VkResult::VK_SUCCESS) From cc9d2c6ab2787586fe16b1aada516866075551e8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 11:43:35 +0200 Subject: [PATCH 052/224] Vulkan/Device: Add proper support for all device functions and extensions At least I hope that's all Former-commit-id: acf25110dc4598f0bb59737d09521570ca39e4ef --- include/Nazara/Vulkan/VkDevice.hpp | 113 +++++++++++++++++++++++++++ include/Nazara/Vulkan/VkDevice.inl | 10 +++ src/Nazara/Vulkan/VkDevice.cpp | 118 ++++++++++++++++++++++++++++- 3 files changed, 239 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 0df3ec68d..06247ab19 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace Nz { @@ -34,6 +35,9 @@ namespace Nz inline const Instance& GetInstance() const; inline VkResult GetLastErrorCode() const; + inline bool IsExtensionLoaded(const String& extensionName); + inline bool IsLayerLoaded(const String& layerName); + inline bool WaitForIdle(); Device& operator=(const Device&) = delete; @@ -45,9 +49,116 @@ namespace Nz #define NAZARA_VULKAN_DEVICE_FUNCTION(func) PFN_##func func // Vulkan core + NAZARA_VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers); + NAZARA_VULKAN_DEVICE_FUNCTION(vkAllocateMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkBindBufferMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkBindImageMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBeginQuery); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBeginRenderPass); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBindDescriptorSets); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBindIndexBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBindPipeline); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBindVertexBuffers); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdBlitImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdClearAttachments); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdClearDepthStencilImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdCopyBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdCopyBufferToImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdCopyImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdCopyImageToBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdCopyQueryPoolResults); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDispatch); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDispatchIndirect); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDraw); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDrawIndexed); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDrawIndexedIndirect); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdDrawIndirect); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdEndQuery); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdEndRenderPass); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdExecuteCommands); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdFillBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdNextSubpass); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdPushConstants); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdResetEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdResetQueryPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdResolveImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetBlendConstants); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetDepthBias); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetDepthBounds); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetLineWidth); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetScissor); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetStencilCompareMask); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetStencilReference); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetStencilWriteMask); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdSetViewport); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdUpdateBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdWaitEvents); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCmdWriteTimestamp); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateBufferView); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateCommandPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateComputePipelines); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateDescriptorSetLayout); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateFramebuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateGraphicsPipelines); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateImageView); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreatePipelineLayout); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateRenderPass); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateSampler); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateSemaphore); + NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateShaderModule); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyBufferView); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyDescriptorSetLayout); NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyDevice); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyFramebuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyImage); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyImageView); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyPipeline); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyPipelineLayout); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyRenderPass); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroySampler); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroySemaphore); + NAZARA_VULKAN_DEVICE_FUNCTION(vkDestroyShaderModule); NAZARA_VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle); + NAZARA_VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers); + NAZARA_VULKAN_DEVICE_FUNCTION(vkFreeDescriptorSets); + NAZARA_VULKAN_DEVICE_FUNCTION(vkFreeMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkFlushMappedMemoryRanges); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetBufferMemoryRequirements); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetDeviceMemoryCommitment); NAZARA_VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetEventStatus); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetFenceStatus); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetImageMemoryRequirements); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetImageSparseMemoryRequirements); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetImageSubresourceLayout); + NAZARA_VULKAN_DEVICE_FUNCTION(vkGetRenderAreaGranularity); + NAZARA_VULKAN_DEVICE_FUNCTION(vkInvalidateMappedMemoryRanges); + NAZARA_VULKAN_DEVICE_FUNCTION(vkMapMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkMergePipelineCaches); + NAZARA_VULKAN_DEVICE_FUNCTION(vkQueueSubmit); + NAZARA_VULKAN_DEVICE_FUNCTION(vkQueueWaitIdle); + NAZARA_VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer); + NAZARA_VULKAN_DEVICE_FUNCTION(vkResetCommandPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkResetDescriptorPool); + NAZARA_VULKAN_DEVICE_FUNCTION(vkResetFences); + NAZARA_VULKAN_DEVICE_FUNCTION(vkResetEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkSetEvent); + NAZARA_VULKAN_DEVICE_FUNCTION(vkUnmapMemory); + NAZARA_VULKAN_DEVICE_FUNCTION(vkUpdateDescriptorSets); + NAZARA_VULKAN_DEVICE_FUNCTION(vkWaitForFences); // VK_KHR_display_swapchain NAZARA_VULKAN_DEVICE_FUNCTION(vkCreateSharedSwapchainsKHR); @@ -75,6 +186,8 @@ namespace Nz VkAllocationCallbacks m_allocator; VkDevice m_device; VkResult m_lastErrorCode; + std::unordered_set m_loadedExtensions; + std::unordered_set m_loadedLayers; }; } } diff --git a/include/Nazara/Vulkan/VkDevice.inl b/include/Nazara/Vulkan/VkDevice.inl index 4eddb4abf..e837f67f6 100644 --- a/include/Nazara/Vulkan/VkDevice.inl +++ b/include/Nazara/Vulkan/VkDevice.inl @@ -51,6 +51,16 @@ namespace Nz return m_lastErrorCode; } + inline bool Device::IsExtensionLoaded(const String& extensionName) + { + return m_loadedExtensions.count(extensionName) > 0; + } + + inline bool Device::IsLayerLoaded(const String& layerName) + { + return m_loadedLayers.count(layerName) > 0; + } + inline bool Device::WaitForIdle() { m_lastErrorCode = vkDeviceWaitIdle(m_device); diff --git a/src/Nazara/Vulkan/VkDevice.cpp b/src/Nazara/Vulkan/VkDevice.cpp index 1c3eafa3c..c2f39da76 100644 --- a/src/Nazara/Vulkan/VkDevice.cpp +++ b/src/Nazara/Vulkan/VkDevice.cpp @@ -26,22 +26,136 @@ namespace Nz else m_allocator.pfnAllocation = nullptr; + // Parse extensions and layers + for (UInt32 i = 0; i < createInfo.enabledExtensionCount; ++i) + m_loadedExtensions.insert(createInfo.ppEnabledExtensionNames[i]); + + for (UInt32 i = 0; i < createInfo.enabledLayerCount; ++i) + m_loadedLayers.insert(createInfo.ppEnabledLayerNames[i]); + #define NAZARA_VULKAN_LOAD_DEVICE(func) func = reinterpret_cast(GetProcAddr(#func)) try { ErrorFlags flags(ErrorFlag_ThrowException, true); + NAZARA_VULKAN_LOAD_DEVICE(vkAllocateCommandBuffers); + NAZARA_VULKAN_LOAD_DEVICE(vkAllocateMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkBeginCommandBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkBindBufferMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkBindImageMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBeginQuery); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBeginRenderPass); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBindDescriptorSets); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBindIndexBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBindPipeline); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBindVertexBuffers); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdBlitImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdClearAttachments); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdClearColorImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdClearDepthStencilImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdCopyBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdCopyBufferToImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdCopyImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdCopyImageToBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdCopyQueryPoolResults); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDispatch); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDispatchIndirect); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDraw); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDrawIndexed); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDrawIndexedIndirect); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdDrawIndirect); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdEndQuery); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdEndRenderPass); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdExecuteCommands); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdFillBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdNextSubpass); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdPipelineBarrier); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdPushConstants); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdResetEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdResetQueryPool); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdResolveImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetBlendConstants); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetDepthBias); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetDepthBounds); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetLineWidth); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetScissor); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetStencilCompareMask); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetStencilReference); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetStencilWriteMask); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdSetViewport); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdUpdateBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdWaitEvents); + NAZARA_VULKAN_LOAD_DEVICE(vkCmdWriteTimestamp); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateBufferView); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateCommandPool); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateComputePipelines); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateDescriptorPool); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateDescriptorSetLayout); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateFramebuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateGraphicsPipelines); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateImage); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateImageView); + NAZARA_VULKAN_LOAD_DEVICE(vkCreatePipelineLayout); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateRenderPass); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateSampler); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateSemaphore); + NAZARA_VULKAN_LOAD_DEVICE(vkCreateShaderModule); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyBufferView); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyCommandPool); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyDescriptorPool); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyDescriptorSetLayout); NAZARA_VULKAN_LOAD_DEVICE(vkDestroyDevice); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyFramebuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyImage); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyImageView); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyPipeline); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyPipelineLayout); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyRenderPass); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroySampler); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroySemaphore); + NAZARA_VULKAN_LOAD_DEVICE(vkDestroyShaderModule); NAZARA_VULKAN_LOAD_DEVICE(vkDeviceWaitIdle); + NAZARA_VULKAN_LOAD_DEVICE(vkEndCommandBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkFreeCommandBuffers); + NAZARA_VULKAN_LOAD_DEVICE(vkFreeDescriptorSets); + NAZARA_VULKAN_LOAD_DEVICE(vkFreeMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkFlushMappedMemoryRanges); + NAZARA_VULKAN_LOAD_DEVICE(vkGetBufferMemoryRequirements); + NAZARA_VULKAN_LOAD_DEVICE(vkGetDeviceMemoryCommitment); NAZARA_VULKAN_LOAD_DEVICE(vkGetDeviceQueue); + NAZARA_VULKAN_LOAD_DEVICE(vkGetEventStatus); + NAZARA_VULKAN_LOAD_DEVICE(vkGetFenceStatus); + NAZARA_VULKAN_LOAD_DEVICE(vkGetImageMemoryRequirements); + NAZARA_VULKAN_LOAD_DEVICE(vkGetImageSparseMemoryRequirements); + NAZARA_VULKAN_LOAD_DEVICE(vkGetImageSubresourceLayout); + NAZARA_VULKAN_LOAD_DEVICE(vkGetRenderAreaGranularity); + NAZARA_VULKAN_LOAD_DEVICE(vkInvalidateMappedMemoryRanges); + NAZARA_VULKAN_LOAD_DEVICE(vkMapMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkMergePipelineCaches); + NAZARA_VULKAN_LOAD_DEVICE(vkQueueSubmit); + NAZARA_VULKAN_LOAD_DEVICE(vkQueueWaitIdle); + NAZARA_VULKAN_LOAD_DEVICE(vkResetCommandBuffer); + NAZARA_VULKAN_LOAD_DEVICE(vkResetCommandPool); + NAZARA_VULKAN_LOAD_DEVICE(vkResetDescriptorPool); + NAZARA_VULKAN_LOAD_DEVICE(vkResetFences); + NAZARA_VULKAN_LOAD_DEVICE(vkResetEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkSetEvent); + NAZARA_VULKAN_LOAD_DEVICE(vkUnmapMemory); + NAZARA_VULKAN_LOAD_DEVICE(vkUpdateDescriptorSets); + NAZARA_VULKAN_LOAD_DEVICE(vkWaitForFences); // VK_KHR_display_swapchain - if (m_instance.IsExtensionLoaded("VK_KHR_display_swapchain")) + if (IsExtensionLoaded("VK_KHR_display_swapchain")) NAZARA_VULKAN_LOAD_DEVICE(vkCreateSharedSwapchainsKHR); // VK_KHR_swapchain - if (m_instance.IsExtensionLoaded("VK_KHR_swapchain")) + if (IsExtensionLoaded("VK_KHR_swapchain")) { NAZARA_VULKAN_LOAD_DEVICE(vkAcquireNextImageKHR); NAZARA_VULKAN_LOAD_DEVICE(vkCreateSwapchainKHR); From d87b0587d7aadbdf1e2053571eab64820ca2763c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 11:43:48 +0200 Subject: [PATCH 053/224] Vulkan: Add support for Swapchains Former-commit-id: 7eafa8f4d38fb3202c63bc42d5d5bb4febfd459a --- include/Nazara/Vulkan/VkSwapchain.hpp | 52 +++++++++++++++++++++ include/Nazara/Vulkan/VkSwapchain.inl | 67 +++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 include/Nazara/Vulkan/VkSwapchain.hpp create mode 100644 include/Nazara/Vulkan/VkSwapchain.inl diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp new file mode 100644 index 000000000..a0f23f8ac --- /dev/null +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKSWAPCHAIN_HPP +#define NAZARA_VULKAN_VKSWAPCHAIN_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Device; + + class NAZARA_VULKAN_API Swapchain + { + public: + inline Swapchain(Device& instance); + Swapchain(const Swapchain&) = delete; + Swapchain(Swapchain&&) = delete; + inline ~Swapchain(); + + bool Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline void Destroy(); + + inline bool IsSupported() const; + + inline VkResult GetLastErrorCode() const; + + Swapchain& operator=(const Swapchain&) = delete; + Swapchain& operator=(Swapchain&&) = delete; + + inline operator VkSwapchainKHR(); + + private: + Device& m_device; + VkAllocationCallbacks m_allocator; + VkSwapchainKHR m_swapchain; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKSWAPCHAIN_HPP diff --git a/include/Nazara/Vulkan/VkSwapchain.inl b/include/Nazara/Vulkan/VkSwapchain.inl new file mode 100644 index 000000000..7ed08b902 --- /dev/null +++ b/include/Nazara/Vulkan/VkSwapchain.inl @@ -0,0 +1,67 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Swapchain::Swapchain(Device& device) : + m_device(device), + m_swapchain(VK_NULL_HANDLE) + { + } + + inline Swapchain::~Swapchain() + { + Destroy(); + } + + inline bool Swapchain::Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_device.vkCreateSwapchainKHR(m_device, &createInfo, allocator, &m_swapchain); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan swapchain"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } + + inline void Swapchain::Destroy() + { + if (m_swapchain != VK_NULL_HANDLE) + m_device.vkDestroySwapchainKHR(m_device, m_swapchain, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + inline VkResult Swapchain::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline bool Swapchain::IsSupported() const + { + if (!m_device.IsExtensionLoaded("VK_KHR_swapchain")) + return false; + } + + inline Swapchain::operator VkSwapchainKHR() + { + return m_swapchain; + } + } +} + +#include From 8a8731f330dc0428344832d22415bf9eea98c233 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Apr 2016 11:44:02 +0200 Subject: [PATCH 054/224] Vulkan: Add support for semaphores Former-commit-id: 429c5b61dd3a8c9666e2cf0d94f17d353e4e59f0 --- include/Nazara/Vulkan/VkSemaphore.hpp | 51 +++++++++++++++++++ include/Nazara/Vulkan/VkSemaphore.inl | 73 +++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 include/Nazara/Vulkan/VkSemaphore.hpp create mode 100644 include/Nazara/Vulkan/VkSemaphore.inl diff --git a/include/Nazara/Vulkan/VkSemaphore.hpp b/include/Nazara/Vulkan/VkSemaphore.hpp new file mode 100644 index 000000000..0cf871d5d --- /dev/null +++ b/include/Nazara/Vulkan/VkSemaphore.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKSEMAPHORE_HPP +#define NAZARA_VULKAN_VKSEMAPHORE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Device; + + class NAZARA_VULKAN_API Semaphore + { + public: + inline Semaphore(Device& instance); + Semaphore(const Semaphore&) = delete; + Semaphore(Semaphore&&) = delete; + inline ~Semaphore(); + + inline bool Create(const VkSemaphoreCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(VkSemaphoreCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr); + inline void Destroy(); + + inline VkResult GetLastErrorCode() const; + + Semaphore& operator=(const Semaphore&) = delete; + Semaphore& operator=(Semaphore&&) = delete; + + inline operator VkSemaphore(); + + private: + Device& m_device; + VkAllocationCallbacks m_allocator; + VkSemaphore m_semaphore; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKSEMAPHORE_HPP diff --git a/include/Nazara/Vulkan/VkSemaphore.inl b/include/Nazara/Vulkan/VkSemaphore.inl new file mode 100644 index 000000000..0fb61c426 --- /dev/null +++ b/include/Nazara/Vulkan/VkSemaphore.inl @@ -0,0 +1,73 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Semaphore::Semaphore(Device& device) : + m_device(device), + m_semaphore(VK_NULL_HANDLE) + { + } + + inline Semaphore::~Semaphore() + { + Destroy(); + } + + inline bool Semaphore::Create(const VkSemaphoreCreateInfo& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_device.vkCreateSemaphore(m_device, &createInfo, allocator, &m_semaphore); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan semaphore"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } + + inline bool Semaphore::Create(VkSemaphoreCreateFlags flags, const VkAllocationCallbacks* allocator) + { + VkSemaphoreCreateInfo createInfo = + { + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + nullptr, + flags + }; + + return Create(createInfo, allocator); + } + + inline void Semaphore::Destroy() + { + if (m_semaphore != VK_NULL_HANDLE) + m_device.vkDestroySemaphore(m_device, m_semaphore, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + inline VkResult Semaphore::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline Semaphore::operator VkSemaphore() + { + return m_semaphore; + } + } +} + +#include From 0b0f7f0755cfd0d41c3cc45e3e75d5f36a8fb27d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 6 May 2016 20:29:45 +0200 Subject: [PATCH 055/224] Vulkan/Device: Make Device a handled object Former-commit-id: 16a96932dfff6cea44cf57261543d3e452028f01 --- include/Nazara/Vulkan/VkDevice.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 06247ab19..084aaa2f0 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -8,6 +8,7 @@ #define NAZARA_VULKAN_VKDEVICE_HPP #include +#include #include #include #include @@ -17,9 +18,12 @@ namespace Nz { namespace Vk { + class Device; class Instance; - class NAZARA_VULKAN_API Device + using DeviceHandle = ObjectHandle; + + class NAZARA_VULKAN_API Device : public HandledObject { public: inline Device(Instance& instance); From a15b31c646fc02b2ad040c1d60ea185fa1df5805 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 12:47:43 +0200 Subject: [PATCH 056/224] Graphics/Material: Add Basic2D and Translucent2D materials Former-commit-id: fd07cb7c039d0e30b6fe74378efb3208808f9d9b --- src/Nazara/Graphics/Material.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index c646d940b..9a95c656b 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -911,12 +911,29 @@ namespace Nz 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; } From 206c0a9adc9a4926cd3195b0f475428c9c7442c1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 12:47:53 +0200 Subject: [PATCH 057/224] Core/Color: Add IsOpaque method Former-commit-id: b730460b9d81adbcee983648145cbc7a97301329 --- include/Nazara/Core/Color.hpp | 2 ++ include/Nazara/Core/Color.inl | 9 +++++++++ 2 files changed, 11 insertions(+) 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])" From 62746921089c2f883e8053a1a5b64dfd54b16673 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 May 2016 13:02:42 +0200 Subject: [PATCH 058/224] Sdk/CameraComponent: Clean include Former-commit-id: 3ff8192a4ae46441c7f3d5554c532f6a0bcc07da --- SDK/include/NDK/Components/CameraComponent.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 { From b37efa53bbec792ab108d3e8f5b8b639916f1147 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 May 2016 14:46:15 +0200 Subject: [PATCH 059/224] Vulkan: Use a generic class helper for all device objects This greatly reduce the amount of code required for wrappers around Vulkan Objects Former-commit-id: 86d366c594cf51cefdf656d04a87180183f5aaf5 --- include/Nazara/Vulkan/VkDeviceObject.hpp | 49 +++++++++++++++++ include/Nazara/Vulkan/VkDeviceObject.inl | 67 ++++++++++++++++++++++++ include/Nazara/Vulkan/VkSemaphore.hpp | 23 +++----- include/Nazara/Vulkan/VkSemaphore.inl | 42 ++------------- include/Nazara/Vulkan/VkSwapchain.hpp | 22 ++------ include/Nazara/Vulkan/VkSwapchain.inl | 42 +-------------- 6 files changed, 133 insertions(+), 112 deletions(-) create mode 100644 include/Nazara/Vulkan/VkDeviceObject.hpp create mode 100644 include/Nazara/Vulkan/VkDeviceObject.inl diff --git a/include/Nazara/Vulkan/VkDeviceObject.hpp b/include/Nazara/Vulkan/VkDeviceObject.hpp new file mode 100644 index 000000000..efad29c30 --- /dev/null +++ b/include/Nazara/Vulkan/VkDeviceObject.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKDEVICEOBJECT_HPP +#define NAZARA_VULKAN_VKDEVICEOBJECT_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + template + class DeviceObject + { + public: + inline DeviceObject(Device& instance); + DeviceObject(const DeviceObject&) = delete; + DeviceObject(DeviceObject&&) = delete; + inline ~DeviceObject(); + + inline bool Create(const CreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline void Destroy(); + + inline VkResult GetLastErrorCode() const; + + DeviceObject& operator=(const DeviceObject&) = delete; + DeviceObject& operator=(DeviceObject&&) = delete; + + inline operator VkType(); + + protected: + Device& m_device; + VkAllocationCallbacks m_allocator; + VkType m_handle; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKDEVICEOBJECT_HPP diff --git a/include/Nazara/Vulkan/VkDeviceObject.inl b/include/Nazara/Vulkan/VkDeviceObject.inl new file mode 100644 index 000000000..7aa313ca9 --- /dev/null +++ b/include/Nazara/Vulkan/VkDeviceObject.inl @@ -0,0 +1,67 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + template + inline DeviceObject::DeviceObject(Device& device) : + m_device(device), + m_handle(VK_NULL_HANDLE) + { + } + + template + inline DeviceObject::~DeviceObject() + { + Destroy(); + } + + template + inline bool DeviceObject::Create(const CreateInfo& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = C::CreateHelper(m_device, &createInfo, allocator, &m_handle); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan object"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } + + template + inline void DeviceObject::Destroy() + { + if (m_handle != VK_NULL_HANDLE) + C::DestroyHelper(m_device, m_handle, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + template + inline VkResult DeviceObject::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + template + inline DeviceObject::operator VkType() + { + return m_handle; + } + } +} + +#include diff --git a/include/Nazara/Vulkan/VkSemaphore.hpp b/include/Nazara/Vulkan/VkSemaphore.hpp index 0cf871d5d..b7983ee0b 100644 --- a/include/Nazara/Vulkan/VkSemaphore.hpp +++ b/include/Nazara/Vulkan/VkSemaphore.hpp @@ -9,39 +9,32 @@ #include #include -#include +#include #include namespace Nz { namespace Vk { - class Device; - - class NAZARA_VULKAN_API Semaphore + class Semaphore : public DeviceObject { + friend DeviceObject; + public: inline Semaphore(Device& instance); Semaphore(const Semaphore&) = delete; Semaphore(Semaphore&&) = delete; - inline ~Semaphore(); + ~Semaphore() = default; - inline bool Create(const VkSemaphoreCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + using DeviceObject::Create; inline bool Create(VkSemaphoreCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr); - inline void Destroy(); - - inline VkResult GetLastErrorCode() const; Semaphore& operator=(const Semaphore&) = delete; Semaphore& operator=(Semaphore&&) = delete; - inline operator VkSemaphore(); - private: - Device& m_device; - VkAllocationCallbacks m_allocator; - VkSemaphore m_semaphore; - VkResult m_lastErrorCode; + static VkResult CreateHelper(Device& device, const VkSemaphoreCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSemaphore* handle); + static void DestroyHelper(Device& device, VkSemaphore handle, const VkAllocationCallbacks* allocator); }; } } diff --git a/include/Nazara/Vulkan/VkSemaphore.inl b/include/Nazara/Vulkan/VkSemaphore.inl index 0fb61c426..fd2bf3427 100644 --- a/include/Nazara/Vulkan/VkSemaphore.inl +++ b/include/Nazara/Vulkan/VkSemaphore.inl @@ -3,8 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include namespace Nz @@ -12,34 +10,10 @@ namespace Nz namespace Vk { inline Semaphore::Semaphore(Device& device) : - m_device(device), - m_semaphore(VK_NULL_HANDLE) + DeviceObject(device) { } - inline Semaphore::~Semaphore() - { - Destroy(); - } - - inline bool Semaphore::Create(const VkSemaphoreCreateInfo& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_device.vkCreateSemaphore(m_device, &createInfo, allocator, &m_semaphore); - if (m_lastErrorCode != VkResult::VK_SUCCESS) - { - NazaraError("Failed to create Vulkan semaphore"); - return false; - } - - // Store the allocator to access them when needed - if (allocator) - m_allocator = *allocator; - else - m_allocator.pfnAllocation = nullptr; - - return true; - } - inline bool Semaphore::Create(VkSemaphoreCreateFlags flags, const VkAllocationCallbacks* allocator) { VkSemaphoreCreateInfo createInfo = @@ -52,20 +26,14 @@ namespace Nz return Create(createInfo, allocator); } - inline void Semaphore::Destroy() + VkResult Semaphore::CreateHelper(Device& device, const VkSemaphoreCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkSemaphore* handle) { - if (m_semaphore != VK_NULL_HANDLE) - m_device.vkDestroySemaphore(m_device, m_semaphore, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + return device.vkCreateSemaphore(device, createInfo, allocator, handle); } - inline VkResult Semaphore::GetLastErrorCode() const + void Semaphore::DestroyHelper(Device& device, VkSemaphore handle, const VkAllocationCallbacks* allocator) { - return m_lastErrorCode; - } - - inline Semaphore::operator VkSemaphore() - { - return m_semaphore; + return device.vkDestroySemaphore(device, handle, allocator); } } } diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp index a0f23f8ac..71ab1a853 100644 --- a/include/Nazara/Vulkan/VkSwapchain.hpp +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -9,40 +9,24 @@ #include #include -#include -#include +#include namespace Nz { namespace Vk { - class Device; - - class NAZARA_VULKAN_API Swapchain + class Swapchain : public DeviceObject { public: inline Swapchain(Device& instance); Swapchain(const Swapchain&) = delete; Swapchain(Swapchain&&) = delete; - inline ~Swapchain(); - - bool Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); - inline void Destroy(); + ~Swapchain() = default; inline bool IsSupported() const; - inline VkResult GetLastErrorCode() const; - Swapchain& operator=(const Swapchain&) = delete; Swapchain& operator=(Swapchain&&) = delete; - - inline operator VkSwapchainKHR(); - - private: - Device& m_device; - VkAllocationCallbacks m_allocator; - VkSwapchainKHR m_swapchain; - VkResult m_lastErrorCode; }; } } diff --git a/include/Nazara/Vulkan/VkSwapchain.inl b/include/Nazara/Vulkan/VkSwapchain.inl index 7ed08b902..8c05c0284 100644 --- a/include/Nazara/Vulkan/VkSwapchain.inl +++ b/include/Nazara/Vulkan/VkSwapchain.inl @@ -12,55 +12,15 @@ namespace Nz namespace Vk { inline Swapchain::Swapchain(Device& device) : - m_device(device), - m_swapchain(VK_NULL_HANDLE) + DeviceObject(device) { } - inline Swapchain::~Swapchain() - { - Destroy(); - } - - inline bool Swapchain::Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) - { - m_lastErrorCode = m_device.vkCreateSwapchainKHR(m_device, &createInfo, allocator, &m_swapchain); - if (m_lastErrorCode != VkResult::VK_SUCCESS) - { - NazaraError("Failed to create Vulkan swapchain"); - return false; - } - - // Store the allocator to access them when needed - if (allocator) - m_allocator = *allocator; - else - m_allocator.pfnAllocation = nullptr; - - return true; - } - - inline void Swapchain::Destroy() - { - if (m_swapchain != VK_NULL_HANDLE) - m_device.vkDestroySwapchainKHR(m_device, m_swapchain, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); - } - - inline VkResult Swapchain::GetLastErrorCode() const - { - return m_lastErrorCode; - } - inline bool Swapchain::IsSupported() const { if (!m_device.IsExtensionLoaded("VK_KHR_swapchain")) return false; } - - inline Swapchain::operator VkSwapchainKHR() - { - return m_swapchain; - } } } From cede56fa279f2c8fbac26bf669a2584c9459d4a8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 May 2016 15:28:29 +0200 Subject: [PATCH 060/224] Vulkan: Remove redundant headers Former-commit-id: b18cbc77440d9be8dfab700b09f8a01a8eb80f26 --- include/Nazara/Vulkan/VkDeviceObject.hpp | 1 - include/Nazara/Vulkan/VkSemaphore.hpp | 2 -- include/Nazara/Vulkan/VkSwapchain.hpp | 1 - 3 files changed, 4 deletions(-) diff --git a/include/Nazara/Vulkan/VkDeviceObject.hpp b/include/Nazara/Vulkan/VkDeviceObject.hpp index efad29c30..d84812a3d 100644 --- a/include/Nazara/Vulkan/VkDeviceObject.hpp +++ b/include/Nazara/Vulkan/VkDeviceObject.hpp @@ -8,7 +8,6 @@ #define NAZARA_VULKAN_VKDEVICEOBJECT_HPP #include -#include #include #include diff --git a/include/Nazara/Vulkan/VkSemaphore.hpp b/include/Nazara/Vulkan/VkSemaphore.hpp index b7983ee0b..e1df38bc2 100644 --- a/include/Nazara/Vulkan/VkSemaphore.hpp +++ b/include/Nazara/Vulkan/VkSemaphore.hpp @@ -8,9 +8,7 @@ #define NAZARA_VULKAN_VKSEMAPHORE_HPP #include -#include #include -#include namespace Nz { diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp index 71ab1a853..7feb6518f 100644 --- a/include/Nazara/Vulkan/VkSwapchain.hpp +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -8,7 +8,6 @@ #define NAZARA_VULKAN_VKSWAPCHAIN_HPP #include -#include #include namespace Nz From e1382845b44535d75fe08670cd5167f21ea0398a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 May 2016 15:41:26 +0200 Subject: [PATCH 061/224] Vulkan/Swapchain: Fix compilation Former-commit-id: 9ab7e69c0b9f61793d334410eb630487e08bcba6 --- include/Nazara/Vulkan/VkSwapchain.hpp | 6 ++++++ include/Nazara/Vulkan/VkSwapchain.inl | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp index 7feb6518f..dbef41394 100644 --- a/include/Nazara/Vulkan/VkSwapchain.hpp +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -16,6 +16,8 @@ namespace Nz { class Swapchain : public DeviceObject { + friend DeviceObject; + public: inline Swapchain(Device& instance); Swapchain(const Swapchain&) = delete; @@ -26,6 +28,10 @@ namespace Nz Swapchain& operator=(const Swapchain&) = delete; Swapchain& operator=(Swapchain&&) = delete; + + private: + static VkResult CreateHelper(Device& device, const VkSwapchainCreateInfoKHR* createInfo, const VkAllocationCallbacks* allocator, VkSwapchainKHR* handle); + static void DestroyHelper(Device& device, VkSwapchainKHR handle, const VkAllocationCallbacks* allocator); }; } } diff --git a/include/Nazara/Vulkan/VkSwapchain.inl b/include/Nazara/Vulkan/VkSwapchain.inl index 8c05c0284..e05dfefd3 100644 --- a/include/Nazara/Vulkan/VkSwapchain.inl +++ b/include/Nazara/Vulkan/VkSwapchain.inl @@ -21,6 +21,16 @@ namespace Nz if (!m_device.IsExtensionLoaded("VK_KHR_swapchain")) return false; } + + VkResult Swapchain::CreateHelper(Device& device, const VkSwapchainCreateInfoKHR* createInfo, const VkAllocationCallbacks* allocator, VkSwapchainKHR* handle) + { + return device.vkCreateSwapchainKHR(device, createInfo, allocator, handle); + } + + void Swapchain::DestroyHelper(Device& device, VkSwapchainKHR handle, const VkAllocationCallbacks* allocator) + { + return device.vkDestroySwapchainKHR(device, handle, allocator); + } } } From e5528abb0fa151d3197abebc0bde39d76651776e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 May 2016 21:28:59 +0200 Subject: [PATCH 062/224] Vulkan: Allow Device Objects to be move-constructed Former-commit-id: 3f0d936867d1830478c5a23c3076f532ea26dc94 --- include/Nazara/Vulkan/VkDeviceObject.hpp | 2 +- include/Nazara/Vulkan/VkDeviceObject.inl | 10 ++++++++++ include/Nazara/Vulkan/VkSemaphore.hpp | 2 +- include/Nazara/Vulkan/VkSurface.hpp | 2 +- include/Nazara/Vulkan/VkSurface.inl | 9 +++++++++ include/Nazara/Vulkan/VkSwapchain.hpp | 2 +- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Vulkan/VkDeviceObject.hpp b/include/Nazara/Vulkan/VkDeviceObject.hpp index d84812a3d..999762098 100644 --- a/include/Nazara/Vulkan/VkDeviceObject.hpp +++ b/include/Nazara/Vulkan/VkDeviceObject.hpp @@ -21,7 +21,7 @@ namespace Nz public: inline DeviceObject(Device& instance); DeviceObject(const DeviceObject&) = delete; - DeviceObject(DeviceObject&&) = delete; + DeviceObject(DeviceObject&&); inline ~DeviceObject(); inline bool Create(const CreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); diff --git a/include/Nazara/Vulkan/VkDeviceObject.inl b/include/Nazara/Vulkan/VkDeviceObject.inl index 7aa313ca9..58645983e 100644 --- a/include/Nazara/Vulkan/VkDeviceObject.inl +++ b/include/Nazara/Vulkan/VkDeviceObject.inl @@ -18,6 +18,16 @@ namespace Nz { } + template + inline DeviceObject::DeviceObject(DeviceObject&& object) : + m_device(object.m_device), + m_allocator(object.m_allocator), + m_handle(object.m_handle), + m_lastErrorCode(object.m_lastErrorCode) + { + object.m_handle = VK_NULL_HANDLE; + } + template inline DeviceObject::~DeviceObject() { diff --git a/include/Nazara/Vulkan/VkSemaphore.hpp b/include/Nazara/Vulkan/VkSemaphore.hpp index e1df38bc2..138d726be 100644 --- a/include/Nazara/Vulkan/VkSemaphore.hpp +++ b/include/Nazara/Vulkan/VkSemaphore.hpp @@ -21,7 +21,7 @@ namespace Nz public: inline Semaphore(Device& instance); Semaphore(const Semaphore&) = delete; - Semaphore(Semaphore&&) = delete; + Semaphore(Semaphore&&) = default; ~Semaphore() = default; using DeviceObject::Create; diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp index 84f8459a2..a27f3d357 100644 --- a/include/Nazara/Vulkan/VkSurface.hpp +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -23,7 +23,7 @@ namespace Nz public: inline Surface(Instance& instance); Surface(const Surface&) = delete; - Surface(Surface&&) = delete; + Surface(Surface&& surface); inline ~Surface(); #ifdef VK_USE_PLATFORM_ANDROID_KHR diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index d045a1f06..e7b0efe64 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -17,6 +17,15 @@ namespace Nz { } + inline Surface::Surface(Surface&& surface) : + m_instance(surface.m_instance), + m_allocator(surface.m_allocator), + m_surface(surface.m_surface), + m_lastErrorCode(surface.m_lastErrorCode) + { + surface.m_surface = VK_NULL_HANDLE; + } + inline Surface::~Surface() { Destroy(); diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp index dbef41394..ea47970d5 100644 --- a/include/Nazara/Vulkan/VkSwapchain.hpp +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -21,7 +21,7 @@ namespace Nz public: inline Swapchain(Device& instance); Swapchain(const Swapchain&) = delete; - Swapchain(Swapchain&&) = delete; + Swapchain(Swapchain&&) = default; ~Swapchain() = default; inline bool IsSupported() const; From bb945d773e5d45a6ecadce6af3a0346de5561429 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 May 2016 00:08:05 +0200 Subject: [PATCH 063/224] Vulkan: Add support for CommandPool and CommandBuffer Former-commit-id: 0ed1e8d09300577be3d4c52b94d6a8f594178a8b --- include/Nazara/Vulkan/VkCommandBuffer.hpp | 50 +++++++++++++++++++++ include/Nazara/Vulkan/VkCommandBuffer.inl | 51 ++++++++++++++++++++++ include/Nazara/Vulkan/VkCommandPool.hpp | 53 +++++++++++++++++++++++ include/Nazara/Vulkan/VkCommandPool.inl | 53 +++++++++++++++++++++++ include/Nazara/Vulkan/VkDeviceObject.hpp | 2 + include/Nazara/Vulkan/VkDeviceObject.inl | 12 +++++ include/Nazara/Vulkan/VkSurface.hpp | 2 +- src/Nazara/Vulkan/VkCommandPool.cpp | 53 +++++++++++++++++++++++ 8 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 include/Nazara/Vulkan/VkCommandBuffer.hpp create mode 100644 include/Nazara/Vulkan/VkCommandBuffer.inl create mode 100644 include/Nazara/Vulkan/VkCommandPool.hpp create mode 100644 include/Nazara/Vulkan/VkCommandPool.inl create mode 100644 src/Nazara/Vulkan/VkCommandPool.cpp diff --git a/include/Nazara/Vulkan/VkCommandBuffer.hpp b/include/Nazara/Vulkan/VkCommandBuffer.hpp new file mode 100644 index 000000000..0399d4cf7 --- /dev/null +++ b/include/Nazara/Vulkan/VkCommandBuffer.hpp @@ -0,0 +1,50 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKCOMMANDBUFFER_HPP +#define NAZARA_VULKAN_VKCOMMANDBUFFER_HPP + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class NAZARA_VULKAN_API CommandBuffer + { + friend CommandPool; + + public: + CommandBuffer(const CommandBuffer&) = delete; + CommandBuffer(CommandBuffer&& commandBuffer); + inline ~CommandBuffer(); + + inline void Free(); + + inline VkResult GetLastErrorCode() const; + + CommandBuffer& operator=(const CommandBuffer&) = delete; + CommandBuffer& operator=(CommandBuffer&&) = delete; + + inline operator VkCommandBuffer(); + + private: + inline CommandBuffer(CommandPool& pool, VkCommandBuffer handle); + + CommandPoolHandle m_pool; + VkAllocationCallbacks m_allocator; + VkCommandBuffer m_handle; + VkResult m_lastErrorCode; + + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKCOMMANDBUFFER_HPP diff --git a/include/Nazara/Vulkan/VkCommandBuffer.inl b/include/Nazara/Vulkan/VkCommandBuffer.inl new file mode 100644 index 000000000..ff4eaede4 --- /dev/null +++ b/include/Nazara/Vulkan/VkCommandBuffer.inl @@ -0,0 +1,51 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline CommandBuffer::CommandBuffer(CommandPool& pool, VkCommandBuffer handle) : + m_pool(&pool), + m_handle(handle) + { + } + + inline CommandBuffer::CommandBuffer(CommandBuffer&& commandBuffer) : + m_pool(std::move(commandBuffer.m_pool)), + m_allocator(commandBuffer.m_allocator), + m_handle(commandBuffer.m_handle), + m_lastErrorCode(commandBuffer.m_lastErrorCode) + { + commandBuffer.m_handle = VK_NULL_HANDLE; + } + + inline CommandBuffer::~CommandBuffer() + { + Free(); + } + + inline void CommandBuffer::Free() + { + m_pool->GetDevice().vkFreeCommandBuffers(m_pool->GetDevice(), *m_pool, 1, &m_handle); + } + + inline VkResult CommandBuffer::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline CommandBuffer::operator VkCommandBuffer() + { + return m_handle; + } + } +} + +#include diff --git a/include/Nazara/Vulkan/VkCommandPool.hpp b/include/Nazara/Vulkan/VkCommandPool.hpp new file mode 100644 index 000000000..8b99513e3 --- /dev/null +++ b/include/Nazara/Vulkan/VkCommandPool.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKCOMMANDPOOL_HPP +#define NAZARA_VULKAN_VKCOMMANDPOOL_HPP + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class CommandBuffer; + class CommandPool; + + using CommandPoolHandle = ObjectHandle; + + class CommandPool : public DeviceObject, public HandledObject + { + friend DeviceObject; + + public: + inline CommandPool(Device& instance); + CommandPool(const CommandPool&) = delete; + CommandPool(CommandPool&&) = default; + ~CommandPool() = default; + + CommandBuffer AllocateCommandBuffer(VkCommandBufferLevel level); + std::vector AllocateCommandBuffers(UInt32 commandBufferCount, VkCommandBufferLevel level); + + using DeviceObject::Create; + inline bool Create(UInt32 queueFamilyIndex, VkCommandPoolCreateFlags flags = 0, const VkAllocationCallbacks* allocator = nullptr); + + inline bool Reset(VkCommandPoolResetFlags flags); + + CommandPool& operator=(const CommandPool&) = delete; + CommandPool& operator=(CommandPool&&) = delete; + + private: + static VkResult CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle); + static void DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator); + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKCOMMANDPOOL_HPP diff --git a/include/Nazara/Vulkan/VkCommandPool.inl b/include/Nazara/Vulkan/VkCommandPool.inl new file mode 100644 index 000000000..f7aef6978 --- /dev/null +++ b/include/Nazara/Vulkan/VkCommandPool.inl @@ -0,0 +1,53 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline CommandPool::CommandPool(Device& device) : + DeviceObject(device) + { + } + + inline bool CommandPool::Create(UInt32 queueFamilyIndex, VkCommandPoolCreateFlags flags, const VkAllocationCallbacks* allocator) + { + VkCommandPoolCreateInfo createInfo = + { + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + nullptr, + flags, + queueFamilyIndex + }; + + return Create(createInfo, allocator); + } + + inline bool CommandPool::Reset(VkCommandPoolResetFlags flags) + { + m_lastErrorCode = m_device.vkResetCommandPool(m_device, m_handle, flags); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + return false; + + return true; + } + + VkResult CommandPool::CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle) + { + return device.vkCreateCommandPool(device, createInfo, allocator, handle); + } + + void CommandPool::DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator) + { + return device.vkDestroyCommandPool(device, handle, allocator); + } + } +} + +#include diff --git a/include/Nazara/Vulkan/VkDeviceObject.hpp b/include/Nazara/Vulkan/VkDeviceObject.hpp index 999762098..dd9da38c9 100644 --- a/include/Nazara/Vulkan/VkDeviceObject.hpp +++ b/include/Nazara/Vulkan/VkDeviceObject.hpp @@ -27,6 +27,8 @@ namespace Nz inline bool Create(const CreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline void Destroy(); + inline Device& GetDevice(); + inline const Device& GetDevice() const; inline VkResult GetLastErrorCode() const; DeviceObject& operator=(const DeviceObject&) = delete; diff --git a/include/Nazara/Vulkan/VkDeviceObject.inl b/include/Nazara/Vulkan/VkDeviceObject.inl index 58645983e..a3136156c 100644 --- a/include/Nazara/Vulkan/VkDeviceObject.inl +++ b/include/Nazara/Vulkan/VkDeviceObject.inl @@ -60,6 +60,18 @@ namespace Nz C::DestroyHelper(m_device, m_handle, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); } + template + inline Device& DeviceObject::GetDevice() + { + return m_device; + } + + template + inline const Device& DeviceObject::GetDevice() const + { + return m_device; + } + template inline VkResult DeviceObject::GetLastErrorCode() const { diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp index a27f3d357..7b7fbcdfd 100644 --- a/include/Nazara/Vulkan/VkSurface.hpp +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -18,7 +18,7 @@ namespace Nz { class Instance; - class NAZARA_VULKAN_API Surface + class Surface { public: inline Surface(Instance& instance); diff --git a/src/Nazara/Vulkan/VkCommandPool.cpp b/src/Nazara/Vulkan/VkCommandPool.cpp new file mode 100644 index 000000000..3ee53ab6f --- /dev/null +++ b/src/Nazara/Vulkan/VkCommandPool.cpp @@ -0,0 +1,53 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + CommandBuffer CommandPool::AllocateCommandBuffer(VkCommandBufferLevel level) + { + VkCommandBufferAllocateInfo createInfo = + { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + nullptr, + m_handle, + level, + 1U + }; + + VkCommandBuffer handle = VK_NULL_HANDLE; + m_lastErrorCode = m_device.vkAllocateCommandBuffers(m_device, &createInfo, &handle); + + return CommandBuffer(*this, handle); + } + + std::vector CommandPool::AllocateCommandBuffers(UInt32 commandBufferCount, VkCommandBufferLevel level) + { + VkCommandBufferAllocateInfo createInfo = + { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + nullptr, + m_handle, + level, + 1U + }; + + std::vector handles(commandBufferCount, VK_NULL_HANDLE); + m_lastErrorCode = m_device.vkAllocateCommandBuffers(m_device, &createInfo, handles.data()); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + return std::vector(); + + std::vector commandBuffers; + for (UInt32 i = 0; i < commandBufferCount; ++i) + commandBuffers.emplace_back(CommandBuffer(*this, handles[i])); + + return commandBuffers; + } + } +} From f35c5182566227e772afd4564cbbead75dfe01b5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 May 2016 00:11:26 +0200 Subject: [PATCH 064/224] Vulkan: Update global header Former-commit-id: b4d773fa8c9d703dc5dc928ff218589366b06642 --- include/Nazara/Vulkan.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Vulkan.hpp b/include/Nazara/Vulkan.hpp index a935674e9..a3e363272 100644 --- a/include/Nazara/Vulkan.hpp +++ b/include/Nazara/Vulkan.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 24 Apr 2016 at 02:26:55 +// This file was automatically generated on 15 May 2016 at 00:11:13 /* Nazara Engine - Vulkan @@ -30,9 +30,15 @@ #define NAZARA_GLOBAL_VULKAN_HPP #include +#include +#include #include +#include #include #include +#include +#include +#include #include #endif // NAZARA_GLOBAL_VULKAN_HPP From 59b9e96f21d63d7cebd5db73cdd92c0813b490b4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 15 May 2016 00:38:19 +0200 Subject: [PATCH 065/224] Build: Make every lib copy its binaries (and dependency bins) to the example/bin folder Former-commit-id: 6f966190fd910968615553f4c9250d2f14a5c726 --- build/scripts/common.lua | 25 ++++++++++++++++++++++++- build/scripts/modules/audio.lua | 4 ++++ build/scripts/tools/ndk.lua | 2 ++ build/scripts/tools/ndk_server.lua | 2 ++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 405b66b60..a0957966d 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -188,6 +188,29 @@ function NazaraBuild:Execute() libdirs("../lib/" .. makeLibDir .. "/x64") targetdir("../lib/" .. makeLibDir .. "/x64") + -- Copy the module binaries to the example folder + if (os.is("windows")) then + configuration({}) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) + + for k,v in pairs(table.join(moduleTable.Libraries, moduleTable.DynLib)) do + local paths = {} + table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) + table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) + table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) + table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) + + for k,v in pairs(paths) do + local config = v[1] + local path = v[2] + if (os.isfile(path)) then + configuration(config) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. path .. [[")}" "..\..\..\examples\bin\" /E /Y]]}) + end + end + end + end + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") @@ -851,7 +874,7 @@ function NazaraBuild:SetupInfoTable(infoTable) infoTable.ConfigurationLibraries.DebugDynamic = {} infoTable.ConfigurationLibraries.ReleaseDynamic = {} - local infos = {"Defines", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"} + local infos = {"Defines", "DynLib", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"} for k,v in ipairs(infos) do infoTable[v] = {} infoTable["Os" .. v] = {} diff --git a/build/scripts/modules/audio.lua b/build/scripts/modules/audio.lua index f03e493a9..4fcb1bf5a 100644 --- a/build/scripts/modules/audio.lua +++ b/build/scripts/modules/audio.lua @@ -14,6 +14,10 @@ MODULE.OsFiles.Windows = { "../src/Nazara/Audio/Win32/**.cpp" } +MODULE.OsDynLib.Windows = { + "soft_oal" +} + MODULE.OsFiles.Posix = { "../src/Nazara/Audio/Posix/**.hpp", "../src/Nazara/Audio/Posix/**.cpp" diff --git a/build/scripts/tools/ndk.lua b/build/scripts/tools/ndk.lua index 78ff544de..5a1084f48 100644 --- a/build/scripts/tools/ndk.lua +++ b/build/scripts/tools/ndk.lua @@ -1,5 +1,7 @@ TOOL.Name = "SDK" +TOOL.CopyTargetToExampleDir = true + TOOL.Directory = "../SDK/lib" TOOL.Kind = "Library" diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index c9c443e57..978d620be 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -1,5 +1,7 @@ TOOL.Name = "SDKServer" +TOOL.CopyTargetToExampleDir = true + TOOL.Directory = "../SDK/lib" TOOL.Kind = "Library" From 4ecc701ad207c2ed87f69cc92715173aa7a44df4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 16 May 2016 20:02:59 +0200 Subject: [PATCH 066/224] Build: Copy all dependency modules to the example directory Former-commit-id: e6c2cb47433d84c17e7277125180469f2b3f0d37 --- build/scripts/common.lua | 53 +++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index a0957966d..ec95c2641 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -190,25 +190,7 @@ function NazaraBuild:Execute() -- Copy the module binaries to the example folder if (os.is("windows")) then - configuration({}) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) - - for k,v in pairs(table.join(moduleTable.Libraries, moduleTable.DynLib)) do - local paths = {} - table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) - table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) - table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) - table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) - - for k,v in pairs(paths) do - local config = v[1] - local path = v[2] - if (os.isfile(path)) then - configuration(config) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. path .. [[")}" "..\..\..\examples\bin\" /E /Y]]}) - end - end - end + self:MakeCopyAfterBuild(moduleTable) end configuration({"vs*", "x32"}) @@ -323,10 +305,7 @@ function NazaraBuild:Execute() -- 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 + self:MakeCopyAfterBuild(toolTable) end configuration({"vs*", "x32"}) @@ -867,6 +846,34 @@ function NazaraBuild:Process(infoTable) end end +function NazaraBuild:MakeCopyAfterBuild(infoTable) + if (os.is("windows")) then + configuration({}) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) + + for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do + local paths = {} + table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) + table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) + table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) + table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) + + for k,v in pairs(paths) do + local config = v[1] + local path = v[2] + if (os.isfile(path)) then + if (infoTable.Kind == "plugin") then + path = "../../" .. path + end + + configuration(config) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. path .. [[")}" "..\..\..\examples\bin\" /E /Y]]}) + end + end + end + end +end + function NazaraBuild:SetupInfoTable(infoTable) infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries.DebugStatic = {} From 8a38bb767d7d134dbdb8103f95286d0c0dfc96bf Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 14:23:45 +0200 Subject: [PATCH 067/224] Utility: Rework PixelFormat (WIP) Former-commit-id: bb48562e5f5caac023fcfca7840931aaae7a7821 --- include/Nazara/Utility/Enums.hpp | 34 +- include/Nazara/Utility/PixelFormat.hpp | 64 +-- include/Nazara/Utility/PixelFormat.inl | 642 ++++++----------------- src/Nazara/Renderer/RenderBuffer.cpp | 2 +- src/Nazara/Renderer/RenderTexture.cpp | 27 +- src/Nazara/Renderer/Texture.cpp | 6 +- src/Nazara/Utility/Formats/DDSLoader.cpp | 2 +- src/Nazara/Utility/Image.cpp | 8 +- src/Nazara/Utility/PixelFormat.cpp | 82 ++- 9 files changed, 306 insertions(+), 561 deletions(-) diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 143390906..3f32945c2 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -142,6 +142,17 @@ namespace Nz NodeType_Max = NodeType_Skeletal }; + enum PixelFormatContent + { + PixelFormatContent_Undefined = -1, + + PixelFormatContent_ColorRGBA, + PixelFormatContent_DepthStencil, + PixelFormatContent_Stencil, + + PixelFormatContent_Max = PixelFormatContent_Stencil + }; + enum PixelFormatType { PixelFormatType_Undefined = -1, @@ -204,27 +215,16 @@ namespace Nz enum PixelFormatSubType { - PixelFormatSubType_Double, // F64 - PixelFormatSubType_Float, // F32 - PixelFormatSubType_Half, // F16 - PixelFormatSubType_Int, // I32 - PixelFormatSubType_Unsigned, // U32 + PixelFormatSubType_Compressed, // Opaque + PixelFormatSubType_Double, // F64 + PixelFormatSubType_Float, // F32 + PixelFormatSubType_Half, // F16 + PixelFormatSubType_Int, // Signed integer + PixelFormatSubType_Unsigned, // Unsigned integer PixelFormatSubType_Max = PixelFormatSubType_Unsigned }; - enum PixelFormatTypeType - { - PixelFormatTypeType_Undefined = -1, - - PixelFormatTypeType_Color, - PixelFormatTypeType_Depth, - PixelFormatTypeType_DepthStencil, - PixelFormatTypeType_Stencil, - - PixelFormatTypeType_Max = PixelFormatTypeType_Stencil - }; - enum PixelFlipping { PixelFlipping_Horizontally, diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index 6844162d5..92eecb7f4 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -23,33 +23,36 @@ namespace Nz { struct PixelFormatInfo { - PixelFormatInfo() : - bitsPerPixel(0) - { - } + inline PixelFormatInfo(); + inline PixelFormatInfo(PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType); + inline PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType); + inline PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, Bitset<> rMask, Bitset<> gMask, Bitset<> bMask, Bitset<> aMask, PixelFormatSubType subType); + inline PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, PixelFormatSubType rType, Bitset<> rMask, PixelFormatSubType gType, Bitset<> gMask, PixelFormatSubType bType, Bitset<> bMask, PixelFormatSubType aType, Bitset<> aMask, UInt8 bpp = 0); - PixelFormatInfo(UInt8 bpp, PixelFormatSubType subType) : - bitsPerPixel(bpp), - redType(subType), - greenType(subType), - blueType(subType), - alphaType(subType) - { - } + inline void Clear(); - // Warning: Bit Endian + inline bool IsCompressed() const; + inline bool IsValid() const; + + inline void RecomputeBitsPerPixel(); + + inline bool Validate() const; + + // Warning: Masks bit order is reversed Bitset<> redMask; Bitset<> greenMask; Bitset<> blueMask; Bitset<> alphaMask; + PixelFormatContent content; PixelFormatSubType redType; PixelFormatSubType greenType; PixelFormatSubType blueType; PixelFormatSubType alphaType; + String name; UInt8 bitsPerPixel; }; - class PixelFormat + class NAZARA_UTILITY_API PixelFormat { friend class Utility; @@ -59,34 +62,35 @@ namespace Nz static inline std::size_t ComputeSize(PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth); - static bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst); - static bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst); + static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst); + static inline bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst); - static bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); + static inline bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); - static UInt8 GetBitsPerPixel(PixelFormatType format); - static UInt8 GetBytesPerPixel(PixelFormatType format); - static PixelFormatTypeType GetType(PixelFormatType format); + static inline UInt8 GetBitsPerPixel(PixelFormatType format); + static inline PixelFormatContent GetContent(PixelFormatType format); + static inline UInt8 GetBytesPerPixel(PixelFormatType format); + static inline const PixelFormatInfo& GetInfo(PixelFormatType format); + static inline const String& GetName(PixelFormatType format); - static bool HasAlpha(PixelFormatType format); + static inline bool HasAlpha(PixelFormatType format); static PixelFormatType IdentifyFormat(const PixelFormatInfo& info); - static bool IsCompressed(PixelFormatType format); - static bool IsConversionSupported(PixelFormatType srcFormat, PixelFormatType dstFormat); - static bool IsValid(PixelFormatType format); + static inline bool IsCompressed(PixelFormatType format); + static inline bool IsConversionSupported(PixelFormatType srcFormat, PixelFormatType dstFormat); + static inline bool IsValid(PixelFormatType format); - static void SetConvertFunction(PixelFormatType srcFormat, PixelFormatType dstFormat, ConvertFunction func); - static void SetFlipFunction(PixelFlipping flipping, PixelFormatType format, FlipFunction func); - - static String ToString(PixelFormatType format); + static inline void SetConvertFunction(PixelFormatType srcFormat, PixelFormatType dstFormat, ConvertFunction func); + static inline void SetFlipFunction(PixelFlipping flipping, PixelFormatType format, FlipFunction func); private: static bool Initialize(); static void Uninitialize(); - static NAZARA_UTILITY_API ConvertFunction s_convertFunctions[PixelFormatType_Max+1][PixelFormatType_Max+1]; - static NAZARA_UTILITY_API std::map s_flipFunctions[PixelFlipping_Max+1]; + static PixelFormatInfo s_pixelFormatInfos[PixelFormatType_Max + 1]; + static ConvertFunction s_convertFunctions[PixelFormatType_Max+1][PixelFormatType_Max+1]; + static std::map s_flipFunctions[PixelFlipping_Max+1]; }; } diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 2d09273b9..7b05ec8fb 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -2,13 +2,151 @@ // 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 namespace Nz { + inline PixelFormatInfo::PixelFormatInfo() : + bitsPerPixel(0), + content(PixelFormatContent_Undefined) + { + } + + inline PixelFormatInfo::PixelFormatInfo(PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType) : + bitsPerPixel(bpp), + content(formatContent), + redType(subType), + greenType(subType), + blueType(subType), + alphaType(subType) + { + } + + inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType) : + bitsPerPixel(bpp), + content(formatContent), + redType(subType), + greenType(subType), + blueType(subType), + alphaType(subType), + name(formatName) + { + } + + inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, Bitset<> rMask, Bitset<> gMask, Bitset<> bMask, Bitset<> aMask, PixelFormatSubType subType) : + redMask(rMask), + greenMask(gMask), + blueMask(bMask), + alphaMask(aMask), + content(formatContent), + redType(subType), + greenType(subType), + blueType(subType), + alphaType(subType), + name(formatName) + { + RecomputeBitsPerPixel(); + } + + inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, PixelFormatSubType rType, Bitset<> rMask, PixelFormatSubType gType, Bitset<> gMask, PixelFormatSubType bType, Bitset<> bMask, PixelFormatSubType aType, Bitset<> aMask, UInt8 bpp) : + redMask(rMask), + greenMask(gMask), + blueMask(bMask), + alphaMask(aMask), + content(formatContent), + redType(rType), + greenType(gType), + blueType(bType), + alphaType(aType), + name(formatName) + { + if (bpp == 0) + RecomputeBitsPerPixel(); + } + + inline void PixelFormatInfo::Clear() + { + bitsPerPixel = 0; + alphaMask.Clear(); + blueMask.Clear(); + greenMask.Clear(); + redMask.Clear(); + name.Clear(); + } + + inline bool PixelFormatInfo::IsCompressed() const + { + return redType == PixelFormatSubType_Compressed || + greenType == PixelFormatSubType_Compressed || + blueType == PixelFormatSubType_Compressed || + alphaType == PixelFormatSubType_Compressed; + } + + inline bool PixelFormatInfo::IsValid() const + { + return bitsPerPixel != 0; + } + + inline void PixelFormatInfo::RecomputeBitsPerPixel() + { + Bitset<> counter; + counter |= redMask; + counter |= greenMask; + counter |= blueMask; + counter |= alphaMask; + + bitsPerPixel = counter.Count(); + } + + inline bool PixelFormatInfo::Validate() const + { + if (!IsValid()) + return false; + + if (content <= PixelFormatContent_Undefined || content > PixelFormatContent_Max) + return false; + + std::array*, 4> masks = {&redMask, &greenMask, &blueMask, &alphaMask}; + std::array types = {redType, greenType, blueType, alphaType}; + + for (unsigned int i = 0; i < 4; ++i) + { + unsigned int usedBits = masks[i]->Count(); + if (usedBits == 0) + continue; + + if (usedBits > bitsPerPixel) + return false; + + switch (types[i]) + { + case PixelFormatSubType_Half: + if (usedBits != 16) + return false; + + break; + + case PixelFormatSubType_Float: + if (usedBits != 32) + return false; + + break; + + default: + break; + } + } + + return true; + } + + + inline std::size_t PixelFormat::ComputeSize(PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth) { if (IsCompressed(format)) @@ -54,13 +192,13 @@ namespace Nz ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; if (!func) { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); + NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " is not supported"); return false; } if (!func(reinterpret_cast(src), reinterpret_cast(src) + GetBytesPerPixel(srcFormat), reinterpret_cast(dst))) { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); + NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " failed"); return false; } @@ -78,13 +216,13 @@ namespace Nz ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; if (!func) { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); + NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " is not supported"); return false; } if (!func(reinterpret_cast(start), reinterpret_cast(end), reinterpret_cast(dst))) { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); + NazaraError("Pixel format conversion from " + GetName(srcFormat) + " to " + GetName(dstFormat) + " failed"); return false; } @@ -189,126 +327,7 @@ namespace Nz inline UInt8 PixelFormat::GetBitsPerPixel(PixelFormatType format) { - switch (format) - { - case PixelFormatType_A8: - return 8; - - case PixelFormatType_BGR8: - return 24; - - case PixelFormatType_BGRA8: - return 32; - - case PixelFormatType_DXT1: - return 8; - - case PixelFormatType_DXT3: - return 16; - - case PixelFormatType_DXT5: - return 16; - - case PixelFormatType_L8: - return 8; - - case PixelFormatType_LA8: - return 16; - - case PixelFormatType_R8: - case PixelFormatType_R8I: - case PixelFormatType_R8UI: - return 8; - - case PixelFormatType_R16: - case PixelFormatType_R16F: - case PixelFormatType_R16I: - case PixelFormatType_R16UI: - return 16; - - case PixelFormatType_R32F: - case PixelFormatType_R32I: - case PixelFormatType_R32UI: - return 32; - - case PixelFormatType_RG8: - case PixelFormatType_RG8I: - case PixelFormatType_RG8UI: - return 16; - - case PixelFormatType_RG16: - case PixelFormatType_RG16F: - case PixelFormatType_RG16I: - case PixelFormatType_RG16UI: - return 32; - - case PixelFormatType_RG32F: - case PixelFormatType_RG32I: - case PixelFormatType_RG32UI: - return 64; - - case PixelFormatType_RGB16F: - case PixelFormatType_RGB16I: - case PixelFormatType_RGB16UI: - return 48; - - case PixelFormatType_RGB32F: - case PixelFormatType_RGB32I: - case PixelFormatType_RGB32UI: - return 96; - - case PixelFormatType_RGBA16F: - case PixelFormatType_RGBA16I: - case PixelFormatType_RGBA16UI: - return 64; - - case PixelFormatType_RGBA32F: - case PixelFormatType_RGBA32I: - case PixelFormatType_RGBA32UI: - return 128; - - case PixelFormatType_RGBA4: - return 16; - - case PixelFormatType_RGB5A1: - return 16; - - case PixelFormatType_RGB8: - return 24; - - case PixelFormatType_RGBA8: - return 32; - - case PixelFormatType_Depth16: - return 16; - - case PixelFormatType_Depth24: - return 24; - - case PixelFormatType_Depth24Stencil8: - return 32; - - case PixelFormatType_Depth32: - return 32; - - case PixelFormatType_Stencil1: - return 1; - - case PixelFormatType_Stencil4: - return 2; - - case PixelFormatType_Stencil8: - return 8; - - case PixelFormatType_Stencil16: - return 16; - - case PixelFormatType_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return 0; + return s_pixelFormatInfos[format].bitsPerPixel; } inline UInt8 PixelFormat::GetBytesPerPixel(PixelFormatType format) @@ -316,212 +335,29 @@ namespace Nz return GetBitsPerPixel(format)/8; } - inline PixelFormatTypeType PixelFormat::GetType(PixelFormatType format) + inline PixelFormatContent PixelFormat::GetContent(PixelFormatType format) { - switch (format) - { - case PixelFormatType_A8: - case PixelFormatType_BGR8: - case PixelFormatType_BGRA8: - case PixelFormatType_DXT1: - case PixelFormatType_DXT3: - case PixelFormatType_DXT5: - case PixelFormatType_L8: - case PixelFormatType_LA8: - case PixelFormatType_R8: - case PixelFormatType_R8I: - case PixelFormatType_R8UI: - case PixelFormatType_R16: - case PixelFormatType_R16F: - case PixelFormatType_R16I: - case PixelFormatType_R16UI: - case PixelFormatType_R32F: - case PixelFormatType_R32I: - case PixelFormatType_R32UI: - case PixelFormatType_RG8: - case PixelFormatType_RG8I: - case PixelFormatType_RG8UI: - case PixelFormatType_RG16: - case PixelFormatType_RG16F: - case PixelFormatType_RG16I: - case PixelFormatType_RG16UI: - case PixelFormatType_RG32F: - case PixelFormatType_RG32I: - case PixelFormatType_RG32UI: - case PixelFormatType_RGB5A1: - case PixelFormatType_RGB8: - case PixelFormatType_RGB16F: - case PixelFormatType_RGB16I: - case PixelFormatType_RGB16UI: - case PixelFormatType_RGB32F: - case PixelFormatType_RGB32I: - case PixelFormatType_RGB32UI: - case PixelFormatType_RGBA4: - case PixelFormatType_RGBA8: - case PixelFormatType_RGBA16F: - case PixelFormatType_RGBA16I: - case PixelFormatType_RGBA16UI: - case PixelFormatType_RGBA32F: - case PixelFormatType_RGBA32I: - case PixelFormatType_RGBA32UI: - return PixelFormatTypeType_Color; + return s_pixelFormatInfos[format].content; + } - case PixelFormatType_Depth16: - case PixelFormatType_Depth24: - case PixelFormatType_Depth32: - return PixelFormatTypeType_Depth; + inline const PixelFormatInfo& PixelFormat::GetInfo(PixelFormatType format) + { + return s_pixelFormatInfos[format]; + } - case PixelFormatType_Depth24Stencil8: - return PixelFormatTypeType_DepthStencil; - - case PixelFormatType_Stencil1: - case PixelFormatType_Stencil4: - case PixelFormatType_Stencil8: - case PixelFormatType_Stencil16: - return PixelFormatTypeType_Stencil; - - case PixelFormatType_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return PixelFormatTypeType_Undefined; + inline const String& PixelFormat::GetName(PixelFormatType format) + { + return s_pixelFormatInfos[format].name; } inline bool PixelFormat::HasAlpha(PixelFormatType format) { - switch (format) - { - case PixelFormatType_A8: - case PixelFormatType_BGRA8: - case PixelFormatType_DXT3: - case PixelFormatType_DXT5: - case PixelFormatType_LA8: - case PixelFormatType_RGB5A1: - case PixelFormatType_RGBA16F: - case PixelFormatType_RGBA16I: - case PixelFormatType_RGBA16UI: - case PixelFormatType_RGBA32F: - case PixelFormatType_RGBA32I: - case PixelFormatType_RGBA32UI: - case PixelFormatType_RGBA4: - case PixelFormatType_RGBA8: - return true; - - case PixelFormatType_BGR8: - case PixelFormatType_DXT1: - case PixelFormatType_L8: - case PixelFormatType_R8: - case PixelFormatType_R8I: - case PixelFormatType_R8UI: - case PixelFormatType_R16: - case PixelFormatType_R16F: - case PixelFormatType_R16I: - case PixelFormatType_R16UI: - case PixelFormatType_R32F: - case PixelFormatType_R32I: - case PixelFormatType_R32UI: - case PixelFormatType_RG8: - case PixelFormatType_RG8I: - case PixelFormatType_RG8UI: - case PixelFormatType_RG16: - case PixelFormatType_RG16F: - case PixelFormatType_RG16I: - case PixelFormatType_RG16UI: - case PixelFormatType_RG32F: - case PixelFormatType_RG32I: - case PixelFormatType_RG32UI: - case PixelFormatType_RGB8: - case PixelFormatType_RGB16F: - case PixelFormatType_RGB16I: - case PixelFormatType_RGB16UI: - case PixelFormatType_RGB32F: - case PixelFormatType_RGB32I: - case PixelFormatType_RGB32UI: - case PixelFormatType_Depth16: - case PixelFormatType_Depth24: - case PixelFormatType_Depth24Stencil8: - case PixelFormatType_Depth32: - case PixelFormatType_Stencil1: - case PixelFormatType_Stencil4: - case PixelFormatType_Stencil8: - case PixelFormatType_Stencil16: - return false; - - case PixelFormatType_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; + return s_pixelFormatInfos[format].alphaMask.TestAny(); } inline bool PixelFormat::IsCompressed(PixelFormatType format) { - switch (format) - { - case PixelFormatType_DXT1: - case PixelFormatType_DXT3: - case PixelFormatType_DXT5: - return true; - - case PixelFormatType_A8: - case PixelFormatType_BGR8: - case PixelFormatType_BGRA8: - case PixelFormatType_L8: - case PixelFormatType_LA8: - case PixelFormatType_R8: - case PixelFormatType_R8I: - case PixelFormatType_R8UI: - case PixelFormatType_R16: - case PixelFormatType_R16F: - case PixelFormatType_R16I: - case PixelFormatType_R16UI: - case PixelFormatType_R32F: - case PixelFormatType_R32I: - case PixelFormatType_R32UI: - case PixelFormatType_RG8: - case PixelFormatType_RG8I: - case PixelFormatType_RG8UI: - case PixelFormatType_RG16: - case PixelFormatType_RG16F: - case PixelFormatType_RG16I: - case PixelFormatType_RG16UI: - case PixelFormatType_RG32F: - case PixelFormatType_RG32I: - case PixelFormatType_RG32UI: - case PixelFormatType_RGB5A1: - case PixelFormatType_RGB8: - case PixelFormatType_RGB16F: - case PixelFormatType_RGB16I: - case PixelFormatType_RGB16UI: - case PixelFormatType_RGB32F: - case PixelFormatType_RGB32I: - case PixelFormatType_RGB32UI: - case PixelFormatType_RGBA4: - case PixelFormatType_RGBA8: - case PixelFormatType_RGBA16F: - case PixelFormatType_RGBA16I: - case PixelFormatType_RGBA16UI: - case PixelFormatType_RGBA32F: - case PixelFormatType_RGBA32I: - case PixelFormatType_RGBA32UI: - case PixelFormatType_Depth16: - case PixelFormatType_Depth24: - case PixelFormatType_Depth24Stencil8: - case PixelFormatType_Depth32: - case PixelFormatType_Stencil1: - case PixelFormatType_Stencil4: - case PixelFormatType_Stencil8: - case PixelFormatType_Stencil16: - return false; - - case PixelFormatType_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; + return s_pixelFormatInfos[format].IsCompressed(); } inline bool PixelFormat::IsConversionSupported(PixelFormatType srcFormat, PixelFormatType dstFormat) @@ -546,174 +382,6 @@ namespace Nz { s_flipFunctions[flipping][format] = func; } - - inline String PixelFormat::ToString(PixelFormatType format) - { - switch (format) - { - case PixelFormatType_A8: - return "A8"; - - case PixelFormatType_BGR8: - return "BGR8"; - - case PixelFormatType_BGRA8: - return "BGRA8"; - - case PixelFormatType_DXT1: - return "DXT1"; - - case PixelFormatType_DXT3: - return "DXT3"; - - case PixelFormatType_DXT5: - return "DXT5"; - - case PixelFormatType_L8: - return "L8"; - - case PixelFormatType_LA8: - return "LA8"; - - case PixelFormatType_R8: - return "R8"; - - case PixelFormatType_R8I: - return "R8I"; - - case PixelFormatType_R8UI: - return "R8UI"; - - case PixelFormatType_R16: - return "R16"; - - case PixelFormatType_R16F: - return "R16F"; - - case PixelFormatType_R16I: - return "R16I"; - - case PixelFormatType_R16UI: - return "R16UI"; - - case PixelFormatType_R32F: - return "R32F"; - - case PixelFormatType_R32I: - return "R32I"; - - case PixelFormatType_R32UI: - return "R32UI"; - - case PixelFormatType_RG8: - return "RG8"; - - case PixelFormatType_RG8I: - return "RG8I"; - - case PixelFormatType_RG8UI: - return "RG8UI"; - - case PixelFormatType_RG16: - return "RG16"; - - case PixelFormatType_RG16F: - return "RG16F"; - - case PixelFormatType_RG16I: - return "RG16I"; - - case PixelFormatType_RG16UI: - return "RG16UI"; - - case PixelFormatType_RG32F: - return "RG32F"; - - case PixelFormatType_RG32I: - return "RG32I"; - - case PixelFormatType_RG32UI: - return "RG32UI"; - - case PixelFormatType_RGB5A1: - return "RGB5A1"; - - case PixelFormatType_RGB8: - return "RGB8"; - - case PixelFormatType_RGB16F: - return "RGB16F"; - - case PixelFormatType_RGB16I: - return "RGB16I"; - - case PixelFormatType_RGB16UI: - return "RGB16UI"; - - case PixelFormatType_RGB32F: - return "RGB32F"; - - case PixelFormatType_RGB32I: - return "RGB32I"; - - case PixelFormatType_RGB32UI: - return "RGB32UI"; - - case PixelFormatType_RGBA4: - return "RGBA4"; - - case PixelFormatType_RGBA8: - return "RGBA8"; - - case PixelFormatType_RGBA16F: - return "RGBA16F"; - - case PixelFormatType_RGBA16I: - return "RGBA16I"; - - case PixelFormatType_RGBA16UI: - return "RGBA16UI"; - - case PixelFormatType_RGBA32F: - return "RGBA32F"; - - case PixelFormatType_RGBA32I: - return "RGBA32I"; - - case PixelFormatType_RGBA32UI: - return "RGBA32UI"; - - case PixelFormatType_Depth16: - return "Depth16"; - - case PixelFormatType_Depth24: - return "Depth24"; - - case PixelFormatType_Depth24Stencil8: - return "Depth24Stencil8"; - - case PixelFormatType_Depth32: - return "Depth32"; - - case PixelFormatType_Stencil1: - return "Stencil1"; - - case PixelFormatType_Stencil4: - return "Stencil4"; - - case PixelFormatType_Stencil8: - return "Stencil8"; - - case PixelFormatType_Stencil16: - return "Stencil16"; - - case PixelFormatType_Undefined: - return "Undefined"; - } - - NazaraError("Invalid pixel format"); - return "Invalid format"; - } } #include diff --git a/src/Nazara/Renderer/RenderBuffer.cpp b/src/Nazara/Renderer/RenderBuffer.cpp index b1316f4c3..b6b182ab8 100644 --- a/src/Nazara/Renderer/RenderBuffer.cpp +++ b/src/Nazara/Renderer/RenderBuffer.cpp @@ -44,7 +44,7 @@ namespace Nz OpenGL::Format openglFormat; if (!OpenGL::TranslateFormat(format, &openglFormat, OpenGL::FormatType_RenderBuffer)) { - NazaraError("Failed to translate pixel format \"" + PixelFormat::ToString(format) + "\" into OpenGL format"); + NazaraError("Failed to translate pixel format \"" + PixelFormat::GetName(format) + "\" into OpenGL format"); return false; } diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 37b45c46a..0ae0d97bf 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -44,12 +44,23 @@ namespace Nz 2 // AttachmentPoint_Stencil }; - AttachmentPoint formatTypeToAttachment[PixelFormatTypeType_Max+1] = + AttachmentPoint FormatTypeToAttachment(PixelFormatType format) { - AttachmentPoint_Color, // PixelFormatTypeType_Color - AttachmentPoint_Depth, // PixelFormatTypeType_Depth - AttachmentPoint_DepthStencil, // PixelFormatTypeType_DepthStencil - AttachmentPoint_Stencil // PixelFormatTypeType_Stencil + const PixelFormatInfo& info = PixelFormat::GetInfo(format); + switch (info.content) + { + case PixelFormatContent_ColorRGBA: + return AttachmentPoint_Color; + + case PixelFormatContent_DepthStencil: + return (!info.greenMask.TestAny()) ? AttachmentPoint_Depth : AttachmentPoint_DepthStencil; + + case PixelFormatContent_Stencil: + return AttachmentPoint_Stencil; + } + + NazaraInternalError("Unexpected pixel format content: 0x" + String::Number(info.content, 16)); + return AttachmentPoint_Max; }; GLuint lockedPrevious = 0; @@ -118,9 +129,9 @@ namespace Nz } } - AttachmentPoint targetAttachmentPoint = formatTypeToAttachment[PixelFormat::GetType(buffer->GetFormat())]; + AttachmentPoint targetAttachmentPoint = FormatTypeToAttachment(buffer->GetFormat()); if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != AttachmentPoint_DepthStencil && - attachmentPoint != AttachmentPoint_Depth && attachmentPoint != AttachmentPoint_Stencil) + attachmentPoint != AttachmentPoint_Depth && attachmentPoint != AttachmentPoint_Stencil) { NazaraError("Pixel format type does not match attachment point type"); return false; @@ -230,7 +241,7 @@ namespace Nz return false; } - AttachmentPoint targetAttachmentPoint = formatTypeToAttachment[PixelFormat::GetType(texture->GetFormat())]; + AttachmentPoint targetAttachmentPoint = FormatTypeToAttachment(texture->GetFormat()); if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != AttachmentPoint_DepthStencil && attachmentPoint != AttachmentPoint_Depth && attachmentPoint != AttachmentPoint_Stencil) { diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index e4382cfc5..835dce85e 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -521,7 +521,7 @@ namespace Nz { ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format PixelFormatType newFormat = (PixelFormat::HasAlpha(format)) ? PixelFormatType_BGRA8 : PixelFormatType_BGR8; - NazaraWarning("Format " + PixelFormat::ToString(format) + " not supported, trying to convert it to " + PixelFormat::ToString(newFormat) + "..."); + NazaraWarning("Format " + PixelFormat::GetName(format) + " not supported, trying to convert it to " + PixelFormat::GetName(newFormat) + "..."); if (PixelFormat::IsConversionSupported(format, newFormat)) { @@ -1197,7 +1197,7 @@ namespace Nz OpenGL::Format openGLFormat; if (!OpenGL::TranslateFormat(m_impl->format, &openGLFormat, OpenGL::FormatType_Texture)) { - NazaraError("Format " + PixelFormat::ToString(m_impl->format) + " not supported by OpenGL"); + NazaraError("Format " + PixelFormat::GetName(m_impl->format) + " not supported by OpenGL"); return false; } @@ -1306,7 +1306,7 @@ namespace Nz glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); } - if (!proxy && PixelFormat::GetType(m_impl->format) == PixelFormatTypeType_Depth) + if (!proxy && PixelFormat::GetContent(m_impl->format) == PixelFormatContent_DepthStencil) { glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index baa2657b3..fe775d97a 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -169,7 +169,7 @@ namespace Nz { if (header.format.flags & (DDPF_RGB | DDPF_ALPHA | DDPF_ALPHAPIXELS | DDPF_LUMINANCE)) { - PixelFormatInfo info(header.format.bpp, PixelFormatSubType_Unsigned); + PixelFormatInfo info(PixelFormatContent_ColorRGBA, header.format.bpp, PixelFormatSubType_Unsigned); if (header.format.flags & DDPF_RGB) { diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 6d05b493c..c8f3e49f1 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -89,7 +89,7 @@ namespace Nz if (!PixelFormat::IsConversionSupported(m_sharedImage->format, newFormat)) { - NazaraError("Conversion from " + PixelFormat::ToString(m_sharedImage->format) + " to " + PixelFormat::ToString(newFormat) + " is not supported"); + NazaraError("Conversion from " + PixelFormat::GetName(m_sharedImage->format) + " to " + PixelFormat::GetName(newFormat) + " is not supported"); return false; } #endif @@ -327,7 +327,7 @@ namespace Nz std::unique_ptr colorBuffer(new UInt8[bpp]); if (!PixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) { - NazaraError("Failed to convert RGBA8 to " + PixelFormat::ToString(m_sharedImage->format)); + NazaraError("Failed to convert RGBA8 to " + PixelFormat::GetName(m_sharedImage->format)); return false; } @@ -405,7 +405,7 @@ namespace Nz std::unique_ptr colorBuffer(new UInt8[bpp]); if (!PixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) { - NazaraError("Failed to convert RGBA8 to " + PixelFormat::ToString(m_sharedImage->format)); + NazaraError("Failed to convert RGBA8 to " + PixelFormat::GetName(m_sharedImage->format)); return false; } @@ -477,7 +477,7 @@ namespace Nz std::unique_ptr colorBuffer(new UInt8[bpp]); if (!PixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) { - NazaraError("Failed to convert RGBA8 to " + PixelFormat::ToString(m_sharedImage->format)); + NazaraError("Failed to convert RGBA8 to " + PixelFormat::GetName(m_sharedImage->format)); return false; } diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index 8c571d62e..a9b740b8f 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -48,7 +48,7 @@ namespace Nz NazaraUnused(dst); NazaraUnused(end); - NazaraInternalError("Conversion from " + PixelFormat::ToString(from) + " to " + PixelFormat::ToString(to) + " is not supported"); + NazaraInternalError("Conversion from " + PixelFormat::GetName(from) + " to " + PixelFormat::GetName(to) + " is not supported"); return nullptr; } @@ -1270,15 +1270,13 @@ namespace Nz PixelFormatType PixelFormat::IdentifyFormat(const PixelFormatInfo& info) { - switch (info.bitsPerPixel) + for (unsigned int i = 0; i <= PixelFormatType_Max; ++i) { - case 32: - if (info.redMask == Bitset<>(0xFF000000) && - info.greenMask == Bitset<>(0x00FF0000) && - info.blueMask == Bitset<>(0x0000FF00) && - info.alphaMask == Bitset<>(0x000000FF)) - return PixelFormatType_RGBA8; - break; + PixelFormatInfo& info2 = s_pixelFormatInfos[i]; + if (info.bitsPerPixel == info2.bitsPerPixel && info.content == info2.content && + info.redMask == info2.redMask && info.greenMask == info2.greenMask && info.blueMask == info2.blueMask && info.alphaMask == info2.alphaMask && + info.redType == info2.redType && info.greenType == info2.greenType && info.blueType == info2.blueType && info.alphaType == info2.alphaType) + return static_cast(i); } return PixelFormatType_Undefined; @@ -1286,7 +1284,67 @@ namespace Nz bool PixelFormat::Initialize() { - // Réinitialisation + // Setup informations about every pixel format + s_pixelFormatInfos[PixelFormatType_A8] = PixelFormatInfo("A8", PixelFormatContent_ColorRGBA, 0, 0, 0, 0xFF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_BGR8] = PixelFormatInfo("BGR8", PixelFormatContent_ColorRGBA, 0x0000FF, 0x00FF00, 0xFF0000, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_BGRA8] = PixelFormatInfo("BGRA8", PixelFormatContent_ColorRGBA, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_DXT1] = PixelFormatInfo("DXT1", PixelFormatContent_ColorRGBA, 8, PixelFormatSubType_Compressed); + s_pixelFormatInfos[PixelFormatType_DXT3] = PixelFormatInfo("DXT3", PixelFormatContent_ColorRGBA, 16, PixelFormatSubType_Compressed); + s_pixelFormatInfos[PixelFormatType_DXT5] = PixelFormatInfo("DXT5", PixelFormatContent_ColorRGBA, 16, PixelFormatSubType_Compressed); + s_pixelFormatInfos[PixelFormatType_L8] = PixelFormatInfo("L8", PixelFormatContent_ColorRGBA, 0xFF, 0xFF, 0xFF, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_LA8] = PixelFormatInfo("LA8", PixelFormatContent_ColorRGBA, 0xFF00, 0xFF00, 0xFF00, 0x00FF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_R8] = PixelFormatInfo("R8", PixelFormatContent_ColorRGBA, 0xFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_R8I] = PixelFormatInfo("R8I", PixelFormatContent_ColorRGBA, 0xFF, 0, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_R8UI] = PixelFormatInfo("R8UI", PixelFormatContent_ColorRGBA, 0xFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_R16] = PixelFormatInfo("R16", PixelFormatContent_ColorRGBA, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_R16F] = PixelFormatInfo("R16F", PixelFormatContent_ColorRGBA, 0xFFFF, 0, 0, 0, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_R16I] = PixelFormatInfo("R16I", PixelFormatContent_ColorRGBA, 0xFFFF, 0, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_R16UI] = PixelFormatInfo("R16UI", PixelFormatContent_ColorRGBA, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_R32F] = PixelFormatInfo("R32F", PixelFormatContent_ColorRGBA, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Float); + s_pixelFormatInfos[PixelFormatType_R32I] = PixelFormatInfo("R32I", PixelFormatContent_ColorRGBA, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_R32UI] = PixelFormatInfo("R32UI", PixelFormatContent_ColorRGBA, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RG8] = PixelFormatInfo("RG8", PixelFormatContent_ColorRGBA, 0xFF00, 0x00FF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RG8I] = PixelFormatInfo("RG8I", PixelFormatContent_ColorRGBA, 0xFF00, 0x00FF, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RG8UI] = PixelFormatInfo("RG8UI", PixelFormatContent_ColorRGBA, 0xFF00, 0x00FF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RG16] = PixelFormatInfo("RG16", PixelFormatContent_ColorRGBA, 0xFFFF0000, 0x0000FFFF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RG16F] = PixelFormatInfo("RG16F", PixelFormatContent_ColorRGBA, 0xFFFF0000, 0x0000FFFF, 0, 0, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_RG16I] = PixelFormatInfo("RG16I", PixelFormatContent_ColorRGBA, 0xFFFF0000, 0x0000FFFF, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RG16UI] = PixelFormatInfo("RG16UI", PixelFormatContent_ColorRGBA, 0xFFFF0000, 0x0000FFFF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RG32F] = PixelFormatInfo("RG32F", PixelFormatContent_ColorRGBA, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0, 0, PixelFormatSubType_Float); + s_pixelFormatInfos[PixelFormatType_RG32I] = PixelFormatInfo("RG32I", PixelFormatContent_ColorRGBA, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RG32UI] = PixelFormatInfo("RG32UI", PixelFormatContent_ColorRGBA, 0xFFFFFFFF00000000, 0x00000000FFFFFFFF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGB8] = PixelFormatInfo("RGB8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGB16F] = PixelFormatInfo("RGB16F", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_RGB16I] = PixelFormatInfo("RGB16I", PixelFormatContent_ColorRGBA, 0xFFFF00000000, 0x0000FFFF0000, 0x00000000FFFF, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RGB16UI] = PixelFormatInfo("RGB16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGB32F] = PixelFormatInfo("RGB32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_RGB32I] = PixelFormatInfo("RGB32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RGB32UI] = PixelFormatInfo("RGB32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGBA4] = PixelFormatInfo("RGBA4", PixelFormatContent_ColorRGBA, 0xF000, 0x0F00, 0x00F0, 0x000F, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGB5A1] = PixelFormatInfo("RGB5A1", PixelFormatContent_ColorRGBA, 0xF800, 0x07C0, 0x003E, 0x0001, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGBA8] = PixelFormatInfo("RGBA8", PixelFormatContent_ColorRGBA, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGBA16F] = PixelFormatInfo("RGBA16F", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_RGBA16I] = PixelFormatInfo("RGBA16I", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RGBA16UI] = PixelFormatInfo("RGBA16UI", PixelFormatContent_ColorRGBA, 0xFFFF000000000000, 0x0000FFFF00000000, 0x00000000FFFF0000, 0x000000000000FFFF, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_RGBA32F] = PixelFormatInfo("RGBA32F", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Half); + s_pixelFormatInfos[PixelFormatType_RGBA32I] = PixelFormatInfo("RGBA32I", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Int); + s_pixelFormatInfos[PixelFormatType_RGBA32UI] = PixelFormatInfo("RGBA32UI", PixelFormatContent_ColorRGBA, 0, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Depth16] = PixelFormatInfo("Depth16", PixelFormatContent_DepthStencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Depth24] = PixelFormatInfo("Depth24", PixelFormatContent_DepthStencil, 0xFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Depth24Stencil8] = PixelFormatInfo("Depth24Stencil8", PixelFormatContent_DepthStencil, 0xFFFFFF00, 0x000000FF, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Depth32] = PixelFormatInfo("Depth32", PixelFormatContent_DepthStencil, 0xFFFFFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Stencil1] = PixelFormatInfo("Stencil1", PixelFormatContent_Stencil, 0x1, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Stencil4] = PixelFormatInfo("Stencil4", PixelFormatContent_Stencil, 0xF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Stencil8] = PixelFormatInfo("Stencil8", PixelFormatContent_Stencil, 0xFF, 0, 0, 0, PixelFormatSubType_Unsigned); + s_pixelFormatInfos[PixelFormatType_Stencil16] = PixelFormatInfo("Stencil16", PixelFormatContent_Stencil, 0xFFFF, 0, 0, 0, PixelFormatSubType_Unsigned); + + for (unsigned int i = 0; i <= PixelFormatType_Max; ++i) + { + if (!s_pixelFormatInfos[i].Validate()) + NazaraWarning("Pixel format 0x" + String::Number(i, 16) + " (" + GetName(static_cast(i)) + ") failed validation tests"); + } + + // Reset functions std::memset(s_convertFunctions, 0, (PixelFormatType_Max+1)*(PixelFormatType_Max+1)*sizeof(PixelFormat::ConvertFunction)); /***********************************A8************************************/ @@ -1511,12 +1569,16 @@ namespace Nz void PixelFormat::Uninitialize() { + for (unsigned int i = 0; i <= PixelFormatType_Max; ++i) + s_pixelFormatInfos[i].Clear(); + std::memset(s_convertFunctions, 0, (PixelFormatType_Max+1)*(PixelFormatType_Max+1)*sizeof(PixelFormat::ConvertFunction)); for (unsigned int i = 0; i <= PixelFlipping_Max; ++i) s_flipFunctions[i].clear(); } + PixelFormatInfo PixelFormat::s_pixelFormatInfos[PixelFormatType_Max + 1]; PixelFormat::ConvertFunction PixelFormat::s_convertFunctions[PixelFormatType_Max+1][PixelFormatType_Max+1]; std::map PixelFormat::s_flipFunctions[PixelFlipping_Max+1]; } From 5be03ab2f26a834551aad5fbfdc114746bba89e0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 17:08:14 +0200 Subject: [PATCH 068/224] Core/Algorithm: Add ReverseBits function Former-commit-id: 10921a52223af92ddaf951f613eb93945133078b --- include/Nazara/Core/Algorithm.hpp | 1 + include/Nazara/Core/Algorithm.inl | 19 +++++++++++++++++ src/Nazara/Core/AlgorithmCore.cpp | 34 +++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/Nazara/Core/AlgorithmCore.cpp diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index f031854c5..b8a3206af 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -26,6 +26,7 @@ namespace Nz template constexpr std::size_t CountOf(T(&name)[N]) noexcept; template std::size_t CountOf(const T& c); template void HashCombine(std::size_t& seed, const T& v); + template T ReverseBits(T integer); template struct PointedType diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 821a9069f..72b5ee27a 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -28,6 +28,8 @@ namespace Nz { return (object .* std::forward(fn))(std::get(std::forward(t))...); } + + NAZARA_CORE_API extern const UInt8 BitReverseTable256[256]; } /*! @@ -164,6 +166,23 @@ namespace Nz seed = static_cast(b * kMul); } + /*! + * \ingroup core + * \brief Reverse the bit order of the integer + * \return integer with reversed bits + * + * \param integer Integer whose bits are to be reversed + */ + template + T ReverseBits(T integer) + { + T reversed = 0; + for (std::size_t i = 0; i < sizeof(T); ++i) + reversed |= T(Detail::BitReverseTable256[(integer >> i * 8) & 0xFF]) << sizeof(T) * 8 - (i + 1) * 8; + + return reversed; + } + template struct PointedType {typedef T type;}; template struct PointedType {typedef T type;}; template struct PointedType {typedef T type;}; diff --git a/src/Nazara/Core/AlgorithmCore.cpp b/src/Nazara/Core/AlgorithmCore.cpp new file mode 100644 index 000000000..1a9d8a171 --- /dev/null +++ b/src/Nazara/Core/AlgorithmCore.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2016 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 +{ + namespace Detail + { + const UInt8 BitReverseTable256[256] = + { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF + }; + } +} + +#include From 3dc81263dc914385b7822e33c48750cfb5b273bf Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 17:08:45 +0200 Subject: [PATCH 069/224] Core/Bitset: Fix OR/XOR with two bitset of similar size Former-commit-id: 5de82c13f397c04497c11a98e1bd745c686cbb50 --- include/Nazara/Core/Bitset.inl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index 568d4a815..f7256bdbb 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -329,8 +329,8 @@ namespace Nz template void Bitset::PerformsOR(const Bitset& a, const Bitset& b) { - const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; - const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; + const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b; + const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a; unsigned int maxBlockCount = greater.GetBlockCount(); unsigned int minBlockCount = lesser.GetBlockCount(); @@ -358,8 +358,8 @@ namespace Nz template void Bitset::PerformsXOR(const Bitset& a, const Bitset& b) { - const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; - const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; + const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b; + const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a; unsigned int maxBlockCount = greater.GetBlockCount(); unsigned int minBlockCount = lesser.GetBlockCount(); From 7df52a3ad0f4740d9f5fe5408f26f3ee531668f9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 17:09:08 +0200 Subject: [PATCH 070/224] Utility/DDSLoader: Fix bit reversing for exotic format Former-commit-id: d12dc599714bbdeefda000eade3159080b764bde --- src/Nazara/Utility/Formats/DDSLoader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index fe775d97a..d9783115b 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -173,16 +173,16 @@ namespace Nz if (header.format.flags & DDPF_RGB) { - // DDS Masks are in little endian - info.redMask = SwapBytes(header.format.redMask); - info.greenMask = SwapBytes(header.format.greenMask); - info.blueMask = SwapBytes(header.format.blueMask); + // Reverse bits for our masks + info.redMask = ReverseBits(header.format.redMask); + info.greenMask = ReverseBits(header.format.greenMask); + info.blueMask = ReverseBits(header.format.blueMask); } else if (header.format.flags & DDPF_LUMINANCE) - info.redMask = SwapBytes(header.format.redMask); + info.redMask = ReverseBits(header.format.redMask); if (header.format.flags & (DDPF_ALPHA | DDPF_ALPHAPIXELS)) - info.alphaMask = SwapBytes(header.format.alphaMask); + info.alphaMask = ReverseBits(header.format.alphaMask); *format = PixelFormat::IdentifyFormat(info); if (!PixelFormat::IsValid(*format)) From e0b714daccece743d2ac0e1aa5a97e988a9c5508 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 18:11:05 +0200 Subject: [PATCH 071/224] Sdk/LuaAPI: Fix handles retrieval Former-commit-id: a1704c9ded36a42badda6303ac28018797772e82 --- SDK/include/NDK/LuaAPI.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index cbd4e7c4a..ae2da917c 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -255,14 +255,14 @@ namespace Nz inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::EntityHandle* handle, TypeTag) { - *handle = std::move(*static_cast(instance.CheckUserdata(index, "Entity"))); + *handle = *static_cast(instance.CheckUserdata(index, "Entity")); return 1; } inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, Ndk::WorldHandle* handle, TypeTag) { - *handle = std::move(*static_cast(instance.CheckUserdata(index, "World"))); + *handle = *static_cast(instance.CheckUserdata(index, "World")); return 1; } From a386a8bd2dd338d9e1f0e6601cc4beed4f4359e2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 20:14:06 +0200 Subject: [PATCH 072/224] Graphics/Light: Fix compilation Former-commit-id: 0ae92c86e52bb18aa9587fbb82c932b71b44484c --- include/Nazara/Graphics/Light.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index 266f7939a..e877852cb 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -178,7 +178,7 @@ namespace Nz inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat) { - NazaraAssert(PixelFormat::GetType(shadowFormat) == PixelFormatTypeType_Depth, "Shadow format type is not a depth format"); + NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format"); m_shadowMapFormat = shadowFormat; From d2a6ead9f3b67afd037a3b4f0863383fac3d7e75 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 May 2016 20:22:30 +0200 Subject: [PATCH 073/224] Plugins/Assimp: Fix UV parameters Former-commit-id: 7130ef5a3303aa24c882fc3daa36cbdf7096c265 --- plugins/Assimp/Plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 395ca6305..1c998e91c 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -104,7 +104,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) | aiProcess_OptimizeGraph | aiProcess_FlipWindingOrder | aiProcess_Debone; - if (!parameters.flipUVs) + if (parameters.flipUVs) postProcess |= aiProcess_FlipUVs; if (parameters.optimizeIndexBuffers) From 840b03691a4ff174a2c68c8138e45938cc4bd1d4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 May 2016 00:44:58 +0200 Subject: [PATCH 074/224] Plugins/Assimp: Fix stack corruption Former-commit-id: 15b1c22cd0bbb1601e23b1e4bd037fe0cc13ab24 --- build/scripts/features/index_template.html | 140 ++++++------ build/scripts/features/style.css | 240 ++++++++++----------- plugins/Assimp/Plugin.cpp | 12 +- 3 files changed, 196 insertions(+), 196 deletions(-) diff --git a/build/scripts/features/index_template.html b/build/scripts/features/index_template.html index 43bf5aea9..852811a4c 100644 --- a/build/scripts/features/index_template.html +++ b/build/scripts/features/index_template.html @@ -1,71 +1,71 @@ - - - - - - Avancement de Nazara - - -
- Nazara Engine - -
- - Retrouvez le moteur sur GitHub !
- Dépôt GitHub

- Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
- OpenClassrooms, Progdupeupl ou ZesteDeSavoir -

- ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? - -
- -

Fonctionnalités de Nazara

- -
Dernière mise à jour : - %DATE% -
- -

Important:

-

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. - C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
- Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

- -

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
- Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

- -

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
- Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

- -
- - - - - - - - - - - %MODULELIST% - -
Sommaire
ModuleAvancement
- - %MODULEDESCRIPTION% -
- - - - - - - - - - %MODULELIST% - -
Sommaire
ModulePourcentage
-
- + + + + + + Avancement de Nazara + + +
+ Nazara Engine + +
+ + Retrouvez le moteur sur GitHub !
+ Dépôt GitHub

+ Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
+ OpenClassrooms, Progdupeupl ou ZesteDeSavoir +

+ ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? + +
+ +

Fonctionnalités de Nazara

+ +
Dernière mise à jour : + %DATE% +
+ +

Important:

+

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. + C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
+ Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

+ +

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
+ Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

+ +

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
+ Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

+ +
+ + + + + + + + + + + %MODULELIST% + +
Sommaire
ModuleAvancement
+ + %MODULEDESCRIPTION% +
+ + + + + + + + + + %MODULELIST% + +
Sommaire
ModulePourcentage
+
+ \ No newline at end of file diff --git a/build/scripts/features/style.css b/build/scripts/features/style.css index ff83f706c..189b2a090 100644 --- a/build/scripts/features/style.css +++ b/build/scripts/features/style.css @@ -1,121 +1,121 @@ -/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ - -body -{ - font-family: sans-serif; - text-align: center; - margin: 0; - background-color: #f1f1f1; -} - -#englob { - display: block; - margin-left: auto; - margin-right: auto; - background-color: white; - width: 50%; - min-width: 765px; - padding: 0 20px; -} - -hr { - height: 0; - border: 0; - border-top: 1px solid #eee; -} - -a -{ - color: #007ACC; -} - -a:hover -{ - color: lightblue; -} - -h1 -{ - display: inline; -} - -h2 -{ - display: inline; - text-decoration: underline; -} - -h4 -{ - text-decoration: underline; -} - -p { - text-align: justify; -} - -ol -{ - list-style-type: none; -} - -table -{ - border-collapse: collapse; - text-align: center; - display: inline-block; - border: white groove; - border-radius: 10px; - box-shadow: 0px 0px 10px lightblue; -} - -th -{ - text-shadow: 2px 2px 4px black; -} - -tr -{ - border: 1px solid white; -} - -tbody tr:hover -{ - text-shadow: 0px 0px 4px white; -} - -.description -{ - margin-left: 20px; -} - -.lastupdate -{ - font-size: x-large; - font-weight: bold; - color: #f1c40f; -} - -.modulename -{ - font-size: x-large; - font-weight: bold; - text-shadow: 2px 2px 10px #007ACC; -} - -.note -{ - margin-left: 20px; - color: #007ACC; -} - -.notedesc -{ - color: rgb(200, 200, 255); -} - -.portability -{ - margin-left: 20px; - color: red; +/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ + +body +{ + font-family: sans-serif; + text-align: center; + margin: 0; + background-color: #f1f1f1; +} + +#englob { + display: block; + margin-left: auto; + margin-right: auto; + background-color: white; + width: 50%; + min-width: 765px; + padding: 0 20px; +} + +hr { + height: 0; + border: 0; + border-top: 1px solid #eee; +} + +a +{ + color: #007ACC; +} + +a:hover +{ + color: lightblue; +} + +h1 +{ + display: inline; +} + +h2 +{ + display: inline; + text-decoration: underline; +} + +h4 +{ + text-decoration: underline; +} + +p { + text-align: justify; +} + +ol +{ + list-style-type: none; +} + +table +{ + border-collapse: collapse; + text-align: center; + display: inline-block; + border: white groove; + border-radius: 10px; + box-shadow: 0px 0px 10px lightblue; +} + +th +{ + text-shadow: 2px 2px 4px black; +} + +tr +{ + border: 1px solid white; +} + +tbody tr:hover +{ + text-shadow: 0px 0px 4px white; +} + +.description +{ + margin-left: 20px; +} + +.lastupdate +{ + font-size: x-large; + font-weight: bold; + color: #f1c40f; +} + +.modulename +{ + font-size: x-large; + font-weight: bold; + text-shadow: 2px 2px 10px #007ACC; +} + +.note +{ + margin-left: 20px; + color: #007ACC; +} + +.notedesc +{ + color: rgb(200, 200, 255); +} + +.portability +{ + margin-left: 20px; + color: red; } \ No newline at end of file diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 1c998e91c..68c443b29 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -206,8 +206,8 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { aiVector3D position = iMesh->mVertices[j]; aiVector3D normal = iMesh->mNormals[j]; - aiVector3D tangent = iMesh->mTangents[j]; - aiVector3D uv = iMesh->mTextureCoords[0][j]; + aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f); + aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); vertex->position = parameters.scale * Vector3f(position.x, position.y, position.z); vertex->normal.Set(normal.x, normal.y, normal.z); @@ -246,8 +246,8 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) 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) + aiTextureMapMode mapMode[3]; + if (aiGetMaterialTexture(aiMat, aiType, 0, &path, nullptr, nullptr, nullptr, nullptr, &mapMode[0], nullptr) == aiReturn_SUCCESS) { matData.SetParameter(MaterialData::CustomDefined); matData.SetParameter(textureKey, stream.GetDirectory() + String(path.data, path.length)); @@ -255,7 +255,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) if (wrapKey) { SamplerWrap wrap = SamplerWrap_Default; - switch (mapMode) + switch (mapMode[0]) { case aiTextureMapMode_Clamp: case aiTextureMapMode_Decal: @@ -271,7 +271,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) break; default: - NazaraWarning("Assimp texture map mode 0x" + String::Number(mapMode, 16) + " not handled"); + NazaraWarning("Assimp texture map mode 0x" + String::Number(mapMode[0], 16) + " not handled"); break; } From 87629156edce8f5d3b332a15987ff2f6644721f0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 May 2016 21:31:49 +0200 Subject: [PATCH 075/224] Vulkan/Instance: Fix support of VK_KHR_surface Former-commit-id: 8947e217413bb432a4221e88991ce89e0c491ea3 --- src/Nazara/Vulkan/VkInstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Vulkan/VkInstance.cpp b/src/Nazara/Vulkan/VkInstance.cpp index e66189b7c..35378a699 100644 --- a/src/Nazara/Vulkan/VkInstance.cpp +++ b/src/Nazara/Vulkan/VkInstance.cpp @@ -65,7 +65,7 @@ namespace Nz } // VK_KHR_surface - if (IsExtensionLoaded("VK_KHR_display")) + if (IsExtensionLoaded("VK_KHR_surface")) { NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySurfaceKHR); NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); From 591498e340accddc60edd04aa7e1bcbc1146676b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 May 2016 21:32:41 +0200 Subject: [PATCH 076/224] Vulkan/Surface: Add a few wrapper methods Former-commit-id: 2d21ec0d2407caf74eac11da6da5c7776cfc584a --- include/Nazara/Vulkan/VkSurface.hpp | 5 ++ include/Nazara/Vulkan/VkSurface.inl | 73 +++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp index 7b7fbcdfd..03a57d2fe 100644 --- a/include/Nazara/Vulkan/VkSurface.hpp +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -64,6 +64,11 @@ namespace Nz inline void Destroy(); + bool GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities); + bool GetFormats(VkPhysicalDevice physicalDevice, std::vector* surfaceFormats); + bool GetPresentModes(VkPhysicalDevice physicalDevice, std::vector* presentModes); + bool GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported); + inline bool IsSupported() const; inline VkResult GetLastErrorCode() const; diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index e7b0efe64..b6cb3a28f 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -173,6 +173,79 @@ namespace Nz return m_lastErrorCode; } + inline bool Surface::GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) + { + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, surfaceCapabilities); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query surface capabilities"); + return false; + } + + return true; + } + + inline bool Surface::GetFormats(VkPhysicalDevice physicalDevice, std::vector* surfaceFormats) + { + // First, query format count + UInt32 surfaceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, nullptr); + if (m_lastErrorCode != VkResult::VK_SUCCESS || surfaceCount == 0) + { + NazaraError("Failed to query format count"); + return false; + } + + // Now we can get the list of the available physical device + surfaceFormats->resize(surfaceCount); + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, surfaceFormats->data()); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query formats"); + return false; + } + + return true; + } + + inline bool Surface::GetPresentModes(VkPhysicalDevice physicalDevice, std::vector* presentModes) + { + // First, query present modes count + UInt32 presentModeCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, nullptr); + if (m_lastErrorCode != VkResult::VK_SUCCESS || presentModeCount == 0) + { + NazaraError("Failed to query present mode count"); + return false; + } + + // Now we can get the list of the available physical device + presentModes->resize(presentModeCount); + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, presentModes->data()); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query present modes"); + return false; + } + + return true; + } + + inline bool Surface::GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) + { + VkBool32 presentationSupported = VK_FALSE; + m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, m_surface, &presentationSupported); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query surface capabilities"); + return false; + } + + *supported = (presentationSupported == VK_TRUE); + + return true; + } + inline bool Surface::IsSupported() const { if (!m_instance.IsExtensionLoaded("VK_KHR_surface")) From c22003df0ec93b3ce6f3b070c2dd6ea7c9161532 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 09:03:49 +0200 Subject: [PATCH 077/224] Vulkan/CommandPool: Fix linking error Former-commit-id: a56db2c2480c280590488396f676b7bd7d80aff5 --- include/Nazara/Vulkan/VkCommandPool.hpp | 6 +++--- include/Nazara/Vulkan/VkCommandPool.inl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Vulkan/VkCommandPool.hpp b/include/Nazara/Vulkan/VkCommandPool.hpp index 8b99513e3..b51061bb2 100644 --- a/include/Nazara/Vulkan/VkCommandPool.hpp +++ b/include/Nazara/Vulkan/VkCommandPool.hpp @@ -20,7 +20,7 @@ namespace Nz using CommandPoolHandle = ObjectHandle; - class CommandPool : public DeviceObject, public HandledObject + class NAZARA_VULKAN_API CommandPool : public DeviceObject, public HandledObject { friend DeviceObject; @@ -42,8 +42,8 @@ namespace Nz CommandPool& operator=(CommandPool&&) = delete; private: - static VkResult CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle); - static void DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator); + static inline VkResult CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle); + static inline void DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator); }; } } diff --git a/include/Nazara/Vulkan/VkCommandPool.inl b/include/Nazara/Vulkan/VkCommandPool.inl index f7aef6978..61cfeaa43 100644 --- a/include/Nazara/Vulkan/VkCommandPool.inl +++ b/include/Nazara/Vulkan/VkCommandPool.inl @@ -38,12 +38,12 @@ namespace Nz return true; } - VkResult CommandPool::CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle) + inline VkResult CommandPool::CreateHelper(Device& device, const VkCommandPoolCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkCommandPool* handle) { return device.vkCreateCommandPool(device, createInfo, allocator, handle); } - void CommandPool::DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator) + inline void CommandPool::DestroyHelper(Device& device, VkCommandPool handle, const VkAllocationCallbacks* allocator) { return device.vkDestroyCommandPool(device, handle, allocator); } From 6ee0b4a51de2c59ce355f7a2d83cc842214f97ce Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 09:04:01 +0200 Subject: [PATCH 078/224] Vulkan/CommandBuffer: Fix crash when moving Former-commit-id: 441095f5be1fc45dac4b56e1cf535c1145327d4b --- include/Nazara/Vulkan/VkCommandBuffer.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Vulkan/VkCommandBuffer.inl b/include/Nazara/Vulkan/VkCommandBuffer.inl index ff4eaede4..7e48901c2 100644 --- a/include/Nazara/Vulkan/VkCommandBuffer.inl +++ b/include/Nazara/Vulkan/VkCommandBuffer.inl @@ -33,7 +33,8 @@ namespace Nz inline void CommandBuffer::Free() { - m_pool->GetDevice().vkFreeCommandBuffers(m_pool->GetDevice(), *m_pool, 1, &m_handle); + if (m_handle) + m_pool->GetDevice().vkFreeCommandBuffers(m_pool->GetDevice(), *m_pool, 1, &m_handle); } inline VkResult CommandBuffer::GetLastErrorCode() const From 230a42ca883f4a34180f4a288913f7bd1c5bd0e8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 09:04:29 +0200 Subject: [PATCH 079/224] Vulkan/Device: Improve and rename GetDeviceQueue method Former-commit-id: 05c53b64d79411cc093d885457f0c7eb68364059 --- include/Nazara/Vulkan/VkDevice.hpp | 2 +- include/Nazara/Vulkan/VkDevice.inl | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 084aaa2f0..8f915e965 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -34,7 +34,7 @@ namespace Nz bool Create(VkPhysicalDevice device, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline void Destroy(); - inline void GetDeviceQueue(UInt32 queueFamilyIndex, UInt32 queueIndex, VkQueue* queue); + inline VkQueue GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex); inline Instance& GetInstance(); inline const Instance& GetInstance() const; inline VkResult GetLastErrorCode() const; diff --git a/include/Nazara/Vulkan/VkDevice.inl b/include/Nazara/Vulkan/VkDevice.inl index e837f67f6..471107c84 100644 --- a/include/Nazara/Vulkan/VkDevice.inl +++ b/include/Nazara/Vulkan/VkDevice.inl @@ -31,9 +31,12 @@ namespace Nz } } - inline void Device::GetDeviceQueue(UInt32 queueFamilyIndex, UInt32 queueIndex, VkQueue* queue) + inline VkQueue Device::GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex) { - return vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, queue); + VkQueue queue; + vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, &queue); + + return queue; } inline Instance& Device::GetInstance() From 5b7476eab778d9dd803bb1da612a53965d747b05 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 09:07:31 +0200 Subject: [PATCH 080/224] Vulkan/Swapchain: Wrap images creation/getters Former-commit-id: 285c51718f7e7aed6bb92e1a66a5ef83f78cb477 --- include/Nazara/Vulkan/VkSwapchain.hpp | 10 +++++ include/Nazara/Vulkan/VkSwapchain.inl | 53 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/Nazara/Vulkan/VkSwapchain.hpp b/include/Nazara/Vulkan/VkSwapchain.hpp index ea47970d5..374ad88e6 100644 --- a/include/Nazara/Vulkan/VkSwapchain.hpp +++ b/include/Nazara/Vulkan/VkSwapchain.hpp @@ -24,6 +24,14 @@ namespace Nz Swapchain(Swapchain&&) = default; ~Swapchain() = default; + inline bool AcquireNextImage(Nz::UInt64 timeout, VkSemaphore semaphore, VkFence fence, UInt32* imageIndex); + + inline bool Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + + inline VkImage GetImage(UInt32 index) const; + inline const std::vector& GetImages() const; + inline UInt32 GetImageCount() const; + inline bool IsSupported() const; Swapchain& operator=(const Swapchain&) = delete; @@ -32,6 +40,8 @@ namespace Nz private: static VkResult CreateHelper(Device& device, const VkSwapchainCreateInfoKHR* createInfo, const VkAllocationCallbacks* allocator, VkSwapchainKHR* handle); static void DestroyHelper(Device& device, VkSwapchainKHR handle, const VkAllocationCallbacks* allocator); + + std::vector m_images; }; } } diff --git a/include/Nazara/Vulkan/VkSwapchain.inl b/include/Nazara/Vulkan/VkSwapchain.inl index e05dfefd3..8865012e4 100644 --- a/include/Nazara/Vulkan/VkSwapchain.inl +++ b/include/Nazara/Vulkan/VkSwapchain.inl @@ -16,6 +16,59 @@ namespace Nz { } + inline bool Swapchain::AcquireNextImage(Nz::UInt64 timeout, VkSemaphore semaphore, VkFence fence, UInt32* imageIndex) + { + m_lastErrorCode = m_device.vkAcquireNextImageKHR(m_device, m_handle, timeout, semaphore, fence, imageIndex); + switch (m_lastErrorCode) + { + case VkResult::VK_SUBOPTIMAL_KHR: + case VkResult::VK_SUCCESS: + return true; + + default: + return false; + } + } + + inline bool Swapchain::Create(const VkSwapchainCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + if (!DeviceObject::Create(createInfo, allocator)) + return false; + + UInt32 imageCount = 0; + m_lastErrorCode = m_device.vkGetSwapchainImagesKHR(m_device, m_handle, &imageCount, nullptr); + if (m_lastErrorCode != VkResult::VK_SUCCESS || imageCount == 0) + { + NazaraError("Failed to query swapchain image count"); + return false; + } + + m_images.resize(imageCount); + m_lastErrorCode = m_device.vkGetSwapchainImagesKHR(m_device, m_handle, &imageCount, m_images.data()); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to query swapchain images"); + return false; + } + + return true; + } + + inline VkImage Swapchain::GetImage(UInt32 index) const + { + return m_images[index]; + } + + inline const std::vector& Swapchain::GetImages() const + { + return m_images; + } + + inline UInt32 Swapchain::GetImageCount() const + { + return m_images.size(); + } + inline bool Swapchain::IsSupported() const { if (!m_device.IsExtensionLoaded("VK_KHR_swapchain")) From 7e63e8fdb6d2478f91ae41ef703ab928a6b2c739 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 18:33:47 +0200 Subject: [PATCH 081/224] Vulkan: Wrap vulkan queues Former-commit-id: 9fff47e3efbb8ce7b2c70be9a468627b7e8a1340 --- build/scripts/features/index_template.html | 140 ++++++------ build/scripts/features/style.css | 240 ++++++++++----------- include/Nazara/Vulkan/VkDevice.hpp | 3 +- include/Nazara/Vulkan/VkDevice.inl | 5 +- include/Nazara/Vulkan/VkQueue.hpp | 52 +++++ include/Nazara/Vulkan/VkQueue.inl | 102 +++++++++ 6 files changed, 349 insertions(+), 193 deletions(-) create mode 100644 include/Nazara/Vulkan/VkQueue.hpp create mode 100644 include/Nazara/Vulkan/VkQueue.inl diff --git a/build/scripts/features/index_template.html b/build/scripts/features/index_template.html index 43bf5aea9..852811a4c 100644 --- a/build/scripts/features/index_template.html +++ b/build/scripts/features/index_template.html @@ -1,71 +1,71 @@ - - - - - - Avancement de Nazara - - -
- Nazara Engine - -
- - Retrouvez le moteur sur GitHub !
- Dépôt GitHub

- Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
- OpenClassrooms, Progdupeupl ou ZesteDeSavoir -

- ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? - -
- -

Fonctionnalités de Nazara

- -
Dernière mise à jour : - %DATE% -
- -

Important:

-

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. - C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
- Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

- -

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
- Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

- -

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
- Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

- -
- - - - - - - - - - - %MODULELIST% - -
Sommaire
ModuleAvancement
- - %MODULEDESCRIPTION% -
- - - - - - - - - - %MODULELIST% - -
Sommaire
ModulePourcentage
-
- + + + + + + Avancement de Nazara + + +
+ Nazara Engine + +
+ + Retrouvez le moteur sur GitHub !
+ Dépôt GitHub

+ Venez vous renseigner sur les topics dédiés à Nazara présents sur plusieurs sites web :
+ OpenClassrooms, Progdupeupl ou ZesteDeSavoir +

+ ... ou pourquoi ne pas venir faire un tour sur le forum dédié au moteur ? + +
+ +

Fonctionnalités de Nazara

+ +
Dernière mise à jour : + %DATE% +
+ +

Important:

+

Afin de faciliter la mise à jour, la page que vous voyez ici a été générée automatiquement par un script Lua, ce qui m'oblige néanmoins à encoder les fonctionnalités de chaque module dans un premier temps. + C'est un travail assez long (pour vous donner une idée, les données du noyau représentent un fichier de 200 lignes), et il n'est pas encore complet, c'est pourquoi des modules manquent sur cette page.
+ Gardez donc à l'esprit que le moteur possède plus de fonctionnalités que ce qui est décrit actuellement sur cette page.

+ +

Oh et bien sûr je ne suis pas concepteur de site web, c'est pourquoi cette page est moche (j'ai essayé de minimiser les dégâts).
+ Si vous sentez en vous l'irrésistible envie d'améliorer cette page, sachez que votre aide serait grandement appréciée (vous pouvez me contacter via le lien de votre choix plus haut).

+ +

Le pourcentage indiqué est calculé automatiquement en fonction des fonctionnalités, cela signifie qu'une fonctionnalité présente sera comptée à 100% à partir du moment où son implémentation de base est considérée fonctionnelle, cela n'est donc pas une assurance qu'aucun bug n'existe concernant cette fonctionnalité (cependant cela signifie que la fonctionnalité est utilisable).
+ Et bien entendu, un module ou une fonctionnalité ayant atteint les 100% peut toujours évoluer par la suite.

+ +
+ + + + + + + + + + + %MODULELIST% + +
Sommaire
ModuleAvancement
+ + %MODULEDESCRIPTION% +
+ + + + + + + + + + %MODULELIST% + +
Sommaire
ModulePourcentage
+
+ \ No newline at end of file diff --git a/build/scripts/features/style.css b/build/scripts/features/style.css index ff83f706c..189b2a090 100644 --- a/build/scripts/features/style.css +++ b/build/scripts/features/style.css @@ -1,121 +1,121 @@ -/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ - -body -{ - font-family: sans-serif; - text-align: center; - margin: 0; - background-color: #f1f1f1; -} - -#englob { - display: block; - margin-left: auto; - margin-right: auto; - background-color: white; - width: 50%; - min-width: 765px; - padding: 0 20px; -} - -hr { - height: 0; - border: 0; - border-top: 1px solid #eee; -} - -a -{ - color: #007ACC; -} - -a:hover -{ - color: lightblue; -} - -h1 -{ - display: inline; -} - -h2 -{ - display: inline; - text-decoration: underline; -} - -h4 -{ - text-decoration: underline; -} - -p { - text-align: justify; -} - -ol -{ - list-style-type: none; -} - -table -{ - border-collapse: collapse; - text-align: center; - display: inline-block; - border: white groove; - border-radius: 10px; - box-shadow: 0px 0px 10px lightblue; -} - -th -{ - text-shadow: 2px 2px 4px black; -} - -tr -{ - border: 1px solid white; -} - -tbody tr:hover -{ - text-shadow: 0px 0px 4px white; -} - -.description -{ - margin-left: 20px; -} - -.lastupdate -{ - font-size: x-large; - font-weight: bold; - color: #f1c40f; -} - -.modulename -{ - font-size: x-large; - font-weight: bold; - text-shadow: 2px 2px 10px #007ACC; -} - -.note -{ - margin-left: 20px; - color: #007ACC; -} - -.notedesc -{ - color: rgb(200, 200, 255); -} - -.portability -{ - margin-left: 20px; - color: red; +/* Je ne suis pas développeur HTML/CSS, je dois y toucher une fois l'an, désolé pour les quelques atrocités que vous pourrez trouver ici */ + +body +{ + font-family: sans-serif; + text-align: center; + margin: 0; + background-color: #f1f1f1; +} + +#englob { + display: block; + margin-left: auto; + margin-right: auto; + background-color: white; + width: 50%; + min-width: 765px; + padding: 0 20px; +} + +hr { + height: 0; + border: 0; + border-top: 1px solid #eee; +} + +a +{ + color: #007ACC; +} + +a:hover +{ + color: lightblue; +} + +h1 +{ + display: inline; +} + +h2 +{ + display: inline; + text-decoration: underline; +} + +h4 +{ + text-decoration: underline; +} + +p { + text-align: justify; +} + +ol +{ + list-style-type: none; +} + +table +{ + border-collapse: collapse; + text-align: center; + display: inline-block; + border: white groove; + border-radius: 10px; + box-shadow: 0px 0px 10px lightblue; +} + +th +{ + text-shadow: 2px 2px 4px black; +} + +tr +{ + border: 1px solid white; +} + +tbody tr:hover +{ + text-shadow: 0px 0px 4px white; +} + +.description +{ + margin-left: 20px; +} + +.lastupdate +{ + font-size: x-large; + font-weight: bold; + color: #f1c40f; +} + +.modulename +{ + font-size: x-large; + font-weight: bold; + text-shadow: 2px 2px 10px #007ACC; +} + +.note +{ + margin-left: 20px; + color: #007ACC; +} + +.notedesc +{ + color: rgb(200, 200, 255); +} + +.portability +{ + margin-left: 20px; + color: red; } \ No newline at end of file diff --git a/include/Nazara/Vulkan/VkDevice.hpp b/include/Nazara/Vulkan/VkDevice.hpp index 8f915e965..1b9d3a470 100644 --- a/include/Nazara/Vulkan/VkDevice.hpp +++ b/include/Nazara/Vulkan/VkDevice.hpp @@ -19,6 +19,7 @@ namespace Nz namespace Vk { class Device; + class Queue; class Instance; using DeviceHandle = ObjectHandle; @@ -34,7 +35,7 @@ namespace Nz bool Create(VkPhysicalDevice device, const VkDeviceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); inline void Destroy(); - inline VkQueue GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex); + inline Queue GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex); inline Instance& GetInstance(); inline const Instance& GetInstance() const; inline VkResult GetLastErrorCode() const; diff --git a/include/Nazara/Vulkan/VkDevice.inl b/include/Nazara/Vulkan/VkDevice.inl index 471107c84..77dc1e254 100644 --- a/include/Nazara/Vulkan/VkDevice.inl +++ b/include/Nazara/Vulkan/VkDevice.inl @@ -5,6 +5,7 @@ #include #include #include +#include #include namespace Nz @@ -31,12 +32,12 @@ namespace Nz } } - inline VkQueue Device::GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex) + inline Queue Device::GetQueue(UInt32 queueFamilyIndex, UInt32 queueIndex) { VkQueue queue; vkGetDeviceQueue(m_device, queueFamilyIndex, queueIndex, &queue); - return queue; + return Queue(*this, queue); } inline Instance& Device::GetInstance() diff --git a/include/Nazara/Vulkan/VkQueue.hpp b/include/Nazara/Vulkan/VkQueue.hpp new file mode 100644 index 000000000..35c8d16e0 --- /dev/null +++ b/include/Nazara/Vulkan/VkQueue.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKQUEUE_HPP +#define NAZARA_VULKAN_VKQUEUE_HPP + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Queue + { + public: + inline Queue(Device& device, VkQueue queue); + inline Queue(const Queue& queue); + inline Queue(Queue&& queue); + inline ~Queue() = default; + + inline Device& GetDevice(); + inline VkResult GetLastErrorCode() const; + + inline bool Present(const VkPresentInfoKHR& presentInfo); + inline bool Present(VkSwapchainKHR swapchain, UInt32 imageIndex, VkSemaphore waitSemaphore = VK_NULL_HANDLE); + + inline bool Submit(const VkSubmitInfo& submit, VkFence fence = VK_NULL_HANDLE); + inline bool Submit(UInt32 submitCount, const VkSubmitInfo* submits, VkFence fence = VK_NULL_HANDLE); + + inline bool WaitIdle(); + + Queue& operator=(const Queue& queue) = delete; + Queue& operator=(Queue&&) = delete; + + inline operator VkQueue(); + + protected: + Device& m_device; + VkQueue m_handle; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // NAZARA_VULKAN_VKQUEUE_HPP diff --git a/include/Nazara/Vulkan/VkQueue.inl b/include/Nazara/Vulkan/VkQueue.inl new file mode 100644 index 000000000..a47918da3 --- /dev/null +++ b/include/Nazara/Vulkan/VkQueue.inl @@ -0,0 +1,102 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Queue::Queue(Device& device, VkQueue queue) : + m_device(device), + m_handle(queue), + m_lastErrorCode(VkResult::VK_SUCCESS) + { + } + + inline Queue::Queue(const Queue& queue) : + m_device(queue.m_device), + m_handle(queue.m_handle), + m_lastErrorCode(queue.m_lastErrorCode) + { + } + + inline Queue::Queue(Queue&& queue) : + m_device(queue.m_device), + m_handle(queue.m_handle), + m_lastErrorCode(queue.m_lastErrorCode) + { + } + + inline Device& Queue::GetDevice() + { + return m_device; + } + + inline VkResult Queue::GetLastErrorCode() const + { + return m_lastErrorCode; + } + + inline bool Queue::Present(const VkPresentInfoKHR& presentInfo) + { + m_lastErrorCode = m_device.vkQueuePresentKHR(m_handle, &presentInfo); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + return false; + + return true; + } + + inline bool Queue::Present(VkSwapchainKHR swapchain, UInt32 imageIndex, VkSemaphore waitSemaphore) + { + VkPresentInfoKHR presentInfo = + { + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + nullptr, + (waitSemaphore) ? 1U : 0U, + &waitSemaphore, + 1U, + &swapchain, + &imageIndex, + nullptr + }; + + return Present(presentInfo); + } + + inline bool Queue::Submit(const VkSubmitInfo& submit, VkFence fence) + { + return Submit(1, &submit, fence); + } + + inline bool Queue::Submit(UInt32 submitCount, const VkSubmitInfo* submits, VkFence fence) + { + m_lastErrorCode = m_device.vkQueueSubmit(m_handle, submitCount, submits, fence); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + return false; + + return true; + } + + inline bool Queue::WaitIdle() + { + m_lastErrorCode = m_device.vkQueueWaitIdle(m_handle); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + return false; + + return true; + } + + inline Queue::operator VkQueue() + { + return m_handle; + } + + } +} + +#include From 80e26a86bef16124d454bccd97cb3aa6e13e1cb5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 May 2016 18:34:03 +0200 Subject: [PATCH 082/224] Vulkan/CommandBuffer: Add Begin/End overloads Former-commit-id: faab408f445aeb74a8d231590825e53648db7817 --- include/Nazara/Vulkan/VkCommandBuffer.hpp | 10 ++- include/Nazara/Vulkan/VkCommandBuffer.inl | 98 +++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Vulkan/VkCommandBuffer.hpp b/include/Nazara/Vulkan/VkCommandBuffer.hpp index 0399d4cf7..2dea341dd 100644 --- a/include/Nazara/Vulkan/VkCommandBuffer.hpp +++ b/include/Nazara/Vulkan/VkCommandBuffer.hpp @@ -23,7 +23,15 @@ namespace Nz CommandBuffer(const CommandBuffer&) = delete; CommandBuffer(CommandBuffer&& commandBuffer); inline ~CommandBuffer(); - + + inline bool Begin(const VkCommandBufferBeginInfo& info); + inline bool Begin(VkCommandBufferUsageFlags flags); + inline bool Begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo& inheritanceInfo); + inline bool Begin(VkCommandBufferUsageFlags flags, VkRenderPass renderPass, UInt32 subpass, VkFramebuffer framebuffer, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics); + inline bool Begin(VkCommandBufferUsageFlags flags, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics); + + inline bool End(); + inline void Free(); inline VkResult GetLastErrorCode() const; diff --git a/include/Nazara/Vulkan/VkCommandBuffer.inl b/include/Nazara/Vulkan/VkCommandBuffer.inl index 7e48901c2..d9944e33b 100644 --- a/include/Nazara/Vulkan/VkCommandBuffer.inl +++ b/include/Nazara/Vulkan/VkCommandBuffer.inl @@ -31,6 +31,104 @@ namespace Nz Free(); } + inline bool CommandBuffer::Begin(const VkCommandBufferBeginInfo& info) + { + m_lastErrorCode = m_pool->GetDevice().vkBeginCommandBuffer(m_handle, &info); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to begin command buffer"); + return false; + } + + return true; + } + + inline bool CommandBuffer::Begin(VkCommandBufferUsageFlags flags) + { + VkCommandBufferBeginInfo beginInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + nullptr, + flags, + nullptr + }; + + return Begin(beginInfo); + } + + inline bool CommandBuffer::Begin(VkCommandBufferUsageFlags flags, const VkCommandBufferInheritanceInfo& inheritanceInfo) + { + VkCommandBufferBeginInfo beginInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + nullptr, + flags, + &inheritanceInfo + }; + + return Begin(beginInfo); + } + + inline bool CommandBuffer::Begin(VkCommandBufferUsageFlags flags, VkRenderPass renderPass, UInt32 subpass, VkFramebuffer framebuffer, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics) + { + NazaraAssert(flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, "Continue bit is required to ignore renderPass, subpass and framebuffer"); + + VkCommandBufferInheritanceInfo inheritanceInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + nullptr, + renderPass, + subpass, + framebuffer, + (occlusionQueryEnable) ? VK_TRUE : VK_FALSE, + queryFlags, + pipelineStatistics + }; + + VkCommandBufferBeginInfo beginInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + nullptr, + flags, + &inheritanceInfo + }; + + return Begin(beginInfo); + } + + inline bool CommandBuffer::Begin(VkCommandBufferUsageFlags flags, bool occlusionQueryEnable, VkQueryControlFlags queryFlags, VkQueryPipelineStatisticFlags pipelineStatistics) + { + NazaraAssert(flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, "Continue bit is required to ignore renderPass, subpass and framebuffer"); + + VkCommandBufferInheritanceInfo inheritanceInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, + nullptr, + VK_NULL_HANDLE, + 0, + VK_NULL_HANDLE, + (occlusionQueryEnable) ? VK_TRUE : VK_FALSE, + queryFlags, + pipelineStatistics + }; + + VkCommandBufferBeginInfo beginInfo = { + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + nullptr, + flags, + &inheritanceInfo + }; + + return Begin(beginInfo); + } + + inline bool CommandBuffer::End() + { + m_lastErrorCode = m_pool->GetDevice().vkEndCommandBuffer(m_handle); + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to end command buffer"); + return false; + } + + return true; + } + inline void CommandBuffer::Free() { if (m_handle) From 8a3339badf88a01c22bc7ba8be65db1f4609e6d6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 May 2016 13:52:10 +0200 Subject: [PATCH 083/224] Fix some GCC warnings Former-commit-id: 31c8460b4656c29ac165d7aa28f335851f2565df --- .../NDK/Components/CameraComponent.inl | 4 +- .../NDK/Components/GraphicsComponent.inl | 3 +- SDK/include/NDK/LuaAPI.inl | 4 ++ SDK/src/NDK/Console.cpp | 5 +++ SDK/src/NDK/LuaBinding.cpp | 4 +- SDK/src/NDK/LuaBinding_Audio.cpp | 18 +++++---- SDK/src/NDK/LuaBinding_Math.cpp | 38 ++++++++++++++++++- include/Nazara/Core/Algorithm.inl | 4 +- include/Nazara/Core/HandledObject.inl | 3 +- include/Nazara/Graphics/Light.inl | 2 +- include/Nazara/Lua/LuaClass.inl | 10 +++-- include/Nazara/Network/IpAddress.inl | 8 ++-- include/Nazara/Network/TcpClient.hpp | 2 +- include/Nazara/Utility/PixelFormat.inl | 28 +++++++------- src/Nazara/Core/File.cpp | 6 +-- src/Nazara/Core/ParameterList.cpp | 13 +++++-- src/Nazara/Graphics/ForwardRenderQueue.cpp | 6 +-- src/Nazara/Renderer/RenderTexture.cpp | 5 ++- src/Nazara/Utility/AlgorithmUtility.cpp | 4 +- 19 files changed, 113 insertions(+), 54 deletions(-) diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index d3bb9177e..d91c357eb 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -11,8 +11,8 @@ namespace Ndk inline CameraComponent::CameraComponent() : m_projectionType(Nz::ProjectionType_Perspective), m_targetRegion(0.f, 0.f, 1.f, 1.f), - m_size(0.f), m_target(nullptr), + m_size(0.f), m_frustumUpdated(false), m_projectionMatrixUpdated(false), m_viewMatrixUpdated(false), @@ -30,8 +30,8 @@ namespace Ndk AbstractViewer(camera), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), - m_size(camera.m_size), m_target(nullptr), + m_size(camera.m_size), m_frustumUpdated(false), m_projectionMatrixUpdated(false), m_viewMatrixUpdated(false), diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 205eb9462..c330da5eb 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -8,6 +8,7 @@ namespace Ndk { inline GraphicsComponent::GraphicsComponent(const GraphicsComponent& graphicsComponent) : Component(graphicsComponent), + HandledObject(graphicsComponent), m_boundingVolume(graphicsComponent.m_boundingVolume), m_transformMatrix(graphicsComponent.m_transformMatrix), m_boundingVolumeUpdated(graphicsComponent.m_boundingVolumeUpdated), @@ -41,7 +42,7 @@ namespace Ndk r.data.renderOrder = renderOrder; r.renderable = std::move(renderable); r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1)); - + InvalidateBoundingVolume(); } diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index ae2da917c..a42479cae 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -84,8 +84,12 @@ namespace Nz inline unsigned int LuaImplQueryArg(const LuaInstance& instance, int index, FontParams* params, TypeTag) { + NazaraUnused(params); + instance.CheckType(index, Nz::LuaType_Table); + // Structure is empty for now + return 1; } diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 24a5d8df2..48ad10196 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -145,6 +145,7 @@ namespace Ndk { case Nz::Keyboard::Down: case Nz::Keyboard::Up: + { if (event.key.code == Nz::Keyboard::Up) m_historyPosition = std::min(m_commandHistory.size(), m_historyPosition + 1); else @@ -159,6 +160,10 @@ namespace Ndk m_inputDrawer.SetText(s_inputPrefix + text); m_inputTextSprite->Update(m_inputDrawer); break; + } + + default: + break; } break; } diff --git a/SDK/src/NDK/LuaBinding.cpp b/SDK/src/NDK/LuaBinding.cpp index 33c70dbe1..6acc05a46 100644 --- a/SDK/src/NDK/LuaBinding.cpp +++ b/SDK/src/NDK/LuaBinding.cpp @@ -29,8 +29,8 @@ namespace Ndk // SDK application("Application"), - nodeComponent("NodeComponent"), entityClass("Entity"), + nodeComponent("NodeComponent"), velocityComponent("VelocityComponent"), worldClass("World") @@ -39,9 +39,9 @@ namespace Ndk // Audio musicClass("Music"), + soundClass("Sound"), soundBuffer("SoundBuffer"), soundEmitter("SoundEmitter"), - soundClass("Sound"), // Graphics instancedRenderable("InstancedRenderable"), diff --git a/SDK/src/NDK/LuaBinding_Audio.cpp b/SDK/src/NDK/LuaBinding_Audio.cpp index d75c8215e..89452d720 100644 --- a/SDK/src/NDK/LuaBinding_Audio.cpp +++ b/SDK/src/NDK/LuaBinding_Audio.cpp @@ -76,6 +76,8 @@ namespace Ndk /*********************************** Nz::SoundBuffer **********************************/ soundBuffer.SetConstructor([] (Nz::LuaInstance& lua, Nz::SoundBufferRef* instance) { + NazaraUnused(lua); + Nz::PlacementNew(instance, Nz::SoundBuffer::New()); return true; }); @@ -115,16 +117,16 @@ namespace Ndk return 1; }); - soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& soundBuffer) -> int + soundBuffer.BindMethod("__tostring", [] (Nz::LuaInstance& lua, Nz::SoundBufferRef& instance) -> int { Nz::StringStream stream("SoundBuffer("); - if (soundBuffer->IsValid()) + if (instance->IsValid()) { - Nz::String filePath = soundBuffer->GetFilePath(); + Nz::String filePath = instance->GetFilePath(); if (!filePath.IsEmpty()) stream << "File: " << filePath << ", "; - - stream << "Duration: " << soundBuffer->GetDuration() / 1000.f << "s"; + + stream << "Duration: " << instance->GetDuration() / 1000.f << "s"; } stream << ')'; @@ -148,17 +150,17 @@ namespace Ndk soundEmitter.BindMethod("IsLooping", &Nz::SoundEmitter::IsLooping); soundEmitter.BindMethod("IsSpatialized", &Nz::SoundEmitter::IsSpatialized); - + soundEmitter.BindMethod("Pause", &Nz::SoundEmitter::Pause); soundEmitter.BindMethod("Play", &Nz::SoundEmitter::Play); - + soundEmitter.BindMethod("SetAttenuation", &Nz::SoundEmitter::SetAttenuation); soundEmitter.BindMethod("SetMinDistance", &Nz::SoundEmitter::SetMinDistance); soundEmitter.BindMethod("SetPitch", &Nz::SoundEmitter::SetPitch); soundEmitter.BindMethod("SetPosition", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetPosition); soundEmitter.BindMethod("SetVelocity", (void(Nz::SoundEmitter::*)(const Nz::Vector3f&)) &Nz::SoundEmitter::SetVelocity); soundEmitter.BindMethod("SetVolume", &Nz::SoundEmitter::SetVolume); - + soundEmitter.BindMethod("Stop", &Nz::SoundEmitter::Stop); } diff --git a/SDK/src/NDK/LuaBinding_Math.cpp b/SDK/src/NDK/LuaBinding_Math.cpp index cf5454450..7db9ae9e2 100644 --- a/SDK/src/NDK/LuaBinding_Math.cpp +++ b/SDK/src/NDK/LuaBinding_Math.cpp @@ -238,9 +238,15 @@ namespace Ndk case 'h': lua.Push(instance.height); return true; + + default: + break; } break; } + + default: + break; } return false; @@ -290,6 +296,9 @@ namespace Ndk } break; } + + default: + break; } return false; @@ -313,7 +322,7 @@ namespace Ndk Nz::PlacementNew(quaternion, *static_cast(lua.ToUserdata(1))); else break; - + return true; } @@ -389,6 +398,9 @@ namespace Ndk case 'z': instance.z = value; return true; + + default: + break; } return false; @@ -455,9 +467,15 @@ namespace Ndk case 'y': lua.Push(instance.y); return true; + + default: + break; } break; } + + default: + break; } return false; @@ -496,9 +514,15 @@ namespace Ndk case 'y': instance.y = value; return true; + + default: + break; } break; } + + default: + break; } return false; @@ -582,9 +606,15 @@ namespace Ndk case 'z': lua.Push(instance.z); return true; + + default: + break; } break; } + + default: + break; } return false; @@ -627,9 +657,15 @@ namespace Ndk case 'z': instance.z = value; return true; + + default: + break; } break; } + + default: + break; } return false; diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 72b5ee27a..048fae8e9 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -78,7 +78,7 @@ namespace Nz * \param v Object to hash * * \remark a HashAppend specialization for type T is required - * + * * \see ComputeHash */ template @@ -178,7 +178,7 @@ namespace Nz { T reversed = 0; for (std::size_t i = 0; i < sizeof(T); ++i) - reversed |= T(Detail::BitReverseTable256[(integer >> i * 8) & 0xFF]) << sizeof(T) * 8 - (i + 1) * 8; + reversed |= T(Detail::BitReverseTable256[(integer >> i * 8) & 0xFF]) << (sizeof(T) * 8 - (i + 1) * 8); return reversed; } diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl index 738a5f7a5..da435302e 100644 --- a/include/Nazara/Core/HandledObject.inl +++ b/include/Nazara/Core/HandledObject.inl @@ -13,6 +13,7 @@ namespace Nz template HandledObject::HandledObject(const HandledObject& object) { + NazaraUnused(object); // Don't copy anything, we're a copy of the object, we have no handle right now } @@ -40,7 +41,7 @@ namespace Nz HandledObject& HandledObject::operator=(const HandledObject& object) { // Nothing to do - return *this; + return *this; } template diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index e877852cb..edff48a66 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -9,9 +9,9 @@ namespace Nz { inline Light::Light(const Light& light) : Renderable(light), + m_color(light.m_color), 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), diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 710b50416..89487b653 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -21,6 +21,8 @@ namespace Nz { SetConstructor([] (Nz::LuaInstance& lua, T* instance) { + NazaraUnused(lua); + PlacementNew(instance); return true; }); @@ -132,9 +134,9 @@ namespace Nz lua.SetField(pair.first); // Method name } - m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& lua) + m_info->instanceGetters[m_info->name] = [info = m_info] (LuaInstance& instance) { - return static_cast(lua.CheckUserdata(1, info->name)); + return static_cast(instance.CheckUserdata(1, info->name)); }; } lua.Pop(); // On pop la metatable @@ -391,11 +393,11 @@ namespace Nz if (!lua.IsValid(-1)) { - for (const ParentFunc& getter : info->parentGetters) + for (const ParentFunc& parentGetter : info->parentGetters) { lua.Pop(); //< Pop the last nil value - getter(lua, instance); + parentGetter(lua, instance); if (lua.IsValid(-1)) return; } diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index c11c1879a..3184bd34d 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -224,7 +224,7 @@ namespace std // This is SDBM adapted for IP addresses, tested to generate the least collisions possible // (It doesn't mean it cannot be improved though) - std::size_t hash = 0; + std::size_t h = 0; switch (ip.GetProtocol()) { case Nz::NetProtocol_Any: @@ -233,20 +233,20 @@ namespace std case Nz::NetProtocol_IPv4: { - hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash; + h = ip.ToUInt32() + (h << 6) + (h << 16) - h; break; } case Nz::NetProtocol_IPv6: { Nz::IpAddress::IPv6 v6 = ip.ToIPv6(); for (std::size_t i = 0; i < v6.size(); i++) - hash = v6[i] + (hash << 6) + (hash << 16) - hash; + h = v6[i] + (h << 6) + (h << 16) - h; break; } } - return ip.GetPort() + (hash << 6) + (hash << 16) - hash; + return ip.GetPort() + (h << 6) + (h << 16) - h; } }; } diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index fda4671f9..0fcedcf39 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -79,8 +79,8 @@ namespace Nz PendingPacket m_pendingPacket; UInt64 m_keepAliveInterval; UInt64 m_keepAliveTime; - bool m_isLowDelayEnabled; bool m_isKeepAliveEnabled; + bool m_isLowDelayEnabled; }; } diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 7b05ec8fb..e30701d3d 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -12,29 +12,29 @@ namespace Nz { inline PixelFormatInfo::PixelFormatInfo() : - bitsPerPixel(0), - content(PixelFormatContent_Undefined) + content(PixelFormatContent_Undefined), + bitsPerPixel(0) { } inline PixelFormatInfo::PixelFormatInfo(PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType) : - bitsPerPixel(bpp), - content(formatContent), - redType(subType), - greenType(subType), - blueType(subType), - alphaType(subType) - { - } - - inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType) : - bitsPerPixel(bpp), content(formatContent), redType(subType), greenType(subType), blueType(subType), alphaType(subType), - name(formatName) + bitsPerPixel(bpp) + { + } + + inline PixelFormatInfo::PixelFormatInfo(const String& formatName, PixelFormatContent formatContent, UInt8 bpp, PixelFormatSubType subType) : + content(formatContent), + redType(subType), + greenType(subType), + blueType(subType), + alphaType(subType), + name(formatName), + bitsPerPixel(bpp) { } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 97504b0ee..39e873373 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -385,7 +385,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param pos Position of the cursor @@ -404,7 +404,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param offset Offset according to the cursor begin position @@ -906,5 +906,5 @@ namespace Nz } return true; - }; + } } diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 91426a0b7..371e91b77 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -94,6 +94,7 @@ namespace Nz break; } + case ParameterType_Color: case ParameterType_Float: case ParameterType_None: case ParameterType_Pointer: @@ -198,6 +199,7 @@ namespace Nz } case ParameterType_Boolean: + case ParameterType_Color: case ParameterType_None: case ParameterType_Pointer: case ParameterType_Userdata: @@ -207,7 +209,7 @@ namespace Nz NazaraError("Parameter value is not representable as a float"); return false; } - + /*! * \brief Gets a parameter as an integer * \return true if the parameter could be represented as an integer @@ -263,6 +265,7 @@ namespace Nz break; } + case ParameterType_Color: case ParameterType_None: case ParameterType_Pointer: case ParameterType_Userdata: @@ -331,6 +334,7 @@ namespace Nz return true; case ParameterType_Boolean: + case ParameterType_Color: case ParameterType_Float: case ParameterType_Integer: case ParameterType_None: @@ -411,7 +415,7 @@ namespace Nz NazaraInternalError("Parameter value is not valid"); return false; } - + /*! * \brief Gets a parameter as an userdata * \return true if the parameter could be represented as a userdata @@ -584,7 +588,7 @@ namespace Nz parameter.type = ParameterType_Integer; parameter.value.intVal = value; } - + /*! * \brief Sets a pointer parameter named `name` * @@ -593,7 +597,7 @@ namespace Nz * \param name Name of the parameter * \param value The pointer value * - * \remark This sets a raw pointer, this class takes no responsibility toward it, + * \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) @@ -639,6 +643,7 @@ namespace Nz switch (it->second.type) { case ParameterType_Boolean: + case ParameterType_Color: case ParameterType_Float: case ParameterType_Integer: case ParameterType_Pointer: diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 683230706..9f0f5d04d 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -524,9 +524,9 @@ namespace Nz Vector3f viewerPos = viewer->GetEyePosition(); Vector3f viewerNormal = viewer->GetForward(); - for (auto& pair : layers) + for (auto& layerPair : layers) { - Layer& layer = pair.second; + Layer& layer = layerPair.second; std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2) { @@ -562,7 +562,7 @@ namespace Nz auto it = layers.find(i); if (it == layers.end()) it = layers.insert(std::make_pair(i, Layer())).first; - + Layer& layer = it->second; layer.clearCount = 0; diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 0ae0d97bf..c6e78df86 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -57,11 +57,14 @@ namespace Nz case PixelFormatContent_Stencil: return AttachmentPoint_Stencil; + + case PixelFormatContent_Undefined: + break; } NazaraInternalError("Unexpected pixel format content: 0x" + String::Number(info.content, 16)); return AttachmentPoint_Max; - }; + } GLuint lockedPrevious = 0; UInt8 lockedLevel = 0; diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index b23542993..7f4dbaf44 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -105,9 +105,9 @@ namespace Nz for (unsigned int i = 0; i < recursionLevel; ++i) { std::size_t triangleCount = triangles.size(); - for (std::size_t i = 0; i < triangleCount; ++i) + for (std::size_t j = 0; j < triangleCount; ++j) { - Vector3ui& triangle = triangles[i]; + Vector3ui& triangle = triangles[j]; unsigned int a = GetMiddleVertex(triangle.x, triangle.y); unsigned int b = GetMiddleVertex(triangle.y, triangle.z); From 18868082fc88036c0ccd6c3d819c8549ba03feb7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 May 2016 07:41:32 +0200 Subject: [PATCH 084/224] Graphics/DepthRenderTechnique: Fix typo in include name Former-commit-id: 8ac7a886fbb406d1c03ceae5ea8ac71bb48364b7 --- include/Nazara/Graphics/DepthRenderTechnique.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index ac75f7e52..42b7f6e0a 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -74,6 +74,6 @@ namespace Nz } -#include +#include #endif // NAZARA_DEPTHRENDERTECHNIQUE_HPP From 6959e0bde6d4bda4d09aef792d043fcfd84cbabd Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 May 2016 08:48:22 +0200 Subject: [PATCH 085/224] Build: Improve build - Help linux default to 64bits build in case of 64bits OS - Fix linux linking with tools Former-commit-id: c6444a691a8b0be6e85b284c60cc3f43056eee01 --- build/scripts/common.lua | 60 +++++++++++++++++++++++------------ examples/FirstScene/build.lua | 4 --- examples/Tut01/build.lua | 4 --- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index ec95c2641..15bf69849 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -5,12 +5,19 @@ function NazaraBuild:Execute() return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien end + local platformData + if (os.is64bit()) then + platformData = {"x64", "x86"} + else + platformData = {"x64", "x86"} + end + if (self.Actions[_ACTION] == nil) then local makeLibDir = os.is("windows") and "mingw" or "gmake" if (#self.OrderedExtLibs > 0) then workspace("NazaraExtlibs") - platforms({"x32", "x64"}) + platforms(platformData) -- Configuration générale configurations({ @@ -23,13 +30,13 @@ function NazaraBuild:Execute() location(_ACTION) kind("StaticLib") - configuration("x32") + configuration("x86") libdirs("../extlibs/lib/common/x86") configuration("x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x32"}) + configuration({"codeblocks or codelite or gmake", "x86"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") @@ -40,7 +47,7 @@ function NazaraBuild:Execute() configuration("vs*") buildoptions("/MP") - configuration({"vs*", "x32"}) + configuration({"vs*", "x86"}) libdirs("../extlibs/lib/msvc/x86") targetdir("../extlibs/lib/msvc/x86") @@ -48,7 +55,7 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/msvc/x64") targetdir("../extlibs/lib/msvc/x64") - configuration({"xcode3 or xcode4", "x32"}) + configuration({"xcode3 or xcode4", "x86"}) libdirs("../extlibs/lib/xcode/x86") targetdir("../extlibs/lib/xcode/x86") @@ -102,7 +109,7 @@ function NazaraBuild:Execute() end workspace("NazaraEngine") - platforms({"x32", "x64"}) + platforms(platformData) -- Configuration générale configurations({ @@ -171,14 +178,14 @@ function NazaraBuild:Execute() libdirs("../lib") libdirs("../extlibs/lib/common") - configuration("x32") + configuration("x86") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x32"}) + configuration({"codeblocks or codelite or gmake", "x86"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86") targetdir("../lib/" .. makeLibDir .. "/x86") @@ -193,7 +200,7 @@ function NazaraBuild:Execute() self:MakeCopyAfterBuild(moduleTable) end - configuration({"vs*", "x32"}) + configuration({"vs*", "x86"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") targetdir("../lib/msvc/x86") @@ -203,7 +210,7 @@ function NazaraBuild:Execute() libdirs("../lib/msvc/x64") targetdir("../lib/msvc/x64") - configuration({"xcode3 or xcode4", "x32"}) + configuration({"xcode3 or xcode4", "x86"}) libdirs("../extlibs/lib/xcode/x86") libdirs("../lib/xcode/x86") targetdir("../lib/xcode/x86") @@ -278,20 +285,20 @@ function NazaraBuild:Execute() libdirs("../lib") libdirs("../extlibs/lib/common") - configuration("x32") + configuration("x86") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x32"}) + configuration({"codeblocks or codelite or gmake", "x86"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86") if (toolTable.Kind == "library") then targetdir("../lib/" .. makeLibDir .. "/x86") elseif (toolTable.Kind == "plugin") then - targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x32") + targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x86") end configuration({"codeblocks or codelite or gmake", "x64"}) @@ -308,7 +315,7 @@ function NazaraBuild:Execute() self:MakeCopyAfterBuild(toolTable) end - configuration({"vs*", "x32"}) + configuration({"vs*", "x86"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") if (toolTable.Kind == "library") then @@ -326,7 +333,7 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x64") end - configuration({"xcode3 or xcode4", "x32"}) + configuration({"xcode3 or xcode4", "x86"}) libdirs("../extlibs/lib/xcode/x86") libdirs("../lib/xcode/x86") if (toolTable.Kind == "library") then @@ -406,26 +413,26 @@ function NazaraBuild:Execute() includedirs(exampleTable.Includes) links(exampleTable.Libraries) - configuration("x32") + configuration("x86") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x32"}) + configuration({"codeblocks or codelite or gmake", "x86"}) libdirs("../lib/" .. makeLibDir .. "/x86") configuration({"codeblocks or codelite or gmake", "x64"}) libdirs("../lib/" .. makeLibDir .. "/x64") - configuration({"vs*", "x32"}) + configuration({"vs*", "x86"}) libdirs("../lib/msvc/x86") configuration({"vs*", "x64"}) libdirs("../lib/msvc/x64") - configuration({"xcode3 or xcode4", "x32"}) + configuration({"xcode3 or xcode4", "x86"}) libdirs("../lib/xcode/x86") configuration({"xcode3 or xcode4", "x64"}) @@ -801,6 +808,17 @@ function NazaraBuild:Process(infoTable) for k,v in ipairs(toolTable.Includes) do table.insert(infoTable.Includes, v) end + + -- And libraries + for k, v in pairs(toolTable.Libraries) do + table.insert(infoTable.Libraries, v) + end + + for config, libs in pairs(toolTable.ConfigurationLibraries) do + for k,v in pairs(libs) do + table.insert(infoTable.ConfigurationLibraries[config], v) + end + end table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") @@ -853,8 +871,8 @@ function NazaraBuild:MakeCopyAfterBuild(infoTable) for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do local paths = {} - table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) - table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) + table.insert(paths, {"x86", "../extlibs/lib/common/x86/" .. v .. ".dll"}) + table.insert(paths, {"x86", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) diff --git a/examples/FirstScene/build.lua b/examples/FirstScene/build.lua index bdcdf8bca..14bf8a42f 100644 --- a/examples/FirstScene/build.lua +++ b/examples/FirstScene/build.lua @@ -7,9 +7,5 @@ EXAMPLE.Files = { } EXAMPLE.Libraries = { - "NazaraCore", - "NazaraGraphics", - "NazaraRenderer", - "NazaraUtility", "NazaraSDK" } diff --git a/examples/Tut01/build.lua b/examples/Tut01/build.lua index 03b4457ab..c12dc35b5 100644 --- a/examples/Tut01/build.lua +++ b/examples/Tut01/build.lua @@ -7,9 +7,5 @@ EXAMPLE.Files = { } EXAMPLE.Libraries = { - "NazaraCore", - "NazaraGraphics", - "NazaraRenderer", - "NazaraUtility", "NazaraSDK" } From 3e4051d82c9b24094e2ba012fddbbf8afeb35226 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 May 2016 08:50:49 +0200 Subject: [PATCH 086/224] Build: Fix linking for audio and utility system for POSIX Former-commit-id: b6bf529230e967996fa27d5636aeedc9f78d6e73 --- build/scripts/modules/audio.lua | 17 ++++++++++++----- build/scripts/modules/utility.lua | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/build/scripts/modules/audio.lua b/build/scripts/modules/audio.lua index 4fcb1bf5a..27e49a08c 100644 --- a/build/scripts/modules/audio.lua +++ b/build/scripts/modules/audio.lua @@ -5,19 +5,26 @@ MODULE.Defines = { } MODULE.Libraries = { - "NazaraCore", + "NazaraCore" +} + +MODULE.OsLibraries.Windows = { "sndfile-1" } +MODULE.OsLibraries.Posix = { + "sndfile" +} + +MODULE.OsDynLib.Windows = { + "soft_oal" +} + MODULE.OsFiles.Windows = { "../src/Nazara/Audio/Win32/**.hpp", "../src/Nazara/Audio/Win32/**.cpp" } -MODULE.OsDynLib.Windows = { - "soft_oal" -} - MODULE.OsFiles.Posix = { "../src/Nazara/Audio/Posix/**.hpp", "../src/Nazara/Audio/Posix/**.cpp" diff --git a/build/scripts/modules/utility.lua b/build/scripts/modules/utility.lua index 1fafbd1a4..c1bc186c0 100644 --- a/build/scripts/modules/utility.lua +++ b/build/scripts/modules/utility.lua @@ -1,7 +1,6 @@ MODULE.Name = "Utility" MODULE.Libraries = { - "freetype-s", "NazaraCore", "stb_image" } @@ -17,10 +16,12 @@ MODULE.OsFiles.Posix = { } MODULE.OsLibraries.Windows = { + "freetype-s", "gdi32" } MODULE.OsLibraries.Posix = { + "freetype", "X11", "xcb", "xcb-cursor", From 406bebe717092615731ae5906e9b2d47112f6f2a Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 13:36:52 +0200 Subject: [PATCH 087/224] Documentation for module: Audio Former-commit-id: 4546f9db5579c219d708f87b7062104d24ec6da2 --- include/Nazara/Audio/Algorithm.inl | 16 +- include/Nazara/Audio/Config.hpp | 15 +- include/Nazara/Audio/ConfigCheck.hpp | 4 +- include/Nazara/Audio/DebugOff.hpp | 2 +- include/Nazara/Audio/Enums.hpp | 2 +- include/Nazara/Audio/OpenAL.hpp | 10 +- include/Nazara/Audio/SoundBuffer.inl | 7 + include/Nazara/Audio/SoundEmitter.hpp | 2 +- src/Nazara/Audio/Audio.cpp | 176 ++++++++++++++++-- src/Nazara/Audio/Music.cpp | 172 +++++++++++++++-- src/Nazara/Audio/OpenAL.cpp | 125 +++++++++++-- src/Nazara/Audio/Sound.cpp | 130 ++++++++++++- src/Nazara/Audio/SoundBuffer.cpp | 144 +++++++++++++- src/Nazara/Audio/SoundEmitter.cpp | 123 +++++++++++- src/Nazara/Audio/SoundStream.cpp | 8 + tests/Engine/Audio/AlgorithmAudio.cpp | 19 ++ tests/Engine/Audio/Music.cpp | 49 +++++ tests/Engine/Audio/Sound.cpp | 44 +++++ tests/Engine/Audio/SoundBuffer.cpp | 21 +++ tests/Engine/Audio/SoundEmitter.cpp | 41 ++++ .../Engine/Audio/Cat.flac.REMOVED.git-id | 1 + .../Audio/The_Brabanconne.ogg.REMOVED.git-id | 1 + tests/resources/Engine/Audio/copyrights.txt | 54 ++++++ 23 files changed, 1110 insertions(+), 56 deletions(-) create mode 100644 tests/Engine/Audio/AlgorithmAudio.cpp create mode 100644 tests/Engine/Audio/Music.cpp create mode 100644 tests/Engine/Audio/Sound.cpp create mode 100644 tests/Engine/Audio/SoundBuffer.cpp create mode 100644 tests/Engine/Audio/SoundEmitter.cpp create mode 100644 tests/resources/Engine/Audio/Cat.flac.REMOVED.git-id create mode 100644 tests/resources/Engine/Audio/The_Brabanconne.ogg.REMOVED.git-id create mode 100644 tests/resources/Engine/Audio/copyrights.txt diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl index ec89cdca9..1075a8b57 100644 --- a/include/Nazara/Audio/Algorithm.inl +++ b/include/Nazara/Audio/Algorithm.inl @@ -7,11 +7,21 @@ namespace Nz { + /*! + * \ingroup audio + * \brief Mixes channels in mono + * + * \param input Input buffer with multiples channels + * \param output Output butter for mono + * \param channelCount Number of channels + * \param frameCount Number of frames + * + * \remark The input buffer may be the same as the output one + */ template void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount) { - ///DOC: Le buffer d'entrée peut être le même que le buffer de sortie - // Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants + // To avoid overflow, we use, as an accumulator, a type which is large enough: (u)int 64 bits for integers, double for floatings typedef typename std::conditional::value, UInt64, Int64>::type BiggestInt; typedef typename std::conditional::value, BiggestInt, double>::type Biggest; @@ -19,7 +29,7 @@ namespace Nz { Biggest acc = Biggest(0); for (unsigned int j = 0; j < channelCount; ++j) - acc += input[i*channelCount + j]; + acc += input[i * channelCount + j]; output[i] = static_cast(acc / channelCount); } diff --git a/include/Nazara/Audio/Config.hpp b/include/Nazara/Audio/Config.hpp index e11bda468..8e2068069 100644 --- a/include/Nazara/Audio/Config.hpp +++ b/include/Nazara/Audio/Config.hpp @@ -27,18 +27,23 @@ #ifndef NAZARA_CONFIG_AUDIO_HPP #define NAZARA_CONFIG_AUDIO_HPP -/// Modifier la configuration d'un module nécessite une recompilation quasi-intégrale de celui-ci et de ceux en héritant +/*! +* \defgroup audio (NazaraAudio) Audio module +* Audio/System module including classes to handle music, sound, etc... +*/ -// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +/// Each modification of a parameter needs a recompilation of the module + +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_AUDIO_MANAGE_MEMORY 0 -// Active les tests de sécurité supplémentaires (Teste notamment les arguments des fonctions, conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_AUDIO_SAFE 1 -// Le nombre de buffers utilisés lors du streaming d'objets audio (Au moins deux) +// The number of buffers used for audio streaming (At least two) #define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2 -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if !defined(NAZARA_STATIC) diff --git a/include/Nazara/Audio/ConfigCheck.hpp b/include/Nazara/Audio/ConfigCheck.hpp index 9ed35c1a4..70d0c6fe5 100644 --- a/include/Nazara/Audio/ConfigCheck.hpp +++ b/include/Nazara/Audio/ConfigCheck.hpp @@ -7,12 +7,12 @@ #ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP #define NAZARA_CONFIG_CHECK_AUDIO_HPP -/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp +/// This file is used to check the constant values defined in Config.hpp #include #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// On force la valeur de MANAGE_MEMORY en mode debug +// We force the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY #undef NAZARA_AUDIO_MANAGE_MEMORY #define NAZARA_AUDIO_MANAGE_MEMORY 0 diff --git a/include/Nazara/Audio/DebugOff.hpp b/include/Nazara/Audio/DebugOff.hpp index 254d7701d..e5149d5b5 100644 --- a/include/Nazara/Audio/DebugOff.hpp +++ b/include/Nazara/Audio/DebugOff.hpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp -// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +// We assume that Debug.hpp has already been included, same thing for Config.hpp #if NAZARA_AUDIO_MANAGE_MEMORY #undef delete #undef new diff --git a/include/Nazara/Audio/Enums.hpp b/include/Nazara/Audio/Enums.hpp index b8d3e3ec6..20866e5e9 100644 --- a/include/Nazara/Audio/Enums.hpp +++ b/include/Nazara/Audio/Enums.hpp @@ -13,7 +13,7 @@ namespace Nz { AudioFormat_Unknown = -1, - // La valeur entière est le nombre de canaux possédés par ce format + // The integer value is the number of channels used by the format AudioFormat_Mono = 1, AudioFormat_Stereo = 2, AudioFormat_Quad = 4, diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index eab95e6d0..aa80f406e 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -15,18 +15,18 @@ #include #include -// Inclusion des headers OpenAL +// Inclusion of OpenAL headers -// Étant donné que les headers OpenAL ne nous permettent pas de n'avoir que les signatures sans les pointeurs de fonctions -// Et que je ne souhaite pas les modifier, je suis contraint de les placer dans un espace de nom différent pour ensuite -// remettre dans l'espace global les choses intéressantes (les typedef notamment) +// OpenAL headers does not allow us to only get the signatures without the pointers to the functions +// And I do no want to modify them, I'm obliged to put them in a different namespace +// to put only interesting things back in the global namespace (specially typedef) namespace OpenALDetail { #include #include } -// Si quelqu'un a une meilleure idée ... +// If someone has a better idea ... using OpenALDetail::ALboolean; using OpenALDetail::ALbyte; using OpenALDetail::ALchar; diff --git a/include/Nazara/Audio/SoundBuffer.inl b/include/Nazara/Audio/SoundBuffer.inl index 9c5d1198b..a4c42be69 100644 --- a/include/Nazara/Audio/SoundBuffer.inl +++ b/include/Nazara/Audio/SoundBuffer.inl @@ -7,6 +7,13 @@ namespace Nz { + /*! + * \brief Creates a new sound buffer from the arguments + * \return A reference to the newly created sound buffer + * + * \param args Arguments for the sound buffer + */ + template SoundBufferRef SoundBuffer::New(Args&&... args) { diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index d56cd1bca..9a68d88cc 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -12,7 +12,7 @@ #include #include -///TODO: Faire hériter SoundEmitter de Node +///TODO: Inherit SoundEmitter from Node namespace Nz { diff --git a/src/Nazara/Audio/Audio.cpp b/src/Nazara/Audio/Audio.cpp index c0e785865..6eaa86c39 100644 --- a/src/Nazara/Audio/Audio.cpp +++ b/src/Nazara/Audio/Audio.cpp @@ -16,6 +16,21 @@ namespace Nz { + /*! + * \ingroup audio + * \class Nz::Audio + * \brief Audio class that represents the module initializer of Audio + */ + + /*! + * \brief Gets the format of the audio + * \return AudioFormat Enumeration type for the format + * + * \param channelCount Number of channels + * + * \remark Produces a NazaraError if the number of channels is erroneous (3 or 5) and AudioFormat_Unknown is returned + */ + AudioFormat Audio::GetAudioFormat(unsigned int channelCount) { switch (channelCount) @@ -34,19 +49,36 @@ namespace Nz } } + /*! + * \brief Gets the factor of the doppler effect + * \return Global factor of the doppler effect + */ + float Audio::GetDopplerFactor() { return alGetFloat(AL_DOPPLER_FACTOR); } + /*! + * \brief Gets the global volume + * \return Float between [0, inf) with 100.f being the default + */ + float Audio::GetGlobalVolume() { ALfloat gain = 0.f; alGetListenerf(AL_GAIN, &gain); - return gain*100.f; + return gain * 100.f; } + /*! + * \brief Gets the direction of the listener + * \return Direction of the listener, in front of the listener + * + * \see GetListenerRotation + */ + Vector3f Audio::GetListenerDirection() { ALfloat orientation[6]; @@ -55,6 +87,13 @@ namespace Nz return Vector3f(orientation[0], orientation[1], orientation[2]); } + /*! + * \brief Gets the position of the listener + * \return Position of the listener + * + * \see GetListenerVelocity + */ + Vector3f Audio::GetListenerPosition() { Vector3f position; @@ -63,6 +102,11 @@ namespace Nz return position; } + /*! + * \brief Gets the rotation of the listener + * \return Rotation of the listener + */ + Quaternionf Audio::GetListenerRotation() { ALfloat orientation[6]; @@ -73,6 +117,13 @@ namespace Nz return Quaternionf::RotationBetween(Vector3f::Forward(), forward); } + /*! + * \brief Gets the velocity of the listener + * \return Velocity of the listener + * + * \see GetListenerPosition + */ + Vector3f Audio::GetListenerVelocity() { Vector3f velocity; @@ -81,20 +132,33 @@ namespace Nz return velocity; } + /*! + * \brief Gets the speed of sound + * \return Speed of sound + */ + float Audio::GetSpeedOfSound() { return alGetFloat(AL_SPEED_OF_SOUND); } + /*! + * \brief Initializes the Audio module + * \return true if initialization is successful + * + * \remark Produces a NazaraError if initialization of modules Core, OpenAL or SoundBuffer failed + * \remark Produces a NazaraNotice + */ + bool Audio::Initialize() { - if (s_moduleReferenceCounter > 0) + if (IsInitialized()) { s_moduleReferenceCounter++; - return true; // Déjà initialisé + return true; // Already initialized } - // Initialisation des dépendances + // Initialisation of dependencies if (!Core::Initialize()) { NazaraError("Failed to initialize core module"); @@ -103,10 +167,10 @@ namespace Nz s_moduleReferenceCounter++; - // Initialisation du module + // Initialisation of the module CallOnExit onExit(Audio::Uninitialize); - // Initialisation d'OpenAL + // Initialisation of OpenAL if (!OpenAL::Initialize()) { NazaraError("Failed to initialize OpenAL"); @@ -119,7 +183,7 @@ namespace Nz return false; } - // Définition de l'orientation par défaut + // Definition of the orientation by default SetListenerDirection(Vector3f::Forward()); // Loaders @@ -131,6 +195,13 @@ namespace Nz return true; } + /*! + * \brief Checks whether the format is supported by the engine + * \return true if it is the case + * + * \param format Format to check + */ + bool Audio::IsFormatSupported(AudioFormat format) { if (format == AudioFormat_Unknown) @@ -139,21 +210,46 @@ namespace Nz return OpenAL::AudioFormat[format] != 0; } + /*! + * \brief Checks whether the module is initialized + * \return true if module is initialized + */ + bool Audio::IsInitialized() { return s_moduleReferenceCounter != 0; } + /*! + * \brief Sets the factor of the doppler effect + * + * \param dopplerFactor Global factor of the doppler effect + */ + void Audio::SetDopplerFactor(float dopplerFactor) { alDopplerFactor(dopplerFactor); } + /*! + * \brief Sets the global volume + * + * \param volume Float between [0, inf) with 100.f being the default + */ + void Audio::SetGlobalVolume(float volume) { - alListenerf(AL_GAIN, volume*0.01f); + alListenerf(AL_GAIN, volume * 0.01f); } + /*! + * \brief Sets the direction of the listener + * + * \param direction Direction of the listener, in front of the listener + * + * \see SetListenerDirection, SetListenerRotation + */ + void Audio::SetListenerDirection(const Vector3f& direction) { Vector3f up = Vector3f::Up(); @@ -167,6 +263,14 @@ namespace Nz alListenerfv(AL_ORIENTATION, orientation); } + /*! + * \brief Sets the direction of the listener + * + * \param (dirX, dirY, dirZ) Direction of the listener, in front of the listener + * + * \see SetListenerDirection, SetListenerRotation + */ + void Audio::SetListenerDirection(float dirX, float dirY, float dirZ) { Vector3f up = Vector3f::Up(); @@ -180,16 +284,38 @@ namespace Nz alListenerfv(AL_ORIENTATION, orientation); } + /*! + * \brief Sets the position of the listener + * + * \param position Position of the listener + * + * \see SetListenerVelocity + */ + void Audio::SetListenerPosition(const Vector3f& position) { alListenerfv(AL_POSITION, position); } + /*! + * \brief Sets the position of the listener + * + * \param (x, y, z) Position of the listener + * + * \see SetListenerVelocity + */ + void Audio::SetListenerPosition(float x, float y, float z) { alListener3f(AL_POSITION, x, y, z); } + /*! + * \brief Sets the rotation of the listener + * + * \param rotation Rotation of the listener + */ + void Audio::SetListenerRotation(const Quaternionf& rotation) { Vector3f forward = rotation * Vector3f::Forward(); @@ -204,33 +330,61 @@ namespace Nz alListenerfv(AL_ORIENTATION, orientation); } + /*! + * \brief Sets the velocity of the listener + * + * \param velocity Velocity of the listener + * + * \see SetListenerPosition + */ + void Audio::SetListenerVelocity(const Vector3f& velocity) { alListenerfv(AL_VELOCITY, velocity); } + /*! + * \brief Sets the velocity of the listener + * + * \param (velX, velY, velZ) Velocity of the listener + * + * \see SetListenerPosition + */ + void Audio::SetListenerVelocity(float velX, float velY, float velZ) { alListener3f(AL_VELOCITY, velX, velY, velZ); } + /*! + * \brief Sets the speed of sound + * + * \param speed Speed of sound + */ + void Audio::SetSpeedOfSound(float speed) { alSpeedOfSound(speed); } + /*! + * \brief Uninitializes the Audio module + * + * \remark Produces a NazaraNotice + */ + void Audio::Uninitialize() { if (s_moduleReferenceCounter != 1) { - // Le module est soit encore utilisé, soit pas initialisé + // The module is still in use, or can not be uninitialized if (s_moduleReferenceCounter > 1) s_moduleReferenceCounter--; return; } - // Libération du module + // Free of module s_moduleReferenceCounter = 0; // Loaders @@ -241,7 +395,7 @@ namespace Nz NazaraNotice("Uninitialized: Audio module"); - // Libération des dépendances + // Free of dependencies Core::Uninitialize(); } diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index bbcb7d813..9e38c7114 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -14,6 +14,19 @@ namespace Nz { + /*! + * \ingroup audio + * \class Nz::Music + * \brief Audio class that represents a music + * + * \remark Module Audio needs to be initialized to use this class + */ + + /*! + * \brief Checks whether the parameters for the loading of the music are correct + * \return true If parameters are valid + */ + bool MusicParams::IsValid() const { return true; @@ -32,11 +45,26 @@ namespace Nz unsigned int sampleRate; }; + /*! + * \brief Destructs the object and calls Destroy + * + * \see Destroy + */ + Music::~Music() { Destroy(); } + /*! + * \brief Creates a music with a sound stream + * \return true if creation was succesful + * + * \param soundStream Sound stream which is the source for the music + * + * \remark Produces a NazaraError if soundStream is invalid with NAZARA_AUDIO_SAFE defined + */ + bool Music::Create(SoundStream* soundStream) { NazaraAssert(soundStream, "Invalid stream"); @@ -48,7 +76,7 @@ namespace Nz m_impl = new MusicImpl; m_impl->sampleRate = soundStream->GetSampleRate(); m_impl->audioFormat = OpenAL::AudioFormat[format]; - m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples + m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples m_impl->stream.reset(soundStream); SetPlayingOffset(0); @@ -56,6 +84,10 @@ namespace Nz return true; } + /*! + * \brief Destroys the current music and frees resources + */ + void Music::Destroy() { if (m_impl) @@ -67,6 +99,14 @@ namespace Nz } } + /*! + * \brief Enables the looping of the music + * + * \param loop Should music loop + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + void Music::EnableLooping(bool loop) { #if NAZARA_AUDIO_SAFE @@ -80,6 +120,13 @@ namespace Nz m_impl->loop = loop; } + /*! + * \brief Gets the duration of the music + * \return Duration of the music in milliseconds + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + UInt32 Music::GetDuration() const { #if NAZARA_AUDIO_SAFE @@ -93,6 +140,13 @@ namespace Nz return m_impl->stream->GetDuration(); } + /*! + * \brief Gets the format of the music + * \return Enumeration of type AudioFormat (mono, stereo, ...) + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + AudioFormat Music::GetFormat() const { #if NAZARA_AUDIO_SAFE @@ -106,6 +160,13 @@ namespace Nz return m_impl->stream->GetFormat(); } + /*! + * \brief Gets the current offset in the music + * \return Offset in milliseconds (works with entire seconds) + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + UInt32 Music::GetPlayingOffset() const { #if NAZARA_AUDIO_SAFE @@ -125,6 +186,13 @@ namespace Nz return static_cast((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate); } + /*! + * \brief Gets the number of samples in the music + * \return Count of samples (number of seconds * sample rate * channel count) + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + UInt32 Music::GetSampleCount() const { #if NAZARA_AUDIO_SAFE @@ -138,6 +206,13 @@ namespace Nz return m_impl->stream->GetSampleCount(); } + /*! + * \brief Gets the rates of sample in the music + * \return Rate of sample in Hertz (Hz) + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + UInt32 Music::GetSampleRate() const { #if NAZARA_AUDIO_SAFE @@ -151,6 +226,14 @@ namespace Nz return m_impl->sampleRate; } + /*! + * \brief Gets the status of the music + * \return Enumeration of type SoundStatus (Playing, Stopped, ...) + * + * \remark If the music is not playing, Stopped is returned + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + SoundStatus Music::GetStatus() const { #if NAZARA_AUDIO_SAFE @@ -163,13 +246,20 @@ namespace Nz SoundStatus status = GetInternalStatus(); - // Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) + // To compensate any delays (or the timelaps between Play() and the thread startup) if (m_impl->streaming && status == SoundStatus_Stopped) status = SoundStatus_Playing; return status; } + /*! + * \brief Checks whether the music is looping + * \return true if it is the case + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + bool Music::IsLooping() const { #if NAZARA_AUDIO_SAFE @@ -183,26 +273,61 @@ namespace Nz return m_impl->loop; } + /*! + * \brief Loads the music from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the music + */ + bool Music::OpenFromFile(const String& filePath, const MusicParams& params) { return MusicLoader::LoadFromFile(this, filePath, params); } + /*! + * \brief Loads the music from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the music + */ + bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params) { return MusicLoader::LoadFromMemory(this, data, size, params); } + /*! + * \brief Loads the music from stream + * \return true if loading is successful + * + * \param stream Stream to the music + * \param params Parameters for the music + */ + bool Music::OpenFromStream(Stream& stream, const MusicParams& params) { return MusicLoader::LoadFromStream(this, stream, params); } + /*! + * \brief Pauses the music + */ + void Music::Pause() { alSourcePause(m_source); } + /*! + * \brief Plays the music + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + void Music::Play() { #if NAZARA_AUDIO_SAFE @@ -238,6 +363,14 @@ namespace Nz } } + /*! + * \brief Sets the playing offset for the music + * + * \param offset Offset in the music in milliseconds + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + void Music::SetPlayingOffset(UInt32 offset) { #if NAZARA_AUDIO_SAFE @@ -260,6 +393,12 @@ namespace Nz Play(); } + /*! + * \brief Stops the music + * + * \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined + */ + void Music::Stop() { #if NAZARA_AUDIO_SAFE @@ -277,6 +416,13 @@ namespace Nz } } + /*! + * \brief Fills the buffer and queues it up + * \return true if operation was successful + * + * \param buffer Index of the buffer + */ + bool Music::FillAndQueueBuffer(unsigned int buffer) { unsigned int sampleCount = m_impl->chunkSamples.size(); @@ -304,27 +450,31 @@ namespace Nz alSourceQueueBuffers(m_source, 1, &buffer); } - return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) + return sampleRead != sampleCount; // End of stream (Does not happen when looping) } + /*! + * \brief Thread function for the music + */ + void Music::MusicThread() { - // Allocation des buffers de streaming + // Allocation of streaming buffers ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) { if (FillAndQueueBuffer(buffers[i])) - break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers + break; // We have reached the end of the stream, there is no use to add new buffers } alSourcePlay(m_source); - // Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) + // Reading loop (Filling new buffers as playing) while (m_impl->streaming) { - // La lecture s'est arrêtée, nous avons atteint la fin du stream + // The reading has stopped, we have reached the end of the stream SoundStatus status = GetInternalStatus(); if (status == SoundStatus_Stopped) { @@ -334,7 +484,7 @@ namespace Nz Nz::LockGuard lock(m_impl->bufferLock); - // On traite les buffers lus + // We treat read buffers ALint processedCount = 0; alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); while (processedCount--) @@ -355,14 +505,14 @@ namespace Nz lock.Unlock(); - // On retourne dormir un peu + // We go back to sleep Thread::Sleep(50); } - // Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) + // Stop playing of the sound (in the case where it has not been already done) alSourceStop(m_source); - // On supprime les buffers du stream + // We delete buffers from the stream ALint queuedBufferCount; alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index f527b682d..489855022 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -23,6 +23,14 @@ namespace Nz ALCcontext* s_context = nullptr; unsigned int s_version; + /*! + * \brief Parses the devices + * \return Number of devices + * + * \param deviceString String for the device (input / output) + * \param devices List of names of the devices + */ + std::size_t ParseDevices(const char* deviceString, std::vector& devices) { if (!deviceString) @@ -41,35 +49,77 @@ namespace Nz } } + /*! + * \ingroup audio + * \class Nz::OpenAL + * \brief Audio class that represents the link with OpenAL + * + * \remark This class is meant to be used by Module Audio + */ + + /*! + * \brief Gets the entry for the function name + * \return Pointer to the function + * + * \param entryPoint Name of the entry + * + * \remark This does not produces a NazaraError if entry does not exist + */ + OpenALFunc OpenAL::GetEntry(const String& entryPoint) { return LoadEntry(entryPoint.GetConstBuffer(), false); } + /*! + * \brief Gets the name of the renderer + * \return Name of the renderer + */ + String OpenAL::GetRendererName() { return s_rendererName; } + /*! + * \brief Gets the name of the vendor + * \return Name of the vendor + */ + String OpenAL::GetVendorName() { return s_vendorName; } + /*! + * \brief Gets the version of OpenAL + * \return Version of OpenAL + */ + unsigned int OpenAL::GetVersion() { return s_version; } + /*! + * \brief Initializes the module OpenAL + * \return true if initialization is successful + * + * \param openDevice True to get information from the device + * + * \remark Produces a NazaraError if one of the entry failed + * \remark Produces a NazaraError if opening device failed with openDevice parameter set to true + */ + bool OpenAL::Initialize(bool openDevice) { - if (s_library.IsLoaded()) + if (IsInitialized()) return true; #if defined(NAZARA_PLATFORM_WINDOWS) - ///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ? - /// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores - /// et de donner plus de possibilités techniques au niveau de l'audio. + ///FIXME: Is OpenAL Soft a better implementation than Creative ? + /// If we could use OpenAL Soft everytime, this would allow us to use sonorous extensions + /// and give us more technical possibilities with audio const char* libs[] = { "soft_oal.dll", "wrap_oal.dll", @@ -217,11 +267,23 @@ namespace Nz return true; } + /*! + * \brief Checks whether the module is initialized + * \return true if it is the case + */ + bool OpenAL::IsInitialized() { return s_library.IsLoaded(); } + /*! + * \brief Queries the input devices + * \return Number of devices + * + * \param devices List of names of the input devices + */ + std::size_t OpenAL::QueryInputDevices(std::vector& devices) { const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER)); @@ -231,6 +293,13 @@ namespace Nz return ParseDevices(deviceString, devices); } + /*! + * \brief Queries the output devices + * \return Number of devices + * + * \param devices List of names of the output devices + */ + std::size_t OpenAL::QueryOutputDevices(std::vector& devices) { const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); @@ -240,6 +309,13 @@ namespace Nz return ParseDevices(deviceString, devices); } + /*! + * \brief Sets the active device + * \return true if device is successfully opened + * + * \param deviceName Name of the device + */ + bool OpenAL::SetDevice(const String& deviceName) { s_deviceName = deviceName; @@ -253,6 +329,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the module + */ + void OpenAL::Uninitialize() { CloseDevice(); @@ -262,8 +342,14 @@ namespace Nz s_library.Unload(); } - ///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format - ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL + ///WARNING: The integer value is the number of canals owned by the format + ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Added values with loading of OpenAL + + /*! + * \brief Closes the device + * + * \remark Produces a NazaraWarning if you try to close an active device + */ void OpenAL::CloseDevice() { @@ -277,24 +363,31 @@ namespace Nz } if (!alcCloseDevice(s_device)) - // Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation + // We could not close the close, this means that it's still in use NazaraWarning("Failed to close device"); s_device = nullptr; } } + /*! + * \brief Opens the device + * \return true if open is successful + * + * \remark Produces a NazaraError if it could not create the context + */ + bool OpenAL::OpenDevice() { - // Initialisation du module - s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut + // Initialisation of the module + s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // We choose the default device if (!s_device) { NazaraError("Failed to open default device"); return false; } - // Un seul contexte nous suffira + // One context is enough s_context = alcCreateContext(s_device, nullptr); if (!s_context) { @@ -341,7 +434,7 @@ namespace Nz s_version = 0; } - // On complète le tableau de formats + // We complete the formats table AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16; AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16; @@ -359,6 +452,16 @@ namespace Nz return true; } + /*! + * \brief Loads the entry for the function name + * \return Pointer to the function + * + * \param name Name of the entry + * \param throwException Should throw exception if failed ? + * + * \remark Produces a std::runtime_error if entry does not exist and throwException is set to true + */ + OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException) { OpenALFunc entry = reinterpret_cast(s_library.GetSymbol(name)); diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 7198a01d6..d2b71318b 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -14,32 +14,76 @@ namespace Nz { + /*! + * \ingroup audio + * \class Nz::Sound + * \brief Audio class that represents a sound + * + * \remark Module Audio needs to be initialized to use this class + */ + + /*! + * \brief Constructs a Sound object + * + * \param soundBuffer Buffer to read sound from + */ + Sound::Sound(const SoundBuffer* soundBuffer) { SetBuffer(soundBuffer); } + /*! + * \brief Constructs a Sound object which is a copy of another + * + * \param sound Sound to copy + */ + Sound::Sound(const Sound& sound) : SoundEmitter(sound) { SetBuffer(sound.m_buffer); } + /*! + * \brief Destructs the object and calls Stop + * + * \see Stop + */ + Sound::~Sound() { Stop(); } + /*! + * \brief Enables the looping of the music + * + * \param loop Should sound loop + */ + void Sound::EnableLooping(bool loop) { alSourcei(m_source, AL_LOOPING, loop); } + /*! + * \brief Gets the internal buffer + * \return Internal buffer + */ + const SoundBuffer* Sound::GetBuffer() const { return m_buffer; } + /*! + * \brief Gets the duration of the sound + * \return Duration of the music in milliseconds + * + * \remark Produces a NazaraError if there is no buffer + */ + UInt32 Sound::GetDuration() const { NazaraAssert(m_buffer, "Invalid sound buffer"); @@ -47,6 +91,11 @@ namespace Nz return m_buffer->GetDuration(); } + /*! + * \brief Gets the current offset in the sound + * \return Offset in milliseconds (works with entire seconds) + */ + UInt32 Sound::GetPlayingOffset() const { ALint samples = 0; @@ -55,11 +104,21 @@ namespace Nz return static_cast(1000ULL * samples / m_buffer->GetSampleRate()); } + /*! + * \brief Gets the status of the music + * \return Enumeration of type SoundStatus (Playing, Stopped, ...) + */ + SoundStatus Sound::GetStatus() const { return GetInternalStatus(); } + /*! + * \brief Checks whether the sound is looping + * \return true if it is the case + */ + bool Sound::IsLooping() const { ALint loop; @@ -68,16 +127,36 @@ namespace Nz return loop != AL_FALSE; } + /*! + * \brief Checks whether the sound is playable + * \return true if it is the case + */ + bool Sound::IsPlayable() const { return m_buffer != nullptr; } + /*! + * \brief Checks whether the sound is playing + * \return true if it is the case + */ + bool Sound::IsPlaying() const { return GetStatus() == SoundStatus_Playing; } + /*! + * \brief Loads the sound from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the sound + * + * \remark Produces a NazaraError if loading failed + */ + bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params) { SoundBufferRef buffer = SoundBuffer::New(); @@ -91,6 +170,17 @@ namespace Nz return true; } + /*! + * \brief Loads the sound from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the sound + * + * \remark Produces a NazaraError if loading failed + */ + bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) { SoundBufferRef buffer = SoundBuffer::New(); @@ -104,6 +194,16 @@ namespace Nz return true; } + /*! + * \brief Loads the sound from stream + * \return true if loading is successful + * + * \param stream Stream to the sound + * \param params Parameters for the sound + * + * \remark Produces a NazaraError if loading failed + */ + bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params) { SoundBufferRef buffer = SoundBuffer::New(); @@ -117,15 +217,25 @@ namespace Nz return true; } + /*! + * \brief Pauses the sound + */ + void Sound::Pause() { alSourcePause(m_source); } + /*! + * \brief Plays the music + * + * \remark Produces a NazaraError if the sound is not playable with NAZARA_AUDIO_SAFE defined + */ + void Sound::Play() { #if NAZARA_AUDIO_SAFE - if (!m_buffer) + if (!IsPlayable()) { NazaraError("Invalid sound buffer"); return; @@ -135,6 +245,14 @@ namespace Nz alSourcePlay(m_source); } + /*! + * \brief Sets the internal buffer + * + * \param buffer Internal buffer + * + * \remark Produces a NazaraError if buffer is invalid with NAZARA_AUDIO_SAFE defined + */ + void Sound::SetBuffer(const SoundBuffer* buffer) { #if NAZARA_AUDIO_SAFE @@ -158,11 +276,21 @@ namespace Nz alSourcei(m_source, AL_BUFFER, AL_NONE); } + /*! + * \brief Sets the playing offset for the sound + * + * \param offset Offset in the sound in milliseconds + */ + void Sound::SetPlayingOffset(UInt32 offset) { alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast(offset/1000.f * m_buffer->GetSampleRate())); } + /*! + * \brief Stops the sound + */ + void Sound::Stop() { alSourceStop(m_source); diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index c01878383..b59e74e23 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -12,10 +12,23 @@ #include #include -///FIXME: Adapter la création +///FIXME: Adapt the creation namespace Nz { + /*! + * \ingroup audio + * \class Nz::SoundBuffer + * \brief Audio class that represents a buffer for sound + * + * \remark Module Audio needs to be initialized to use this class + */ + + /*! + * \brief Checks whether the parameters for the buffer' sound are correct + * \return true If parameters are valid + */ + bool SoundBufferParams::IsValid() const { return true; @@ -31,6 +44,20 @@ namespace Nz UInt32 sampleRate; }; + /*! + * \brief Constructs a SoundBuffer object + * + * \param format Format for the audio + * \param sampleCount Number of samples + * \param sampleRate Rate of samples + * \param samples Samples raw data + * + * \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined + * \remark Produces a std::runtime_error if creation went wrong with NAZARA_AUDIO_SAFE defined + * + * \see Create + */ + SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) { Create(format, sampleCount, sampleRate, samples); @@ -44,6 +71,12 @@ namespace Nz #endif } + /*! + * \brief Destructs the object and calls Destroy + * + * \see Destroy + */ + SoundBuffer::~SoundBuffer() { OnSoundBufferRelease(this); @@ -51,6 +84,19 @@ namespace Nz Destroy(); } + /*! + * \brief Creates the SoundBuffer object + * \return true if creation is successful + * + * \param format Format for the audio + * \param sampleCount Number of samples + * \param sampleRate Rate of samples + * \param samples Samples raw data + * + * \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined, + * this could happen if parameters are invalid or creation of OpenAL buffers failed + */ + bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) { Destroy(); @@ -81,7 +127,7 @@ namespace Nz } #endif - // On vide le stack d'erreurs + // We empty the error stack while (alGetError() != AL_NO_ERROR); ALuint buffer; @@ -115,6 +161,10 @@ namespace Nz return true; } + /*! + * \brief Destroys the current sound buffer and frees resources + */ + void SoundBuffer::Destroy() { if (m_impl) @@ -126,6 +176,13 @@ namespace Nz } } + /*! + * \brief Gets the duration of the sound buffer + * \return Duration of the sound buffer in milliseconds + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + UInt32 SoundBuffer::GetDuration() const { #if NAZARA_AUDIO_SAFE @@ -139,6 +196,13 @@ namespace Nz return m_impl->duration; } + /*! + * \brief Gets the format of the sound buffer + * \return Enumeration of type AudioFormat (mono, stereo, ...) + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + AudioFormat SoundBuffer::GetFormat() const { #if NAZARA_AUDIO_SAFE @@ -152,6 +216,13 @@ namespace Nz return m_impl->format; } + /*! + * \brief Gets the internal raw samples + * \return Pointer to raw data + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + const Int16* SoundBuffer::GetSamples() const { #if NAZARA_AUDIO_SAFE @@ -165,6 +236,13 @@ namespace Nz return m_impl->samples.get(); } + /*! + * \brief Gets the number of samples in the sound buffer + * \return Count of samples (number of seconds * sample rate * channel count) + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + unsigned int SoundBuffer::GetSampleCount() const { #if NAZARA_AUDIO_SAFE @@ -178,6 +256,13 @@ namespace Nz return m_impl->sampleCount; } + /*! + * \brief Gets the rates of sample in the sound buffer + * \return Rate of sample in Hertz (Hz) + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + unsigned int SoundBuffer::GetSampleRate() const { #if NAZARA_AUDIO_SAFE @@ -191,31 +276,75 @@ namespace Nz return m_impl->sampleRate; } + /*! + * \brief Checks whether the sound buffer is valid + * \return true if it is the case + */ + bool SoundBuffer::IsValid() const { return m_impl != nullptr; } + /*! + * \brief Loads the sound buffer from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the sound buffer + */ + bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params) { return SoundBufferLoader::LoadFromFile(this, filePath, params); } + /*! + * \brief Loads the sound buffer from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the sound buffer + */ + bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) { return SoundBufferLoader::LoadFromMemory(this, data, size, params); } + /*! + * \brief Loads the sound buffer from stream + * \return true if loading is successful + * + * \param stream Stream to the sound buffer + * \param params Parameters for the sound buffer + */ + bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params) { return SoundBufferLoader::LoadFromStream(this, stream, params); } + /*! + * \brief Checks whether the format is supported by the engine + * \return true if it is the case + * + * \param format Format to check + */ + bool SoundBuffer::IsFormatSupported(AudioFormat format) { return Audio::IsFormatSupported(format); } + /*! + * \brief Gets the internal OpenAL buffer + * \return The index of the OpenAL buffer + * + * \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined + */ + unsigned int SoundBuffer::GetOpenALBuffer() const { #ifdef NAZARA_DEBUG @@ -229,6 +358,13 @@ namespace Nz return m_impl->buffer; } + /*! + * \brief Initializes the libraries and managers + * \return true if initialization is successful + * + * \remark Produces a NazaraError if sub-initialization failed + */ + bool SoundBuffer::Initialize() { if (!SoundBufferLibrary::Initialize()) @@ -246,6 +382,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the libraries and managers + */ + void SoundBuffer::Uninitialize() { SoundBufferManager::Uninitialize(); diff --git a/src/Nazara/Audio/SoundEmitter.cpp b/src/Nazara/Audio/SoundEmitter.cpp index cbee8a8f9..840c4f47d 100644 --- a/src/Nazara/Audio/SoundEmitter.cpp +++ b/src/Nazara/Audio/SoundEmitter.cpp @@ -11,11 +11,32 @@ namespace Nz { + /*! + * \ingroup audio + * \class Nz::SoundEmitter + * \brief Audio class that represents a sound source, that emits sound + * + * \remark Module Audio needs to be initialized to use this class + * \remark This class is abstract + */ + + /*! + * \brief Constructs a SoundEmitter object + */ + SoundEmitter::SoundEmitter() { alGenSources(1, &m_source); } + /*! + * \brief Constructs a SoundEmitter object which is a copy of another + * + * \param emitter SoundEmitter to copy + * + * \remark Position and velocity are not copied + */ + SoundEmitter::SoundEmitter(const SoundEmitter& emitter) { alGenSources(1, &m_source); @@ -23,20 +44,35 @@ namespace Nz SetAttenuation(emitter.GetAttenuation()); SetMinDistance(emitter.GetMinDistance()); SetPitch(emitter.GetPitch()); - // Pas de copie de position ou de vitesse + // No copy for position or velocity SetVolume(emitter.GetVolume()); } + /*! + * \brief Destructs the object + */ + SoundEmitter::~SoundEmitter() { alDeleteSources(1, &m_source); } + /*! + * \brief Enables spatialization + * + * \param spatialization True if spatialization is enabled + */ + void SoundEmitter::EnableSpatialization(bool spatialization) { alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization); } + /*! + * \brief Gets the attenuation + * \return Amount that your sound will drop off as by the inverse square law + */ + float SoundEmitter::GetAttenuation() const { ALfloat attenuation; @@ -45,6 +81,11 @@ namespace Nz return attenuation; } + /*! + * \brief Gets the minimum distance to hear + * \return Distance to begin to hear + */ + float SoundEmitter::GetMinDistance() const { ALfloat distance; @@ -53,6 +94,11 @@ namespace Nz return distance; } + /*! + * \brief Gets the pitch + * \return Pitch of the sound + */ + float SoundEmitter::GetPitch() const { ALfloat pitch; @@ -61,6 +107,11 @@ namespace Nz return pitch; } + /*! + * \brief Gets the position of the emitter + * \return Position of the sound + */ + Vector3f SoundEmitter::GetPosition() const { Vector3f position; @@ -69,6 +120,11 @@ namespace Nz return position; } + /*! + * \brief Gets the velocity of the emitter + * \return Velocity of the sound + */ + Vector3f SoundEmitter::GetVelocity() const { Vector3f velocity; @@ -77,6 +133,11 @@ namespace Nz return velocity; } + /*! + * \brief Gets the volume of the emitter + * \param volume Float between [0, inf) with 100.f being the default + */ + float SoundEmitter::GetVolume() const { ALfloat gain; @@ -85,6 +146,11 @@ namespace Nz return gain * 100.f; } + /*! + * \brief Checks whether the sound emitter has spatialization enabled + * \return true if it the case + */ + bool SoundEmitter::IsSpatialized() const { ALint relative; @@ -93,46 +159,99 @@ namespace Nz return relative == AL_FALSE; } + /*! + * \brief Sets the attenuation + * + * \param attenuation Amount that your sound will drop off as by the inverse square law + */ + void SoundEmitter::SetAttenuation(float attenuation) { alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation); } + /*! + * \brief Sets the minimum distance to hear + * + * \param minDistance to begin to hear + */ + void SoundEmitter::SetMinDistance(float minDistance) { alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance); } + /*! + * \brief Sets the pitch + * + * \param pitch of the sound + */ + void SoundEmitter::SetPitch(float pitch) { alSourcef(m_source, AL_PITCH, pitch); } + /*! + * \brief Sets the position of the emitter + * + * \param position Position of the sound + */ + void SoundEmitter::SetPosition(const Vector3f& position) { alSourcefv(m_source, AL_POSITION, position); } + /*! + * \brief Sets the position of the emitter + * + * \param position Position of the sound with (x, y, z) + */ + void SoundEmitter::SetPosition(float x, float y, float z) { alSource3f(m_source, AL_POSITION, x, y, z); } + /*! + * \brief Sets the velocity of the emitter + * + * \param velocity Velocity of the sound + */ + void SoundEmitter::SetVelocity(const Vector3f& velocity) { alSourcefv(m_source, AL_VELOCITY, velocity); } + /*! + * \brief Sets the velocity of the emitter + * + * \param velocity Velocity with (velX, velY, velZ) + */ + void SoundEmitter::SetVelocity(float velX, float velY, float velZ) { alSource3f(m_source, AL_VELOCITY, velX, velY, velZ); } + /*! + * \brief Sets the volume of the emitter + * + * \param volume Float between [0, inf) with 100.f being the default + */ + void SoundEmitter::SetVolume(float volume) { - alSourcef(m_source, AL_GAIN, volume*0.01f); + alSourcef(m_source, AL_GAIN, volume * 0.01f); } + /*! + * \brief Gets the status of the sound emitter + * \return Enumeration of type SoundStatus (Playing, Stopped, ...) + */ + SoundStatus SoundEmitter::GetInternalStatus() const { ALint state; diff --git a/src/Nazara/Audio/SoundStream.cpp b/src/Nazara/Audio/SoundStream.cpp index c243e875f..88bc0069b 100644 --- a/src/Nazara/Audio/SoundStream.cpp +++ b/src/Nazara/Audio/SoundStream.cpp @@ -6,5 +6,13 @@ namespace Nz { + /*! + * \ingroup audio + * \class Nz::SoundStream + * \brief Audio class that represents a sound stream + * + * \remark This class is abstract + */ + SoundStream::~SoundStream() = default; } diff --git a/tests/Engine/Audio/AlgorithmAudio.cpp b/tests/Engine/Audio/AlgorithmAudio.cpp new file mode 100644 index 000000000..dfcfeee56 --- /dev/null +++ b/tests/Engine/Audio/AlgorithmAudio.cpp @@ -0,0 +1,19 @@ +#include +#include + +#include + +TEST_CASE("MixToMono", "[AUDIO][ALGORITHM]") +{ + SECTION("Mix two channels together") + { + std::array input{ 1, 3, 5, 3 }; + std::array output{ 0, 0 }; + + // Two channels and two frames ! + Nz::MixToMono(input.data(), output.data(), 2, 2); + + std::array theoric{ 2, 4 }; // It's the mean of the two channels + REQUIRE(output == theoric); + } +} diff --git a/tests/Engine/Audio/Music.cpp b/tests/Engine/Audio/Music.cpp new file mode 100644 index 000000000..404c57c5f --- /dev/null +++ b/tests/Engine/Audio/Music.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include +#include + +SCENARIO("Music", "[AUDIO][MUSIC]") +{ + GIVEN("A music") + { + Nz::Music music; + + WHEN("We load our music") + { + REQUIRE(music.OpenFromFile("resources/Engine/Audio/The_Brabanconne.ogg")); + + THEN("We can ask the informations of the file") + { + REQUIRE(music.GetDuration() <= 64000); // 1 min 03 = 63s = 63000ms + REQUIRE(music.GetDuration() >= 63000); + REQUIRE(music.GetFormat() == Nz::AudioFormat_Stereo); + REQUIRE(music.GetPlayingOffset() == 0); + REQUIRE(music.GetSampleCount() <= 5644800); // 64s * 44100 Hz * 2 (stereo) + REQUIRE(music.GetSampleCount() >= 5556600); // 63s * 44100 Hz * 2 (stereo) + REQUIRE(music.GetSampleRate() == 44100 /* Hz */); + REQUIRE(music.GetStatus() == Nz::SoundStatus_Stopped); + REQUIRE(music.IsLooping() == false); + } + + THEN("We can play it and get the time offset") + { + Nz::Audio::SetGlobalVolume(0.f); + + music.Play(); + Nz::Thread::Sleep(1000); + REQUIRE(music.GetPlayingOffset() >= 950); + Nz::Thread::Sleep(200); + REQUIRE(music.GetPlayingOffset() <= 1300); + music.Pause(); + REQUIRE(music.GetStatus() == Nz::SoundStatus_Paused); + + music.SetPlayingOffset(3500); + REQUIRE(music.GetPlayingOffset() >= 3500); + + Nz::Audio::SetGlobalVolume(100.f); + } + } + } +} diff --git a/tests/Engine/Audio/Sound.cpp b/tests/Engine/Audio/Sound.cpp new file mode 100644 index 000000000..684138ccd --- /dev/null +++ b/tests/Engine/Audio/Sound.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include +#include + +SCENARIO("Sound", "[AUDIO][SOUND]") +{ + GIVEN("A sound") + { + Nz::Sound sound; + + WHEN("We load our sound") + { + REQUIRE(sound.LoadFromFile("resources/Engine/Audio/Cat.flac")); + + THEN("We can ask the informations of the file") + { + REQUIRE(sound.GetDuration() <= 8500); // 8s = 8000ms + REQUIRE(sound.GetDuration() >= 8000); + REQUIRE(sound.GetStatus() == Nz::SoundStatus_Stopped); + REQUIRE(sound.IsLooping() == false); + } + + THEN("We can play it and get the time offset") + { + Nz::Audio::SetGlobalVolume(0.f); + + sound.Play(); + Nz::Thread::Sleep(1000); + REQUIRE(sound.GetPlayingOffset() >= 950); + Nz::Thread::Sleep(200); + REQUIRE(sound.GetPlayingOffset() <= 1300); + sound.Pause(); + REQUIRE(sound.GetStatus() == Nz::SoundStatus_Paused); + + sound.SetPlayingOffset(3500); + REQUIRE(sound.GetPlayingOffset() >= 3500); + + Nz::Audio::SetGlobalVolume(100.f); + } + } + } +} diff --git a/tests/Engine/Audio/SoundBuffer.cpp b/tests/Engine/Audio/SoundBuffer.cpp new file mode 100644 index 000000000..ed5f2f6c6 --- /dev/null +++ b/tests/Engine/Audio/SoundBuffer.cpp @@ -0,0 +1,21 @@ +#include +#include + +SCENARIO("SoundBuffer", "[AUDIO][SOUNDBUFFER]") +{ + GIVEN("A sound buffer") + { + Nz::SoundBuffer soundBuffer; + + WHEN("We load our sound") + { + REQUIRE(soundBuffer.LoadFromFile("resources/Engine/Audio/Cat.flac")); + + THEN("We can ask the informations of the file") + { + REQUIRE(soundBuffer.GetDuration() <= 8500); // 8s = 8000ms + REQUIRE(soundBuffer.GetDuration() >= 8000); + } + } + } +} diff --git a/tests/Engine/Audio/SoundEmitter.cpp b/tests/Engine/Audio/SoundEmitter.cpp new file mode 100644 index 000000000..baac41eb3 --- /dev/null +++ b/tests/Engine/Audio/SoundEmitter.cpp @@ -0,0 +1,41 @@ +#include +#include + +#include + +SCENARIO("SoundEmitter", "[AUDIO][SOUNDEMITTER]") +{ + GIVEN("A sound emitter") + { + Nz::Sound sound; + + WHEN("We load our sound") + { + REQUIRE(sound.LoadFromFile("resources/Engine/Audio/Cat.flac")); + + THEN("We can ask information about position and velocity") + { + sound.EnableSpatialization(true); + sound.SetPosition(Nz::Vector3f::Zero()); + sound.SetVelocity(Nz::Vector3f::UnitX()); + + REQUIRE(sound.IsSpatialized()); + REQUIRE(sound.GetPosition() == Nz::Vector3f::Zero()); + REQUIRE(sound.GetVelocity() == Nz::Vector3f::UnitX()); + } + + THEN("We can ask information about attenuation, pitch, ...") + { + sound.SetAttenuation(0.4f); + sound.SetMinDistance(40.f); + sound.SetPitch(0.8f); + sound.SetVolume(50.f); + + REQUIRE(Approx(sound.GetAttenuation()) == 0.4f); + REQUIRE(Approx(sound.GetMinDistance()) == 40.f); + REQUIRE(Approx(sound.GetPitch()) == 0.8f); + REQUIRE(Approx(sound.GetVolume()) == 50.f); + } + } + } +} diff --git a/tests/resources/Engine/Audio/Cat.flac.REMOVED.git-id b/tests/resources/Engine/Audio/Cat.flac.REMOVED.git-id new file mode 100644 index 000000000..a686bc57d --- /dev/null +++ b/tests/resources/Engine/Audio/Cat.flac.REMOVED.git-id @@ -0,0 +1 @@ +6993cbcca9ac596667135cb0f30bea4841178d3b \ No newline at end of file diff --git a/tests/resources/Engine/Audio/The_Brabanconne.ogg.REMOVED.git-id b/tests/resources/Engine/Audio/The_Brabanconne.ogg.REMOVED.git-id new file mode 100644 index 000000000..bfd8dbd70 --- /dev/null +++ b/tests/resources/Engine/Audio/The_Brabanconne.ogg.REMOVED.git-id @@ -0,0 +1 @@ +94b2c47c9143adbac0fb7e81df5cc87f969f7150 \ No newline at end of file diff --git a/tests/resources/Engine/Audio/copyrights.txt b/tests/resources/Engine/Audio/copyrights.txt new file mode 100644 index 000000000..7b01b7090 --- /dev/null +++ b/tests/resources/Engine/Audio/copyrights.txt @@ -0,0 +1,54 @@ +The_Brabanconne.ogg + +https://en.wikipedia.org/wiki/File:The_Brabanconne.ogg + +Original file: +The_Brabanconne.ogg ‎(Ogg Vorbis sound file, length 1 min 3 s, 378 kbps) + +Summary: + +Description: The Belgian national anthem (instrumental version) performed by the United States Navy Band. Direct link is at http://www.navyband.navy.mil/anthems/ANTHEMS/Belgium.mp3. +Date: 19 October 2004 +Source: http://www.navyband.navy.mil/anthems/national_anthems.htm +Author: United States Navy Band (rendition), uploaded to Wikimedia by Keith Lehwald + +Licencing: + +This file is a work of a sailor or employee of the U.S. Navy, taken or made as part of that person's official duties. As a work of the U.S. federal government, the image is in the public domain. +This file has been identified as being free of known restrictions under copyright law, including all related and neighboring rights. + +------------------------------------------------------------------------------------------------- + +Cat.flac: + +http://www.freesound.org/people/EARR/sounds/148013/ + +Original file: +148013__earr__angry-cat.flac (Flac sound file, length 8 s, 96000 Hz, 24 bit depth) + +Author: + +EARR + +Description: + +Slightly angry cat. She is a beautiful Siamese cat called Agostina. She is angry for the recording because i pressed his tail. + +Information about the recording and equipment: + +-Location: Living room. +-Type of acoustic environment: Small, diffuse, moderately reflective. +-Distance from sound source to microphones: Approx a few centimeters. +-Miking technique: Jecklin disk. + +-Microphones: 2 Brüel & Kjaer type 4190 capsules with type 2669L head amplifier. +-Microphone preamps: Modified Brüel & Kjaer type 5935L. +-ADC: Echo Audiofire 4. (line inputs 3 & 4). +-Recorder: Echo Audiofire 4 and Dell D630C running Samplitude 10. + +Eq: Compensation only for the response of the microphones (In this case for flat response at 60º. See Brüel & Kjaer type 4190 datasheet). +No reverb, no compression, no fx. + +Licencing: + +Creative commons From dc4510d5cfb44ecb6fe44b200645f4d17037725a Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 May 2016 13:50:52 +0200 Subject: [PATCH 088/224] Examples: Add empty project for testing purposes Former-commit-id: bdecb65da518637c42e608e77ac49fedeb24ef00 --- examples/Tut00/build.lua | 20 ++++++++++++++++++++ examples/Tut00/main.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 examples/Tut00/build.lua create mode 100644 examples/Tut00/main.cpp diff --git a/examples/Tut00/build.lua b/examples/Tut00/build.lua new file mode 100644 index 000000000..d0c499df6 --- /dev/null +++ b/examples/Tut00/build.lua @@ -0,0 +1,20 @@ +EXAMPLE.Name = "Tut00_EmptyProject" + +EXAMPLE.Console = true + +EXAMPLE.Files = { + "main.cpp" +} + +EXAMPLE.Libraries = { + "NazaraAudio", + "NazaraCore", + "NazaraGraphics", + "NazaraLua", + "NazaraNetwork", + "NazaraNoise", + "NazaraPhysics", + "NazaraRenderer", + "NazaraUtility", + "NazaraSDK" +} diff --git a/examples/Tut00/main.cpp b/examples/Tut00/main.cpp new file mode 100644 index 000000000..472db3148 --- /dev/null +++ b/examples/Tut00/main.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main() +{ + // This "example" has only one purpose: Giving an empty project for you to test whatever you want + // If you wish to have multiple test projects, you only have to copy/paste this directory and change the name in the build.lua + Ndk::Application app; + + // Do what you want here + + return EXIT_SUCCESS; +} \ No newline at end of file From 79c15d6271939bd18f67f0521014615e60aaa596 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 May 2016 13:52:08 +0200 Subject: [PATCH 089/224] Build: Fix default platform on 32bits os Former-commit-id: 01a32275da73f662048a9acb4750c43e7d483305 --- build/scripts/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 15bf69849..822067ea2 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -9,7 +9,7 @@ function NazaraBuild:Execute() if (os.is64bit()) then platformData = {"x64", "x86"} else - platformData = {"x64", "x86"} + platformData = {"x86", "x64"} end if (self.Actions[_ACTION] == nil) then From 7721fd228452f07d1fa7b317d91be305954c53c2 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:09:51 +0200 Subject: [PATCH 091/224] Fix documentation for module: Core Former-commit-id: 5f47321109e66e3961a09c4a2394335c4868453f --- include/Nazara/Core/Algorithm.inl | 2 +- include/Nazara/Core/ConfigCheck.hpp | 2 +- include/Nazara/Core/HandledObject.inl | 67 ++++++- include/Nazara/Core/ObjectHandle.inl | 265 +++++++++++++++++++++++-- include/Nazara/Core/ParameterList.hpp | 6 +- include/Nazara/Core/ResourceLoader.inl | 2 +- src/Nazara/Core/Core.cpp | 2 +- src/Nazara/Core/File.cpp | 6 +- src/Nazara/Core/ParameterList.cpp | 62 ++++++ tests/Engine/Core/ByteArray.cpp | 20 ++ tests/Engine/Core/File.cpp | 12 +- 11 files changed, 421 insertions(+), 25 deletions(-) diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 048fae8e9..6997f8d1e 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -78,7 +78,7 @@ namespace Nz * \param v Object to hash * * \remark a HashAppend specialization for type T is required - * + * * \see ComputeHash */ template diff --git a/include/Nazara/Core/ConfigCheck.hpp b/include/Nazara/Core/ConfigCheck.hpp index 8329f4ff0..aa1ac5cfa 100644 --- a/include/Nazara/Core/ConfigCheck.hpp +++ b/include/Nazara/Core/ConfigCheck.hpp @@ -12,7 +12,7 @@ #include #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// We fore the value of MANAGE_MEMORY in debug +// We force the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY #undef NAZARA_CORE_MANAGE_MEMORY #define NAZARA_CORE_MANAGE_MEMORY 0 diff --git a/include/Nazara/Core/HandledObject.inl b/include/Nazara/Core/HandledObject.inl index da435302e..6b4d64c45 100644 --- a/include/Nazara/Core/HandledObject.inl +++ b/include/Nazara/Core/HandledObject.inl @@ -10,6 +10,17 @@ namespace Nz { + /*! + * \ingroup core + * \class Nz::HandledObject + * \brief Core class that represents a handled object + */ + + /*! + * \brief Constructs a HandledObject object by assignation + * + * \param object HandledObject to assign into this + */ template HandledObject::HandledObject(const HandledObject& object) { @@ -17,6 +28,11 @@ namespace Nz // Don't copy anything, we're a copy of the object, we have no handle right now } + /*! + * \brief Constructs a HandledObject object by move semantic + * + * \param object HandledObject to move into this + */ template HandledObject::HandledObject(HandledObject&& object) : m_handles(std::move(object.m_handles)) @@ -25,25 +41,46 @@ namespace Nz handle->OnObjectMoved(static_cast(this)); } + /*! + * \brief Destructs the object and calls UnregisterAllHandles + * + * \see UnregisterAllHandles + */ template HandledObject::~HandledObject() { UnregisterAllHandles(); } + /*! + * \brief Creates a ObjectHandle for this + * \return ObjectHandle to this + */ template ObjectHandle HandledObject::CreateHandle() { return ObjectHandle(static_cast(this)); } + /*! + * \brief Sets the reference of the HandledObject with the handle from another + * \return A reference to this + * + * \param object The other HandledObject + */ template HandledObject& HandledObject::operator=(const HandledObject& object) { // Nothing to do - return *this; + return *this; } + /*! + * \brief Moves the HandledObject into this + * \return A reference to this + * + * \param object HandledObject to move in this + */ template HandledObject& HandledObject::operator=(HandledObject&& object) { @@ -54,13 +91,22 @@ namespace Nz return *this; } + /*! + * \brief Registers a handle + * + * \param handle Handle to register + * + * \remark One handle can only be registered once, errors can occur if it's more than once + */ template void HandledObject::RegisterHandle(ObjectHandle* handle) { - ///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois m_handles.push_back(handle); } + /*! + * \brief Unregisters all handles + */ template void HandledObject::UnregisterAllHandles() { @@ -71,10 +117,17 @@ namespace Nz m_handles.clear(); } + /*! + * \brief Unregisters a handle + * + * \param handle Handle to unregister + * + * \remark One handle can only be unregistered once, crash can occur if it's more than once + * \remark Produces a NazaraAssert if handle not registered + */ template 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 registered"); @@ -83,6 +136,14 @@ namespace Nz m_handles.pop_back(); } + /*! + * \brief Updates one handle with another + * + * \param oldHandle Old handle to replace + * \param newHandle New handle to take place + * + * \remark Produces a NazaraAssert if handle not registered + */ template void HandledObject::UpdateHandle(ObjectHandle* oldHandle, ObjectHandle* newHandle) noexcept { diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index cfcd6bc0d..ee6e26268 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -9,12 +9,26 @@ namespace Nz { + /*! + * \ingroup core + * \class Nz::ObjectHandle + * \brief Core class that represents a object handle + */ + + /*! + * \brief Constructs a ObjectHandle object by default + */ template ObjectHandle::ObjectHandle() : m_object(nullptr) { } + /*! + * \brief Constructs a ObjectHandle object with a pointer to an object + * + * \param object Pointer to handle like an object (can be nullptr) + */ template ObjectHandle::ObjectHandle(T* object) : ObjectHandle() @@ -22,59 +36,97 @@ namespace Nz Reset(object); } + /*! + * \brief Constructs a ObjectHandle object by assignation + * + * \param handle ObjectHandle to assign into this + */ template - ObjectHandle::ObjectHandle(const ObjectHandle& handle) : + ObjectHandle::ObjectHandle(const ObjectHandle& handle) : ObjectHandle() { Reset(handle); } + /*! + * \brief Constructs a ObjectHandle object by move semantic + * + * \param handle ObjectHandle to move into this + */ template - ObjectHandle::ObjectHandle(ObjectHandle&& handle) noexcept : + ObjectHandle::ObjectHandle(ObjectHandle&& handle) noexcept : ObjectHandle() { Reset(std::move(handle)); } + /*! + * \brief Destructs the object and calls reset with nullptr + * + * \see Reset + */ template ObjectHandle::~ObjectHandle() { Reset(nullptr); } + /*! + * \brief Gets the underlying object + * \return Underlying object + */ template T* ObjectHandle::GetObject() const { return m_object; } + /*! + * \brief Checks whether the object is valid + * \return true if object is not nullptr + */ template bool ObjectHandle::IsValid() const { return m_object != nullptr; } + /*! + * \brief Resets the content of the ObjectHandle with another object + * + * \param object Object to handle + */ template void ObjectHandle::Reset(T* object) { - // Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle + // If we already have an entity, we must alert it that we are not pointing to it anymore if (m_object) m_object->UnregisterHandle(this); m_object = object; if (m_object) - // On informe la nouvelle entité que nous pointons sur elle + // We alert the new entity that we are pointing to it m_object->RegisterHandle(this); } + /*! + * \brief Resets the content of this with another object + * + * \param handle New object to handle + */ template - void ObjectHandle::Reset(const ObjectHandle& handle) + void ObjectHandle::Reset(const ObjectHandle& handle) { Reset(handle.GetObject()); } + /*! + * \brief Resets the content of this with another object by move semantic + * + * \param handle New object to handle to move into this + */ template - void ObjectHandle::Reset(ObjectHandle&& handle) noexcept + void ObjectHandle::Reset(ObjectHandle&& handle) noexcept { if (m_object) m_object->UnregisterHandle(this); @@ -87,12 +139,18 @@ namespace Nz } } + /*! + * \brief Swaps the content of the two ObjectHandle + * \return A reference to this + * + * \param handle ObjectHandle to swap + */ template - ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) + ObjectHandle& ObjectHandle::Swap(ObjectHandle& handle) { - // Comme nous inversons les handles, nous devons prévenir les entités - // La version par défaut de swap (à base de move) aurait fonctionné, - // mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). + // As we swap the two handles, we must alert the entities + // The default version with swap (move) would be working, + // but will register handles one more time (due to temporary copy). if (m_object) { m_object->UnregisterHandle(this); @@ -105,11 +163,15 @@ namespace Nz handle.m_object->RegisterHandle(this); } - // On effectue l'échange + // We do the swap std::swap(m_object, handle.m_object); return *this; } + /*! + * \brief Gives a string representation + * \return A string representation of the object "ObjectHandle(object representation) or Null" + */ template Nz::String ObjectHandle::ToString() const { @@ -125,24 +187,44 @@ namespace Nz return ss; } + /*! + * \brief Converts the ObjectHandle to bool + * \return true if reference is not nullptr + * + * \see IsValid + */ template ObjectHandle::operator bool() const { return IsValid(); } + /*! + * \brief Dereferences the ObjectHandle + * \return Underlying pointer + */ template ObjectHandle::operator T*() const { return m_object; } + /*! + * \brief Dereferences the ObjectHandle + * \return Underlying pointer + */ template T* ObjectHandle::operator->() const { return m_object; } + /*! + * \brief Assigns the entity into this + * \return A reference to this + * + * \param entity Pointer to handle like an object (can be nullptr) + */ template ObjectHandle& ObjectHandle::operator=(T* entity) { @@ -151,22 +233,37 @@ namespace Nz return *this; } + /*! + * \brief Sets the handle of the ObjectHandle with the handle from another + * \return A reference to this + * + * \param handle The other ObjectHandle + */ template - ObjectHandle& ObjectHandle::operator=(const ObjectHandle& handle) + ObjectHandle& ObjectHandle::operator=(const ObjectHandle& handle) { Reset(handle); return *this; } + /*! + * \brief Moves the ObjectHandle into this + * \return A reference to this + * + * \param handle ObjectHandle to move in this + */ template - ObjectHandle& ObjectHandle::operator=(ObjectHandle&& handle) noexcept + ObjectHandle& ObjectHandle::operator=(ObjectHandle&& handle) noexcept { Reset(std::move(handle)); return *this; } + /*! + * \brief Action to do on object destruction + */ template void ObjectHandle::OnObjectDestroyed() { @@ -174,6 +271,9 @@ namespace Nz m_object = nullptr; } + /*! + * \brief Action to do on object move + */ template void ObjectHandle::OnObjectMoved(T* newObject) { @@ -181,114 +281,247 @@ namespace Nz m_object = newObject; } + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param handle The ObjectHandle to output + */ template std::ostream& operator<<(std::ostream& out, const ObjectHandle& handle) { return handle.ToString(); } + /*! + * \brief Checks whether the first object handle is equal to the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator==(const ObjectHandle& lhs, const ObjectHandle& rhs) { return lhs.GetObject() == rhs.GetObject(); } + /*! + * \brief Checks whether the object is equal to the second object handle + * \return true if it is the case + * + * \param first Object to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator==(const T& lhs, const ObjectHandle& rhs) { return &lhs == rhs.GetObject(); } + /*! + * \brief Checks whether the object handle is equal to the second object + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second Object to compare in right hand side + */ template bool operator==(const ObjectHandle& lhs, const T& rhs) { return lhs.GetObject() == &rhs; } + /*! + * \brief Checks whether the first object handle is equal to the second object handle + * \return false if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator!=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs == rhs); } + /*! + * \brief Checks whether the object is equal to the second object handle + * \return false if it is the case + * + * \param first Object to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator!=(const T& lhs, const ObjectHandle& rhs) { return !(lhs == rhs); } + /*! + * \brief Checks whether the object handle is equal to the second object + * \return false if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second Object to compare in right hand side + */ template bool operator!=(const ObjectHandle& lhs, const T& rhs) { return !(lhs == rhs); } + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<(const ObjectHandle& lhs, const ObjectHandle& rhs) { return lhs.m_object < rhs.m_object; } + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<(const T& lhs, const ObjectHandle& rhs) { return &lhs < rhs.m_object; } + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<(const ObjectHandle& lhs, const T& rhs) { return lhs.m_object < &rhs; } + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs > rhs); } + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<=(const T& lhs, const ObjectHandle& rhs) { return !(lhs > rhs); } + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator<=(const ObjectHandle& lhs, const T& rhs) { return !(lhs > rhs); } + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>(const ObjectHandle& lhs, const ObjectHandle& rhs) { return rhs < lhs; } + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>(const T& lhs, const ObjectHandle& rhs) { return rhs < lhs; } + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>(const ObjectHandle& lhs, const T& rhs) { return rhs < lhs; } + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>=(const ObjectHandle& lhs, const ObjectHandle& rhs) { return !(lhs < rhs); } + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>=(const T& lhs, const ObjectHandle& rhs) { return !(lhs < rhs); } + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectHandle to compare in left hand side + * \param second ObjectHandle to compare in right hand side + */ template bool operator>=(const ObjectHandle& lhs, const T& rhs) { @@ -301,6 +534,12 @@ namespace Nz namespace std { + /*! + * \brief Swaps two ObjectHandle, specialisation of std + * + * \param lhs First object handle + * \param rhs Second object handle + */ template void swap(Nz::ObjectHandle& lhs, Nz::ObjectHandle& rhs) { diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index 119d05cca..751746aea 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -50,6 +50,8 @@ namespace Nz void SetParameter(const String& name, void* value); void SetParameter(const String& name, void* value, Destructor destructor); + String ToString() const; + ParameterList& operator=(const ParameterList& list); ParameterList& operator=(ParameterList&&) = default; @@ -73,7 +75,7 @@ namespace Nz ParameterType type; union Value { - // On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union + // We define an empty constructor/destructor, to be able to put classes in the union Value() {} Value(const Value&) {} // Placeholder ~Value() {} @@ -98,4 +100,6 @@ namespace Nz }; } +std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList); + #endif // NAZARA_PARAMETERLIST_HPP diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index af0a8a7f0..74e59067d 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -66,7 +66,7 @@ namespace Nz return false; } - File file(path); // Ouvert seulement en cas de besoin + File file(path); // Open only if needed bool found = false; for (Loader& loader : Type::s_loaders) diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 1ccb35212..026e4a247 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -28,7 +28,7 @@ namespace Nz bool Core::Initialize() { - if (s_moduleReferenceCounter > 0) + if (IsInitialized()) { s_moduleReferenceCounter++; return true; // Already initialized diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 39e873373..97504b0ee 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -385,7 +385,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param pos Position of the cursor @@ -404,7 +404,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param offset Offset according to the cursor begin position @@ -906,5 +906,5 @@ namespace Nz } return true; - } + }; } diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 371e91b77..abe93c640 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -607,6 +607,54 @@ namespace Nz parameter.value.ptrVal = value; } + /*! + * \brief Gives a string representation + * \return A string representation of the object: "ParameterList(Name: Type(value), ...)" + */ + String ParameterList::ToString() const + { + StringStream ss; + + ss << "ParameterList("; + for (auto it = m_parameters.cbegin(); it != m_parameters.cend();) + { + ss << it->first << ": "; + switch (it->second.type) + { + case ParameterType_Boolean: + ss << "Boolean(" << String::Boolean(it->second.value.boolVal) << ")"; + break; + case ParameterType_Color: + ss << "Color(" << it->second.value.colorVal.ToString() << ")"; + break; + case ParameterType_Float: + ss << "Float(" << it->second.value.floatVal << ")"; + break; + case ParameterType_Integer: + ss << "Integer(" << it->second.value.intVal << ")"; + break; + case ParameterType_String: + ss << "String(" << it->second.value.stringVal << ")"; + break; + case ParameterType_Pointer: + ss << "Pointer(" << String::Pointer(it->second.value.ptrVal) << ")"; + break; + case ParameterType_Userdata: + ss << "Userdata(" << String::Pointer(it->second.value.userdataVal->ptr) << ")"; + break; + case ParameterType_None: + ss << "None"; + break; + } + + if (++it != m_parameters.cend()) + ss << ", "; + } + ss << ")"; + + return ss; + } + /*! * \brief Sets a userdata parameter named `name` * @@ -724,3 +772,17 @@ namespace Nz } } } + +/*! +* \brief Output operator +* \return The stream +* +* \param out The stream +* \param parameterList The ParameterList to output +*/ + +std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList) +{ + out << parameterList.ToString(); + return out; +} diff --git a/tests/Engine/Core/ByteArray.cpp b/tests/Engine/Core/ByteArray.cpp index 476643d5e..d085585a5 100644 --- a/tests/Engine/Core/ByteArray.cpp +++ b/tests/Engine/Core/ByteArray.cpp @@ -213,4 +213,24 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") } } } + + GIVEN("A default byte array") + { + Nz::ByteArray defaultByteArray; + + WHEN("We resize") + { + Nz::UInt64 oldSize = defaultByteArray.GetSize(); + REQUIRE(oldSize == 0); + defaultByteArray.Resize(10); + + THEN("Capacity has increased") + { + REQUIRE(defaultByteArray[oldSize] == 0); + + REQUIRE(defaultByteArray.GetCapacity() >= 10); + REQUIRE(defaultByteArray.GetSize() == 10); + } + } + } } diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index 2ddbfebbf..1163a8aad 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -32,12 +32,22 @@ SCENARIO("File", "[CORE][FILE]") REQUIRE(Nz::String(message) == "Test String"); } + AND_THEN("We can get its size") + { + REQUIRE(file.GetSize() == 33U); + } + AND_THEN("We close it") { file.Close(); - REQUIRE(file.GetSize() == 33U); CHECK(!file.IsOpen()); } + + AND_THEN("Change its size") + { + file.SetSize(50U); + REQUIRE(file.GetSize() == 50U); + } } WHEN("We delete this file") From 2c941827eddcc7739b0d0b356459895be37f598b Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:21:36 +0200 Subject: [PATCH 092/224] Documentation for module: Graphics Former-commit-id: 1757c33318443aade1dc38e16d053240d7dc885c --- include/Nazara/Graphics/Billboard.inl | 101 +++- include/Nazara/Graphics/ColorBackground.inl | 7 + include/Nazara/Graphics/Config.hpp | 19 +- include/Nazara/Graphics/ConfigCheck.hpp | 4 +- include/Nazara/Graphics/DebugOff.hpp | 2 +- include/Nazara/Graphics/DeferredBloomPass.hpp | 2 +- include/Nazara/Graphics/DeferredDOFPass.hpp | 2 +- include/Nazara/Graphics/DeferredFXAAPass.hpp | 2 +- include/Nazara/Graphics/DeferredFinalPass.hpp | 2 +- include/Nazara/Graphics/DeferredFogPass.hpp | 2 +- .../Nazara/Graphics/DeferredForwardPass.hpp | 2 +- .../Nazara/Graphics/DeferredGeometryPass.hpp | 2 +- .../Graphics/DeferredPhongLightingPass.hpp | 2 +- .../Nazara/Graphics/DeferredRenderPass.hpp | 2 +- .../Graphics/DeferredRenderTechnique.hpp | 2 +- include/Nazara/Graphics/DepthRenderQueue.inl | 8 + include/Nazara/Graphics/Enums.hpp | 4 +- .../Nazara/Graphics/ForwardRenderQueue.hpp | 1 + .../Graphics/ForwardRenderTechnique.hpp | 10 +- .../Graphics/ForwardRenderTechnique.inl | 58 ++ .../Nazara/Graphics/InstancedRenderable.inl | 31 ++ include/Nazara/Graphics/Light.inl | 174 ++++++ include/Nazara/Graphics/Material.hpp | 6 +- include/Nazara/Graphics/Material.inl | 509 ++++++++++++++++++ include/Nazara/Graphics/Model.hpp | 2 - include/Nazara/Graphics/Model.inl | 7 + .../Nazara/Graphics/ParticleDeclaration.hpp | 10 +- include/Nazara/Graphics/ParticleMapper.inl | 28 +- include/Nazara/Graphics/Renderable.inl | 14 + include/Nazara/Graphics/SkyboxBackground.inl | 56 ++ include/Nazara/Graphics/Sprite.inl | 120 ++++- include/Nazara/Graphics/TextSprite.inl | 84 ++- include/Nazara/Graphics/TextureBackground.inl | 18 + include/Nazara/Math/Frustum.inl | 4 +- include/Nazara/Math/Sphere.inl | 2 +- src/Nazara/Graphics/AbstractBackground.cpp | 8 + src/Nazara/Graphics/AbstractRenderQueue.cpp | 32 ++ .../Graphics/AbstractRenderTechnique.cpp | 30 ++ src/Nazara/Graphics/AbstractViewer.cpp | 8 + src/Nazara/Graphics/Billboard.cpp | 19 +- src/Nazara/Graphics/ColorBackground.cpp | 39 ++ src/Nazara/Graphics/DeferredBloomPass.cpp | 85 ++- src/Nazara/Graphics/DeferredDOFPass.cpp | 34 +- src/Nazara/Graphics/DeferredFXAAPass.cpp | 21 +- src/Nazara/Graphics/DeferredFinalPass.cpp | 21 +- src/Nazara/Graphics/DeferredFogPass.cpp | 26 +- src/Nazara/Graphics/DeferredForwardPass.cpp | 23 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 73 ++- .../Graphics/DeferredPhongLightingPass.cpp | 44 +- src/Nazara/Graphics/DeferredRenderPass.cpp | 34 ++ src/Nazara/Graphics/DeferredRenderQueue.cpp | 205 ++++++- .../Graphics/DeferredRenderTechnique.cpp | 166 +++++- src/Nazara/Graphics/DepthRenderQueue.cpp | 183 +++++++ src/Nazara/Graphics/DepthRenderTechnique.cpp | 136 ++++- src/Nazara/Graphics/Drawable.cpp | 8 + src/Nazara/Graphics/ForwardRenderQueue.cpp | 479 ++++++++++------ .../Graphics/ForwardRenderTechnique.cpp | 291 +++++++--- src/Nazara/Graphics/Graphics.cpp | 53 +- .../Graphics/GuillotineTextureAtlas.cpp | 28 +- src/Nazara/Graphics/InstancedRenderable.cpp | 54 ++ src/Nazara/Graphics/Light.cpp | 77 ++- src/Nazara/Graphics/Material.cpp | 64 ++- src/Nazara/Graphics/Model.cpp | 219 +++++++- src/Nazara/Graphics/ParticleController.cpp | 31 ++ src/Nazara/Graphics/ParticleDeclaration.cpp | 108 +++- src/Nazara/Graphics/ParticleEmitter.cpp | 72 ++- src/Nazara/Graphics/ParticleGenerator.cpp | 31 ++ src/Nazara/Graphics/ParticleMapper.cpp | 13 + src/Nazara/Graphics/ParticleRenderer.cpp | 29 + src/Nazara/Graphics/ParticleSystem.cpp | 244 ++++++++- src/Nazara/Graphics/RenderTechniques.cpp | 80 ++- src/Nazara/Graphics/Renderable.cpp | 27 + src/Nazara/Graphics/SkeletalModel.cpp | 167 +++++- src/Nazara/Graphics/SkinningManager.cpp | 69 ++- src/Nazara/Graphics/SkyboxBackground.cpp | 36 +- src/Nazara/Graphics/Sprite.cpp | 34 ++ src/Nazara/Graphics/TextSprite.cpp | 85 ++- src/Nazara/Graphics/TextureBackground.cpp | 28 + tests/Engine/Graphics/Billboard.cpp | 34 ++ tests/Engine/Graphics/ColorBackground.cpp | 20 + .../Graphics/DeferredRenderTechnique.cpp | 29 + tests/Engine/Graphics/Light.cpp | 31 ++ tests/Engine/Graphics/Model.cpp | 24 + tests/Engine/Graphics/ParticleDeclaration.cpp | 29 + tests/Engine/Graphics/ParticleSystem.cpp | 103 ++++ tests/Engine/Graphics/RenderTechniques.cpp | 47 ++ tests/Engine/Graphics/SkeletalModel.cpp | 26 + tests/Engine/Graphics/SkyboxBackground.cpp | 25 + tests/Engine/Graphics/TextureBackground.cpp | 20 + tests/Engine/Math/Sphere.cpp | 12 +- tests/main.cpp | 16 +- .../Engine/Graphics/Bob lamp/Readme.txt | 24 + .../resources/Engine/Graphics/copyrights.txt | 82 +++ .../Engine/Graphics/dragon_recon/README | 27 + 94 files changed, 4858 insertions(+), 504 deletions(-) create mode 100644 tests/Engine/Graphics/Billboard.cpp create mode 100644 tests/Engine/Graphics/ColorBackground.cpp create mode 100644 tests/Engine/Graphics/DeferredRenderTechnique.cpp create mode 100644 tests/Engine/Graphics/Light.cpp create mode 100644 tests/Engine/Graphics/Model.cpp create mode 100644 tests/Engine/Graphics/ParticleDeclaration.cpp create mode 100644 tests/Engine/Graphics/ParticleSystem.cpp create mode 100644 tests/Engine/Graphics/RenderTechniques.cpp create mode 100644 tests/Engine/Graphics/SkeletalModel.cpp create mode 100644 tests/Engine/Graphics/SkyboxBackground.cpp create mode 100644 tests/Engine/Graphics/TextureBackground.cpp create mode 100644 tests/resources/Engine/Graphics/Bob lamp/Readme.txt create mode 100644 tests/resources/Engine/Graphics/copyrights.txt create mode 100644 tests/resources/Engine/Graphics/dragon_recon/README diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index c9760d0d1..6c4a1e0a9 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -7,6 +7,10 @@ namespace Nz { + /*! + * \brief Constructs a Billboard object by default + */ + inline Billboard::Billboard() { SetColor(Color::White); @@ -15,6 +19,12 @@ namespace Nz SetSize(64.f, 64.f); } + /*! + * \brief Constructs a Billboard object with a reference to a material + * + * \param material Reference to a material + */ + inline Billboard::Billboard(MaterialRef material) { SetColor(Color::White); @@ -23,6 +33,12 @@ namespace Nz SetSize(64.f, 64.f); } + /*! + * \brief Constructs a Billboard object with a pointer to a texture + * + * \param texture Pointer to a texture + */ + inline Billboard::Billboard(Texture* texture) { SetColor(Color::White); @@ -31,6 +47,12 @@ namespace Nz SetTexture(texture, true); } + /*! + * \brief Constructs a Billboard object by assignation + * + * \param billboard Billboard to copy into this + */ + inline Billboard::Billboard(const Billboard& billboard) : InstancedRenderable(billboard), m_color(billboard.m_color), @@ -41,31 +63,61 @@ namespace Nz { } + /*! + * \brief Gets the color of the billboard + * \return Current color + */ + inline const Color& Billboard::GetColor() const { return m_color; } + /*! + * \brief Gets the material of the billboard + * \return Current material + */ + inline const MaterialRef& Billboard::GetMaterial() const { return m_material; } + /*! + * \brief Gets the rotation of the billboard + * \return Current rotation + */ + inline float Billboard::GetRotation() const { return m_rotation; } + /*! + * \brief Gets the size of the billboard + * \return Current size + */ + inline const Vector2f& Billboard::GetSize() const { return m_size; } + /*! + * \brief Sets the color of the billboard + * + * \param color Color for the billboard + */ + inline void Billboard::SetColor(const Color& color) { m_color = color; } + /*! + * \brief Sets the default material of the billboard (just default material) + */ + inline void Billboard::SetDefaultMaterial() { MaterialRef material = Material::New(); @@ -75,6 +127,13 @@ namespace Nz SetMaterial(std::move(material)); } + /*! + * \brief Sets the material of the billboard + * + * \param material Material for the billboard + * \param resizeBillboard Should billboard be resized to the material size (diffuse map) + */ + inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) { m_material = std::move(material); @@ -86,25 +145,51 @@ namespace Nz } } + /*! + * \brief Sets the rotation of the billboard + * + * \param rotation Rotation for the billboard + */ + inline void Billboard::SetRotation(float rotation) { m_rotation = rotation; m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation)); } + /*! + * \brief Sets the size of the billboard + * + * \param size Size for the billboard + */ + inline void Billboard::SetSize(const Vector2f& size) { m_size = size; - // On invalide la bounding box + // We invalidate the bounding volume InvalidateBoundingVolume(); } + /*! + * \brief Sets the size of the billboard + * + * \param sizeX Size in X for the billboard + * \param sizeY Size in Y for the billboard + */ + inline void Billboard::SetSize(float sizeX, float sizeY) { SetSize(Vector2f(sizeX, sizeY)); } + /*! + * \brief Sets the texture of the billboard + * + * \param texture Texture for the billboard + * \param resizeBillboard Should billboard be resized to the texture size + */ + inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) { if (!m_material) @@ -118,6 +203,13 @@ namespace Nz m_material->SetDiffuseMap(std::move(texture)); } + /*! + * \brief Sets the current billboard with the content of the other one + * \return A reference to this + * + * \param billboard The other Billboard + */ + inline Billboard& Billboard::operator=(const Billboard& billboard) { InstancedRenderable::operator=(billboard); @@ -131,6 +223,13 @@ namespace Nz return *this; } + /*! + * \brief Creates a new billboard from the arguments + * \return A reference to the newly created billboard + * + * \param args Arguments for the billboard + */ + template BillboardRef Billboard::New(Args&&... args) { diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl index 21b67d92c..67b1f2558 100644 --- a/include/Nazara/Graphics/ColorBackground.inl +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -7,6 +7,13 @@ namespace Nz { + /*! + * \brief Creates a new color background from the arguments + * \return A reference to the newly created color background + * + * \param args Arguments for the color background + */ + template ColorBackgroundRef ColorBackground::New(Args&&... args) { diff --git a/include/Nazara/Graphics/Config.hpp b/include/Nazara/Graphics/Config.hpp index 77f1669c4..e47c8d3a5 100644 --- a/include/Nazara/Graphics/Config.hpp +++ b/include/Nazara/Graphics/Config.hpp @@ -27,23 +27,28 @@ #ifndef NAZARA_CONFIG_GRAPHICS_HPP #define NAZARA_CONFIG_GRAPHICS_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/*! +* \defgroup graphics (NazaraGraphics) Graphics module +* Graphics/System module including classes to handle graphical elements... +*/ -// À partir de combien d'instances d'un même mesh/matériau l'instancing doit-il être utilisé ? +/// Each modification of a paramater of the module needs a recompilation of the unit + +// How much instances are need of a same mesh/material to enable instancing ? #define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 10 -// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_GRAPHICS_MANAGE_MEMORY 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_GRAPHICS_SAFE 1 -/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code +/// Each modification of a parameter following implies a modification (often minor) of the code -// Le nombre maximum de lumières qu'un shader standard supportera +// The maximum number of lights in a standard shader #define NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS 3 -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if defined(NAZARA_STATIC) diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp index e93c8e0ec..c2bbda886 100644 --- a/include/Nazara/Graphics/ConfigCheck.hpp +++ b/include/Nazara/Graphics/ConfigCheck.hpp @@ -7,12 +7,12 @@ #ifndef NAZARA_CONFIG_CHECK_GRAPHICS_HPP #define NAZARA_CONFIG_CHECK_GRAPHICS_HPP -/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp +/// This file is used to check the constant values defined in Config.hpp #include #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type ::value && name op val, #type err) -// On force la valeur de MANAGE_MEMORY en mode debug +// We fore the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY #undef NAZARA_GRAPHICS_MANAGE_MEMORY #define NAZARA_GRAPHICS_MANAGE_MEMORY 0 diff --git a/include/Nazara/Graphics/DebugOff.hpp b/include/Nazara/Graphics/DebugOff.hpp index 38a452aab..c90640fc0 100644 --- a/include/Nazara/Graphics/DebugOff.hpp +++ b/include/Nazara/Graphics/DebugOff.hpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +// We suppose that Debug.hpp is already included, same goes for Config.hpp #if NAZARA_GRAPHICS_MANAGE_MEMORY #undef delete #undef new diff --git a/include/Nazara/Graphics/DeferredBloomPass.hpp b/include/Nazara/Graphics/DeferredBloomPass.hpp index 603998d84..5c45a2277 100644 --- a/include/Nazara/Graphics/DeferredBloomPass.hpp +++ b/include/Nazara/Graphics/DeferredBloomPass.hpp @@ -29,7 +29,7 @@ namespace Nz float GetBrightThreshold() const; Texture* GetTexture(unsigned int i) const; - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; bool Resize(const Vector2ui& dimensions); void SetBlurPassCount(unsigned int passCount); diff --git a/include/Nazara/Graphics/DeferredDOFPass.hpp b/include/Nazara/Graphics/DeferredDOFPass.hpp index 4da8824c7..c3d6e4c0f 100644 --- a/include/Nazara/Graphics/DeferredDOFPass.hpp +++ b/include/Nazara/Graphics/DeferredDOFPass.hpp @@ -23,7 +23,7 @@ namespace Nz DeferredDOFPass(); virtual ~DeferredDOFPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; bool Resize(const Vector2ui& dimensions); protected: diff --git a/include/Nazara/Graphics/DeferredFXAAPass.hpp b/include/Nazara/Graphics/DeferredFXAAPass.hpp index 34fc46867..1c74ffb1c 100644 --- a/include/Nazara/Graphics/DeferredFXAAPass.hpp +++ b/include/Nazara/Graphics/DeferredFXAAPass.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFXAAPass(); virtual ~DeferredFXAAPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredFinalPass.hpp b/include/Nazara/Graphics/DeferredFinalPass.hpp index c800d44d1..f6b633925 100644 --- a/include/Nazara/Graphics/DeferredFinalPass.hpp +++ b/include/Nazara/Graphics/DeferredFinalPass.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFinalPass(); virtual ~DeferredFinalPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredFogPass.hpp b/include/Nazara/Graphics/DeferredFogPass.hpp index 37466305b..babccb0bf 100644 --- a/include/Nazara/Graphics/DeferredFogPass.hpp +++ b/include/Nazara/Graphics/DeferredFogPass.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredFogPass(); virtual ~DeferredFogPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; protected: RenderStates m_states; diff --git a/include/Nazara/Graphics/DeferredForwardPass.hpp b/include/Nazara/Graphics/DeferredForwardPass.hpp index 0b1d8aa0a..cd5341d85 100644 --- a/include/Nazara/Graphics/DeferredForwardPass.hpp +++ b/include/Nazara/Graphics/DeferredForwardPass.hpp @@ -21,7 +21,7 @@ namespace Nz virtual ~DeferredForwardPass(); void Initialize(DeferredRenderTechnique* technique); - bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const; + bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const; protected: const ForwardRenderTechnique* m_forwardTechnique; diff --git a/include/Nazara/Graphics/DeferredGeometryPass.hpp b/include/Nazara/Graphics/DeferredGeometryPass.hpp index 652060b3d..15437f0d8 100644 --- a/include/Nazara/Graphics/DeferredGeometryPass.hpp +++ b/include/Nazara/Graphics/DeferredGeometryPass.hpp @@ -21,7 +21,7 @@ namespace Nz DeferredGeometryPass(); virtual ~DeferredGeometryPass(); - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; bool Resize(const Vector2ui& dimensions); protected: diff --git a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp index 40b480217..68eb96264 100644 --- a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp +++ b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp @@ -28,7 +28,7 @@ namespace Nz bool IsLightMeshesDrawingEnabled() const; - bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const; protected: LightUniforms m_directionalLightUniforms; diff --git a/include/Nazara/Graphics/DeferredRenderPass.hpp b/include/Nazara/Graphics/DeferredRenderPass.hpp index d9ad69919..34a4020a6 100644 --- a/include/Nazara/Graphics/DeferredRenderPass.hpp +++ b/include/Nazara/Graphics/DeferredRenderPass.hpp @@ -38,7 +38,7 @@ namespace Nz bool IsEnabled() const; - virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const = 0; + virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const = 0; virtual bool Resize(const Vector2ui& GBufferSize); DeferredRenderPass& operator=(const DeferredRenderPass&) = delete; diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index 99d1fc813..e9e357184 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -67,7 +67,7 @@ namespace Nz }; std::map>, RenderPassComparator> m_passes; - ForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue + ForwardRenderTechnique m_forwardTechnique; // Must be initialized before the RenderQueue DeferredRenderQueue m_renderQueue; mutable RenderBufferRef m_depthStencilBuffer; mutable RenderTexture m_GBufferRTT; diff --git a/include/Nazara/Graphics/DepthRenderQueue.inl b/include/Nazara/Graphics/DepthRenderQueue.inl index 7d6c9221f..a8a8da45e 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.inl +++ b/include/Nazara/Graphics/DepthRenderQueue.inl @@ -6,6 +6,14 @@ namespace Nz { + + /*! + * \brief Checks whether the material is suitable to fit in the render queue + * \return true If it is the case + * + * \param material Material to verify + */ + bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const { NazaraAssert(material, "Invalid material"); diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 6703f88a0..d378058f7 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -128,7 +128,7 @@ namespace Nz SceneNodeType_Max = SceneNodeType_User }; - // Ces paramètres sont indépendants du matériau: ils peuvent être demandés à tout moment + // These parameters are independant of the material: they can not be asked for the moment enum ShaderFlags { ShaderFlags_None = 0, @@ -139,7 +139,7 @@ namespace Nz ShaderFlags_TextureOverlay = 0x08, ShaderFlags_VertexColor = 0x10, - ShaderFlags_Max = ShaderFlags_VertexColor*2-1 + ShaderFlags_Max = ShaderFlags_VertexColor * 2 - 1 }; } diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 9a17f5d2f..c358e331c 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -159,6 +159,7 @@ namespace Nz std::map layers; private: + BillboardData* GetBillboardData(int renderOrder, const Material* material, unsigned int count); Layer& GetLayer(int i); ///TODO: Inline void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 447818958..21b3a0899 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -31,7 +31,7 @@ namespace Nz AbstractRenderQueue* GetRenderQueue() override; RenderTechniqueType GetType() const override; - void SetMaxLightPassPerObject(unsigned int passCount); + void SetMaxLightPassPerObject(unsigned int maxLightPassPerObject); static bool Initialize(); static void Uninitialize(); @@ -70,11 +70,11 @@ namespace Nz LightUniforms lightUniforms; bool hasLightUniforms; - /// Moins coûteux en mémoire que de stocker un LightUniforms par index de lumière, - /// à voir si ça fonctionne chez tout le monde - int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + /// Less costly in memory than storing a LightUniforms by index of light, + /// this may not work everywhere + int lightOffset; // "Distance" between Lights[0].type and Lights[1].type - // Autre uniformes + // Other uniforms int eyePosition; int sceneAmbient; int textureOverlay; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index bf9e5674c..6490513f8 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -6,6 +6,16 @@ namespace Nz { + /*! + * \brief Sens the uniforms for light + * + * \param shader Shader to send uniforms to + * \param uniforms Uniforms to send + * \param index Index of the light + * \param uniformOffset Offset for the uniform + * \param availableTextureUnit Unit texture available + */ + 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.. @@ -104,6 +114,14 @@ namespace Nz } } + /*! + * \brief Computes the score for directional light + * \return 0.f + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) { NazaraUnused(object); @@ -113,18 +131,42 @@ namespace Nz return 0.f; } + /*! + * \brief Computes the score for point light + * \return Distance to the light + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light) { ///TODO: Compute a score depending on the light luminosity return object.SquaredDistance(light.position); } + /*! + * \brief Computes the score for spot light + * \return Distance to the light + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light) { ///TODO: Compute a score depending on the light luminosity and spot direction return object.SquaredDistance(light.position); } + /*! + * \brief Checks whether the directional light is suitable for the computations + * \return true if light is enoughly close + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) { NazaraUnused(object); @@ -134,12 +176,28 @@ namespace Nz return true; } + /*! + * \brief Checks whether the point light is suitable for the computations + * \return true if light is enoughly close + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light) { // If the object is too far away from this point light, there is not way it could light it return object.SquaredDistance(light.position) <= light.radius * light.radius; } + /*! + * \brief Checks whether the spot light is suitable for the computations + * \return true if light is enoughly close + * + * \param object Sphere symbolising the object + * \param light Light to compute + */ + inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light) { ///TODO: Exclude spot lights based on their direction and outer angle? diff --git a/include/Nazara/Graphics/InstancedRenderable.inl b/include/Nazara/Graphics/InstancedRenderable.inl index 0cc97f101..7f2537fbf 100644 --- a/include/Nazara/Graphics/InstancedRenderable.inl +++ b/include/Nazara/Graphics/InstancedRenderable.inl @@ -4,6 +4,12 @@ namespace Nz { + /*! + * \brief Constructs a InstancedRenderable object by assignation + * + * \param renderable InstancedRenderable to copy into this + */ + inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) : RefCounted(), m_boundingVolume(renderable.m_boundingVolume), @@ -11,22 +17,43 @@ namespace Nz { } + /*! + * \brief Ensures that the bounding volume is up to date + */ + inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const { if (!m_boundingVolumeUpdated) UpdateBoundingVolume(); } + /*! + * \brief Invalidates the bounding volume + */ + inline void InstancedRenderable::InvalidateBoundingVolume() { m_boundingVolumeUpdated = false; } + /*! + * \brief Invalidates the instance data based on flags + * + * \param flags Flags to invalidate + */ + inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags) { OnInstancedRenderableInvalidateData(this, flags); } + /*! + * \brief Sets the current instanced renderable with the content of the other one + * \return A reference to this + * + * \param renderable The other InstancedRenderable + */ + inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable) { m_boundingVolume = renderable.m_boundingVolume; @@ -35,6 +62,10 @@ namespace Nz return *this; } + /*! + * \brief Updates the bounding volume + */ + inline void InstancedRenderable::UpdateBoundingVolume() const { MakeBoundingVolume(); diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index edff48a66..2852834b7 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -7,6 +7,10 @@ namespace Nz { + /*! + * \brief Constructs a Light object by default + */ + inline Light::Light(const Light& light) : Renderable(light), m_color(light.m_color), @@ -28,6 +32,12 @@ namespace Nz { } + /*! + * \brief Enables shadow casting + * + * \param castShadows Should shadows be cast + */ + inline void Light::EnableShadowCasting(bool castShadows) { if (m_shadowCastingEnabled != castShadows) @@ -37,72 +47,141 @@ namespace Nz } } + /*! + * \brief Ensures that the shadow map is up to date + */ + inline void Light::EnsureShadowMapUpdate() const { if (!m_shadowMapUpdated) UpdateShadowMap(); } + /*! + * \brief Gets the ambient factor + * \return Current ambient factor + */ + inline float Light::GetAmbientFactor() const { return m_ambientFactor; } + /*! + * \brief Gets the light attenuation (in 1 / R^2) + * \return Attenuation + */ + inline float Light::GetAttenuation() const { return m_attenuation; } + /*! + * \brief Gets the color of the light + * \return Light color + */ + inline Color Light::GetColor() const { return m_color; } + /*! + * \brief Gets the diffuse factor + * \return Current diffuse factor + */ + inline float Light::GetDiffuseFactor() const { return m_diffuseFactor; } + /*! + * \brief Gets the inner angle in spot light + * \return Inner angle + */ + inline float Light::GetInnerAngle() const { return m_innerAngle; } + /*! + * \brief Gets the cosine inner angle in spot light + * \return Cosine inner angle + */ + inline float Light::GetInnerAngleCosine() const { return m_innerAngleCosine; } + /*! + * \brief Gets the inverse of the radius + * \return Inverse of the radius + */ + inline float Light::GetInvRadius() const { return m_invRadius; } + /*! + * \brief Gets the type of the light + * \return Light type + */ + inline LightType Light::GetLightType() const { return m_type; } + /*! + * \brief Gets the outer angle in spot light + * \return Outer angle + */ + inline float Light::GetOuterAngle() const { return m_outerAngle; } + /*! + * \brief Gets the cosine outer angle in spot light + * \return Cosine outer angle + */ + inline float Light::GetOuterAngleCosine() const { return m_outerAngleCosine; } + /*! + * \brief Gets the tangent outer angle in spot light + * \return Tangent outer angle + */ + inline float Light::GetOuterAngleTangent() const { return m_outerAngleTangent; } + /*! + * \brief Gets the radius of the light + * \return Light radius + */ + inline float Light::GetRadius() const { return m_radius; } + /*! + * \brief Gets the shadow map + * \return Reference to the shadow map texture + */ + inline TextureRef Light::GetShadowMap() const { EnsureShadowMapUpdate(); @@ -110,47 +189,97 @@ namespace Nz return m_shadowMap; } + /*! + * \brief Gets the format of the shadow map + * \return Shadow map format + */ + inline PixelFormatType Light::GetShadowMapFormat() const { return m_shadowMapFormat; } + /*! + * \brief Gets the size of the shadow map + * \return Shadow map size + */ + inline const Vector2ui& Light::GetShadowMapSize() const { return m_shadowMapSize; } + /*! + * \brief Checks whether the shadow casting is enabled + * \return true If it is the case + */ + inline bool Light::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; } + /*! + * \brief Sets the ambient factor + * + * \param factor Ambient factor + */ + inline void Light::SetAmbientFactor(float factor) { m_ambientFactor = factor; } + /*! + * \brief Sets the light attenuation (in 1 / R^2) + * + * \param attenuation Light attenuation + */ + inline void Light::SetAttenuation(float attenuation) { m_attenuation = attenuation; } + /*! + * \brief Sets the color of the light + * + * \param color Light color + */ + inline void Light::SetColor(const Color& color) { m_color = color; } + /*! + * \brief Sets the diffuse factor + * + * \param factor Diffuse factor + */ + inline void Light::SetDiffuseFactor(float factor) { m_diffuseFactor = factor; } + /*! + * \brief Sets the inner angle in spot light + * \return innerAngle Inner angle + */ + inline void Light::SetInnerAngle(float innerAngle) { m_innerAngle = innerAngle; m_innerAngleCosine = std::cos(DegreeToRadian(m_innerAngle)); } + /*! + * \brief Sets the type of light + * + * \param type Light type + */ + inline void Light::SetLightType(LightType type) { m_type = type; @@ -158,6 +287,13 @@ namespace Nz InvalidateShadowMap(); } + /*! + * \brief Sets the outer angle in spot light + * \return outerAngle Outer angle + * + * \remark Invalidates the bounding volume + */ + inline void Light::SetOuterAngle(float outerAngle) { m_outerAngle = outerAngle; @@ -167,6 +303,13 @@ namespace Nz InvalidateBoundingVolume(); } + /*! + * \brief Sets the radius of the light + * \return radius Light radius + * + * \remark Invalidates the bounding volume + */ + inline void Light::SetRadius(float radius) { m_radius = radius; @@ -176,6 +319,15 @@ namespace Nz InvalidateBoundingVolume(); } + /*! + * \brief Sets the shadow map format + * + * \param shadowFormat Shadow map format + * + * \remark Invalidates the shadow map + * \remark Produces a NazaraAssert if format is not a depth type + */ + inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat) { NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format"); @@ -185,6 +337,15 @@ namespace Nz InvalidateShadowMap(); } + /*! + * \brief Sets the size of the shadow map + * + * \param size Shadow map size + * + * \remark Invalidates the shadow map + * \remark Produces a NazaraAssert if size is zero + */ + inline void Light::SetShadowMapSize(const Vector2ui& size) { NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size"); @@ -194,6 +355,15 @@ namespace Nz InvalidateShadowMap(); } + /*! + * \brief Sets the current light with the content of the other one + * \return A reference to this + * + * \param light The other Light + * + * \remark Invalidates the shadow map + */ + inline Light& Light::operator=(const Light& light) { Renderable::operator=(light); @@ -218,6 +388,10 @@ namespace Nz return *this; } + /*! + * \brief Invalidates the shadow map + */ + inline void Light::InvalidateShadowMap() { m_shadowMapUpdated = false; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 4a110c64f..85c4d315c 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -151,7 +151,7 @@ namespace Nz inline Material& operator=(const Material& material); - static MaterialRef GetDefault(); + inline static MaterialRef GetDefault(); template static MaterialRef New(Args&&... args); // Signals: @@ -163,7 +163,7 @@ namespace Nz { const Shader* shader; UberShaderInstance* uberInstance = nullptr; - int uniforms[MaterialUniform_Max+1]; + int uniforms[MaterialUniform_Max + 1]; }; void Copy(const Material& material); @@ -187,7 +187,7 @@ namespace Nz TextureRef m_normalMap; TextureRef m_specularMap; UberShaderConstRef m_uberShader; - mutable ShaderInstance m_shaders[ShaderFlags_Max+1]; + mutable ShaderInstance m_shaders[ShaderFlags_Max + 1]; bool m_alphaTestEnabled; bool m_depthSortingEnabled; bool m_lightingEnabled; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index c8559e11f..cdb9e0d5f 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -7,11 +7,21 @@ namespace Nz { + /*! + * \brief Constructs a Material object by default + */ + inline Material::Material() { Reset(); } + /*! + * \brief Constructs a Material object by assignation + * + * \param material Material to copy into this + */ + inline Material::Material(const Material& material) : RefCounted(), Resource(material) @@ -19,11 +29,26 @@ namespace Nz Copy(material); } + /*! + * \brief Destructs the object and calls OnMaterialRelease + * + * \see OnMaterialRelease + */ + inline Material::~Material() { OnMaterialRelease(this); } + /*! + * \brief Enables a renderer parameter + * + * \param renderParameter Parameter for the rendering + * \param enable Should the parameter be enabled + * + * \remark Produces a NazaraAssert if enumeration is invalid + */ + inline void Material::Enable(RendererParameter renderParameter, bool enable) { NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum"); @@ -31,6 +56,14 @@ namespace Nz m_states.parameters[renderParameter] = enable; } + /*! + * \brief Enables the alpha test + * + * \param alphaTest Should the parameter be enabled + * + * \remark Invalidates the shaders + */ + inline void Material::EnableAlphaTest(bool alphaTest) { m_alphaTestEnabled = alphaTest; @@ -38,12 +71,26 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Enables the depth sorting + * + * \param depthSorting Should the parameter be enabled + */ + inline void Material::EnableDepthSorting(bool depthSorting) { // Has no influence on shaders m_depthSortingEnabled = depthSorting; } + /*! + * \brief Enables the lighting + * + * \param lighting Should the parameter be enabled + * + * \remark Invalidates the shaders + */ + inline void Material::EnableLighting(bool lighting) { m_lightingEnabled = lighting; @@ -51,12 +98,26 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Enables the shadow casting + * + * \param castShadows Should shadow casting be enabled + */ + inline void Material::EnableShadowCasting(bool castShadows) { // Has no influence on shaders m_shadowCastingEnabled = castShadows; } + /*! + * \brief Enables the shadow on receiving object + * + * \param receiveShadow Should receiving object have shadows enabled + * + * \remark Invalidates the shaders + */ + inline void Material::EnableShadowReceive(bool receiveShadows) { m_shadowReceiveEnabled = receiveShadows; @@ -64,6 +125,14 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Enables the transformation + * + * \param transform Should the parameter be enabled + * + * \remark Invalidates the shaders + */ + inline void Material::EnableTransform(bool transform) { m_transformEnabled = transform; @@ -71,91 +140,183 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Gets the alpha map + * \return Constant reference to the current texture + */ + inline const TextureRef& Material::GetAlphaMap() const { return m_alphaMap; } + /*! + * \brief Gets the alpha threshold + * \return The threshold value for the alpha + */ + inline float Material::GetAlphaThreshold() const { return m_alphaThreshold; } + /*! + * \brief Gets the ambient color + * \return Ambient color + */ + inline Color Material::GetAmbientColor() const { return m_ambientColor; } + /*! + * \brief Gets the function to compare depth + * \return Function comparing the depth of two materials + */ + inline RendererComparison Material::GetDepthFunc() const { return m_states.depthFunc; } + /*! + * \brief Gets the depth material + * \return Constant reference to the depth material + */ + inline const MaterialRef& Material::GetDepthMaterial() const { return m_depthMaterial; } + /*! + * \brief Gets the diffuse color + * \return Diffuse color + */ + inline Color Material::GetDiffuseColor() const { return m_diffuseColor; } + /*! + * \brief Gets the diffuse sampler + * \return Reference to the current texture sampler for the diffuse + */ + inline TextureSampler& Material::GetDiffuseSampler() { return m_diffuseSampler; } + /*! + * \brief Gets the diffuse sampler + * \return Constant reference to the current texture sampler for the diffuse + */ + inline const TextureSampler& Material::GetDiffuseSampler() const { return m_diffuseSampler; } + /*! + * \brief Gets the diffuse map + * \return Constant reference to the texture + */ + const TextureRef& Material::GetDiffuseMap() const { return m_diffuseMap; } + /*! + * \brief Gets the dst in blend + * \return Function for dst blending + */ + inline BlendFunc Material::GetDstBlend() const { return m_states.dstBlend; } + /*! + * \brief Gets the emissive map + * \return Constant reference to the texture + */ + inline const TextureRef& Material::GetEmissiveMap() const { return m_emissiveMap; } + /*! + * \brief Gets the face culling + * \return Current face culling side + */ + inline FaceSide Material::GetFaceCulling() const { return m_states.faceCulling; } + /*! + * \brief Gets the face filling + * \return Current face filling + */ + inline FaceFilling Material::GetFaceFilling() const { return m_states.faceFilling; } + /*! + * \brief Gets the height map + * \return Constant reference to the texture + */ + inline const TextureRef& Material::GetHeightMap() const { return m_heightMap; } + /*! + * \brief Gets the normal map + * \return Constant reference to the texture + */ + inline const TextureRef& Material::GetNormalMap() const { return m_normalMap; } + /*! + * \brief Gets the render states + * \return Constant reference to the render states + */ + inline const RenderStates& Material::GetRenderStates() const { return m_states; } + /*! + * \brief Gets the shader of this material + * \return Constant pointer to the ubershader used + */ + inline const UberShader* Material::GetShader() const { return m_uberShader; } + /*! + * \brief Gets the shader instance based on the flag + * \return Constant pointer to the ubershader instance + * + * \param flags Flag of the shader + */ + inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const { const ShaderInstance& instance = m_shaders[flags]; @@ -165,81 +326,165 @@ namespace Nz return instance.uberInstance; } + /*! + * \brief Gets the shininess + * \return Current shininess + */ + inline float Material::GetShininess() const { return m_shininess; } + /*! + * \brief Gets the specular color + * \return Specular color + */ + inline Color Material::GetSpecularColor() const { return m_specularColor; } + /*! + * \brief Gets the specular map + * \return Constant reference to the texture + */ + inline const TextureRef& Material::GetSpecularMap() const { return m_specularMap; } + /*! + * \brief Gets the specular sampler + * \return Reference to the current texture sampler for the specular + */ + inline TextureSampler& Material::GetSpecularSampler() { return m_specularSampler; } + /*! + * \brief Gets the specular sampler + * \return Constant reference to the current texture sampler for the specular + */ + inline const TextureSampler& Material::GetSpecularSampler() const { return m_specularSampler; } + /*! + * \brief Gets the src in blend + * \return Function for src blending + */ + inline BlendFunc Material::GetSrcBlend() const { return m_states.srcBlend; } + /*! + * \brief Checks whether this material has an alpha map + * \return true If it is the case + */ + inline bool Material::HasAlphaMap() const { return m_alphaMap.IsValid(); } + /*! + * \brief Checks whether this material has a depth material + * \return true If it is the case + */ + inline bool Material::HasDepthMaterial() const { return m_depthMaterial.IsValid(); } + /*! + * \brief Checks whether this material has a diffuse map + * \return true If it is the case + */ + inline bool Material::HasDiffuseMap() const { return m_diffuseMap.IsValid(); } + /*! + * \brief Checks whether this material has a emissive map + * \return true If it is the case + */ + inline bool Material::HasEmissiveMap() const { return m_emissiveMap.IsValid(); } + /*! + * \brief Checks whether this material has a height map + * \return true If it is the case + */ + inline bool Material::HasHeightMap() const { return m_heightMap.IsValid(); } + /*! + * \brief Checks whether this material has a normal map + * \return true If it is the case + */ + inline bool Material::HasNormalMap() const { return m_normalMap.IsValid(); } + /*! + * \brief Checks whether this material has a specular map + * \return true If it is the case + */ + inline bool Material::HasSpecularMap() const { return m_specularMap.IsValid(); } + /*! + * \brief Checks whether this material has alpha test enabled + * \return true If it is the case + */ + inline bool Material::IsAlphaTestEnabled() const { return m_alphaTestEnabled; } + /*! + * \brief Checks whether this material has depth sorting enabled + * \return true If it is the case + */ + inline bool Material::IsDepthSortingEnabled() const { return m_depthSortingEnabled; } + /*! + * \brief Checks whether this material has the render parameter enabled + * \return true If it is the case + * + * \param parameter Parameter for the rendering + * + * \remark Produces a NazaraAssert if enumeration is invalid + */ + inline bool Material::IsEnabled(RendererParameter parameter) const { NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum"); @@ -247,41 +492,93 @@ namespace Nz return m_states.parameters[parameter]; } + /*! + * \brief Checks whether this material has lightning enabled + * \return true If it is the case + */ + inline bool Material::IsLightingEnabled() const { return m_lightingEnabled; } + /*! + * \brief Checks whether this material cast shadow + * \return true If it is the case + */ + inline bool Material::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; } + /*! + * \brief Checks whether this material receive shadow + * \return true If it is the case + */ + inline bool Material::IsShadowReceiveEnabled() const { return m_shadowReceiveEnabled; } + /*! + * \brief Checks whether this material has transformation enabled + * \return true If it is the case + */ + inline bool Material::IsTransformEnabled() const { return m_transformEnabled; } + /*! + * \brief Loads the material from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the material + */ + inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) { return MaterialLoader::LoadFromFile(this, filePath, params); } + /*! + * \brief Loads the material from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the material + */ + inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) { return MaterialLoader::LoadFromMemory(this, data, size, params); } + /*! + * \brief Loads the material from stream + * \return true if loading is successful + * + * \param stream Stream to the material + * \param params Parameters for the material + */ + inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) { return MaterialLoader::LoadFromStream(this, stream, params); } + /*! + * \brief Sets the alpha map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetAlphaMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -296,6 +593,15 @@ namespace Nz return true; } + /*! + * \brief Sets the alpha map with a reference to a texture + * \return true If successful + * + * \param alphaMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetAlphaMap(TextureRef alphaMap) { m_alphaMap = std::move(alphaMap); @@ -303,31 +609,69 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the alpha threshold + * + * \param alphaThreshold Threshold for the alpha + */ + inline void Material::SetAlphaThreshold(float alphaThreshold) { m_alphaThreshold = alphaThreshold; } + /*! + * \brief Sets the color for ambient + * + * \param ambient Color for ambient + */ + inline void Material::SetAmbientColor(const Color& ambient) { m_ambientColor = ambient; } + /*! + * \brief Sets the depth functor + * + * \param depthFunc + */ + inline void Material::SetDepthFunc(RendererComparison depthFunc) { m_states.depthFunc = depthFunc; } + /*! + * \brief Sets the depth material + * \return true If successful + * + * \param depthMaterial Material for depth + */ + inline void Material::SetDepthMaterial(MaterialRef depthMaterial) { m_depthMaterial = std::move(depthMaterial); } + /*! + * \brief Sets the color for diffuse + * + * \param diffuse Color for diffuse + */ + inline void Material::SetDiffuseColor(const Color& diffuse) { m_diffuseColor = diffuse; } + /*! + * \brief Sets the diffuse map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetDiffuseMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -342,6 +686,15 @@ namespace Nz return true; } + /*! + * \brief Sets the diffuse map with a reference to a texture + * \return true If successful + * + * \param diffuseMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetDiffuseMap(TextureRef diffuseMap) { m_diffuseMap = std::move(diffuseMap); @@ -349,16 +702,35 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the diffuse sampler + * + * \param sampler Diffuse sample + */ + inline void Material::SetDiffuseSampler(const TextureSampler& sampler) { m_diffuseSampler = sampler; } + /*! + * \brief Sets the dst in blend + * + * \param func Function for dst blending + */ + inline void Material::SetDstBlend(BlendFunc func) { m_states.dstBlend = func; } + /*! + * \brief Sets the emissive map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetEmissiveMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -373,6 +745,15 @@ namespace Nz return true; } + /*! + * \brief Sets the emissive map with a reference to a texture + * \return true If successful + * + * \param emissiveMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetEmissiveMap(TextureRef emissiveMap) { m_emissiveMap = std::move(emissiveMap); @@ -380,16 +761,35 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the face culling + * + * \param faceSide Face to cull + */ + inline void Material::SetFaceCulling(FaceSide faceSide) { m_states.faceCulling = faceSide; } + /*! + * \brief Sets the face filling + * + * \param filling Face to fill + */ + inline void Material::SetFaceFilling(FaceFilling filling) { m_states.faceFilling = filling; } + /*! + * \brief Sets the height map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetHeightMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -404,6 +804,15 @@ namespace Nz return true; } + /*! + * \brief Sets the height map with a reference to a texture + * \return true If successful + * + * \param heightMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetHeightMap(TextureRef heightMap) { m_heightMap = std::move(heightMap); @@ -411,6 +820,13 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the normal map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetNormalMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -425,6 +841,15 @@ namespace Nz return true; } + /*! + * \brief Sets the normal map with a reference to a texture + * \return true If successful + * + * \param normalMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetNormalMap(TextureRef normalMap) { m_normalMap = std::move(normalMap); @@ -432,11 +857,25 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the render states + * + * \param states States for the rendering + */ + inline void Material::SetRenderStates(const RenderStates& states) { m_states = states; } + /*! + * \brief Sets the shader with a constant reference to a ubershader + * + * \param uberShader Uber shader to apply + * + * \remark Invalidates the shaders + */ + inline void Material::SetShader(UberShaderConstRef uberShader) { m_uberShader = std::move(uberShader); @@ -444,6 +883,13 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the shader by name + * \return true If successful + * + * \param uberShaderName Named shader + */ + inline bool Material::SetShader(const String& uberShaderName) { UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); @@ -454,16 +900,35 @@ namespace Nz return true; } + /*! + * \brief Sets the shininess of the material + * + * \param shininess Value of the shininess + */ + inline void Material::SetShininess(float shininess) { m_shininess = shininess; } + /*! + * \brief Sets the color for specular + * + * \param specular Color + */ + inline void Material::SetSpecularColor(const Color& specular) { m_specularColor = specular; } + /*! + * \brief Sets the specular map by name + * \return true If successful + * + * \param textureName Named texture + */ + inline bool Material::SetSpecularMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -478,6 +943,15 @@ namespace Nz return true; } + /*! + * \brief Sets the specular map with a reference to a texture + * \return true If successful + * + * \param specularMap Texture + * + * \remark Invalidates the shaders + */ + inline void Material::SetSpecularMap(TextureRef specularMap) { m_specularMap = std::move(specularMap); @@ -485,16 +959,35 @@ namespace Nz InvalidateShaders(); } + /*! + * \brief Sets the specular sampler + * + * \param sampler Specular sample + */ + inline void Material::SetSpecularSampler(const TextureSampler& sampler) { m_specularSampler = sampler; } + /*! + * \brief Sets the src in blend + * + * \param func Function for src blending + */ + inline void Material::SetSrcBlend(BlendFunc func) { m_states.srcBlend = func; } + /*! + * \brief Sets the current material with the content of the other one + * \return A reference to this + * + * \param material The other Material + */ + inline Material& Material::operator=(const Material& material) { Resource::operator=(material); @@ -503,17 +996,33 @@ namespace Nz return *this; } + /*! + * \brief Gets the default material + * \return Reference to the default material + */ + inline MaterialRef Material::GetDefault() { return s_defaultMaterial; } + /*! + * \brief Invalidates the shaders + */ + inline void Material::InvalidateShaders() { for (ShaderInstance& instance : m_shaders) instance.uberInstance = nullptr; } + /*! + * \brief Creates a new material from the arguments + * \return A reference to the newly created material + * + * \param args Arguments for the material + */ + template MaterialRef Material::New(Args&&... args) { diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index b4564d1b8..f119072c8 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -68,8 +68,6 @@ namespace Nz bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material); void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material); virtual void SetMesh(Mesh* mesh); - bool SetSequence(const String& sequenceName); - void SetSequence(unsigned int sequenceIndex); void SetSkin(unsigned int skin); void SetSkinCount(unsigned int skinCount); diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index ea30ebd72..a2b4c3967 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -7,6 +7,13 @@ namespace Nz { + /*! + * \brief Creates a new Model from the arguments + * \return A reference to the newly created model + * + * \param args Arguments for the model + */ + template ModelRef Model::New(Args&&... args) { diff --git a/include/Nazara/Graphics/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp index 4fd8b6c33..0edfba85f 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.hpp +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -62,16 +62,16 @@ namespace Nz /* ** -Lynix: - ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas - ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. - ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! + ** It would be also possible to precise the stride by an independant way, what I don't allow + ** to decomplexify the interface of something I consider useless. + ** If you think that could be useful, don't hesitate to make me aware ! */ }; - Component m_components[ParticleComponent_Max+1]; + Component m_components[ParticleComponent_Max + 1]; unsigned int m_stride; - static ParticleDeclaration s_declarations[ParticleLayout_Max+1]; + static ParticleDeclaration s_declarations[ParticleLayout_Max + 1]; static ParticleDeclarationLibrary::LibraryMap s_library; }; } diff --git a/include/Nazara/Graphics/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl index a28315312..63c9c49ba 100644 --- a/include/Nazara/Graphics/ParticleMapper.inl +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -7,10 +7,20 @@ namespace Nz { + /*! + * \brief Gets a pointer to iterate through same components + * \return SparsePtr pointing to same components + * + * \param component Component to get in the declaration + * + * \remark The same components are not continguous but separated by sizeof(ParticleSize) + * \remark Produces a NazaraError if component is disabled + */ + template SparsePtr ParticleMapper::GetComponentPtr(ParticleComponent component) { - // Ensuite le composant qui nous intéresse + // Then the component that are interesting bool enabled; ComponentType type; unsigned int offset; @@ -18,7 +28,7 @@ namespace Nz if (enabled) { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + ///TODO: Check the ratio between the type of the attribute and the template type ? return SparsePtr(m_ptr + offset, m_declaration->GetStride()); } else @@ -28,10 +38,20 @@ namespace Nz } } + /*! + * \brief Gets a pointer to iterate through same components + * \return SparsePtr pointing to same components + * + * \param component Component to get in the declaration + * + * \remark The same components are not continguous but separated by sizeof(ParticleSize) + * \remark Produces a NazaraError if component is disabled + */ + template SparsePtr ParticleMapper::GetComponentPtr(ParticleComponent component) const { - // Ensuite le composant qui nous intéresse + // Then the component that are interesting bool enabled; ComponentType type; unsigned int offset; @@ -39,7 +59,7 @@ namespace Nz if (enabled) { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + ///TODO: Check the ratio between the type of the attribute and the template type ? return SparsePtr(m_ptr + offset, m_declaration->GetStride()); } else diff --git a/include/Nazara/Graphics/Renderable.inl b/include/Nazara/Graphics/Renderable.inl index ed445ec96..9a69329a5 100644 --- a/include/Nazara/Graphics/Renderable.inl +++ b/include/Nazara/Graphics/Renderable.inl @@ -4,17 +4,31 @@ namespace Nz { + /*! + * \brief Ensures that the bounding volume is up to date + */ + inline void Renderable::EnsureBoundingVolumeUpdated() const { if (!m_boundingVolumeUpdated) UpdateBoundingVolume(); } + /*! + * \brief Invalidates the bounding volume + */ + inline void Renderable::InvalidateBoundingVolume() { m_boundingVolumeUpdated = false; } + /*! + * \brief Updates the bounding volume by a matrix + * + * \param transformMatrix Matrix transformation for our bounding volume + */ + inline void Renderable::UpdateBoundingVolume() const { MakeBoundingVolume(); diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index 8edb694c9..6171f1e28 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -7,31 +7,62 @@ namespace Nz { + /*! + * \brief Gets the movement offset + * \return Offset of the movement + */ + inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const { return m_movementOffset; } + /*! + * \brief Gets the movement scale + * \return Scale of the movement + */ + inline float SkyboxBackground::GetMovementScale() const { return m_movementScale; } + /*! + * \brief Gets the texture of the background + * \return Texture of the background + */ + inline const TextureRef& SkyboxBackground::GetTexture() const { return m_texture; } + /*! + * \brief Gets the texture sampler of the background + * \return A reference to the texture sampler of the background + */ + inline TextureSampler& SkyboxBackground::GetTextureSampler() { return m_sampler; } + /*! + * \brief Gets the texture sampler of the background + * \return A constant reference to the texture sampler of the background + */ + inline const TextureSampler& SkyboxBackground::GetTextureSampler() const { return m_sampler; } + /*! + * \brief Sets the movement offset + * + * \param offset Offset of the movement + */ + inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset) { NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector"); @@ -39,6 +70,12 @@ namespace Nz m_movementOffset = offset; } + /*! + * \brief Sets the movement scale + * + * \param scale Scale of the movement + */ + inline void SkyboxBackground::SetMovementScale(float scale) { NazaraAssert(std::isfinite(scale), "Scale must be a finite value"); @@ -46,6 +83,12 @@ namespace Nz m_movementScale = scale; } + /*! + * \brief Sets the texture of the background + * + * \param cubemapTexture Texture of the background + */ + inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture) { NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture"); @@ -54,11 +97,24 @@ namespace Nz m_texture = std::move(cubemapTexture); } + /*! + * \brief Sets the texture sampler of the background + * + * \param sampler Texture sampler of the background + */ + void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler) { m_sampler = sampler; } + /*! + * \brief Creates a new skybox background from the arguments + * \return A reference to the newly created skybox background + * + * \param args Arguments for the skybox background + */ + template SkyboxBackgroundRef SkyboxBackground::New(Args&&... args) { diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 8969cddf0..840a930e6 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -8,6 +8,10 @@ namespace Nz { + /*! + * \brief Constructs a Sprite object by default + */ + inline Sprite::Sprite() : m_color(Color::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), @@ -16,6 +20,12 @@ namespace Nz SetDefaultMaterial(); } + /*! + * \brief Constructs a Sprite object with a reference to a material + * + * \param material Reference to a material + */ + inline Sprite::Sprite(MaterialRef material) : m_color(Color::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), @@ -24,6 +34,12 @@ namespace Nz SetMaterial(std::move(material), true); } + /*! + * \brief Constructs a Sprite object with a pointer to a texture + * + * \param texture Pointer to a texture + */ + inline Sprite::Sprite(Texture* texture) : m_color(Color::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), @@ -32,6 +48,12 @@ namespace Nz SetTexture(texture, true); } + /*! + * \brief Constructs a Sprite object by assignation + * + * \param sprite Sprite to copy into this + */ + inline Sprite::Sprite(const Sprite& sprite) : InstancedRenderable(sprite), m_color(sprite.m_color), @@ -41,26 +63,52 @@ namespace Nz { } + /*! + * \brief Gets the color of the sprite + * \return Current color + */ + inline const Color& Sprite::GetColor() const { return m_color; } + /*! + * \brief Gets the material of the sprite + * \return Current material + */ + inline const MaterialRef& Sprite::GetMaterial() const { return m_material; } + /*! + * \brief Gets the size of the sprite + * \return Current size + */ + inline const Vector2f& Sprite::GetSize() const { return m_size; } + /*! + * \brief Gets the texture coordinates of the sprite + * \return Current texture coordinates + */ + inline const Rectf& Sprite::GetTextureCoords() const { return m_textureCoords; } + /*! + * \brief Sets the color of the billboard + * + * \param color Color for the billboard + */ + inline void Sprite::SetColor(const Color& color) { m_color = color; @@ -68,6 +116,10 @@ namespace Nz InvalidateVertices(); } + /*! + * \brief Sets the default material of the sprite (just default material) + */ + inline void Sprite::SetDefaultMaterial() { MaterialRef material = Material::New(); @@ -77,6 +129,13 @@ namespace Nz SetMaterial(std::move(material)); } + /*! + * \brief Sets the material of the sprite + * + * \param material Material for the sprite + * \param resizeSprite Should sprite be resized to the material size (diffuse map) + */ + inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite) { m_material = std::move(material); @@ -88,6 +147,12 @@ namespace Nz } } + /*! + * \brief Sets the size of the sprite + * + * \param size Size for the sprite + */ + inline void Sprite::SetSize(const Vector2f& size) { m_size = size; @@ -97,11 +162,25 @@ namespace Nz InvalidateVertices(); } + /*! + * \brief Sets the size of the sprite + * + * \param sizeX Size in X for the sprite + * \param sizeY Size in Y for the sprite + */ + inline void Sprite::SetSize(float sizeX, float sizeY) { SetSize(Vector2f(sizeX, sizeY)); } + /*! + * \brief Sets the texture of the sprite + * + * \param texture Texture for the sprite + * \param resizeSprite Should sprite be resized to the texture size + */ + inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite) { if (!m_material) @@ -115,12 +194,27 @@ namespace Nz m_material->SetDiffuseMap(std::move(texture)); } + /*! + * \brief Sets the texture coordinates of the sprite + * + * \param coords Texture coordinates + */ + inline void Sprite::SetTextureCoords(const Rectf& coords) { m_textureCoords = coords; InvalidateVertices(); } + /*! + * \brief Sets the texture rectangle of the sprite + * + * \param rect Rectangles symbolizing the size of the texture + * + * \remark Produces a NazaraAssert if material is invalid + * \remark Produces a NazaraAssert if material has no diffuse map + */ + inline void Sprite::SetTextureRect(const Rectui& rect) { NazaraAssert(m_material, "Sprite has no material"); @@ -128,12 +222,19 @@ namespace Nz Texture* diffuseMap = m_material->GetDiffuseMap(); - float invWidth = 1.f/diffuseMap->GetWidth(); - float invHeight = 1.f/diffuseMap->GetHeight(); + float invWidth = 1.f / diffuseMap->GetWidth(); + float invHeight = 1.f / diffuseMap->GetHeight(); - SetTextureCoords(Rectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); + SetTextureCoords(Rectf(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height)); } + /*! + * \brief Sets the current sprite with the content of the other one + * \return A reference to this + * + * \param sprite The other Sprite + */ + inline Sprite& Sprite::operator=(const Sprite& sprite) { InstancedRenderable::operator=(sprite); @@ -143,18 +244,29 @@ namespace Nz m_textureCoords = sprite.m_textureCoords; m_size = sprite.m_size; - // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon + // We do not copy final vertices because it's highly probable that our parameters are modified and they must be regenerated InvalidateBoundingVolume(); InvalidateVertices(); return *this; } + /*! + * \brief Invalidates the vertices + */ + inline void Sprite::InvalidateVertices() { InvalidateInstanceData(0); } + /*! + * \brief Creates a new sprite from the arguments + * \return A reference to the newly created sprite + * + * \param args Arguments for the sprite + */ + template SpriteRef Sprite::New(Args&&... args) { diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index 312658557..baeeb50db 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -7,6 +7,10 @@ namespace Nz { + /*! + * \brief Constructs a TextSprite object by default + */ + inline TextSprite::TextSprite() : m_color(Color::White), m_scale(1.f) @@ -14,12 +18,24 @@ namespace Nz SetDefaultMaterial(); } + /*! + * \brief Constructs a TextSprite object with a drawer + * + * \param drawer Drawer used to compose text on the sprite + */ + inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) : TextSprite() { Update(drawer); } + /*! + * \brief Constructs a TextSprite object by assignation + * + * \param sprite TextSprite to copy into this + */ + inline TextSprite::TextSprite(const TextSprite& sprite) : InstancedRenderable(sprite), m_renderInfos(sprite.m_renderInfos), @@ -40,6 +56,10 @@ namespace Nz } } + /*! + * \brief Clears the data + */ + inline void TextSprite::Clear() { m_atlases.clear(); @@ -48,21 +68,42 @@ namespace Nz m_renderInfos.clear(); } + /*! + * \brief Gets the color of the text sprite + * \return Current color + */ + inline const Color& TextSprite::GetColor() const { return m_color; } + /*! + * \brief Gets the material of the text sprite + * \return Current material + */ + inline const MaterialRef& TextSprite::GetMaterial() const { return m_material; } + /*! + * \brief Gets the current scale of the text sprite + * \return Current scale + */ + inline float TextSprite::GetScale() const { return m_scale; } + /*! + * \brief Sets the color of the text sprite + * + * \param color Color for the text sprite + */ + inline void TextSprite::SetColor(const Color& color) { m_color = color; @@ -70,6 +111,11 @@ namespace Nz InvalidateVertices(); } + /*! + * \brief Sets the default material of the text sprite (just default material) + */ + + inline void TextSprite::SetDefaultMaterial() { MaterialRef material = Material::New(); @@ -83,11 +129,23 @@ namespace Nz SetMaterial(material); } + /*! + * \brief Sets the material of the text sprite + * + * \param material Material for the text sprite + */ + inline void TextSprite::SetMaterial(MaterialRef material) { m_material = std::move(material); } + /*! + * \brief Sets the current scale of the text sprite + * + * \param scale Scale of the text sprite + */ + inline void TextSprite::SetScale(float scale) { m_scale = scale; @@ -95,10 +153,12 @@ namespace Nz InvalidateVertices(); } - inline void TextSprite::InvalidateVertices() - { - InvalidateInstanceData(0); - } + /*! + * \brief Sets the current text sprite with the content of the other one + * \return A reference to this + * + * \param text sprite The other TextSprite + */ inline TextSprite& TextSprite::operator=(const TextSprite& text) { @@ -130,6 +190,22 @@ namespace Nz return *this; } + /*! + * \brief Invalidates the vertices + */ + + inline void TextSprite::InvalidateVertices() + { + InvalidateInstanceData(0); + } + + /*! + * \brief Creates a new text sprite from the arguments + * \return A reference to the newly created text sprite + * + * \param args Arguments for the text sprite + */ + template TextSpriteRef TextSprite::New(Args&&... args) { diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl index c40ad3d2d..31067f36c 100644 --- a/include/Nazara/Graphics/TextureBackground.inl +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -7,11 +7,22 @@ namespace Nz { + /*! + * \brief Gets the texture of the background + * \return Texture of the background + */ + inline const TextureRef& TextureBackground::GetTexture() const { return m_texture; } + /*! + * \brief Sets the texture of the background + * + * \param texture Texture of the background + */ + inline void TextureBackground::SetTexture(TextureRef texture) { NazaraAssert(!texture || texture->IsValid(), "Invalid texture"); @@ -19,6 +30,13 @@ namespace Nz m_texture = std::move(texture); } + /*! + * \brief Creates a new texture background from the arguments + * \return A reference to the newly created texture background + * + * \param args Arguments for the texture background + */ + template TextureBackgroundRef TextureBackground::New(Args&&... args) { diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index b9f56c1e1..71f385cac 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -491,8 +491,8 @@ namespace Nz * * \remark If volume is infinite, IntersectionSide_Intersecting is returned * \remark If volume is null, IntersectionSide_Outside is returned - * \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned - * \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library + * \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and IntersectionSide_Outside is returned + * \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and IntersectionSide_Outside is returned. This should not never happen for a user of the library */ template diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index b87bd51a7..0a8d1adae 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -485,7 +485,7 @@ namespace Nz template T Sphere::SquaredDistance(const Vector3& point) const { - return Vector3f::Distance(point, GetPosition()) - radius * radius; + return Vector3f::SquaredDistance(point, GetPosition() + (point - GetPosition()).Normalize() * radius); } /*! diff --git a/src/Nazara/Graphics/AbstractBackground.cpp b/src/Nazara/Graphics/AbstractBackground.cpp index 628819edd..28d0f0d4f 100644 --- a/src/Nazara/Graphics/AbstractBackground.cpp +++ b/src/Nazara/Graphics/AbstractBackground.cpp @@ -7,6 +7,14 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::AbstractBackground + * \brief Graphics class that represents the background for our scene + * + * \remark This class is abstract + */ + AbstractBackground::~AbstractBackground() = default; BackgroundLibrary::LibraryMap AbstractBackground::s_library; diff --git a/src/Nazara/Graphics/AbstractRenderQueue.cpp b/src/Nazara/Graphics/AbstractRenderQueue.cpp index d00816f85..1346e37ff 100644 --- a/src/Nazara/Graphics/AbstractRenderQueue.cpp +++ b/src/Nazara/Graphics/AbstractRenderQueue.cpp @@ -7,23 +7,55 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::AbstractRenderQueue + * \brief Graphics class that represents the rendering queue for our scene + * + * \remark This class is abstract + */ + AbstractRenderQueue::~AbstractRenderQueue() = default; + /*! + * \brief Adds a directional light to the rendering queue + * + * \param light Directional light + */ + void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light) { directionalLights.push_back(light); } + /*! + * \brief Adds a point light to the rendering queue + * + * \param light Point light + */ + void AbstractRenderQueue::AddPointLight(const PointLight& light) { pointLights.push_back(light); } + /*! + * \brief Adds a spot light to the rendering queue + * + * \param light Spot light + */ + void AbstractRenderQueue::AddSpotLight(const SpotLight& light) { spotLights.push_back(light); } + /*! + * \brief Clears the rendering queue + * + * \param fully Should everything be cleared ? + */ + void AbstractRenderQueue::Clear(bool fully) { NazaraUnused(fully); diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index 11d894a00..9872178cf 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -10,6 +10,18 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::AbstractRenderTechnique + * \brief Graphics class that represents the rendering technique for our scene + * + * \remark This class is abstract + */ + + /*! + * \brief Constructs a AbstractRenderTechnique object + */ + AbstractRenderTechnique::AbstractRenderTechnique() : m_instancingEnabled(true) { @@ -17,16 +29,34 @@ namespace Nz AbstractRenderTechnique::~AbstractRenderTechnique() = default; + /*! + * \brief Enables the instancing + * + * \param instancing Should instancing be enabled + * + * \remark This may improve performances + */ + void AbstractRenderTechnique::EnableInstancing(bool instancing) { m_instancingEnabled = instancing; } + /*! + * \brief Gets the name of the actual technique + * \return Name of the technique being used + */ + String AbstractRenderTechnique::GetName() const { return RenderTechniques::ToString(GetType()); } + /*! + * \brief Checks whether the instancing is enabled + * \return true If it is the case + */ + bool AbstractRenderTechnique::IsInstancingEnabled() const { return m_instancingEnabled; diff --git a/src/Nazara/Graphics/AbstractViewer.cpp b/src/Nazara/Graphics/AbstractViewer.cpp index cc9a4b96a..bd8752bc7 100644 --- a/src/Nazara/Graphics/AbstractViewer.cpp +++ b/src/Nazara/Graphics/AbstractViewer.cpp @@ -7,5 +7,13 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::AbstractViewer + * \brief Graphics class that represents the viewer for our scene + * + * \remark This class is abstract + */ + AbstractViewer::~AbstractViewer() = default; } diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 3e5173c89..6f47e9847 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -12,6 +12,19 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Billboard + * \brief Graphics class that represents a billboard, a 2D surface which simulates a 3D object + */ + + /*! + * \brief Adds this billboard to the render queue + * + * \param renderQueue Queue to be added + * \param instanceData Data used for instance + */ + void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { if (!m_material) @@ -20,11 +33,15 @@ namespace Nz renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); } + /* + * \brief Makes the bounding volume of this billboard + */ + void Billboard::MakeBoundingVolume() const { constexpr float sqrt2 = float(M_SQRT2); - m_boundingVolume.Set(Vector3f(0.f), sqrt2*m_size.x*Vector3f::Right() + sqrt2*m_size.y*Vector3f::Down()); + m_boundingVolume.Set(Vector3f(0.f), sqrt2 * m_size.x * Vector3f::Right() + sqrt2 * m_size.y * Vector3f::Down()); } BillboardLibrary::LibraryMap Billboard::s_library; diff --git a/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index 76f717858..33c282390 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -11,6 +11,11 @@ namespace Nz { namespace { + /*! + * \brief Defines render states + * \return RenderStates for the color background + */ + RenderStates BuildRenderStates() { RenderStates states; @@ -24,6 +29,18 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::ColorBackground + * \brief Graphics class that represents a background with uniform color + */ + + /*! + * \brief Constructs a ColorBackground object with a color + * + * \param color Uniform color (by default Black) + */ + ColorBackground::ColorBackground(const Color& color) : m_color(color) { @@ -38,6 +55,12 @@ namespace Nz m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); } + /*! + * \brief Draws this relatively to the viewer + * + * \param viewer Viewer for the background + */ + void ColorBackground::Draw(const AbstractViewer* viewer) const { NazaraUnused(viewer); @@ -55,16 +78,32 @@ namespace Nz Renderer::DrawFullscreenQuad(); } + /*! + * \brief Gets the background type + * \return Type of background + */ + BackgroundType ColorBackground::GetBackgroundType() const { return BackgroundType_Color; } + /*! + * \brief Gets the color of the background + * \return Background color + */ + Color ColorBackground::GetColor() const { return m_color; } + /*! + * \brief Sets the color of the background + * + * \param color Background color + */ + void ColorBackground::SetColor(const Color& color) { m_color = color; diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index 0fc80e750..c902c7615 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -9,6 +9,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredBloomPass + * \brief Graphics class that represents the pass for bloom in deferred rendering + */ + + /*! + * \brief Constructs a DeferredBloomPass object by default + */ + DeferredBloomPass::DeferredBloomPass() : m_uniformUpdated(false), m_brightLuminance(0.8f), @@ -32,26 +42,55 @@ namespace Nz DeferredBloomPass::~DeferredBloomPass() = default; + /*! + * \brief Gets the number of pass for blur + * \return Number of pass for blur + */ + unsigned int DeferredBloomPass::GetBlurPassCount() const { return m_blurPassCount; } + /*! + * \brief Gets the coefficiant for luminosity + * \return Luminosity of bright elements + */ + float DeferredBloomPass::GetBrightLuminance() const { return m_brightLuminance; } + /*! + * \brief Gets the coefficiant for the middle grey + * \return Luminosity of grey elements + */ + float DeferredBloomPass::GetBrightMiddleGrey() const { return m_brightMiddleGrey; } + /*! + * \brief Gets the coefficiant for things to be bright + * \return Threshold for bright elements + */ + float DeferredBloomPass::GetBrightThreshold() const { return m_brightThreshold; } + /*! + * \brief Gets the ith texture + * \return Texture computed + * + * \param i Index of the texture + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid + */ + Texture* DeferredBloomPass::GetTexture(unsigned int i) const { #if NAZARA_GRAPHICS_SAFE @@ -65,7 +104,16 @@ namespace Nz return m_bloomTextures[i]; } - bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraUnused(sceneData); @@ -91,7 +139,7 @@ namespace Nz Renderer::DrawFullscreenQuad(); Renderer::SetTarget(&m_bloomRTT); - Renderer::SetViewport(Recti(0, 0, m_dimensions.x/8, m_dimensions.y/8)); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x / 8, m_dimensions.y / 8)); Renderer::SetShader(m_gaussianBlurShader); @@ -124,6 +172,13 @@ namespace Nz return true; } + /*! + * \brief Resizes the texture sizes + * \return true If successful + * + * \param dimensions Dimensions for the compute texture + */ + bool DeferredBloomPass::Resize(const Vector2ui& dimensions) { DeferredRenderPass::Resize(dimensions); @@ -131,7 +186,7 @@ namespace Nz m_bloomRTT.Create(true); for (unsigned int i = 0; i < 2; ++i) { - m_bloomTextures[i]->Create(ImageType_2D, PixelFormatType_RGBA8, dimensions.x/8, dimensions.y/8); + m_bloomTextures[i]->Create(ImageType_2D, PixelFormatType_RGBA8, dimensions.x / 8, dimensions.y / 8); m_bloomRTT.AttachTexture(AttachmentPoint_Color, i, m_bloomTextures[i]); } m_bloomRTT.Unlock(); @@ -145,23 +200,47 @@ namespace Nz return true; } + /*! + * \brief Sets the number of pass for blur + * + * \param passCount Number of pass for blur + */ + void DeferredBloomPass::SetBlurPassCount(unsigned int passCount) { m_blurPassCount = passCount; // N'est pas une uniforme } + /*! + * \brief Sets the coefficiant for luminosity + * + * \param luminance Luminosity of bright elements + */ + void DeferredBloomPass::SetBrightLuminance(float luminance) { m_brightLuminance = luminance; m_uniformUpdated = false; } + /*! + * \brief Sets the coefficiant for the middle grey + * + * \param middleGrey Luminosity of grey elements + */ + void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey) { m_brightMiddleGrey = middleGrey; m_uniformUpdated = false; } + /*! + * \brief Sets the coefficiant for things to be bright + * + * \param threshold Threshold for bright elements + */ + void DeferredBloomPass::SetBrightThreshold(float threshold) { m_brightThreshold = threshold; diff --git a/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index f29529749..63df2c400 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -13,6 +13,10 @@ namespace Nz { namespace { + /*! + * \brief Builds the shader for the depth of field + * \return Reference to the shader newly created + */ // http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/ ShaderRef BuildDepthOfFieldShader() { @@ -92,6 +96,16 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::DeferredDOFPass + * \brief Graphics class that represents the pass for depth of field in deferred rendering + */ + + /*! + * \brief Constructs a DeferredDOFPass object by default + */ + DeferredDOFPass::DeferredDOFPass() { m_dofShader = BuildDepthOfFieldShader(); @@ -118,7 +132,16 @@ namespace Nz DeferredDOFPass::~DeferredDOFPass() = default; - bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraUnused(sceneData); @@ -162,6 +185,13 @@ namespace Nz return true; } + /*! + * \brief Resizes the texture sizes + * \return true If successful + * + * \param dimensions Dimensions for the compute texture + */ + bool DeferredDOFPass::Resize(const Vector2ui& dimensions) { DeferredRenderPass::Resize(dimensions); @@ -181,5 +211,5 @@ namespace Nz } return true; -} + } } diff --git a/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index 3a300392a..3f1e9395a 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -10,6 +10,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredFXAAPass + * \brief Graphics class that represents the pass for FXAA in deferred rendering + */ + + /*! + * \brief Constructs a DeferredFXAAPass object by default + */ + DeferredFXAAPass::DeferredFXAAPass() { m_fxaaShader = ShaderLibrary::Get("DeferredFXAA"); @@ -23,7 +33,16 @@ namespace Nz DeferredFXAAPass::~DeferredFXAAPass() = default; - bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraUnused(sceneData); diff --git a/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index 6ca1e72c4..091c95af6 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -10,6 +10,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredFinalPass + * \brief Graphics class that represents the final pass in deferred rendering + */ + + /*! + * \brief Constructs a DeferredFinalPass object by default + */ + DeferredFinalPass::DeferredFinalPass() { m_pointSampler.SetAnisotropyLevel(1); @@ -34,7 +44,16 @@ namespace Nz DeferredFinalPass::~DeferredFinalPass() = default; - bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index af00a7c1d..f64521daf 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -13,6 +13,11 @@ namespace Nz { namespace { + /*! + * \brief Builds the shader for the fog + * \return Reference to the shader newly created + */ + ShaderRef BuildFogShader() { /*const UInt8 fragmentSource[] = { @@ -117,6 +122,16 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::DeferredFogPass + * \brief Graphics class that represents the pass for fog in deferred rendering + */ + + /*! + * \brief Constructs a DeferredFogPass object by default + */ + DeferredFogPass::DeferredFogPass() { m_pointSampler.SetAnisotropyLevel(1); @@ -131,7 +146,16 @@ namespace Nz DeferredFogPass::~DeferredFogPass() = default; - bool DeferredFogPass::Process( const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredFogPass::Process( const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); diff --git a/src/Nazara/Graphics/DeferredForwardPass.cpp b/src/Nazara/Graphics/DeferredForwardPass.cpp index 35daabae8..ed7ad45d1 100644 --- a/src/Nazara/Graphics/DeferredForwardPass.cpp +++ b/src/Nazara/Graphics/DeferredForwardPass.cpp @@ -13,9 +13,21 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredForwardPass + * \brief Graphics class that represents the forward pass in deferred rendering + */ + DeferredForwardPass::DeferredForwardPass() = default; DeferredForwardPass::~DeferredForwardPass() = default; + /*! + * \brief Initializes the deferred forward pass which needs the forward technique + * + * \param technique Rendering technique + */ + void DeferredForwardPass::Initialize(DeferredRenderTechnique* technique) { DeferredRenderPass::Initialize(technique); @@ -23,7 +35,16 @@ namespace Nz m_forwardTechnique = technique->GetForwardTechnique(); } - bool DeferredForwardPass::Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredForwardPass::Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); NazaraUnused(workTexture); diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 2ae39ed9b..08b111a70 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -18,6 +18,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredGeometryPass + * \brief Graphics class that represents the pass for geometries in deferred rendering + */ + + /*! + * \brief Constructs a DeferredGeometryPass object by default + */ + DeferredGeometryPass::DeferredGeometryPass() { m_clearShader = ShaderLibrary::Get("DeferredGBufferClear"); @@ -31,7 +41,16 @@ namespace Nz DeferredGeometryPass::~DeferredGeometryPass() = default; - bool DeferredGeometryPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + /*! + * \brief Processes the work on the data while working with textures + * \return false + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + + bool DeferredGeometryPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); NazaraUnused(firstWorkTexture); @@ -72,22 +91,22 @@ namespace Nz bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - // On commence par récupérer le programme du matériau + // We begin by getting the program for materials UInt32 flags = ShaderFlags_Deferred; if (useInstancing) flags |= ShaderFlags_Instancing; const Shader* shader = material->Apply(flags); - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + // The uniforms are conserved in our program, there's no point to send them back if they don't change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambient color for the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; @@ -105,7 +124,7 @@ namespace Nz const IndexBuffer* indexBuffer = meshData.indexBuffer; const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - // Gestion du draw call avant la boucle de rendu + // Handle draw call before rendering loop Renderer::DrawCall drawFunc; Renderer::DrawCallInstanced instancedDrawFunc; unsigned int indexCount; @@ -128,33 +147,33 @@ namespace Nz if (useInstancing) { - // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices + // We get the buffer for instance of Renderer and we configure it to work with matrices 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 de matrices que peut contenir le buffer + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // The number of matrices that can be hold in the buffer while (instanceCount > 0) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + // We compute the number of instances that we will be able to show this time (Depending on the instance buffer size) unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); instanceCount -= renderedInstanceCount; - // On remplit l'instancing buffer avec nos matrices world + // We fill the instancing buffer with our world matrices instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); instanceMatrices += renderedInstanceCount; - // Et on affiche + // And we show 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 + // Without instancing, we must do one draw call for each instance + // This may be faster than instancing under a threshold + // Due to the time to modify the instancing buffer for (const Matrix4f& matrix : instances) { Renderer::SetMatrix(MatrixType_World, matrix); @@ -167,16 +186,23 @@ namespace Nz } } - // Et on remet à zéro les données + // Abd we set it back data to zero matEntry.enabled = false; matEntry.instancingEnabled = false; } } } - return false; // On ne fait que remplir le G-Buffer, les work texture ne sont pas affectées + return false; // We only fill the G-Buffer, the work texture are unchanged } + /*! + * \brief Resizes the texture sizes + * \return true If successful + * + * \param dimensions Dimensions for the compute texture + */ + bool DeferredGeometryPass::Resize(const Vector2ui& dimensions) { DeferredRenderPass::Resize(dimensions); @@ -241,6 +267,13 @@ namespace Nz } } + /*! + * \brief Gets the uniforms of a shader + * \return Uniforms of the shader + * + * \param shader Shader to get uniforms from + */ + const DeferredGeometryPass::ShaderUniforms* DeferredGeometryPass::GetShaderUniforms(const Shader* shader) const { auto it = m_shaderUniforms.find(shader); @@ -260,6 +293,12 @@ namespace Nz return &it->second; } + /*! + * \brief Handle the invalidation of a shader + * + * \param shader Shader being invalidated + */ + void DeferredGeometryPass::OnShaderInvalidated(const Shader* shader) const { m_shaderUniforms.erase(shader); diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index c340d89a2..efcc88e75 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -13,6 +13,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredPhongLightingPass + * \brief Graphics class that represents the pass for phong lighting in deferred rendering + */ + + /*! + * \brief Constructs a DeferredPhongLightingPass object by default + */ + DeferredPhongLightingPass::DeferredPhongLightingPass() : m_lightMeshesDrawing(false) { @@ -21,7 +31,7 @@ namespace Nz m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient"); m_directionalLightUniforms.ubo = false; - m_directionalLightUniforms.locations.type = -1; // Type déjà connu + m_directionalLightUniforms.locations.type = -1; // Type already known m_directionalLightUniforms.locations.color = m_directionalLightShader->GetUniformLocation("LightColor"); m_directionalLightUniforms.locations.factors = m_directionalLightShader->GetUniformLocation("LightFactors"); m_directionalLightUniforms.locations.parameters1 = m_directionalLightShader->GetUniformLocation("LightDirection"); @@ -56,16 +66,36 @@ namespace Nz DeferredPhongLightingPass::~DeferredPhongLightingPass() = default; + /*! + * \brief Enables the drawing of meshes with light + * + * \param enable Should meshes with light parameter be drawed + */ + void DeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable) { m_lightMeshesDrawing = enable; } + /*! + * \brief Checks whether the drawing of meshes with light is enabled + * \return true If it is the case + */ + bool DeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const { return m_lightMeshesDrawing; } + /*! + * \brief Processes the work on the data while working with textures + * \return true + * + * \param sceneData Data for the scene + * \param firstWorkTexture Index of the first texture to work with + * \param firstWorkTexture Index of the second texture to work with + */ + bool DeferredPhongLightingPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -151,12 +181,12 @@ namespace Nz m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, Vector4f(light.position, light.attenuation)); m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, Vector4f(0.f, 0.f, 0.f, light.invRadius)); - lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère + lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // To correct imperfections due to the sphere lightMatrix.SetTranslation(light.position); Renderer::SetMatrix(MatrixType_World, lightMatrix); - // Rendu de la sphère dans le stencil buffer + // Sphere rendering in the stencil buffer Renderer::Enable(RendererParameter_ColorWrite, false); Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_FaceCulling, false); @@ -166,7 +196,7 @@ namespace Nz Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); - // Rendu de la sphère comme zone d'effet + // Sphere rendering as effect zone Renderer::Enable(RendererParameter_ColorWrite, true); Renderer::Enable(RendererParameter_DepthBuffer, false); Renderer::Enable(RendererParameter_FaceCulling, true); @@ -192,7 +222,7 @@ namespace Nz Renderer::SetShader(shader); for (const auto& light : m_renderQueue->pointLights) { - lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère + lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // To correct imperfections due to the sphere lightMatrix.SetTranslation(light.position); Renderer::SetMatrix(MatrixType_World, lightMatrix); @@ -230,7 +260,7 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, lightMatrix); - // Rendu de la sphère dans le stencil buffer + // Sphere rendering in the stencil buffer Renderer::Enable(RendererParameter_ColorWrite, false); Renderer::Enable(RendererParameter_DepthBuffer, true); Renderer::Enable(RendererParameter_FaceCulling, false); @@ -240,7 +270,7 @@ namespace Nz Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); - // Rendu de la sphère comme zone d'effet + // Sphere rendering as effect zone Renderer::Enable(RendererParameter_ColorWrite, true); Renderer::Enable(RendererParameter_DepthBuffer, false); Renderer::Enable(RendererParameter_FaceCulling, true); diff --git a/src/Nazara/Graphics/DeferredRenderPass.cpp b/src/Nazara/Graphics/DeferredRenderPass.cpp index 8d688c871..da40c01da 100644 --- a/src/Nazara/Graphics/DeferredRenderPass.cpp +++ b/src/Nazara/Graphics/DeferredRenderPass.cpp @@ -9,6 +9,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredRenderPass + * \brief Graphics class that represents the pass for rendering in deferred rendering + */ + + /*! + * \brief Constructs a DeferredRenderPass object by default + */ + DeferredRenderPass::DeferredRenderPass() : m_enabled(true) { @@ -16,11 +26,23 @@ namespace Nz DeferredRenderPass::~DeferredRenderPass() = default; + /*! + * \brief Enables the deferred rendering + * + * \param enable Should deferred rendering be activated + */ + void DeferredRenderPass::Enable(bool enable) { m_enabled = enable; } + /*! + * \brief Initializes the deferred forward pass which needs the deferred technique + * + * \param technique Rendering technique + */ + void DeferredRenderPass::Initialize(DeferredRenderTechnique* technique) { m_deferredTechnique = technique; @@ -37,11 +59,23 @@ namespace Nz m_workTextures[i] = technique->GetWorkTexture(i); } + /*! + * \brief Checks whether the deferred rendering is enabled + * \return true If it the case + */ + bool DeferredRenderPass::IsEnabled() const { return m_enabled; } + /*! + * \brief Resizes the texture sizes + * \return true If successful + * + * \param dimensions Dimensions for the compute texture + */ + bool DeferredRenderPass::Resize(const Vector2ui& dimensions) { m_dimensions = dimensions; diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 5bd0931e3..738e7b799 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -8,69 +8,207 @@ #include #include -///TODO: Rendre les billboards via Deferred Shading si possible +///TODO: Render billboards using Deferred Shading if possible namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DeferredRenderQueue + * \brief Graphics class that represents the rendering queue for deferred rendering + */ + + /*! + * \brief Constructs a DeferredRenderQueue object with the rendering queue of forward rendering + * + * \param forwardQueue Queue of data to render + */ + DeferredRenderQueue::DeferredRenderQueue(ForwardRenderQueue* forwardQueue) : m_forwardQueue(forwardQueue) { } + /*! + * \brief Adds billboard to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboard + * \param position Position of the billboard + * \param size Sizes of the billboard + * \param sinCos Rotation of the billboard + * \param color Color of the billboard + */ + void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + */ + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } + /*! + * \brief Adds drawable to the queue + * + * \param renderOrder Order of rendering + * \param drawable Drawable user defined + * + * \remark Produces a NazaraError if drawable is invalid + */ + void DeferredRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { m_forwardQueue->AddDrawable(renderOrder, drawable); } + /*! + * \brief Adds mesh to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the mesh + * \param meshData Data of the mesh + * \param meshAABB Box of the mesh + * \param transformMatrix Matrix of the mesh + */ + void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_Blend)) - // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis + // One transparent material ? I don't like it, go see if I'm in the forward queue m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix); else { @@ -103,21 +241,37 @@ namespace Nz it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - // On ajoute la matrice à la liste des instances de cet objet + // We add matrices to the list of instances of this object std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + // Do we have enough instances to perform instancing ? if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Thus we can activate it } } + /*! + * \brief Adds sprites to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the sprites + * \param vertices Buffer of data for the sprites + * \param spriteCount Number of sprites + * \param overlay Texture of the sprites + */ + void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay); } + /*! + * \brief Clears the queue + * + * \param fully Should everything be cleared or we can keep layers + */ + void DeferredRenderQueue::Clear(bool fully) { AbstractRenderQueue::Clear(fully); @@ -137,6 +291,13 @@ namespace Nz m_forwardQueue->Clear(fully); } + /*! + * \brief Gets the ith layer + * \return Reference to the ith layer for the queue + * + * \param i Index of the layer + */ + DeferredRenderQueue::Layer& DeferredRenderQueue::GetLayer(unsigned int i) { auto it = layers.find(i); @@ -149,6 +310,12 @@ namespace Nz return layer; } + /*! + * \brief Handle the invalidation of an index buffer + * + * \param indexBuffer Index buffer being invalidated + */ + void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { for (auto& pair : layers) @@ -170,6 +337,12 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a material + * + * \param material Material being invalidated + */ + void DeferredRenderQueue::OnMaterialInvalidation(const Material* material) { for (auto& pair : layers) @@ -180,6 +353,12 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a vertex buffer + * + * \param vertexBuffer Vertex buffer being invalidated + */ + void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { for (auto& pair : layers) @@ -201,6 +380,14 @@ namespace Nz } } + /*! + * \brief Functor to compare two batched model with material + * \return true If first material is "smaller" than the second one + * + * \param mat1 First material to compare + * \param mat2 Second material to compare + */ + bool DeferredRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const { const UberShader* uberShader1 = mat1->GetShader(); @@ -221,6 +408,14 @@ namespace Nz return mat1 < mat2; } + /*! + * \brief Functor to compare two mesh data + * \return true If first mesh is "smaller" than the second one + * + * \param data1 First mesh to compare + * \param data2 Second mesh to compare + */ + bool DeferredRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const { const Buffer* buffer1; diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 88335d92b..585091406 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -77,7 +77,18 @@ namespace Nz 3, // RenderPassType_SSAO }; - static_assert(sizeof(RenderPassPriority)/sizeof(unsigned int) == RenderPassType_Max+1, "Render pass priority array is incomplete"); + static_assert(sizeof(RenderPassPriority) / sizeof(unsigned int) == RenderPassType_Max + 1, "Render pass priority array is incomplete"); + + /*! + * \brief Registers the deferred shader + * \return Reference to the newly created shader + * + * \param name Name of the shader + * \param fragmentSource Raw data to fragment shader + * \param fragmentSourceLength Size of the fragment source + * \param vertexStage Stage of the shader + * \param err Pointer to string to contain error message + */ inline ShaderRef RegisterDeferredShader(const String& name, const UInt8* fragmentSource, unsigned int fragmentSourceLength, const ShaderStage& vertexStage, String* err) { @@ -109,6 +120,18 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::DeferredRenderTechnique + * \brief Graphics class that represents the technique used in deferred rendering + */ + + /*! + * \brief Constructs a DeferredRenderTechnique object by default + * + * \remark Produces a NazaraError if one pass could not be created + */ + DeferredRenderTechnique::DeferredRenderTechnique() : m_renderQueue(static_cast(m_forwardTechnique.GetRenderQueue())), m_GBufferSize(0U) @@ -204,11 +227,27 @@ namespace Nz DeferredRenderTechnique::~DeferredRenderTechnique() = default; + /*! + * \brief Clears the data + * + * \param sceneData Data of the scene + */ + void DeferredRenderTechnique::Clear(const SceneData& sceneData) const { NazaraUnused(sceneData); } + /*! + * \brief Draws the data of the scene + * \return true If successful + * + * \param sceneData Data of the scene + * + * \remark Produces a NazaraAssert if viewer of the scene is invalid + * \remark Produces a NazaraError if updating viewport dimensions failed + */ + bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -242,6 +281,14 @@ namespace Nz return true; } + /*! + * \brief Enables a pass + * + * \param renderPass Enumeration for the pass + * \param position Position of the pass + * \param enable Should the pass be enabled + */ + void DeferredRenderTechnique::EnablePass(RenderPassType renderPass, int position, bool enable) { auto it = m_passes.find(renderPass); @@ -253,11 +300,25 @@ namespace Nz } } + /*! + * \brief Gets the stencil buffer + * \return Pointer to the rendering buffer + */ + RenderBuffer* DeferredRenderTechnique::GetDepthStencilBuffer() const { return m_depthStencilBuffer; } + /*! + * \brief Gets the G-buffer + * \return Pointer to the ith texture + * + * \param i Index of the G-buffer + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid + */ + Texture* DeferredRenderTechnique::GetGBuffer(unsigned int i) const { #if NAZARA_GRAPHICS_SAFE @@ -271,16 +332,34 @@ namespace Nz return m_GBuffer[i]; } + /*! + * \brief Gets the rendering texture of the G-buffer + * \return Pointer to the rendering buffer + */ + RenderTexture* DeferredRenderTechnique::GetGBufferRTT() const { return &m_GBufferRTT; } + /*! + * \brief Gets the forward technique + * \return Constant pointer to the forward technique + */ + const ForwardRenderTechnique* DeferredRenderTechnique::GetForwardTechnique() const { return &m_forwardTechnique; } + /*! + * \brief Gets the pass + * \return Pointer to the deferred render pass + * + * \param renderPass Enumeration for the pass + * \param position Position of the pass + */ + DeferredRenderPass* DeferredRenderTechnique::GetPass(RenderPassType renderPass, int position) { auto it = m_passes.find(renderPass); @@ -294,21 +373,45 @@ namespace Nz return nullptr; } + /*! + * \brief Gets the render queue + * \return Pointer to the render queue + */ + AbstractRenderQueue* DeferredRenderTechnique::GetRenderQueue() { return &m_renderQueue; } + /*! + * \brief Gets the type of the current technique + * \return Type of the render technique + */ + RenderTechniqueType DeferredRenderTechnique::GetType() const { return RenderTechniqueType_DeferredShading; } + /*! + * \brief Gets the render texture used to work + * \return Pointer to the rendering texture + */ + RenderTexture* DeferredRenderTechnique::GetWorkRTT() const { return &m_workRTT; } + /*! + * \brief Gets the ith texture to work + * \return Pointer to the texture + * + * \param i Index of the texture used to work + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid + */ + Texture* DeferredRenderTechnique::GetWorkTexture(unsigned int i) const { #if NAZARA_GRAPHICS_SAFE @@ -322,6 +425,14 @@ namespace Nz return m_workTextures[i]; } + /*! + * \brief Checks whether the pass is enable + * \return true If it is the case + * + * \param renderPass Enumeration for the pass + * \param position Position of the pass + */ + bool DeferredRenderTechnique::IsPassEnabled(RenderPassType renderPass, int position) { auto it = m_passes.find(renderPass); @@ -335,9 +446,17 @@ namespace Nz return false; } + /*! + * \brief Resets the pass + * \return Pointer to the new deferred render pass + * + * \param renderPass Enumeration for the pass + * \param position Position of the pass + */ + DeferredRenderPass* DeferredRenderTechnique::ResetPass(RenderPassType renderPass, int position) { - std::unique_ptr smartPtr; // Nous évite un leak en cas d'exception + std::unique_ptr smartPtr; // We avoid to leak in case of exception switch (renderPass) { @@ -386,6 +505,14 @@ namespace Nz return smartPtr.release(); } + /*! + * \brief Sets the pass + * + * \param relativeTo Enumeration for the pass + * \param position Position of the pass + * \param pass Render pass to set + */ + void DeferredRenderTechnique::SetPass(RenderPassType relativeTo, int position, DeferredRenderPass* pass) { if (pass) @@ -400,12 +527,26 @@ namespace Nz m_passes[relativeTo].erase(position); } + /*! + * \brief Checks whether the technique is supported + * \return true if it is the case + */ + bool DeferredRenderTechnique::IsSupported() { - // Depuis qu'OpenGL 3.3 est la version minimale, le Renderer supporte ce qu'il faut, mais par acquis de conscience... + // Since OpenGL 3.3 is the minimal version, the Renderer supports what it needs, but we are never sure... return Renderer::GetMaxColorAttachments() >= 4 && Renderer::GetMaxRenderTargets() >= 4; } + /*! + * \brief Resizes the texture sizes used for the render technique + * \return true If successful + * + * \param dimensions Dimensions for the render technique + * + * \param Produces a NazaraError if one pass could not be resized + */ + bool DeferredRenderTechnique::Resize(const Vector2ui& dimensions) const { try @@ -427,6 +568,13 @@ namespace Nz } } + /*! + * \brief Initializes the deferred render technique + * \return true If successful + * + * \remark Produces a NazaraError if one shader creation failed + */ + bool DeferredRenderTechnique::Initialize() { const char vertexSource_Basic[] = @@ -560,6 +708,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the deferred render technique + */ + void DeferredRenderTechnique::Uninitialize() { ShaderLibrary::Unregister("DeferredGBufferClear"); @@ -571,6 +723,14 @@ namespace Nz ShaderLibrary::Unregister("DeferredGaussianBlur"); } + /*! + * \brief Functor to compare two render pass + * \return true If first render pass is "smaller" than the second one + * + * \param pass1 First render pass to compare + * \param pass2 Second render pass to compare + */ + bool DeferredRenderTechnique::RenderPassComparator::operator()(RenderPassType pass1, RenderPassType pass2) const { return RenderPassPriority[pass1] < RenderPassPriority[pass2]; diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index e6fc71ae0..dc31d2a45 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -9,6 +9,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::DepthRenderQueue + * \brief Graphics class that represents the rendering queue for depth rendering + */ + + /*! + * \brief Constructs a DepthRenderTechnique object by default + */ + DepthRenderQueue::DepthRenderQueue() { // Material @@ -18,6 +28,19 @@ namespace Nz //m_baseMaterial->SetFaceCulling(FaceSide_Front); } + /*! + * \brief Adds billboard to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboard + * \param position Position of the billboard + * \param size Sizes of the billboard + * \param sinCos Rotation of the billboard + * \param color Color of the billboard + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { NazaraAssert(material, "Invalid material"); @@ -34,6 +57,20 @@ namespace Nz ForwardRenderQueue::AddBillboard(0, material, position, size, sinCos, color); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -50,6 +87,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -66,6 +117,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -82,6 +147,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -98,6 +177,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -114,6 +207,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -130,6 +237,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -146,6 +267,20 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -162,12 +297,32 @@ namespace Nz ForwardRenderQueue::AddBillboards(0, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } + /*! + * \brief Adds a direcitonal light to the queue + * + * \param light Light to add + * + * \remark Produces a NazaraAssert + */ + void DepthRenderQueue::AddDirectionalLight(const DirectionalLight& light) { NazaraAssert(false, "Depth render queue doesn't handle lights"); NazaraUnused(light); } + /*! + * \brief Adds mesh to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the mesh + * \param meshData Data of the mesh + * \param meshAABB Box of the mesh + * \param transformMatrix Matrix of the mesh + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { NazaraAssert(material, "Invalid material"); @@ -185,18 +340,46 @@ namespace Nz ForwardRenderQueue::AddMesh(0, material, meshData, meshAABB, transformMatrix); } + /*! + * \brief Adds a point light to the queue + * + * \param light Light to add + * + * \remark Produces a NazaraAssert + */ + void DepthRenderQueue::AddPointLight(const PointLight& light) { NazaraAssert(false, "Depth render queue doesn't handle lights"); NazaraUnused(light); } + /*! + * \brief Adds a spot light to the queue + * + * \param light Light to add + * + * \remark Produces a NazaraAssert + */ + void DepthRenderQueue::AddSpotLight(const SpotLight& light) { NazaraAssert(false, "Depth render queue doesn't handle lights"); NazaraUnused(light); } + /*! + * \brief Adds sprites to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the sprites + * \param vertices Buffer of data for the sprites + * \param spriteCount Number of sprites + * \param overlay Texture of the sprites + * + * \remark Produces a NazaraAssert if material is invalid + */ + void DepthRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { NazaraAssert(material, "Invalid material"); diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 46e7fb043..233eb9c72 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -37,6 +37,16 @@ namespace Nz unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB } + /*! + * \ingroup graphics + * \class Nz::DepthRenderTechnique + * \brief Graphics class that represents the technique used in depth rendering + */ + + /*! + * \brief Constructs a DepthRenderTechnique object by default + */ + DepthRenderTechnique::DepthRenderTechnique() : m_vertexBuffer(BufferType_Vertex) { @@ -48,6 +58,12 @@ namespace Nz m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); } + /*! + * \brief Clears the data + * + * \param sceneData Data of the scene + */ + void DepthRenderTechnique::Clear(const SceneData& sceneData) const { Renderer::Enable(RendererParameter_DepthBuffer, true); @@ -59,6 +75,13 @@ namespace Nz // sceneData.background->Draw(sceneData.viewer); } + /*! + * \brief Draws the data of the scene + * \return true If successful + * + * \param sceneData Data of the scene + */ + bool DepthRenderTechnique::Draw(const SceneData& sceneData) const { for (auto& pair : m_renderQueue.layers) @@ -81,16 +104,33 @@ namespace Nz return true; } + /*! + * \brief Gets the render queue + * \return Pointer to the render queue + */ + AbstractRenderQueue* DepthRenderTechnique::GetRenderQueue() { return &m_renderQueue; } + /*! + * \brief Gets the type of the current technique + * \return Type of the render technique + */ + RenderTechniqueType DepthRenderTechnique::GetType() const { return RenderTechniqueType_Depth; } + /*! + * \brief Initializes the depth render technique + * \return true If successful + * + * \remark Produces a NazaraError if one shader creation failed + */ + bool DepthRenderTechnique::Initialize() { try @@ -149,12 +189,23 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the depth render technique + */ + void DepthRenderTechnique::Uninitialize() { s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } + /*! + * \brief Draws basic sprites + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + */ + void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { const Shader* lastShader = nullptr; @@ -180,7 +231,7 @@ namespace Nz unsigned int spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) UInt32 flags = 0; if (overlay) flags |= ShaderFlags_TextureOverlay; @@ -195,26 +246,26 @@ namespace Nz 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); // Overlay shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position de la caméra + // Position of the camera 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 + unsigned int spriteChain = 0; // Which chain of sprites are we treating + unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain do { - // On ouvre le buffer en écriture + // We open the buffer in writing mode BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); @@ -232,7 +283,7 @@ namespace Nz spriteCount += count; spriteChainOffset += count; - // Avons-nous traité la chaîne entière ? + // Have we treated the entire chain ? if (spriteChainOffset == currentChain.spriteCount) { spriteChain++; @@ -257,6 +308,13 @@ namespace Nz } } + /*! + * \brief Draws billboards + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + */ + void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { const Shader* lastShader = nullptr; @@ -278,16 +336,16 @@ namespace Nz unsigned int billboardCount = billboardVector.size(); if (billboardCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; @@ -325,16 +383,16 @@ namespace Nz unsigned int billboardCount = billboardVector.size(); if (billboardCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); lastShader = shader; @@ -396,6 +454,13 @@ namespace Nz } } + /*! + * \brief Draws opaques models + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + */ + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { const Shader* lastShader = nullptr; @@ -415,14 +480,14 @@ namespace Nz bool instancing = m_instancingEnabled && matEntry.instancingEnabled; - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); lastShader = shader; } @@ -441,7 +506,7 @@ namespace Nz const IndexBuffer* indexBuffer = meshData.indexBuffer; const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - // Gestion du draw call avant la boucle de rendu + // Handle draw call before rendering loop Renderer::DrawCall drawFunc; Renderer::DrawCallInstanced instancedDrawFunc; unsigned int indexCount; @@ -464,33 +529,33 @@ namespace Nz if (instancing) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) 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 + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // The maximum number of instances in one batch while (instanceCount > 0) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); instanceCount -= renderedInstanceCount; - // On remplit l'instancing buffer avec nos matrices world + // We fill the instancing buffer with our world matrices instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); instanceMatrices += renderedInstanceCount; - // Et on affiche + // And we draw 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 + // Without instancing, we must do a draw call for each instance + // This may be faster than instancing under a certain number + // Due to the time to modify the instancing buffer for (const Matrix4f& matrix : instances) { Renderer::SetMatrix(MatrixType_World, matrix); @@ -502,13 +567,20 @@ namespace Nz } } - // Et on remet à zéro les données + // And we set the data back to zero matEntry.enabled = false; matEntry.instancingEnabled = false; } } } + /*! + * \brief Gets the shader uniforms + * \return Uniforms of the shader + * + * \param shader Shader to get uniforms from + */ + const DepthRenderTechnique::ShaderUniforms* DepthRenderTechnique::GetShaderUniforms(const Shader* shader) const { auto it = m_shaderUniforms.find(shader); @@ -527,6 +599,12 @@ namespace Nz return &it->second; } + /*! + * \brief Handle the invalidation of a shader + * + * \param shader Shader being invalidated + */ + void DepthRenderTechnique::OnShaderInvalidated(const Shader* shader) const { m_shaderUniforms.erase(shader); diff --git a/src/Nazara/Graphics/Drawable.cpp b/src/Nazara/Graphics/Drawable.cpp index baac1defb..7db121225 100644 --- a/src/Nazara/Graphics/Drawable.cpp +++ b/src/Nazara/Graphics/Drawable.cpp @@ -7,5 +7,13 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Drawable + * \brief Graphics class that represents something drawable for our scene + * + * \remark This class is abstract + */ + Drawable::~Drawable() = default; } diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 9f0f5d04d..0f182a185 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -7,10 +7,29 @@ #include #include -///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) +///TODO: Replace sinus/cosinus by a lookup table (which will lead to a speed up about 10x) namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ForwardRenderQueue + * \brief Graphics class that represents the rendering queue for forward rendering + */ + + /*! + * \brief Adds billboard to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboard + * \param position Position of the billboard + * \param size Sizes of the billboard + * \param sinCos Rotation of the billboard + * \param color Color of the billboard + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { NazaraAssert(material, "Invalid material"); @@ -32,37 +51,33 @@ namespace Nz billboardVector.push_back(BillboardData{color, position, size, sinCos}); } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { 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 Vector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 if (!sinCosPtr) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile if (!colorPtr) - colorPtr.Reset(&Color::White, 0); // Pareil + colorPtr.Reset(&Color::White, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -73,39 +88,35 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); - ///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) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile float defaultAlpha = 1.f; if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil + alphaPtr.Reset(&defaultAlpha, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -116,37 +127,33 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); - ///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) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile if (!colorPtr) - colorPtr.Reset(&Color::White, 0); // Pareil + colorPtr.Reset(&Color::White, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(ToRadians(*anglePtr)); @@ -161,39 +168,35 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Sizes of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); - ///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) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile float defaultAlpha = 1.f; if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil + alphaPtr.Reset(&defaultAlpha, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(ToRadians(*anglePtr)); @@ -208,37 +211,33 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); - ///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) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile if (!colorPtr) - colorPtr.Reset(&Color::White, 0); // Pareil + colorPtr.Reset(&Color::White, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -249,39 +248,35 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param sinCosPtr Rotation of the billboards if null, Vector2f(0.f, 1.f) is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); - ///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) - sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + sinCosPtr.Reset(&defaultSinCos, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile float defaultAlpha = 1.f; if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil + alphaPtr.Reset(&defaultAlpha, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -292,37 +287,33 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param colorPtr Color of the billboards if null, Color::White is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); - ///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) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile if (!colorPtr) - colorPtr.Reset(&Color::White, 0); // Pareil + colorPtr.Reset(&Color::White, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(ToRadians(*anglePtr)); @@ -337,39 +328,35 @@ namespace Nz } } + /*! + * \brief Adds multiple billboards to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the billboards + * \param count Number of billboards + * \param positionPtr Position of the billboards + * \param sizePtr Size of the billboards + * \param anglePtr Rotation of the billboards if null, 0.f is used + * \param alphaPtr Alpha parameters of the billboards if null, 1.f is used + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); - ///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) - anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + anglePtr.Reset(&defaultRotation, 0); // The trick here is to put the stride to zero, which leads the pointer to be immobile float defaultAlpha = 1.f; if (!alphaPtr) - alphaPtr.Reset(&defaultAlpha, 0); // Pareil + alphaPtr.Reset(&defaultAlpha, 0); // Same - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; + BillboardData* billboardData = GetBillboardData(renderOrder, material, count); for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(ToRadians(*anglePtr)); @@ -384,6 +371,15 @@ namespace Nz } } + /*! + * \brief Adds drawable to the queue + * + * \param renderOrder Order of rendering + * \param drawable Drawable user defined + * + * \remark Produces a NazaraError if drawable is invalid + */ + void ForwardRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { #if NAZARA_GRAPHICS_SAFE @@ -399,15 +395,29 @@ namespace Nz otherDrawables.push_back(drawable); } + /*! + * \brief Adds mesh to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the mesh + * \param meshData Data of the mesh + * \param meshAABB Box of the mesh + * \param transformMatrix Matrix of the mesh + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { + NazaraAssert(material, "Invalid material"); + if (material->IsEnabled(RendererParameter_Blend)) { Layer& currentLayer = GetLayer(renderOrder); auto& transparentModels = currentLayer.transparentModels; auto& transparentModelData = currentLayer.transparentModelData; - // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) + // The material is transparent, we must draw this mesh using another way (after the rendering of opages objects while sorting them) unsigned int index = transparentModelData.size(); transparentModelData.resize(index+1); @@ -455,14 +465,28 @@ namespace Nz std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + // Do we have enough instances to perform instancing ? if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Thus we can activate it } } + /*! + * \brief Adds sprites to the queue + * + * \param renderOrder Order of rendering + * \param material Material of the sprites + * \param vertices Buffer of data for the sprites + * \param spriteCount Number of sprites + * \param overlay Texture of the sprites + * + * \remark Produces a NazaraAssert if material is invalid + */ + void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { + NazaraAssert(material, "Invalid material"); + Layer& currentLayer = GetLayer(renderOrder); auto& basicSprites = currentLayer.basicSprites; @@ -494,6 +518,12 @@ namespace Nz spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } + /*! + * \brief Clears the queue + * + * \param fully Should everything be cleared or we can keep layers + */ + void ForwardRenderQueue::Clear(bool fully) { AbstractRenderQueue::Clear(fully); @@ -518,15 +548,21 @@ namespace Nz } } + /*! + * \brief Sorts the object according to the viewer position, furthest to nearest + * + * \param viewer Viewer of the scene + */ + void ForwardRenderQueue::Sort(const AbstractViewer* viewer) { Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near); Vector3f viewerPos = viewer->GetEyePosition(); Vector3f viewerNormal = viewer->GetForward(); - for (auto& layerPair : layers) + for (auto& pair : layers) { - Layer& layer = layerPair.second; + Layer& layer = pair.second; std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2) { @@ -557,18 +593,61 @@ namespace Nz } } + /*! + * \brief Gets the billboard data + * \return Pointer to the data of the billboards + * + * \param renderOrder Order of rendering + * \param material Material of the billboard + */ + + ForwardRenderQueue::BillboardData* ForwardRenderQueue::GetBillboardData(int renderOrder, const Material* material, unsigned int count) + { + auto& billboards = GetLayer(renderOrder).billboards; + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + return &billboardVector[prevSize]; + } + + /*! + * \brief Gets the ith layer + * \return Reference to the ith layer for the queue + * + * \param i Index of the layer + */ + ForwardRenderQueue::Layer& ForwardRenderQueue::GetLayer(int i) { auto it = layers.find(i); if (it == layers.end()) it = layers.insert(std::make_pair(i, Layer())).first; - + Layer& layer = it->second; layer.clearCount = 0; return layer; } + /*! + * \brief Handle the invalidation of an index buffer + * + * \param indexBuffer Index buffer being invalidated + */ + void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { for (auto& pair : layers) @@ -590,6 +669,12 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a material + * + * \param material Material being invalidated + */ + void ForwardRenderQueue::OnMaterialInvalidation(const Material* material) { for (auto& pair : layers) @@ -602,6 +687,12 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a texture + * + * \param texture Texture being invalidated + */ + void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture) { for (auto& pair : layers) @@ -615,6 +706,12 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a vertex buffer + * + * \param vertexBuffer Vertex buffer being invalidated + */ + void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { for (auto& pair : layers) @@ -635,6 +732,14 @@ namespace Nz } } + /*! + * \brief Functor to compare two batched billboard with material + * \return true If first material is "smaller" than the second one + * + * \param mat1 First material to compare + * \param mat2 Second material to compare + */ + bool ForwardRenderQueue::BatchedBillboardComparator::operator()(const Material* mat1, const Material* mat2) const { const UberShader* uberShader1 = mat1->GetShader(); @@ -655,6 +760,14 @@ namespace Nz return mat1 < mat2; } + /*! + * \brief Functor to compare two batched model with material + * \return true If first material is "smaller" than the second one + * + * \param mat1 First material to compare + * \param mat2 Second material to compare + */ + bool ForwardRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const { const UberShader* uberShader1 = mat1->GetShader(); @@ -675,6 +788,14 @@ namespace Nz return mat1 < mat2; } + /*! + * \brief Functor to compare two batched sprites with material + * \return true If first material is "smaller" than the second one + * + * \param mat1 First material to compare + * \param mat2 Second material to compare + */ + bool ForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const Material* mat1, const Material* mat2) { const UberShader* uberShader1 = mat1->GetShader(); @@ -695,6 +816,14 @@ namespace Nz return mat1 < mat2; } + /*! + * \brief Functor to compare two mesh data + * \return true If first mesh is "smaller" than the second one + * + * \param data1 First mesh to compare + * \param data2 Second mesh to compare + */ + bool ForwardRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const { const Buffer* buffer1; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 2ec95aee7..482852347 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -33,10 +33,20 @@ namespace Nz Vector2f uv; }; - unsigned int s_maxQuads = std::numeric_limits::max()/6; - unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB + unsigned int s_maxQuads = std::numeric_limits::max() / 6; + unsigned int s_vertexBufferSize = 4 * 1024 * 1024; // 4 MiB } + /*! + * \ingroup graphics + * \class Nz::ForwardRenderTechnique + * \brief Graphics class that represents the technique used in forward rendering + */ + + /*! + * \brief Constructs a ForwardRenderTechnique object by default + */ + ForwardRenderTechnique::ForwardRenderTechnique() : m_vertexBuffer(BufferType_Vertex), m_maxLightPassPerObject(3) @@ -49,6 +59,12 @@ namespace Nz m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); } + /*! + * \brief Clears the data + * + * \param sceneData Data of the scene + */ + void ForwardRenderTechnique::Clear(const SceneData& sceneData) const { Renderer::Enable(RendererParameter_DepthBuffer, true); @@ -59,6 +75,15 @@ namespace Nz sceneData.background->Draw(sceneData.viewer); } + /*! + * \brief Draws the data of the scene + * \return true If successful + * + * \param sceneData Data of the scene + * + * \remark Produces a NazaraAssert if viewer of the scene is invalid + */ + bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -88,55 +113,83 @@ namespace Nz return true; } + /*! + * \brief Gets the maximum number of lights available per pass per object + * \return Maximum number of light simulatenously per object + */ + unsigned int ForwardRenderTechnique::GetMaxLightPassPerObject() const { return m_maxLightPassPerObject; } + /*! + * \brief Gets the render queue + * \return Pointer to the render queue + */ + AbstractRenderQueue* ForwardRenderTechnique::GetRenderQueue() { return &m_renderQueue; } + /*! + * \brief Gets the type of the current technique + * \return Type of the render technique + */ + RenderTechniqueType ForwardRenderTechnique::GetType() const { return RenderTechniqueType_BasicForward; } - void ForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount) + /*! + * \brief Sets the maximum number of lights available per pass per object + * + * \param passCount Maximum number of light simulatenously per object + */ + + void ForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int maxLightPassPerObject) { - m_maxLightPassPerObject = passCount; + m_maxLightPassPerObject = maxLightPassPerObject; } + /*! + * \brief Initializes the forward render technique + * \return true If successful + * + * \remark Produces a NazaraError if one shader creation failed + */ + bool ForwardRenderTechnique::Initialize() { try { ErrorFlags flags(ErrorFlag_ThrowException, true); - s_quadIndexBuffer.Reset(false, s_maxQuads*6, DataStorage_Hardware, BufferUsage_Static); + 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 + 0; + *indices++ = i * 4 + 2; + *indices++ = i * 4 + 1; - *indices++ = i*4 + 2; - *indices++ = i*4 + 3; - *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 + mapper.Unmap(); // No point to keep the buffer open any longer - // Quad buffer (utilisé pour l'instancing de billboard et de sprites) - //Note: Les UV sont calculés dans le shader + // Quad buffer (used for instancing of billboards and sprites) + //Note: UV are computed in the shader s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); - float vertices[2*4] = { + float vertices[2 * 4] = { -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, @@ -145,14 +198,14 @@ namespace Nz s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); - // Déclaration lors du rendu des billboards par sommet + // Declaration used when rendering the vertex billboards 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 + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Includes 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 + // Declaration used when rendering the billboards with intancing + // The main advantage is the direct copy (std::memcpy) of data in the RenderQueue to the GPU buffer 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)); @@ -169,12 +222,23 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the forward render technique + */ + void ForwardRenderTechnique::Uninitialize() { s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } + /*! + * \brief Chooses the nearest lights for one object + * + * \param object Sphere symbolising the object + * \param includeDirectionalLights Should directional lights be included in the computation + */ + void ForwardRenderTechnique::ChooseLights(const Spheref& object, bool includeDirectionalLights) const { m_lights.clear(); @@ -213,6 +277,15 @@ namespace Nz }); } + /*! + * \brief Draws basic sprites + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + * + * \remark Produces a NazaraAssert is viewer is invalid + */ + void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -240,7 +313,7 @@ namespace Nz unsigned int spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) UInt32 flags = ShaderFlags_VertexColor; if (overlay) flags |= ShaderFlags_TextureOverlay; @@ -255,46 +328,46 @@ namespace Nz 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Overlay shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); 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 + unsigned int spriteChain = 0; // Which chain of sprites are we treating + unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain do { - // On ouvre le buffer en écriture + // We open the buffer in writing mode BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); VertexStruct_XYZ_Color_UV* vertices = static_cast(vertexMapper.GetPointer()); unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + 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; + 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 ? + // Have we treated the entire chain ? if (spriteChainOffset == currentChain.spriteCount) { spriteChain++; @@ -305,7 +378,7 @@ namespace Nz vertexMapper.Unmap(); - Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, spriteCount*6); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, spriteCount * 6); } while (spriteChain < spriteChainCount); @@ -313,12 +386,21 @@ namespace Nz } } - // On remet à zéro + // We set it back to zero matEntry.enabled = false; } } } + /*! + * \brief Draws billboards + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + * + * \remark Produces a NazaraAssert is viewer is invalid + */ + void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -342,18 +424,18 @@ namespace Nz unsigned int billboardCount = billboardVector.size(); if (billboardCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; @@ -391,32 +473,32 @@ namespace Nz unsigned int billboardCount = billboardVector.size(); if (billboardCount > 0) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); + 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); + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount * 4); BillboardPoint* vertices = static_cast(vertexMapper.GetPointer()); for (unsigned int i = 0; i < renderedBillboardCount; ++i) @@ -454,7 +536,7 @@ namespace Nz vertexMapper.Unmap(); - Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount * 6); } while (billboardCount > 0); @@ -464,6 +546,15 @@ namespace Nz } } + /*! + * \brief Draws opaques models + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + * + * \remark Produces a NazaraAssert is viewer is invalid + */ + void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -483,25 +574,25 @@ namespace Nz { const Material* material = matIt.first; - // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active - // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches - // (Le deferred shading n'a pas ce problème) + // We only use instancing when no light (other than directional) is active + // This is because instancing is not compatible with the search of nearest lights + // Deferred shading does not have this problem bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; @@ -521,7 +612,7 @@ namespace Nz const IndexBuffer* indexBuffer = meshData.indexBuffer; const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - // Gestion du draw call avant la boucle de rendu + // Handle draw call before rendering loop Renderer::DrawCall drawFunc; Renderer::DrawCallInstanced instancedDrawFunc; unsigned int indexCount; @@ -544,17 +635,17 @@ namespace Nz if (instancing) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - // Avec l'instancing, impossible de sélectionner les lumières pour chaque objet - // Du coup, il n'est activé que pour les lumières directionnelles + // With instancing, impossible to select the lights for each object + // So, it's only activated for directional lights unsigned int lightCount = m_renderQueue.directionalLights.size(); unsigned int lightIndex = 0; RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; for (unsigned int pass = 0; pass < passCount; ++pass) { if (shaderUniforms->hasLightUniforms) @@ -564,10 +655,10 @@ namespace Nz if (pass == 1) { - // Pour additionner le résultat des calculs de lumière - // Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques - // (Autrement dit, sans blending) - // Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois + // To add the result of light computations + // We won't interfeer with materials parameters because we only render opaques objects + // (A.K.A., without blending) + // About the depth function, it must be applied only the first time Renderer::Enable(RendererParameter_Blend, true); Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); Renderer::SetDepthFunc(RendererComparison_Equal); @@ -575,32 +666,32 @@ namespace Nz // Sends the uniforms for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i); - // Et on passe à l'affichage + // And we give them to draw drawFunc(meshData.primitiveMode, 0, indexCount); } const Matrix4f* instanceMatrices = &instances[0]; unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Maximum number of instance in one batch while (instanceCount > 0) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); instanceCount -= renderedInstanceCount; - // On remplit l'instancing buffer avec nos matrices world + // We fill the instancing buffer with our world matrices instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); instanceMatrices += renderedInstanceCount; - // Et on affiche + // And we draw instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); } } - // On n'oublie pas de désactiver le blending pour ne pas interférer sur le reste du rendu + // We don't forget to disable the blending to avoid to interfeer with the rest of the rendering Renderer::Enable(RendererParameter_Blend, false); Renderer::SetDepthFunc(oldDepthFunc); } @@ -617,19 +708,19 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, matrix); unsigned int lightIndex = 0; - RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // Dans le cas où nous aurions à le changer + RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // In the case where we have to change it - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; for (unsigned int pass = 0; pass < passCount; ++pass) { lightCount -= std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); if (pass == 1) { - // Pour additionner le résultat des calculs de lumière - // Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques - // (Autrement dit, sans blending) - // Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois + // To add the result of light computations + // We won't interfeer with materials parameters because we only render opaques objects + // (A.K.A., without blending) + // About the depth function, it must be applied only the first time Renderer::Enable(RendererParameter_Blend, true); Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); Renderer::SetDepthFunc(RendererComparison_Equal); @@ -639,7 +730,7 @@ namespace Nz for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); - // Et on passe à l'affichage + // And we draw drawFunc(meshData.primitiveMode, 0, indexCount); } @@ -649,9 +740,9 @@ namespace Nz } 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 + // Without instancing, we must do a draw call for each instance + // This may be faster than instancing under a certain number + // Due to the time to modify the instancing buffer for (const Matrix4f& matrix : instances) { Renderer::SetMatrix(MatrixType_World, matrix); @@ -664,13 +755,22 @@ namespace Nz } } - // Et on remet à zéro les données + // And we set the data back to zero matEntry.enabled = false; matEntry.instancingEnabled = false; } } } + /*! + * \brief Draws transparent models + * + * \param sceneData Data of the scene + * \param layer Layer of the rendering + * + * \remark Produces a NazaraAssert is viewer is invalid + */ + void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -683,25 +783,25 @@ namespace Nz { const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index]; - // Matériau + // Material const Material* material = modelData.material; - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + // We begin to apply the material (and get the shader activated doing so) 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 + // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) { - // Index des uniformes dans le shader + // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Couleur ambiante de la scène + // Ambiant color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra + // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) + // We send the directional lights if there is one (same for all) if (shaderUniforms->hasLightUniforms) { lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); @@ -720,7 +820,7 @@ namespace Nz const IndexBuffer* indexBuffer = meshData.indexBuffer; const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - // Gestion du draw call avant la boucle de rendu + // Handle draw call before the rendering loop Renderer::DrawCall drawFunc; unsigned int indexCount; @@ -754,6 +854,13 @@ namespace Nz } } + /*! + * \brief Gets the shader uniforms + * \return Uniforms of the shader + * + * \param shader Shader to get uniforms from + */ + const ForwardRenderTechnique::ShaderUniforms* ForwardRenderTechnique::GetShaderUniforms(const Shader* shader) const { auto it = m_shaderUniforms.find(shader); @@ -795,6 +902,12 @@ namespace Nz return &it->second; } + /*! + * \brief Handle the invalidation of a shader + * + * \param shader Shader being invalidated + */ + void ForwardRenderTechnique::OnShaderInvalidated(const Shader* shader) const { m_shaderUniforms.erase(shader); diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index b501682bc..c9cc652a8 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -28,15 +28,29 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Graphics + * \brief Graphics class that represents the module initializer of Graphics + */ + + /*! + * \brief Initializes the Graphics module + * \return true if initialization is successful + * + * \remark Produces a NazaraNotice + * \remark Produces a NazaraError if one submodule failed + */ + bool Graphics::Initialize() { - if (s_moduleReferenceCounter > 0) + if (IsInitialized()) { s_moduleReferenceCounter++; - return true; // Déjà initialisé + return true; // Already initialized } - // Initialisation des dépendances + // Initialisation of dependances if (!Renderer::Initialize()) { NazaraError("Failed to initialize Renderer module"); @@ -45,7 +59,7 @@ namespace Nz s_moduleReferenceCounter++; - // Initialisation du module + // Initialisation of the module CallOnExit onExit(Graphics::Uninitialize); if (!Material::Initialize()) @@ -96,7 +110,7 @@ namespace Nz return false; } - // Loaders génériques + // Generic loaders Loaders::RegisterMesh(); Loaders::RegisterTexture(); @@ -133,43 +147,54 @@ namespace Nz return true; } + /*! + * \brief Checks whether the module is initialized + * \return true if module is initialized + */ + bool Graphics::IsInitialized() { return s_moduleReferenceCounter != 0; } + /*! + * \brief Uninitializes the Core module + * + * \remark Produces a NazaraNotice + */ + void Graphics::Uninitialize() { if (s_moduleReferenceCounter != 1) { - // Le module est soit encore utilisé, soit pas initialisé + // The module is still in use, or can not be uninitialized if (s_moduleReferenceCounter > 1) s_moduleReferenceCounter--; return; } - // Libération du module + // Free of module s_moduleReferenceCounter = 0; - // Libération de l'atlas s'il vient de nous + // Free of atlas if it is ours std::shared_ptr defaultAtlas = Font::GetDefaultAtlas(); if (defaultAtlas && defaultAtlas->GetStorage() & DataStorage_Hardware) { Font::SetDefaultAtlas(nullptr); - // La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique) - // du coup, si la police par défaut utilise un atlas hardware, on lui enlève. - // Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant + // The default police can make live one hardware atlas after the free of a module (which could be problematic) + // So, if the default police use a hardware atlas, we stole it. + // I don't like this solution, but I don't have any better if (!defaultAtlas.unique()) { - // Encore au moins une police utilise l'atlas + // Still at least one police use the atlas Font* defaultFont = Font::GetDefault(); defaultFont->SetAtlas(nullptr); if (!defaultAtlas.unique()) { - // Toujours pas seuls propriétaires ? Ah ben zut. + // Still not the only one to own it ? Then crap. NazaraWarning("Default font atlas uses hardware storage and is still used"); } } @@ -195,7 +220,7 @@ namespace Nz NazaraNotice("Uninitialized: Graphics module"); - // Libération des dépendances + // Free of dependances Renderer::Uninitialize(); } diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index c8034d7b9..7c2122281 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -9,11 +9,32 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::GuillotineTextureAtlas + * \brief Graphics class that represents an atlas texture for guillotine + */ + + /*! + * \brief Gets the underlying data storage + * \return Value of the enumeration of the underlying data storage + */ + UInt32 GuillotineTextureAtlas::GetStorage() const { return DataStorage_Hardware; } + /*! + * \brief Resizes the image + * \return Updated texture + * + * \param oldImage Old image to resize + * \param size New image size + * + * \remark Produces a NazaraError if resize failed + */ + AbstractImage* GuillotineTextureAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const { std::unique_ptr newTexture(new Texture); @@ -23,8 +44,8 @@ namespace Nz { Texture* oldTexture = static_cast(oldImage); - // Copie des anciennes données - ///TODO: Copie de texture à texture + // Copy of old data + ///TODO: Copy from texture to texture Image image; if (!oldTexture->Download(&image)) { @@ -43,8 +64,7 @@ namespace Nz } else { - // Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique - // ou que nous manquons de mémoire + // If we are here, it is that the size is too big for the graphic card or we don't have enough return nullptr; } } diff --git a/src/Nazara/Graphics/InstancedRenderable.cpp b/src/Nazara/Graphics/InstancedRenderable.cpp index 780f11a67..ef5f62b96 100644 --- a/src/Nazara/Graphics/InstancedRenderable.cpp +++ b/src/Nazara/Graphics/InstancedRenderable.cpp @@ -7,16 +7,43 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::InstancedRenderable + * \brief Graphics class that represents an instancer renderable + * + * \remark This class is abstract + */ + + /*! + * \brief Destructs the object and calls OnInstancedRenderableRelease + * + * \see OnInstancedRenderableRelease + */ + InstancedRenderable::~InstancedRenderable() { OnInstancedRenderableRelease(this); } + /*! + * \brief Culls the instanced if not in the frustum + * \return true If instanced is in the frustum + * + * \param frustum Symbolizing the field of view + * \param transformMatrix Matrix transformation for our object + */ + bool InstancedRenderable::Cull(const Frustumf& frustum, const InstanceData& instanceData) const { return frustum.Contains(instanceData.volume); } + /*! + * \brief Gets the bounding volume + * \return Bounding volume of the instanced + */ + const BoundingVolumef& InstancedRenderable::GetBoundingVolume() const { EnsureBoundingVolumeUpdated(); @@ -24,11 +51,30 @@ namespace Nz return m_boundingVolume; } + /*! + * \brief Invalidates data for instanced + * + * \param instanceData Pointer to data of instances + * \param flags Flags for the instances + * + * \remark Produces a NazaraAssert if instanceData is invalid + */ + void InstancedRenderable::InvalidateData(InstanceData* instanceData, UInt32 flags) const { + NazaraAssert(instanceData, "Invalid instance data"); + instanceData->flags |= flags; } + /*! + * \brief Updates the bounding volume + * + * \param instanceData Pointer to data of instances + * + * \remark Produces a NazaraAssert if instanceData is invalid + */ + void InstancedRenderable::UpdateBoundingVolume(InstanceData* instanceData) const { NazaraAssert(instanceData, "Invalid instance data"); @@ -37,6 +83,14 @@ namespace Nz instanceData->volume.Update(instanceData->transformMatrix); } + /*! + * \brief Updates the instance data + * + * \param instanceData Pointer to data of instances + * + * \remark Produces a NazaraAssert if instanceData is invalid + */ + void InstancedRenderable::UpdateData(InstanceData* instanceData) const { NazaraAssert(instanceData, "Invalid instance data"); diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 14e33100b..275d78a79 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -13,11 +13,23 @@ #include #include -///TODO: Utilisation des UBOs +///TODO: Use of UBOs ///TODO: Scale ? namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Light + * \brief Graphics class that represents a light + */ + + /*! + * \brief Constructs a Light object with a type + * + * \param type Type of the light + */ + Light::Light(LightType type) : m_type(type), m_shadowMapFormat(PixelFormatType_Depth16), @@ -34,6 +46,15 @@ namespace Nz SetRadius(5.f); } + /*! + * \brief Adds this light to the render queue + * + * \param renderQueue Queue to be added + * \param transformMatrix Matrix transformation for this light + * + * \remark Produces a NazaraError if type is invalid + */ + void Light::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const { static Matrix4f biasMatrix(0.5f, 0.f, 0.f, 0.f, @@ -100,16 +121,36 @@ namespace Nz } } + /*! + * \brief Clones this light + * \return Pointer to newly allocated Light + */ + Light* Light::Clone() const { return new Light(*this); } + /*! + * \brief Creates a default light + * \return Pointer to newly allocated light + */ + Light* Light::Create() const { return new Light; } + /*! + * \brief Culls the light if not in the frustum + * \return true If light is in the frustum + * + * \param frustum Symbolizing the field of view + * \param transformMatrix Matrix transformation for our object + * + * \remark Produces a NazaraError if type is invalid + */ + bool Light::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const { switch (m_type) @@ -128,6 +169,14 @@ namespace Nz return false; } + /*! + * \brief Updates the bounding volume by a matrix + * + * \param transformMatrix Matrix transformation for our bounding volume + * + * \remark Produces a NazaraError if type is invalid + */ + void Light::UpdateBoundingVolume(const Matrix4f& transformMatrix) { switch (m_type) @@ -149,6 +198,12 @@ namespace Nz } } + /* + * \brief Makes the bounding volume of this light + * + * \remark Produces a NazaraError if type is invalid + */ + void Light::MakeBoundingVolume() const { switch (m_type) @@ -166,19 +221,19 @@ namespace Nz case LightType_Spot: { - // On forme une boite sur l'origine + // We make a box center in the origin Boxf box(Vector3f::Zero()); - // On calcule le reste des points - Vector3f base(Vector3f::Forward()*m_radius); + // We compute the other points + Vector3f base(Vector3f::Forward() * m_radius); - // Il nous faut maintenant le rayon du cercle projeté à cette distance - // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente + // Now we need the radius of the projected circle depending on the distance + // Tangent = Opposite/Adjacent <=> Opposite = Adjacent * Tangent float radius = m_radius * m_outerAngleTangent; - Vector3f lExtend = Vector3f::Left()*radius; - Vector3f uExtend = Vector3f::Up()*radius; + Vector3f lExtend = Vector3f::Left() * radius; + Vector3f uExtend = Vector3f::Up() * radius; - // Et on ajoute ensuite les quatres extrémités de la pyramide + // And we add the four extremities of our pyramid box.ExtendTo(base + lExtend + uExtend); box.ExtendTo(base + lExtend - uExtend); box.ExtendTo(base - lExtend + uExtend); @@ -194,6 +249,10 @@ namespace Nz } } + /*! + * \brief Updates the shadow map + */ + void Light::UpdateShadowMap() const { if (m_shadowCastingEnabled) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 44ec0310d..24323960d 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #ifndef NAZARA_RENDERER_OPENGL -#define NAZARA_RENDERER_OPENGL // Nécessaire pour inclure les headers OpenGL +#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers #endif #include @@ -36,6 +36,17 @@ namespace Nz }; } + /*! + * \ingroup graphics + * \class Nz::Material + * \brief Graphics class that represents a material + */ + + /*! + * \brief Checks whether the parameters for the material are correct + * \return true If parameters are valid + */ + bool MaterialParams::IsValid() const { if (!UberShaderLibrary::Has(shaderName)) @@ -44,6 +55,15 @@ namespace Nz return true; } + /*! + * \brief Applies shader to the material + * \return Constant pointer to the shader + * + * \param shaderFlags Flags for the shader + * \param textureUnit Unit for the texture GL_TEXTURE"i" + * \param lastUsedUnit Optional argument to get the last texture unit + */ + const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const { const ShaderInstance& instance = m_shaders[shaderFlags]; @@ -123,6 +143,13 @@ namespace Nz return instance.shader; } + /*! + * \brief Builds the material from parameters + * + * \param matData Data information for the material + * \param matParams Parameters for the material + */ + void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams) { Color color; @@ -283,6 +310,10 @@ namespace Nz SetShader(matParams.shaderName); } + /*! + * \brief Resets the material, cleans everything + */ + void Material::Reset() { OnMaterialReset(this); @@ -319,9 +350,15 @@ namespace Nz SetShader("Basic"); } + /*! + * \brief Copies the other material + * + * \param material Material to copy into this + */ + void Material::Copy(const Material& material) { - // Copie des états de base + // Copy of base states m_alphaTestEnabled = material.m_alphaTestEnabled; m_alphaThreshold = material.m_alphaThreshold; m_ambientColor = material.m_ambientColor; @@ -337,7 +374,7 @@ namespace Nz m_states = material.m_states; m_transformEnabled = material.m_transformEnabled; - // Copie des références de texture + // Copy of reference to the textures m_alphaMap = material.m_alphaMap; m_depthMaterial = material.m_depthMaterial; m_diffuseMap = material.m_diffuseMap; @@ -347,10 +384,16 @@ namespace Nz m_specularMap = material.m_specularMap; m_uberShader = material.m_uberShader; - // On copie les instances de shader par la même occasion - std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max+1)*sizeof(ShaderInstance)); + // We copy the instances of the shader too + std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max + 1) * sizeof(ShaderInstance)); } + /*! + * \brief Generates the shader based on flag + * + * \param flags Flag for the shaer + */ + void Material::GenerateShader(UInt32 flags) const { ParameterList list; @@ -396,6 +439,13 @@ namespace Nz #undef CacheUniform } + /*! + * \brief Initializes the material librairies + * \return true If successful + * + * \remark Produces a NazaraError if the material library failed to be initialized + */ + bool Material::Initialize() { if (!MaterialLibrary::Initialize()) @@ -462,6 +512,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the material librairies + */ + void Material::Uninitialize() { s_defaultMaterial.Reset(); diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index e8954a886..d382c77d9 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -12,11 +12,26 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Model + * \brief Graphics class that represents a model + */ + + /*! + * \brief Constructs a ModelParameters object by default + */ + ModelParameters::ModelParameters() { material.shaderName = "PhongLighting"; } + /*! + * \brief Checks whether the parameters for the model are correct + * \return true If parameters are valid + */ + bool ModelParameters::IsValid() const { if (loadMaterials && !material.IsValid()) @@ -25,6 +40,10 @@ namespace Nz return mesh.IsValid(); } + /*! + * \brief Constructs a Model object by default + */ + Model::Model() : m_matCount(0), m_skin(0), @@ -32,11 +51,24 @@ namespace Nz { } + /*! + * \brief Destructs the object and calls Reset + * + * \see Reset + */ + Model::~Model() { Reset(); } + /*! + * \brief Adds this model to the render queue + * + * \param renderQueue Queue to be added + * \param instanceData Data used for this instance + */ + void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { unsigned int submeshCount = m_mesh->GetSubMeshCount(); @@ -54,6 +86,17 @@ namespace Nz } } + /*! + * \brief Gets the material of the named submesh + * \return Pointer to the current material + * + * \param subMeshName Name of the subMesh + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no mesh + * \remark Produces a NazaraError if there is no subMesh with that name + * \remark Produces a NazaraError if material is invalid + */ + Material* Model::GetMaterial(const String& subMeshName) const { #if NAZARA_GRAPHICS_SAFE @@ -78,9 +121,18 @@ namespace Nz return nullptr; } - return m_materials[m_skin*m_matCount + matIndex]; + return m_materials[m_skin * m_matCount + matIndex]; } + /*! + * \brief Gets the material by index + * \return Pointer to the current material + * + * \param matIndex Index of the material + * + * \remark Produces a NazaraError if index is invalid + */ + Material* Model::GetMaterial(unsigned int matIndex) const { #if NAZARA_GRAPHICS_SAFE @@ -91,9 +143,21 @@ namespace Nz } #endif - return m_materials[m_skin*m_matCount + matIndex]; + return m_materials[m_skin * m_matCount + matIndex]; } + /*! + * \brief Gets the material by index of the named submesh + * \return Pointer to the current material + * + * \param skinIndex Index of the skin + * \param subMeshName Name of the subMesh + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid + * \remark Produces a NazaraError if there is no subMesh with that name + * \remark Produces a NazaraError if material index is invalid + */ + Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const { #if NAZARA_GRAPHICS_SAFE @@ -118,9 +182,20 @@ namespace Nz return nullptr; } - return m_materials[skinIndex*m_matCount + matIndex]; + return m_materials[skinIndex * m_matCount + matIndex]; } + /*! + * \brief Gets the material by index with skin + * \return Pointer to the current material + * + * \param skinIndex Index of the skin + * \param matIndex Index of the material + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid + */ + Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const { #if NAZARA_GRAPHICS_SAFE @@ -137,49 +212,103 @@ namespace Nz } #endif - return m_materials[skinIndex*m_matCount + matIndex]; + return m_materials[skinIndex * m_matCount + matIndex]; } + /*! + * \brief Gets the number of materials + * \return Current number of materials + */ + unsigned int Model::GetMaterialCount() const { return m_matCount; } + /*! + * \brief Gets the mesh + * \return Current mesh + */ + Mesh* Model::GetMesh() const { return m_mesh; } + /*! + * \brief Gets the skin + * \return Current skin + */ + unsigned int Model::GetSkin() const { return m_skin; } + /*! + * \brief Gets the number of skins + * \return Current number of skins + */ + unsigned int Model::GetSkinCount() const { return m_skinCount; } + /*! + * \brief Checks whether the model is animated + * \return false + */ + bool Model::IsAnimated() const { return false; } + /*! + * \brief Loads the model from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the model + */ + bool Model::LoadFromFile(const String& filePath, const ModelParameters& params) { return ModelLoader::LoadFromFile(this, filePath, params); } + /*! + * \brief Loads the model from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the model + */ + bool Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params) { return ModelLoader::LoadFromMemory(this, data, size, params); } + /*! + * \brief Loads the model from stream + * \return true if loading is successful + * + * \param stream Stream to the model + * \param params Parameters for the model + */ + bool Model::LoadFromStream(Stream& stream, const ModelParameters& params) { return ModelLoader::LoadFromStream(this, stream, params); } + /*! + * \brief Resets the model, cleans everything + */ + void Model::Reset() { m_matCount = 0; @@ -192,6 +321,17 @@ namespace Nz } } + /*! + * \brief Sets the material of the named submesh + * \return true If successful + * + * \param subMeshName Name of the subMesh + * \param material Pointer to the material + * + * \remark Produces a NazaraError if there is no subMesh with that name + * \remark Produces a NazaraError if material index is invalid + */ + bool Model::SetMaterial(const String& subMeshName, Material* material) { SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); @@ -208,7 +348,7 @@ namespace Nz return false; } - unsigned int index = m_skin*m_matCount + matIndex; + unsigned int index = m_skin * m_matCount + matIndex; if (material) m_materials[index] = material; @@ -218,6 +358,16 @@ namespace Nz return true; } + /*! + * \brief Sets the material by index + * \return true If successful + * + * \param matIndex Index of the material + * \param material Pointer to the material + * + * \remark Produces a NazaraError with if NAZARA_GRAPHICS_SAFE defined index is invalid + */ + void Model::SetMaterial(unsigned int matIndex, Material* material) { #if NAZARA_GRAPHICS_SAFE @@ -228,7 +378,7 @@ namespace Nz } #endif - unsigned int index = m_skin*m_matCount + matIndex; + unsigned int index = m_skin * m_matCount + matIndex; if (material) m_materials[index] = material; @@ -236,6 +386,19 @@ namespace Nz m_materials[index] = Material::GetDefault(); } + /*! + * \brief Sets the material by index of the named submesh + * \return true If successful + * + * \param skinIndex Index of the skin + * \param subMeshName Name of the subMesh + * \param material Pointer to the material + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid + * \remark Produces a NazaraError if there is no subMesh with that name + * \remark Produces a NazaraError if material index is invalid + */ + bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material) { #if NAZARA_GRAPHICS_SAFE @@ -260,7 +423,7 @@ namespace Nz return false; } - unsigned int index = skinIndex*m_matCount + matIndex; + unsigned int index = skinIndex * m_matCount + matIndex; if (material) m_materials[index] = material; @@ -270,6 +433,18 @@ namespace Nz return true; } + /*! + * \brief Sets the material by index with skin + * \return true If successful + * + * \param skinIndex Index of the skin + * \param matIndex Index of the material + * \param material Pointer to the material + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skinIndex is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if matIndex is invalid + */ + void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material) { #if NAZARA_GRAPHICS_SAFE @@ -286,7 +461,7 @@ namespace Nz } #endif - unsigned int index = skinIndex*m_matCount + matIndex; + unsigned int index = skinIndex * m_matCount + matIndex; if (material) m_materials[index] = material; @@ -294,6 +469,14 @@ namespace Nz m_materials[index] = Material::GetDefault(); } + /*! + * \brief Sets the mesh + * + * \param pointer to the mesh + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if mesh is invalid + */ + void Model::SetMesh(Mesh* mesh) { #if NAZARA_GRAPHICS_SAFE @@ -323,6 +506,14 @@ namespace Nz InvalidateBoundingVolume(); } + /*! + * \brief Sets the skin + * + * \param skin Skin to use + * + * \remark Produces a NazaraError if skin is invalid + */ + void Model::SetSkin(unsigned int skin) { #if NAZARA_GRAPHICS_SAFE @@ -336,6 +527,14 @@ namespace Nz m_skin = skin; } + /*! + * \brief Sets the number of skins + * + * \param skinCount Number of skins + * + * \remark Produces a NazaraError if skinCount equals zero + */ + void Model::SetSkinCount(unsigned int skinCount) { #if NAZARA_GRAPHICS_SAFE @@ -350,6 +549,10 @@ namespace Nz m_skinCount = skinCount; } + /* + * \brief Makes the bounding volume of this billboard + */ + void Model::MakeBoundingVolume() const { if (m_mesh) diff --git a/src/Nazara/Graphics/ParticleController.cpp b/src/Nazara/Graphics/ParticleController.cpp index 252887246..d46bb1621 100644 --- a/src/Nazara/Graphics/ParticleController.cpp +++ b/src/Nazara/Graphics/ParticleController.cpp @@ -7,17 +7,44 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleController + * \brief Graphics class which controls a flow of particles + * + * \remark This class is abstract + */ + + /*! + * \brief Constructs a ParticleController object by assignation + * + * \param controller ParticleController to copy into this + */ + ParticleController::ParticleController(const ParticleController& controller) : RefCounted() { NazaraUnused(controller); } + /*! + * \brief Destructs the object and calls OnParticleControllerRelease + * + * \see OnParticleControllerRelease + */ + ParticleController::~ParticleController() { OnParticleControllerRelease(this); } + /*! + * \brief Initializes the particle controller librairies + * \return true If successful + * + * \remark Produces a NazaraError if the particle controller library failed to be initialized + */ + bool ParticleController::Initialize() { if (!ParticleControllerLibrary::Initialize()) @@ -29,6 +56,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the particle controller librairies + */ + void ParticleController::Uninitialize() { ParticleControllerLibrary::Uninitialize(); diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index 8d68b88ce..ecd09c752 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -15,23 +15,54 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleDeclaration + * \brief Graphics class that represents the declaration of the particle, works like an ECS + */ + + /*! + * \brief Constructs a ParticleDeclaration object by default + */ + ParticleDeclaration::ParticleDeclaration() : m_stride(0) { } + /*! + * \brief Constructs a ParticleDeclaration object by assignation + * + * \param declaration ParticleDeclaration to copy into this + */ + ParticleDeclaration::ParticleDeclaration(const ParticleDeclaration& declaration) : RefCounted(), m_stride(declaration.m_stride) { - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(ParticleComponent_Max+1)); + std::memcpy(m_components, declaration.m_components, sizeof(Component) * (ParticleComponent_Max + 1)); } + /*! + * \brief Destructs the object and calls OnParticleDeclarationRelease + * + * \see OnParticleDeclarationRelease + */ + ParticleDeclaration::~ParticleDeclaration() { OnParticleDeclarationRelease(this); } + /*! + * \brief Disables a component + * + * \param component Component to disable in the declaration + * + * \remark Produces a NazaraError with NAZARA_DEBUG defined if enumeration is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if enumeration is equal to ParticleComponent_Unused + */ + void ParticleDeclaration::DisableComponent(ParticleComponent component) { #ifdef NAZARA_DEBUG @@ -58,6 +89,17 @@ namespace Nz } } + /*! + * \brief Enables a component + * + * \param component Component to enable in the declaration + * \param type Type of this component + * \param offset Offset in the declaration + * + * \remark Produces a NazaraError with NAZARA_DEBUG defined if enumeration is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if type is not supported + */ + void ParticleDeclaration::EnableComponent(ParticleComponent component, ComponentType type, unsigned int offset) { #ifdef NAZARA_DEBUG @@ -91,6 +133,18 @@ namespace Nz m_stride += Utility::ComponentStride[type]; } + /*! + * \brief Gets a component + * + * \param component Component in the declaration + * \param enabled Optional argument to get if this component is enabled + * \param type Optional argument to get if the type of the component + * \param offset Optional argument to get if the offset in the declaration + * + * \remark Produces a NazaraError with NAZARA_DEBUG defined if enumeration is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if enumeration is equal to ParticleComponent_Unused + */ + void ParticleDeclaration::GetComponent(ParticleComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const { #ifdef NAZARA_DEBUG @@ -121,24 +175,51 @@ namespace Nz *offset = particleComponent.offset; } + /*! + * \brief Gets the stride of the declaration + * \return Stride of the declaration + */ + unsigned int ParticleDeclaration::GetStride() const { return m_stride; } + /*! + * \brief Sets the stride of the declaration + * + * \param stride Stride of the declaration + */ + void ParticleDeclaration::SetStride(unsigned int stride) { m_stride = stride; } + /*! + * \brief Sets the current particle declaration with the content of the other one + * \return A reference to this + * + * \param declaration The other ParticleDeclaration + */ + ParticleDeclaration& ParticleDeclaration::operator=(const ParticleDeclaration& declaration) { - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(ParticleComponent_Max+1)); + std::memcpy(m_components, declaration.m_components, sizeof(Component) * (ParticleComponent_Max + 1)); m_stride = declaration.m_stride; return *this; } + /*! + * \brief Gets the particle declaration based on the layout + * \return Pointer to the declaration + * + * \param layout Layout of the particle declaration + * + * \remark Produces a NazaraError with NAZARA_DEBUG if enumeration is invalid + */ + ParticleDeclaration* ParticleDeclaration::Get(ParticleLayout layout) { #ifdef NAZARA_DEBUG @@ -152,6 +233,15 @@ namespace Nz return &s_declarations[layout]; } + /*! + * \brief Checks whether the type is supported + * \return true If it is the case + * + * \param type Type of the component + * + * \remark Produces a NazaraError if enumeration is invalid + */ + bool ParticleDeclaration::IsTypeSupported(ComponentType type) { switch (type) @@ -177,6 +267,14 @@ namespace Nz return false; } + /*! + * \brief Initializes the particle declaration librairies + * \return true If successful + * + * \remark Produces a NazaraError if the particle declaration library failed to be initialized + * \remark Produces a NazaraAssert if memory layout of declaration does not match the corresponding structure + */ + bool ParticleDeclaration::Initialize() { if (!ParticleDeclarationLibrary::Initialize()) @@ -231,11 +329,15 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the particle declaration librairies + */ + void ParticleDeclaration::Uninitialize() { ParticleDeclarationLibrary::Uninitialize(); } - ParticleDeclaration ParticleDeclaration::s_declarations[ParticleLayout_Max+1]; + ParticleDeclaration ParticleDeclaration::s_declarations[ParticleLayout_Max + 1]; ParticleDeclarationLibrary::LibraryMap ParticleDeclaration::s_library; } diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 9e87eb7c0..ded77d80e 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -14,6 +14,16 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleEmitter + * \brief Graphics class that represents an emitter of particles + */ + + /*! + * \brief Constructs a ParticleEmitter object by default + */ + ParticleEmitter::ParticleEmitter() : m_lagCompensationEnabled(false), m_emissionAccumulator(0.f), @@ -24,28 +34,35 @@ namespace Nz ParticleEmitter::~ParticleEmitter() = default; + /*! + * \brief Emits particles according to the delta time between the previous frame + * + * \param system Particle system to work on + * \param elapsedTime Delta time between the previous frame + */ + void ParticleEmitter::Emit(ParticleSystem& system, float elapsedTime) const { if (m_emissionRate > 0.f) { - // On accumule la partie réelle (pour éviter qu'un taux d'update élevé empêche des particules de se former) - m_emissionAccumulator += elapsedTime*m_emissionRate; + // We accumulate the real part (to avoid that a high emission rate prevents particles to form) + m_emissionAccumulator += elapsedTime * m_emissionRate; - float emissionCount = std::floor(m_emissionAccumulator); // Le nombre d'émissions de cette mise à jour - m_emissionAccumulator -= emissionCount; // On enlève la partie entière + float emissionCount = std::floor(m_emissionAccumulator); // The number of emissions in this update + m_emissionAccumulator -= emissionCount; // We get rid off the integer part if (emissionCount >= 1.f) { - // On calcule le nombre maximum de particules pouvant être émises cette fois-ci + // We compute the maximum number of particles which can be emitted unsigned int emissionCountInt = static_cast(emissionCount); - unsigned int maxParticleCount = emissionCountInt*m_emissionCount; + unsigned int maxParticleCount = emissionCountInt * m_emissionCount; - // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre + // We get the number of particles that we are able to create (depending on the free space) unsigned int particleCount = std::min(maxParticleCount, system.GetMaxParticleCount() - system.GetParticleCount()); if (particleCount == 0) return; - // Et on émet nos particules + // And we emit our particles void* particles = system.GenerateParticles(particleCount); ParticleMapper mapper(particles, system.GetDeclaration()); @@ -53,40 +70,73 @@ namespace Nz if (m_lagCompensationEnabled) { - // On va maintenant appliquer les contrôleurs - float invEmissionRate = 1.f/m_emissionRate; + // We will now apply our controllers + float invEmissionRate = 1.f / m_emissionRate; for (unsigned int i = 1; i <= emissionCountInt; ++i) - system.ApplyControllers(mapper, std::min(m_emissionCount*i, particleCount), invEmissionRate); + system.ApplyControllers(mapper, std::min(m_emissionCount * i, particleCount), invEmissionRate); } } } } + /*! + * \brief Enables the lag compensation + * + * \param enable Should lag compensation be enabled + */ + void ParticleEmitter::EnableLagCompensation(bool enable) { m_lagCompensationEnabled = enable; } + /*! + * \brief Gets the emission count + * \return Current emission count + */ + unsigned int ParticleEmitter::GetEmissionCount() const { return m_emissionCount; } + /*! + * \brief Gets the emission rate + * \return Current emission rate + */ + float ParticleEmitter::GetEmissionRate() const { return m_emissionRate; } + /*! + * \brief Checks whether the lag compensation is enabled + * \return true If it is the case + */ + bool ParticleEmitter::IsLagCompensationEnabled() const { return m_lagCompensationEnabled; } + /*! + * \brief Sets the emission count + * + * \param count Emission count + */ + void ParticleEmitter::SetEmissionCount(unsigned int count) { m_emissionCount = count; } + /*! + * \brief Sets the emission rate + * + * \param rate Emission rate + */ + void ParticleEmitter::SetEmissionRate(float rate) { m_emissionRate = rate; diff --git a/src/Nazara/Graphics/ParticleGenerator.cpp b/src/Nazara/Graphics/ParticleGenerator.cpp index d5e3b80ff..304a99e8c 100644 --- a/src/Nazara/Graphics/ParticleGenerator.cpp +++ b/src/Nazara/Graphics/ParticleGenerator.cpp @@ -7,17 +7,44 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleGenerator + * \brief Graphics class which generates particles + * + * \remark This class is abstract + */ + + /*! + * \brief Constructs a ParticleGenerator object by assignation + * + * \param generator ParticleGenerator to copy into this + */ + ParticleGenerator::ParticleGenerator(const ParticleGenerator& generator) : RefCounted() { NazaraUnused(generator); } + /*! + * \brief Destructs the object and calls OnParticleGeneratorRelease + * + * \see OnParticleGeneratorRelease + */ + ParticleGenerator::~ParticleGenerator() { OnParticleGeneratorRelease(this); } + /*! + * \brief Initializes the particle generator librairies + * \return true If successful + * + * \remark Produces a NazaraError if the particle generator library failed to be initialized + */ + bool ParticleGenerator::Initialize() { if (!ParticleGeneratorLibrary::Initialize()) @@ -29,6 +56,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the particle generator librairies + */ + void ParticleGenerator::Uninitialize() { ParticleGeneratorLibrary::Uninitialize(); diff --git a/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp index ce883e6e0..27a4b4075 100644 --- a/src/Nazara/Graphics/ParticleMapper.cpp +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -8,6 +8,19 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleMapper + * \brief Graphics class that represents the mapping between the internal buffer and the particle declaration + */ + + /*! + * \brief Constructs a ParticleMapper object with a raw buffer and a particle declaration + * + * \param buffer Raw buffer to store particles data + * \param declaration Declaration of the particle + */ + ParticleMapper::ParticleMapper(void* buffer, const ParticleDeclaration* declaration) : m_declaration(declaration), m_ptr(static_cast(buffer)) diff --git a/src/Nazara/Graphics/ParticleRenderer.cpp b/src/Nazara/Graphics/ParticleRenderer.cpp index 96ff3dd8a..e5fa56c74 100644 --- a/src/Nazara/Graphics/ParticleRenderer.cpp +++ b/src/Nazara/Graphics/ParticleRenderer.cpp @@ -7,17 +7,42 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleRenderer + * \brief Graphics class that represents the rendering of the particle + */ + + /*! + * \brief Constructs a ParticleRenderer object by assignation + * + * \param renderer ParticleRenderer to copy into this + */ + ParticleRenderer::ParticleRenderer(const ParticleRenderer& renderer) : RefCounted() { NazaraUnused(renderer); } + /*! + * \brief Destructs the object and calls OnParticleRendererRelease + * + * \see OnParticleRendererRelease + */ + ParticleRenderer::~ParticleRenderer() { OnParticleRendererRelease(this); } + /*! + * \brief Initializes the particle renderer librairies + * \return true If successful + * + * \remark Produces a NazaraError if the particle renderer library failed to be initialized + */ + bool ParticleRenderer::Initialize() { if (!ParticleRendererLibrary::Initialize()) @@ -29,6 +54,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the particle renderer librairies + */ + void ParticleRenderer::Uninitialize() { ParticleRendererLibrary::Uninitialize(); diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 2ac54e4af..0783dd7fd 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -13,25 +13,51 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::ParticleSystem + * \brief Graphics class that represents the system to handle particles + */ + + /*! + * \brief Constructs a ParticleSystem object with a maximal number of particles and a layout + * + * \param maxParticleCount Maximum number of particles to generate + * \param layout Enumeration for the layout of data information for the particles + */ + ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleLayout layout) : ParticleSystem(maxParticleCount, ParticleDeclaration::Get(layout)) { } + /*! + * \brief Constructs a ParticleSystem object with a maximal number of particles and a particle declaration + * + * \param maxParticleCount Maximum number of particles to generate + * \param declaration Data information for the particles + */ + ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration) : m_declaration(std::move(declaration)), m_processing(false), m_maxParticleCount(maxParticleCount), m_particleCount(0) { - // En cas d'erreur, un constructeur ne peut que lancer une exception + // In case of error, the constructor can only throw an exception ErrorFlags flags(ErrorFlag_ThrowException, true); - m_particleSize = m_declaration->GetStride(); // La taille de chaque particule + m_particleSize = m_declaration->GetStride(); // The size of each particle ResizeBuffer(); } + /*! + * \brief Constructs a ParticleSystem object by assignation + * + * \param system ParticleSystem to copy into this + */ + ParticleSystem::ParticleSystem(const ParticleSystem& system) : Renderable(system), m_controllers(system.m_controllers), @@ -47,12 +73,20 @@ namespace Nz ResizeBuffer(); - // On ne copie que les particules vivantes + // We only copy alive particles std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); } ParticleSystem::~ParticleSystem() = default; + /*! + * \brief Adds a controller to the particles + * + * \param controller Controller for the particles + * + * \remark Produces a NazaraAssert if controller is invalid + */ + void ParticleSystem::AddController(ParticleControllerRef controller) { NazaraAssert(controller, "Invalid particle controller"); @@ -60,6 +94,14 @@ namespace Nz m_controllers.emplace_back(std::move(controller)); } + /*! + * \brief Adds an emitter to the particles + * + * \param emitter Emitter for the particles + * + * \remark Produces a NazaraAssert if emitter is invalid + */ + void ParticleSystem::AddEmitter(ParticleEmitter* emitter) { NazaraAssert(emitter, "Invalid particle emitter"); @@ -67,6 +109,14 @@ namespace Nz m_emitters.emplace_back(emitter); } + /*! + * \brief Adds a generator to the particles + * + * \param generator Generator for the particles + * + * \remark Produces a NazaraAssert if generator is invalid + */ + void ParticleSystem::AddGenerator(ParticleGeneratorRef generator) { NazaraAssert(generator, "Invalid particle generator"); @@ -74,6 +124,16 @@ namespace Nz m_generators.emplace_back(std::move(generator)); } + /*! + * \brief Adds the particle system to the rendering queue + * + * \param renderQueue Queue to be added + * \param transformMatrix Transformation matrix for the system + * + * \remark Produces a NazaraAssert if inner renderer is invalid + * \remark Produces a NazaraAssert if renderQueue is invalid + */ + void ParticleSystem::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const { NazaraAssert(m_renderer, "Invalid particle renderer"); @@ -83,45 +143,63 @@ namespace Nz if (m_particleCount > 0) { ParticleMapper mapper(m_buffer.data(), m_declaration); - m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); + m_renderer->Render(*this, mapper, 0, m_particleCount - 1, renderQueue); } } + /*! + * \brief Applies the controllers + * + * \param mapper Mapper containing layout information of each particle + * \param particleCount Number of particles + * \param elapsedTime Delta time between the previous frame + */ + void ParticleSystem::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) { m_processing = true; - // Pour éviter un verrouillage en cas d'exception + // To avoid a lock in case of exception CallOnExit onExit([this]() { m_processing = false; }); for (ParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, particleCount-1, elapsedTime); + controller->Apply(*this, mapper, 0, particleCount - 1, elapsedTime); onExit.CallAndReset(); - // On tue maintenant les particules mortes durant la mise à jour + // We only kill now the dead particles during the update if (m_dyingParticles.size() < m_particleCount) { - // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater - // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, - // sans cette solution certaines particules pourraient échapper à la mort + // We kill them in reverse order, std::set sorting them via std::greater + // The reason is simple, as the death of a particle means the move of the last particle in the buffer, + // without this solution, certain particles could avoid the death for (unsigned int index : m_dyingParticles) KillParticle(index); } else - KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide + KillParticles(); // Every particles are dead, this is way faster m_dyingParticles.clear(); } + /*! + * \brief Creates one particle + * \return Pointer to the particle memory buffer + */ + void* ParticleSystem::CreateParticle() { return CreateParticles(1); } + /*! + * \brief Creates multiple particles + * \return Pointer to the first particle memory buffer + */ + void* ParticleSystem::CreateParticles(unsigned int count) { if (count == 0) @@ -133,14 +211,24 @@ namespace Nz unsigned int particlesIndex = m_particleCount; m_particleCount += count; - return &m_buffer[particlesIndex*m_particleSize]; + return &m_buffer[particlesIndex * m_particleSize]; } + /*! + * \brief Generates one particle + * \return Pointer to the particle memory buffer + */ + void* ParticleSystem::GenerateParticle() { return GenerateParticles(1); } + /*! + * \brief Generates multiple particles + * \return Pointer to the first particle memory buffer + */ + void* ParticleSystem::GenerateParticles(unsigned int count) { void* ptr = CreateParticles(count); @@ -149,57 +237,108 @@ namespace Nz ParticleMapper mapper(ptr, m_declaration); for (ParticleGenerator* generator : m_generators) - generator->Generate(*this, mapper, 0, count-1); + generator->Generate(*this, mapper, 0, count - 1); return ptr; } + /*! + * \brief Gets the particle declaration + * \return Particle declaration + */ + const ParticleDeclarationConstRef& ParticleSystem::GetDeclaration() const { return m_declaration; } + /*! + * \brief Gets the fixed step size + * \return Current fixed step size + */ + float ParticleSystem::GetFixedStepSize() const { return m_stepSize; } + /*! + * \brief Gets the maximum number of particles + * \return Current maximum number + */ + unsigned int ParticleSystem::GetMaxParticleCount() const { return m_maxParticleCount; } + /*! + * \brief Gets the number of particles + * \return Current number + */ + unsigned int ParticleSystem::GetParticleCount() const { return m_particleCount; } + /*! + * \brief Gets the size of particles + * \return Current size + */ + unsigned int ParticleSystem::GetParticleSize() const { return m_particleSize; } + /*! + * \brief Checks whether the fixed step is enabled + * \return true If it is the case + */ + + bool ParticleSystem::IsFixedStepEnabled() const + { + return m_fixedStepEnabled; + } + + /*! + * \brief Kills one particle + * + * \param index Index of the particle + */ + void ParticleSystem::KillParticle(unsigned int index) { - ///FIXME: Vérifier index + ///FIXME: Verify the index if (m_processing) { - // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste d'attente + // The buffer is being modified, we can not reduce its size, we put the particle in the waiting list m_dyingParticles.insert(index); return; } - // On déplace la dernière particule vivante à la place de celle-ci + // We move the last alive particle to the place of this one if (--m_particleCount > 0) - std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); + std::memcpy(&m_buffer[index * m_particleSize], &m_buffer[m_particleCount * m_particleSize], m_particleSize); } + /*! + * \brief Kills every particles + */ + void ParticleSystem::KillParticles() { m_particleCount = 0; } + /*! + * \brief Removes a controller to the particles + * + * \param controller Controller for the particles to remove + */ + void ParticleSystem::RemoveController(ParticleController* controller) { auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); @@ -207,6 +346,12 @@ namespace Nz m_controllers.erase(it); } + /*! + * \brief Removes an emitter to the particles + * + * \param emitter Emitter for the particles to remove + */ + void ParticleSystem::RemoveEmitter(ParticleEmitter* emitter) { auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); @@ -214,6 +359,12 @@ namespace Nz m_emitters.erase(it); } + /*! + * \brief Removes a generator to the particles + * + * \param generator Generator for the particles to remove + */ + void ParticleSystem::RemoveGenerator(ParticleGenerator* generator) { auto it = std::find(m_generators.begin(), m_generators.end(), generator); @@ -221,31 +372,55 @@ namespace Nz m_generators.erase(it); } + /*! + * \brief Sets the fixed step size + * + * \param stepSize Fixed step size + */ + void ParticleSystem::SetFixedStepSize(float stepSize) { m_stepSize = stepSize; } + /*! + * \brief Sets the renderer of the particles + * + * \param renderer Renderer for the particles + */ + void ParticleSystem::SetRenderer(ParticleRenderer* renderer) { m_renderer = renderer; } + /*! + * \brief Updates the system + * + * \param elapsedTime Delta time between the previous frame + */ + void ParticleSystem::Update(float elapsedTime) { - // Émission + // Emission for (ParticleEmitter* emitter : m_emitters) emitter->Emit(*this, elapsedTime); - // Mise à jour + // Update if (m_particleCount > 0) { - ///TODO: Mettre à jour en utilisant des threads + ///TODO: Update using threads ParticleMapper mapper(m_buffer.data(), m_declaration); ApplyControllers(mapper, m_particleCount, elapsedTime); } } + /*! + * \brief Updates the bounding volume by a matrix + * + * \param transformMatrix Matrix transformation for our bounding volume + */ + void ParticleSystem::UpdateBoundingVolume(const Matrix4f& transformMatrix) { NazaraUnused(transformMatrix); @@ -253,6 +428,13 @@ namespace Nz // Nothing to do here (our bounding volume is global) } + /*! + * \brief Sets the current particle system with the content of the other one + * \return A reference to this + * + * \param system The other ParticleSystem + */ + ParticleSystem& ParticleSystem::operator=(const ParticleSystem& system) { ErrorFlags flags(ErrorFlag_ThrowException, true); @@ -268,29 +450,39 @@ namespace Nz m_renderer = system.m_renderer; m_stepSize = system.m_stepSize; - // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier + // The copy can not (or should not) happen during the update, there is no use to copy m_dyingParticles.clear(); m_processing = false; m_stepAccumulator = 0.f; - m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose + m_buffer.clear(); // To avoid a copy due to resize() which will be pointless ResizeBuffer(); - // On ne copie que les particules vivantes - std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); + // We only copy alive particles + std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount * m_particleSize); return *this; } + /*! + * \brief Makes the bounding volume of this text + */ + void ParticleSystem::MakeBoundingVolume() const { - ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) + ///TODO: Compute the AABB (taking into account the size of particles) m_boundingVolume.MakeInfinite(); } + /*! + * \brief Resizes the internal buffer + * + * \remark Produces a NazaraError if resize did not work + */ + void ParticleSystem::ResizeBuffer() { - // Histoire de décrire un peu mieux l'erreur en cas d'échec + // Just to have a better description of our problem in case of error try { m_buffer.resize(m_maxParticleCount*m_particleSize); diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index df3eb5582..46d84d9c4 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -23,7 +23,7 @@ namespace Nz "User" }; - static_assert(sizeof(techniquesName)/sizeof(const char*) == RenderTechniqueType_Max+1, "Render technique type name array is incomplete"); + static_assert(sizeof(techniquesName) / sizeof(const char*) == RenderTechniqueType_Max + 1, "Render technique type name array is incomplete"); struct RenderTechnique { @@ -34,6 +34,22 @@ namespace Nz std::unordered_map s_renderTechniques; } + /*! + * \ingroup graphics + * \class Nz::RenderTechniques + * \brief Graphics class that represents the techniques used in rendering + */ + + /*! + * \brief Gets the technique by enumeration + * \return A reference to the newly created technique + * + * \param renderTechnique Enumeration of the technique + * \param techniqueRanking Ranking for the technique + * + * \remark Produces a NazaraError if renderTechnique does not exist + */ + AbstractRenderTechnique* RenderTechniques::GetByEnum(RenderTechniqueType renderTechnique, int* techniqueRanking) { #ifdef NAZARA_DEBUG @@ -47,6 +63,16 @@ namespace Nz return GetByName(techniquesName[renderTechnique], techniqueRanking); } + /*! + * \brief Gets the technique by index + * \return A reference to the newly created technique + * + * \param index Index of the technique + * \param techniqueRanking Ranking for the technique + * + * \remark Produces a NazaraError if index is out or range + */ + AbstractRenderTechnique* RenderTechniques::GetByIndex(unsigned int index, int* techniqueRanking) { #if NAZARA_GRAPHICS_SAFE @@ -66,6 +92,16 @@ namespace Nz return it->second.factory(); } + /*! + * \brief Gets the technique by name + * \return A reference to the newly created technique + * + * \param name Name of the technique + * \param techniqueRanking Ranking for the technique + * + * \remark Produces a NazaraError if name does not exist or is invalid + */ + AbstractRenderTechnique* RenderTechniques::GetByName(const String& name, int* techniqueRanking) { #if NAZARA_GRAPHICS_SAFE @@ -89,6 +125,16 @@ namespace Nz return it->second.factory(); } + /*! + * \brief Gets the technique by ranking + * \return A reference to the newly created technique + * + * \param maxRanking Ranking maximum of the technique + * \param techniqueRanking Ranking for the technique + * + * \remark Produces a NazaraError if name does not exist or is invalid + */ + AbstractRenderTechnique* RenderTechniques::GetByRanking(int maxRanking, int* techniqueRanking) { if (maxRanking < 0) @@ -119,11 +165,28 @@ namespace Nz return technique->factory(); } + /*! + * \brief Gets the number of techniques available + * \return Number of techniques + */ + unsigned int RenderTechniques::GetCount() { return s_renderTechniques.size(); } + /*! + * \brief Registers a technique + * + * \param name Name of the technique + * \param ranking Ranking of the technique + * \param factory Factory to create the technique + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if name is empty + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if ranking is negative + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if factory is invalid is invalid + */ + void RenderTechniques::Register(const String& name, int ranking, RenderTechniqueFactory factory) { #if NAZARA_GRAPHICS_SAFE @@ -149,6 +212,15 @@ namespace Nz s_renderTechniques[name] = {factory, ranking}; } + /*! + * \brief Converts the enumeration to string + * \return String symbolizing the technique + * + * \param renderTechnique Enumeration of the technique + * + * \remark Produces a NazaraError if renderTechnique does not exist and returns "Error" + */ + String RenderTechniques::ToString(RenderTechniqueType renderTechnique) { #ifdef NAZARA_DEBUG @@ -162,6 +234,12 @@ namespace Nz return techniquesName[renderTechnique]; } + /*! + * \brief Unregisters a technique + * + * \param name Name of the technique + */ + void RenderTechniques::Unregister(const String& name) { s_renderTechniques.erase(name); diff --git a/src/Nazara/Graphics/Renderable.cpp b/src/Nazara/Graphics/Renderable.cpp index 932a8d127..5b02cd5cb 100644 --- a/src/Nazara/Graphics/Renderable.cpp +++ b/src/Nazara/Graphics/Renderable.cpp @@ -7,8 +7,24 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Renderable + * \brief Graphics class that represents a renderable element for our scene + * + * \remark This class is abstract + */ + Renderable::~Renderable() = default; + /*! + * \brief Culls the model if not in the frustum + * \return true If renderable is in the frustum + * + * \param frustum Symbolizing the field of view + * \param transformMatrix Matrix transformation for our object + */ + bool Renderable::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const { NazaraUnused(transformMatrix); @@ -16,6 +32,11 @@ namespace Nz return frustum.Contains(m_boundingVolume); } + /*! + * \brief Gets the bounding volume + * \return Bounding volume of the renderable element + */ + const BoundingVolumef& Renderable::GetBoundingVolume() const { EnsureBoundingVolumeUpdated(); @@ -23,6 +44,12 @@ namespace Nz return m_boundingVolume; } + /*! + * \brief Updates the bounding volume by a matrix + * + * \param transformMatrix Matrix transformation for our bounding volume + */ + void Renderable::UpdateBoundingVolume(const Matrix4f& transformMatrix) { m_boundingVolume.Update(transformMatrix); diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 12bf10b6d..b91ac0076 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -14,6 +14,17 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::SkeletalModel + * \brief Graphics class that represents a model with a skeleton + */ + + /*! + * \brief Checks whether the parameters for the skeletal mesh are correct + * \return true If parameters are valid + */ + bool SkeletalModelParameters::IsValid() const { if (!ModelParameters::IsValid()) @@ -25,12 +36,23 @@ namespace Nz return true; } + /*! + * \brief Constructs a SkeletalModel object by default + */ + SkeletalModel::SkeletalModel() : m_currentSequence(nullptr), m_animationEnabled(true) { } + /*! + * \brief Adds the skeletal mesh to the rendering queue + * + * \param renderQueue Queue to be added + * \param instanceData Data for the instance + */ + void SkeletalModel::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { if (!m_mesh) @@ -51,6 +73,14 @@ namespace Nz } } + /*! + * \brief Updates the animation of the mesh + * + * \param elapsedTime Delta time between two frames + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if there is no animation + */ + void SkeletalModel::AdvanceAnimation(float elapsedTime) { #if NAZARA_GRAPHICS_SAFE @@ -67,7 +97,7 @@ namespace Nz m_interpolation -= 1.f; unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; - if (m_nextFrame+1 > lastFrame) + if (m_nextFrame + 1 > lastFrame) { if (m_animation->IsLoopPointInterpolationEnabled()) { @@ -77,7 +107,7 @@ namespace Nz else { m_currentFrame = m_currentSequence->firstFrame; - m_nextFrame = m_currentFrame+1; + m_nextFrame = m_currentFrame + 1; } } else @@ -92,26 +122,52 @@ namespace Nz InvalidateBoundingVolume(); } + /*! + * \brief Clones this skeletal model + * \return Pointer to newly allocated SkeletalModel + */ + SkeletalModel* SkeletalModel::Clone() const { return new SkeletalModel(*this); } + /*! + * \brief Creates a default skeletal model + * \return Pointer to newly allocated SkeletalModel + */ + SkeletalModel* SkeletalModel::Create() const { return new SkeletalModel; } + /*! + * \brief Enables the animation of the model + * + * \param animation Should the model be animated + */ + void SkeletalModel::EnableAnimation(bool animation) { m_animationEnabled = animation; } + /*! + * \brief Gets the animation of the model + * \return Pointer to the animation + */ + Animation* SkeletalModel::GetAnimation() const { return m_animation; } + /*! + * \brief Gets the skeleton of the model + * \return Pointer to the skeleton + */ + Skeleton* SkeletalModel::GetSkeleton() { InvalidateBoundingVolume(); @@ -119,41 +175,96 @@ namespace Nz return &m_skeleton; } + /*! + * \brief Gets the skeleton of the model + * \return Constant pointer to the skeleton + */ + const Skeleton* SkeletalModel::GetSkeleton() const { return &m_skeleton; } + /*! + * \brief Checks whether the skeleton has an animation + * \return true If it is the case + * + * \see IsAnimated, IsAnimationEnabled + */ + bool SkeletalModel::HasAnimation() const { return m_animation != nullptr; } + /*! + * \brief Checks whether the skeleton is animated + * \return true + * + * \see HasAnimation, IsAnimationEnabled + */ + bool SkeletalModel::IsAnimated() const { return true; } + /*! + * \brief Checks whether the skeleton is currently animated + * \return true If it is the case + * + * \see HasAnimation, IsAnimated + */ + bool SkeletalModel::IsAnimationEnabled() const { return m_animationEnabled; } + /*! + * \brief Loads the skeleton model from file + * \return true if loading is successful + * + * \param filePath Path to the file + * \param params Parameters for the skeleton model + */ + bool SkeletalModel::LoadFromFile(const String& filePath, const SkeletalModelParameters& params) { return SkeletalModelLoader::LoadFromFile(this, filePath, params); } + /*! + * \brief Loads the skeleton model from memory + * \return true if loading is successful + * + * \param data Raw memory + * \param size Size of the memory + * \param params Parameters for the skeleton model + */ + bool SkeletalModel::LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params) { return SkeletalModelLoader::LoadFromMemory(this, data, size, params); } + /*! + * \brief Loads the skeleton model from stream + * \return true if loading is successful + * + * \param stream Stream to the skeleton model + * \param params Parameters for the skeleton model + */ + bool SkeletalModel::LoadFromStream(Stream& stream, const SkeletalModelParameters& params) { return SkeletalModelLoader::LoadFromStream(this, stream, params); } + /*! + * \brief Resets the model + */ + void SkeletalModel::Reset() { Model::Reset(); @@ -161,6 +272,16 @@ namespace Nz m_skeleton.Destroy(); } + /*! + * \brief Sets the animation for the model + * \return true If successful + * + * \param animation Animation for the model + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no mesh + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if animation is invalid + */ + bool SkeletalModel::SetAnimation(Animation* animation) { #if NAZARA_GRAPHICS_SAFE @@ -204,6 +325,14 @@ namespace Nz return true; } + /*! + * \brief Sets the mesh for the model + * + * \param mesh Mesh for the model + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no mesh or if invalid + */ + void SkeletalModel::SetMesh(Mesh* mesh) { #if NAZARA_GRAPHICS_SAFE @@ -224,13 +353,23 @@ namespace Nz SetAnimation(nullptr); } - m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template + m_skeleton = *m_mesh->GetSkeleton(); // Copy of skeleton template } } + /*! + * \brief Sets the sequence for the model + * \return true If successful + * + * \param sequenceName Name for the sequence animation + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no animation + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if sequence name does not exist for the current animation + */ + bool SkeletalModel::SetSequence(const String& sequenceName) { - ///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log) + ///TODO: Make this error "safe" with the new system of error handling (No-log) #if NAZARA_GRAPHICS_SAFE if (!m_animation) { @@ -240,11 +379,13 @@ namespace Nz #endif const Sequence* currentSequence = m_animation->GetSequence(sequenceName); + #if NAZARA_GRAPHICS_SAFE if (!currentSequence) { NazaraError("Sequence not found"); return false; } + #endif m_currentSequence = currentSequence; m_nextFrame = m_currentSequence->firstFrame; @@ -252,6 +393,15 @@ namespace Nz return true; } + /*! + * \brief Sets the sequence for the model + * + * \param sequenceIndex Index for the sequence animation + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if there is no animation + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE if sequence name does not exist for the current animation + */ + void SkeletalModel::SetSequence(unsigned int sequenceIndex) { #if NAZARA_GRAPHICS_SAFE @@ -275,13 +425,22 @@ namespace Nz m_nextFrame = m_currentSequence->firstFrame; } + /* + * \brief Makes the bounding volume of this text + */ + void SkeletalModel::MakeBoundingVolume() const { m_boundingVolume.Set(m_skeleton.GetAABB()); } + /*! + * \brief Updates the model + */ + void SkeletalModel::Update() { + ///TODO /*if (m_animationEnabled && m_animation) AdvanceAnimation(m_scene->GetUpdateTime());*/ } diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 0f4b3140a..7391eeea6 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -46,6 +46,13 @@ namespace Nz SkeletonMap s_cache; std::vector s_skinningQueue; + /*! + * \brief Skins the mesh for a single thread context + * + * \param mesh Skeletal mesh to get vertex buffer from + * \param skeleton Skeleton to consider for getting data + * \param buffer Vertex buffer symbolizing the transition + */ void Skin_MonoCPU(const SkeletalMesh* mesh, const Skeleton* skeleton, VertexBuffer* buffer) { @@ -60,6 +67,14 @@ namespace Nz SkinPositionNormalTangent(skinningData, 0, mesh->GetVertexCount()); } + /*! + * \brief Skins the mesh for a multi-threaded context + * + * \param mesh Skeletal mesh to get vertex buffer from + * \param skeleton Skeleton to consider for getting data + * \param buffer Vertex buffer symbolizing the transition + */ + void Skin_MultiCPU(const SkeletalMesh* mesh, const Skeleton* skeleton, VertexBuffer* buffer) { BufferMapper inputMapper(mesh->GetVertexBuffer(), BufferAccess_ReadOnly); @@ -70,8 +85,8 @@ namespace Nz skinningData.outputVertex = static_cast(outputMapper.GetPointer()); skinningData.joints = skeleton->GetJoints(); - // Afin d'empêcher les différents threads de vouloir mettre à jour la même matrice en même temps, - // on se charge de la mettre à jour avant de les lancer + // To avoid different threads to update the same matrix at the same time + // We try to update them before launching the tasks unsigned int jointCount = skeleton->GetJointCount(); for (unsigned int i = 0; i < jointCount; ++i) skinningData.joints[i].EnsureSkinningMatrixUpdate(); @@ -87,6 +102,23 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::SkinningManager + * \brief Graphics class that represents the management of skinning + */ + + /*! + * \brief Gets the vertex buffer from a skeletal mesh with its skeleton + * \return A pointer to the vertex buffer newly created + * + * \param mesh Skeletal mesh to get vertex buffer from + * \param skeleton Skeleton to consider for getting data + * + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if mesh is invalid + * \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if skeleton is invalid + */ + VertexBuffer* SkinningManager::GetBuffer(const SkeletalMesh* mesh, const Skeleton* skeleton) { #if NAZARA_GRAPHICS_SAFE @@ -149,6 +181,10 @@ namespace Nz return buffer; } + /*! + * \brief Skins the skeletal mesh + */ + void SkinningManager::Skin() { for (QueueData& data : s_skinningQueue) @@ -157,6 +193,11 @@ namespace Nz s_skinningQueue.clear(); } + /*! + * \brief Initializes the skinning librairies + * \return true + */ + bool SkinningManager::Initialize() { ///TODO: GPU Skinning @@ -165,9 +206,15 @@ namespace Nz else s_skinFunc = Skin_MonoCPU; - return true; // Rien de particulier à faire + return true; // Nothing particular to do } + /*! + * \brief Handle the destruction of a skeletal mesh + * + * \param mesh SkeletalMesh being destroyed + */ + void SkinningManager::OnSkeletalMeshDestroy(const SkeletalMesh* mesh) { for (auto& pair : s_cache) @@ -177,17 +224,33 @@ namespace Nz } } + /*! + * \brief Handle the invalidation of a skeletal mesh + * + * \param mesh SkeletalMesh being invalidated + */ + void SkinningManager::OnSkeletonInvalidated(const Skeleton* skeleton) { for (auto& pair : s_cache.at(skeleton).meshMap) pair.second.updated = false; } + /*! + * \brief Handle the release of a skeletal mesh + * + * \param skeleton SkeletalMesh being released + */ + void SkinningManager::OnSkeletonRelease(const Skeleton* skeleton) { s_cache.erase(skeleton); } + /*! + * \brief Uninitializes the skinning librairies + */ + void SkinningManager::Uninitialize() { s_cache.clear(); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index a70a9dd2d..75bc0cc12 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -22,6 +22,18 @@ namespace Nz static VertexBufferRef s_vertexBuffer; } + /*! + * \ingroup graphics + * \class Nz::SkyboxBackground + * \brief Graphics class that represents a background with a cubemap texture + */ + + /*! + * \brief Constructs a SkyboxBackground object with a cubemap texture + * + * \param cubemapTexture Cubemap texture + */ + SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture) : m_movementOffset(Vector3f::Zero()), m_movementScale(0.f) @@ -31,6 +43,12 @@ namespace Nz SetTexture(std::move(cubemapTexture)); } + /*! + * \brief Draws this relatively to the viewer + * + * \param viewer Viewer for the background + */ + void SkyboxBackground::Draw(const AbstractViewer* viewer) const { Matrix4f skyboxMatrix(viewer->GetViewMatrix()); @@ -65,14 +83,26 @@ namespace Nz Renderer::SetMatrix(MatrixType_View, viewer->GetViewMatrix()); } + /*! + * \brief Gets the background type + * \return Type of background + */ + BackgroundType SkyboxBackground::GetBackgroundType() const { return BackgroundType_Skybox; } + /*! + * \brief Initializes the skybox + * \return true If successful + * + * \remark Produces a NazaraError if initialization failed + */ + bool SkyboxBackground::Initialize() { - const UInt16 indices[6*6] = + const UInt16 indices[6 * 6] = { 0, 1, 2, 0, 2, 3, 3, 2, 6, 3, 6, 7, @@ -170,6 +200,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the skybox + */ + void SkyboxBackground::Uninitialize() { s_indexBuffer.Reset(); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index fd4ab758f..76bf5fff2 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -11,6 +11,19 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::Sprite + * \brief Graphics class that represents the rendering of a sprite + */ + + /*! + * \brief Adds the sprite to the rendering queue + * + * \param renderQueue Queue to be added + * \param instanceData Data for the instance + */ + void Sprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { if (!m_material) @@ -20,11 +33,21 @@ namespace Nz renderQueue->AddSprites(instanceData.renderOrder, m_material, vertices, 1); } + /*! + * \brief Makes the bounding volume of this text + */ + void Sprite::MakeBoundingVolume() const { m_boundingVolume.Set(Vector3f(0.f), m_size.x*Vector3f::Right() + m_size.y*Vector3f::Down()); } + /*! + * \brief Updates the data of the sprite + * + * \param instanceData Data of the instance + */ + void Sprite::UpdateData(InstanceData* instanceData) const { instanceData->data.resize(4 * sizeof(VertexStruct_XYZ_Color_UV)); @@ -51,6 +74,13 @@ namespace Nz *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightBottom); } + /*! + * \brief Initializes the sprite librairies + * \return true If successful + * + * \remark Produces a NazaraError if the sprite library failed to be initialized + */ + bool Sprite::Initialize() { if (!SpriteLibrary::Initialize()) @@ -62,6 +92,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the sprite librairies + */ + void Sprite::Uninitialize() { SpriteLibrary::Uninitialize(); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 6d0e41f52..3459b22cd 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -13,6 +13,19 @@ namespace Nz { + /*! + * \ingroup graphics + * \class Nz::TextSprite + * \brief Graphics class that represents the rendering of a sprite containing text + */ + + /*! + * \brief Adds the text to the rendering queue + * + * \param renderQueue Queue to be added + * \param instanceData Data for the instance + */ + void TextSprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { if (!m_material) @@ -26,11 +39,19 @@ namespace Nz if (indices.count > 0) { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first*4], indices.count, overlay); + renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first * 4], indices.count, overlay); } } } + /*! + * \brief Updates the text + * + * \param drawer Drawer used to compose the text + * + * \remark Produces a NazaraAssert if atlas does not use a hardware storage + */ + void TextSprite::Update(const AbstractTextDrawer& drawer) { CallOnExit clearOnFail([this]() @@ -138,8 +159,8 @@ namespace Nz // First, compute the uv coordinates from our atlas rect Vector2ui size(texture->GetSize()); - float invWidth = 1.f/size.x; - float invHeight = 1.f/size.y; + float invWidth = 1.f / size.x; + float invHeight = 1.f / size.y; Rectf uvRect(glyph.atlasRect); uvRect.x *= invWidth; @@ -155,9 +176,9 @@ namespace Nz for (unsigned int j = 0; j < 4; ++j) { // Remember that indices->count is a counter here, not a count value - m_localVertices[indices->count*4 + j].color = glyph.color; - m_localVertices[indices->count*4 + j].position.Set(glyph.corners[j]); - m_localVertices[indices->count*4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j])); + m_localVertices[indices->count * 4 + j].color = glyph.color; + m_localVertices[indices->count * 4 + j].position.Set(glyph.corners[j]); + m_localVertices[indices->count * 4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j])); } // Increment the counter, go to next glyph @@ -172,15 +193,25 @@ namespace Nz clearOnFail.Reset(); } + /* + * \brief Makes the bounding volume of this text + */ + void TextSprite::MakeBoundingVolume() const { Rectf bounds(m_localBounds); Vector2f max = bounds.GetMaximum(); Vector2f min = bounds.GetMinimum(); - m_boundingVolume.Set(min.x*Vector3f::Right() + min.y*Vector3f::Down(), max.x*Vector3f::Right() + max.y*Vector3f::Down()); + m_boundingVolume.Set(min.x * Vector3f::Right() + min.y * Vector3f::Down(), max.x * Vector3f::Right() + max.y * Vector3f::Down()); } + /*! + * \brief Handle the invalidation of an atlas + * + * \param atlas Atlas being invalidated + */ + void TextSprite::OnAtlasInvalidated(const AbstractAtlas* atlas) { #ifdef NAZARA_DEBUG @@ -195,6 +226,14 @@ namespace Nz Clear(); } + /*! + * \brief Handle the invalidation of an atlas layer + * + * \param atlas Atlas being invalidated + * \param oldLayer Pointer to the previous layer + * \param newLayer Pointer to the new layer + */ + void TextSprite::OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer) { NazaraUnused(atlas); @@ -207,23 +246,23 @@ namespace Nz } #endif - // La texture d'un atlas vient d'être recréée (changement de taille) - // nous devons ajuster les coordonnées de textures et la texture du rendu + // The texture of an atlas have just been recreated (size change) + // we have to adjust the coordinates of the texture and the rendering texture Texture* oldTexture = static_cast(oldLayer); Texture* newTexture = static_cast(newLayer); - // Il est possible que nous n'utilisions pas la texture en question (l'atlas nous prévenant pour chacun de ses layers) + // It is possible that we don't use the texture (the atlas warning us for each of its layers) auto it = m_renderInfos.find(oldTexture); if (it != m_renderInfos.end()) { - // Nous utilisons bien cette texture, nous devons mettre à jour les coordonnées de texture + // We indeed use this texture, we have to update its coordinates RenderIndices indices = std::move(it->second); Vector2ui oldSize(oldTexture->GetSize()); Vector2ui newSize(newTexture->GetSize()); - Vector2f scale = Vector2f(oldSize)/Vector2f(newSize); // ratio ancienne et nouvelle taille + Vector2f scale = Vector2f(oldSize) / Vector2f(newSize); // ratio of the old one to the new one - // On va maintenant parcourir toutes les coordonnées de texture concernées pour les multiplier par ce ratio + // Now we will iterate through each coordinates of the concerned texture to multiply them by the ratio SparsePtr texCoordPtr(&m_localVertices[indices.first].uv, sizeof(VertexStruct_XYZ_Color_UV)); for (unsigned int i = 0; i < indices.count; ++i) { @@ -231,12 +270,18 @@ namespace Nz m_localVertices[i*4 + j].uv *= scale; } - // Nous enlevons l'ancienne texture et rajoutons la nouvelle à sa place (pour les mêmes indices) + // We get rid off the old texture and we set the new one at the place (same for indices) m_renderInfos.erase(it); m_renderInfos.insert(std::make_pair(newTexture, std::move(indices))); } } + /*! + * \brief Updates the data of the sprite + * + * \param instanceData Data of the instance + */ + void TextSprite::UpdateData(InstanceData* instanceData) const { instanceData->data.resize(m_localVertices.size() * sizeof(VertexStruct_XYZ_Color_UV)); @@ -246,18 +291,18 @@ namespace Nz SparsePtr posPtr(&vertices[0].position, sizeof(VertexStruct_XYZ_Color_UV)); SparsePtr texCoordPtr(&vertices[0].uv, sizeof(VertexStruct_XYZ_Color_UV)); - // Nous allons maintenant initialiser les sommets finaux (ceux envoyés à la RenderQueue) - // à l'aide du repère, de la matrice et de notre attribut de couleur + // We will not initialize the final vertices (those send to the RenderQueue) + // With the help of the coordinates axis, the matrix and our color attribute for (auto& pair : m_renderInfos) { RenderIndices& indices = pair.second; if (indices.count == 0) continue; //< Ignore empty render indices - SparsePtr color = colorPtr + indices.first*4; - SparsePtr pos = posPtr + indices.first*4; - SparsePtr uv = texCoordPtr + indices.first*4; - VertexStruct_XY_Color_UV* localVertex = &m_localVertices[indices.first*4]; + SparsePtr color = colorPtr + indices.first * 4; + SparsePtr pos = posPtr + indices.first * 4; + SparsePtr uv = texCoordPtr + indices.first * 4; + VertexStruct_XY_Color_UV* localVertex = &m_localVertices[indices.first * 4]; for (unsigned int i = 0; i < indices.count; ++i) { for (unsigned int j = 0; j < 4; ++j) diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index 9ceb633e6..1b2e53e72 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -11,6 +11,11 @@ namespace Nz { namespace { + /*! + * \brief Defines render states + * \return RenderStates for the color background + */ + RenderStates BuildRenderStates() { RenderStates states; @@ -24,6 +29,18 @@ namespace Nz } } + /*! + * \ingroup graphics + * \class Nz::TextureBackground + * \brief Graphics class that represents a background with a texture + */ + + /*! + * \brief Constructs a TextureBackground object with a texture + * + * \param texture Texture + */ + TextureBackground::TextureBackground(TextureRef texture) { m_uberShader = UberShaderLibrary::Get("Basic"); @@ -43,6 +60,12 @@ namespace Nz SetTexture(std::move(texture)); } + /*! + * \brief Draws this relatively to the viewer + * + * \param viewer Viewer for the background + */ + void TextureBackground::Draw(const AbstractViewer* viewer) const { NazaraUnused(viewer); @@ -62,6 +85,11 @@ namespace Nz Renderer::DrawFullscreenQuad(); } + /*! + * \brief Gets the background type + * \return Type of background + */ + BackgroundType TextureBackground::GetBackgroundType() const { return BackgroundType_Texture; diff --git a/tests/Engine/Graphics/Billboard.cpp b/tests/Engine/Graphics/Billboard.cpp new file mode 100644 index 000000000..5136e3af6 --- /dev/null +++ b/tests/Engine/Graphics/Billboard.cpp @@ -0,0 +1,34 @@ +#include +#include + +SCENARIO("Billboard", "[GRAPHICS][BILLBOARD]") +{ + GIVEN("A default billboard") + { + Nz::Billboard billboard; + + WHEN("We assign it to another") + { + Nz::MaterialRef materialRef = Nz::Material::New(); + materialRef->LoadFromFile("resources/Engine/Graphics/Nazara.png"); + Nz::Color materialColor = materialRef->GetDiffuseColor(); + Nz::BillboardRef otherBillboard = Nz::Billboard::New(materialRef); + + billboard = *otherBillboard; + + THEN("The old one has the same properties than the new one") + { + REQUIRE(billboard.GetColor() == materialColor); + REQUIRE(billboard.GetMaterial().Get() == materialRef.Get()); + REQUIRE(billboard.GetRotation() == Approx(0.f)); + REQUIRE(billboard.GetSize() == Nz::Vector2f(64.f, 64.f)); // Default sizes + } + + THEN("We set it with our new material and ask for its real size") + { + billboard.SetMaterial(materialRef, true); + REQUIRE(billboard.GetSize() == Nz::Vector2f(765.f, 212.f)); // Nazara.png sizes + } + } + } +} diff --git a/tests/Engine/Graphics/ColorBackground.cpp b/tests/Engine/Graphics/ColorBackground.cpp new file mode 100644 index 000000000..f4a88eb30 --- /dev/null +++ b/tests/Engine/Graphics/ColorBackground.cpp @@ -0,0 +1,20 @@ +#include +#include + +SCENARIO("ColorBackground", "[GRAPHICS][COLORBACKGROUND]") +{ + GIVEN("A default color background") + { + Nz::ColorBackground colorBackground; + + WHEN("We assign it a color") + { + colorBackground.SetColor(Nz::Color::Red); + + THEN("We can get it") + { + REQUIRE(colorBackground.GetColor() == Nz::Color::Red); + } + } + } +} diff --git a/tests/Engine/Graphics/DeferredRenderTechnique.cpp b/tests/Engine/Graphics/DeferredRenderTechnique.cpp new file mode 100644 index 000000000..f61c9800c --- /dev/null +++ b/tests/Engine/Graphics/DeferredRenderTechnique.cpp @@ -0,0 +1,29 @@ +#include +#include + +SCENARIO("DeferredRenderTechnique", "[GRAPHICS][DEFERREDRENDERTECHNIQUE]") +{ + GIVEN("A default deferred render technique") + { + Nz::DeferredRenderTechnique deferredRenderTechnique; + + WHEN("We can disable a pass") + { + REQUIRE(deferredRenderTechnique.IsPassEnabled(Nz::RenderPassType::RenderPassType_AA, 0)); + deferredRenderTechnique.EnablePass(Nz::RenderPassType::RenderPassType_AA, 0, false); + + THEN("It is disabled") + { + REQUIRE(!deferredRenderTechnique.IsPassEnabled(Nz::RenderPassType::RenderPassType_AA, 0)); + } + + AND_THEN("We reset it, it is disabled and not the same as the old one") + { + Nz::DeferredRenderPass* oldPass = deferredRenderTechnique.GetPass(Nz::RenderPassType::RenderPassType_AA, 0); + deferredRenderTechnique.ResetPass(Nz::RenderPassType::RenderPassType_AA, 0); + REQUIRE(!deferredRenderTechnique.IsPassEnabled(Nz::RenderPassType::RenderPassType_AA, 0)); + REQUIRE(deferredRenderTechnique.GetPass(Nz::RenderPassType::RenderPassType_AA, 0) != oldPass); + } + } + } +} diff --git a/tests/Engine/Graphics/Light.cpp b/tests/Engine/Graphics/Light.cpp new file mode 100644 index 000000000..bd5f1c7f9 --- /dev/null +++ b/tests/Engine/Graphics/Light.cpp @@ -0,0 +1,31 @@ +#include +#include + +SCENARIO("Light", "[GRAPHICS][LIGHT]") +{ + GIVEN("Different light") + { + Nz::Light directionalLight(Nz::LightType_Directional); + Nz::Light pointLight(Nz::LightType_Point); + Nz::Light spotLight(Nz::LightType_Spot); + + WHEN("We try to cull") + { + Nz::Frustumf frustum; + frustum.Build(90.f, 16.f / 9.f, 1.f, 1000.f, Nz::Vector3f::Zero(), Nz::Vector3f::UnitX()); + Nz::Matrix4f Unit3InX = Nz::Matrix4f::Translate(Nz::Vector3f::UnitX() * 3.f); + Nz::Matrix4f rotationTowardsY = Unit3InX * Nz::Matrix4f::Rotate(Nz::EulerAnglesf(Nz::FromDegrees(90.f), 0.f, 0.f).ToQuaternion()); + + THEN("These results are expected") + { + REQUIRE(directionalLight.Cull(frustum, Unit3InX)); + REQUIRE(pointLight.Cull(frustum, Unit3InX)); + REQUIRE(!spotLight.Cull(frustum, Unit3InX)); + + REQUIRE(directionalLight.Cull(frustum, rotationTowardsY)); + REQUIRE(pointLight.Cull(frustum, rotationTowardsY)); + REQUIRE(!spotLight.Cull(frustum, rotationTowardsY)); + } + } + } +} diff --git a/tests/Engine/Graphics/Model.cpp b/tests/Engine/Graphics/Model.cpp new file mode 100644 index 000000000..d67a261bb --- /dev/null +++ b/tests/Engine/Graphics/Model.cpp @@ -0,0 +1,24 @@ +#include +#include + +SCENARIO("Model", "[GRAPHICS][MODEL]") +{ + GIVEN("The standford dragon model") + { + WHEN("We get general informations") + { + THEN("These results are expected") + { + Nz::ModelRef model = Nz::Model::New(); + REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj")); + + REQUIRE(model->GetMaterialCount() == 2); + REQUIRE(model->GetSkin() == 0); + REQUIRE(model->GetSkinCount() == 1); + + Nz::Material* material = model->GetMaterial(0); + REQUIRE(material->GetAmbientColor() == Nz::Color(128)); + } + } + } +} diff --git a/tests/Engine/Graphics/ParticleDeclaration.cpp b/tests/Engine/Graphics/ParticleDeclaration.cpp new file mode 100644 index 000000000..1bc1739d3 --- /dev/null +++ b/tests/Engine/Graphics/ParticleDeclaration.cpp @@ -0,0 +1,29 @@ +#include +#include + +SCENARIO("ParticleDeclaration", "[GRAPHICS][PARTICLEDECLARATION]") +{ + GIVEN("A particle declaration of a model") + { + Nz::ParticleDeclaration* particleDeclaration = Nz::ParticleDeclaration::Get(Nz::ParticleLayout_Model); + + WHEN("We disable a component") + { + bool enabled; + Nz::ComponentType type; + unsigned int offset; + particleDeclaration->GetComponent(Nz::ParticleComponent_Position, &enabled, &type, &offset); + REQUIRE(enabled); + unsigned int oldStride = particleDeclaration->GetStride(); + + particleDeclaration->DisableComponent(Nz::ParticleComponent_Position); + REQUIRE(oldStride != particleDeclaration->GetStride()); + + THEN("We can enable it and the stride is back") + { + particleDeclaration->EnableComponent(Nz::ParticleComponent_Position, type, offset); + REQUIRE(oldStride == particleDeclaration->GetStride()); + } + } + } +} diff --git a/tests/Engine/Graphics/ParticleSystem.cpp b/tests/Engine/Graphics/ParticleSystem.cpp new file mode 100644 index 000000000..32f5f01f9 --- /dev/null +++ b/tests/Engine/Graphics/ParticleSystem.cpp @@ -0,0 +1,103 @@ +#include +#include + +#include +#include + +class TestParticleController : public Nz::ParticleController +{ + public: + // Be aware that the interval is [startId, endId] and NOT [startId, endId) + void Apply(Nz::ParticleSystem& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) override + { + Nz::SparsePtr positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); + Nz::SparsePtr velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); + Nz::SparsePtr lifePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Life); + + for (unsigned int i = startId; i <= endId; ++i) + { + Nz::Vector3f& particlePosition = positionPtr[i]; + Nz::Vector3f& particleVelocity = velocityPtr[i]; + float& particleLife = lifePtr[i]; + + particleLife -= elapsedTime; + if (particleLife <= 0.f) + system.KillParticle(i); + } + } +}; + +class TestParticleEmitter : public Nz::ParticleEmitter +{ + public: + ~TestParticleEmitter() override = default; + + void Emit(Nz::ParticleSystem& system, float elapsedTime) const override + { + system.GenerateParticles(GetEmissionCount()); + } + + private: + void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override + { + } +}; + +class TestParticleGenerator : public Nz::ParticleGenerator +{ + public: + ~TestParticleGenerator() override = default; + + // Be aware that the interval is [startId, endId] and NOT [startId, endId) + void Generate(Nz::ParticleSystem& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId) override + { + Nz::SparsePtr positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); + Nz::SparsePtr velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); + Nz::SparsePtr lifePtr = mapper.GetComponentPtr(Nz::ParticleComponent_Life); + + for (unsigned int i = startId; i <= endId; ++i) + { + Nz::Vector3f& particlePosition = positionPtr[i]; + Nz::Vector3f& particleVelocity = velocityPtr[i]; + float& particleLife = lifePtr[i]; + + particlePosition = Nz::Vector3f::Zero(); + particleVelocity = Nz::Vector3f::UnitX(); + particleLife = 1.3f; + } + } +}; + +SCENARIO("ParticleSystem", "[GRAPHICS][PARTICLESYSTEM]") +{ + GIVEN("A particle system of maximum 10 billboards with its generators") + { + // These need to be alive longer than the particle system + TestParticleController particleController; + TestParticleGenerator particleGenerator; + Nz::ParticleSystem particleSystem(10, Nz::ParticleLayout_Billboard); + + particleSystem.AddController(&particleController); + TestParticleEmitter particleEmitter; + particleEmitter.SetEmissionCount(10); + particleSystem.AddEmitter(&particleEmitter); + + particleSystem.AddGenerator(&particleGenerator); + + WHEN("We update to generate 10 particles") + { + particleSystem.Update(1.f); + + THEN("There must be 10 particles") + { + REQUIRE(particleSystem.GetParticleCount() == 10); + } + + AND_THEN("We update to make them die") + { + particleSystem.Update(2.f); + REQUIRE(particleSystem.GetParticleCount() == 0); + } + } + } +} diff --git a/tests/Engine/Graphics/RenderTechniques.cpp b/tests/Engine/Graphics/RenderTechniques.cpp new file mode 100644 index 000000000..ac5849da9 --- /dev/null +++ b/tests/Engine/Graphics/RenderTechniques.cpp @@ -0,0 +1,47 @@ +#include +#include + +#include +#include + +SCENARIO("RenderTechniques", "[GRAPHICS][RENDERTECHNIQUES]") +{ + GIVEN("Nothing") + { + WHEN("We try to get a technique") + { + THEN("We should get it") + { + std::unique_ptr forwardByEnum(Nz::RenderTechniques::GetByEnum(Nz::RenderTechniqueType_BasicForward)); + REQUIRE(forwardByEnum->GetType() == Nz::RenderTechniqueType_BasicForward); + + std::unique_ptr forwardByIndex(Nz::RenderTechniques::GetByIndex(1)); + REQUIRE(forwardByIndex->GetType() == Nz::RenderTechniqueType_BasicForward); + + std::unique_ptr forwardByName(Nz::RenderTechniques::GetByName(Nz::RenderTechniques::ToString(Nz::RenderTechniqueType_BasicForward))); + REQUIRE(forwardByName->GetType() == Nz::RenderTechniqueType_BasicForward); + } + + THEN("We can register a render technique") + { + unsigned int previousCount = Nz::RenderTechniques::GetCount(); + + Nz::RenderTechniques::Register("test", 23, []() -> Nz::AbstractRenderTechnique* { + return new Nz::ForwardRenderTechnique; + }); + + REQUIRE(previousCount < Nz::RenderTechniques::GetCount()); + + std::unique_ptr forwardByRanking(Nz::RenderTechniques::GetByRanking(23)); + REQUIRE(forwardByRanking->GetType() == Nz::RenderTechniqueType_BasicForward); + + std::unique_ptr forwardByName(Nz::RenderTechniques::GetByName("test")); + REQUIRE(forwardByName->GetType() == Nz::RenderTechniqueType_BasicForward); + + Nz::RenderTechniques::Unregister("test"); + + REQUIRE(previousCount == Nz::RenderTechniques::GetCount()); + } + } + } +} \ No newline at end of file diff --git a/tests/Engine/Graphics/SkeletalModel.cpp b/tests/Engine/Graphics/SkeletalModel.cpp new file mode 100644 index 000000000..87d2e43f1 --- /dev/null +++ b/tests/Engine/Graphics/SkeletalModel.cpp @@ -0,0 +1,26 @@ +#include +#include + +SCENARIO("SkeletalModel", "[GRAPHICS][SKELETALMODEL]") +{ + GIVEN("A default skeletal model") + { + Nz::SkeletalModel skeletalModel; + Nz::AnimationRef animation = Nz::Animation::New(); + + WHEN("We can load the bob lamp") + { + REQUIRE(skeletalModel.LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5mesh")); + REQUIRE(animation->LoadFromFile("resources/Engine/Graphics/Bob lamp/bob_lamp_update.md5anim")); + skeletalModel.SetAnimation(animation); + + THEN("We can enable its animation") + { + REQUIRE(skeletalModel.HasAnimation()); + skeletalModel.EnableAnimation(true); + skeletalModel.AdvanceAnimation(0.10f); + REQUIRE(skeletalModel.IsAnimationEnabled()); + } + } + } +} diff --git a/tests/Engine/Graphics/SkyboxBackground.cpp b/tests/Engine/Graphics/SkyboxBackground.cpp new file mode 100644 index 000000000..36ceb0db5 --- /dev/null +++ b/tests/Engine/Graphics/SkyboxBackground.cpp @@ -0,0 +1,25 @@ +#include +#include + +SCENARIO("SkyboxBackground", "[GRAPHICS][SKYBOXBACKGROUND]") +{ + GIVEN("A skybox background with a loaded image") + { + Nz::TextureRef textureRef = Nz::Texture::New(); + textureRef->LoadCubemapFromFile("resources/Engine/Graphics/skybox.png"); + Nz::SkyboxBackgroundRef skyboxBackgroundRef = Nz::SkyboxBackground::New(textureRef); + + WHEN("We assign it parameters") + { + skyboxBackgroundRef->SetMovementOffset(Nz::Vector3f::Unit()); + skyboxBackgroundRef->SetMovementScale(1.f); + + THEN("We can get it") + { + REQUIRE(skyboxBackgroundRef->GetMovementOffset() == Nz::Vector3f::Unit()); + REQUIRE(skyboxBackgroundRef->GetMovementScale() == Approx(1.f)); + REQUIRE(skyboxBackgroundRef->GetTexture().Get() == textureRef.Get()); + } + } + } +} diff --git a/tests/Engine/Graphics/TextureBackground.cpp b/tests/Engine/Graphics/TextureBackground.cpp new file mode 100644 index 000000000..33178d87f --- /dev/null +++ b/tests/Engine/Graphics/TextureBackground.cpp @@ -0,0 +1,20 @@ +#include +#include + +SCENARIO("TextureBackground", "[GRAPHICS][TEXTUREBACKGROUND]") +{ + GIVEN("A default texture background") + { + Nz::TextureRef textureRef = Nz::Texture::New(); + textureRef->LoadFromFile("resources/Engine/Graphics/skybox.png"); + Nz::TextureBackgroundRef textureBackgroundRef = Nz::TextureBackground::New(textureRef); + + WHEN("We assign it parameters") + { + THEN("We can get it") + { + REQUIRE(textureBackgroundRef->GetTexture().Get() == textureRef.Get()); + } + } + } +} \ No newline at end of file diff --git a/tests/Engine/Math/Sphere.cpp b/tests/Engine/Math/Sphere.cpp index 1820acd35..ef13ffb38 100644 --- a/tests/Engine/Math/Sphere.cpp +++ b/tests/Engine/Math/Sphere.cpp @@ -39,14 +39,14 @@ SCENARIO("Sphere", "[MATH][SPHERE]") WHEN("We ask for distance") { - THEN("These results are expected") + THEN("These results are expected because we don't take into account the border") { - REQUIRE(firstCenterAndUnit.Distance(Nz::Vector3f::UnitX()) == Approx(1.f)); - REQUIRE(firstCenterAndUnit.SquaredDistance(Nz::Vector3f::UnitX()) == Approx(1.f)); + REQUIRE(firstCenterAndUnit.Distance(Nz::Vector3f::UnitX() * 2.f) == Approx(1.f)); + REQUIRE(firstCenterAndUnit.SquaredDistance(Nz::Vector3f::UnitX() * 2.f) == Approx(1.f)); Nz::Spheref tmp(Nz::Vector3f::UnitX(), 1.f); - REQUIRE(tmp.Distance(Nz::Vector3f::UnitX() * 4.f) == Approx(3.f)); - REQUIRE(tmp.SquaredDistance(Nz::Vector3f::UnitX() * 4.f) == Approx(9.f)); + REQUIRE(tmp.Distance(Nz::Vector3f::UnitX() * 4.f) == Approx(2.f)); + REQUIRE(tmp.SquaredDistance(Nz::Vector3f::UnitX() * 4.f) == Approx(4.f)); } } @@ -84,7 +84,7 @@ SCENARIO("Sphere", "[MATH][SPHERE]") THEN("Sphere must contain it and distance should be good") { CHECK(firstCenterAndUnit.Contains(point)); - REQUIRE(firstCenterAndUnit.Distance(point) == 2.f); + REQUIRE(firstCenterAndUnit.Distance(point) == 1.f); } } diff --git a/tests/main.cpp b/tests/main.cpp index 7be81a57e..5ba9e8e01 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,2 +1,16 @@ -#define CATCH_CONFIG_MAIN +#define CATCH_CONFIG_RUNNER #include + +#include +#include +#include +#include + +int main(int argc, char* const argv[]) +{ + Nz::Initializer modules; + + int result = Catch::Session().run(argc, argv); + + return result; +} diff --git a/tests/resources/Engine/Graphics/Bob lamp/Readme.txt b/tests/resources/Engine/Graphics/Bob lamp/Readme.txt new file mode 100644 index 000000000..bd605ec7d --- /dev/null +++ b/tests/resources/Engine/Graphics/Bob lamp/Readme.txt @@ -0,0 +1,24 @@ +############################# +MD5 sample mesh and animation +############################# + +INFORMATION & USAGE +=================== +File includes *.blend source files and TGA format textures for MD5 animated mesh testing. +For extensive information and usage instructions visit http://www.katsbits.com/smforum/index.php?topic=178.0 + + - bob_lamp_update.blend contain mesh and armature as would be prior to preparation for export. + - bob_lamp_update_export contains triangulated mesh ready for export. + +NOTES +===== +Included files are for use in **Blender 2.69** or above; opening files in older versions may result in errors dues to internal differences between Blender versions. +Files and media are provided "as is" without any warranties of functionality. + +COPYRIGHT & DISTRIBUTION +======================== +Copyright © 2014 KatsBits. All Rights Reserved. +For more information visit http://www.katsbits.com/ or email info@katsbits.com + +For NON-COMMERCIAL USE ONLY. This file and/or its contents and/or associated materials may not be reproduced, duplicated, distributed or otherwise 'monetised' without prior consent. +Contact info@katsbits.com or visit http://copyright.katsbits.com/ for further details regarding this material and/or distribution/copyright. diff --git a/tests/resources/Engine/Graphics/copyrights.txt b/tests/resources/Engine/Graphics/copyrights.txt new file mode 100644 index 000000000..7cd13413c --- /dev/null +++ b/tests/resources/Engine/Graphics/copyrights.txt @@ -0,0 +1,82 @@ +skybox.png + +https://commons.wikimedia.org/wiki/File:Skybox_example.png + +Original file: +Skybox example.ogg ‎(Ogg Vorbis sound file, length 1 min 3 s, 378 kbps) + +Summary: + +Description: English: An example of a skybox and how the faces can be aligned +Date: 8 June 2011 +Source: Own work +Author: Creator:Arieee + +Description: The Belgian national anthem (instrumental version) performed by the United States Navy Band. Direct link is at http://www.navyband.navy.mil/anthems/ANTHEMS/Belgium.mp3. +Date: 19 October 2004 +Source: http://www.navyband.navy.mil/anthems/national_anthems.htm +Author: United States Navy Band (rendition), uploaded to Wikimedia by Keith Lehwald + +Licencing: + +This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. + + You are free: + + to share – to copy, distribute and transmit the work + to remix – to adapt the work + + Under the following conditions: + + attribution – You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). + share alike – If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one. + +------------------------------------------------------------------------------------------------- + +Bob lamp + +http://www.katsbits.com/download/models/md5-example.php + +Original file: +bob_lamp_update.zip (Animated MD5 sample file) + +Summary: + +Description: Updated version of "Bob", a low-poly character mesh for general export and testing of MD5 mesh and animation - "*.md5mesh" and "*.md5anim". File and it's contents should be opened in Blender 2.69 or above to avoid compatibility issues with older versions of Blender and/or resulting MD5 exports (md5mesh & md5anim). + +File includes two versions of the source file, one 'working' - mesh is intact with surfaces in 'quad' form; and one 'prepped' (exported) - mesh has been tessilated (triangulated) for export. +Date: Januari 2014 +Source: http://www.katsbits.com/download/models/md5-example.php +Author: KatsBits + +Licencing: + +Please, refer to "Bob lamp/Readme.txt" file. + +------------------------------------------------------------------------------------------------- + +Standford dragon + +http://graphics.stanford.edu/data/3Dscanrep/ + +Original file: +dragon_recon.tar.gz (PLY files) + +Summary: + +Dragon +Source: Stanford University Computer Graphics Laboratory +Scanner: Cyberware 3030 MS + spacetime analysis +Number of scans: ~70 +Total size of scans: 2,748,318 points (about 5,500,000 triangles) +Reconstruction: vrip (conservatively decimated) +Size of reconstruction: 566,098 vertices, 1,132,830 triangles +Comments: contains numerous small holes +Date: 1996 +Source: http://graphics.stanford.edu/data/3Dscanrep/ +Author: Stanford University Computer Graphics Laboratory + +Licencing: + +Please be sure to acknowledge the source of the data and models you take from this repository. In each of the listings below, we have cited the source of the range data and reconstructed models. You are welcome to use the data and models for research purposes. You are also welcome to mirror or redistribute them for free. Finally, you may publish images made using these models, or the images on this web site, in a scholarly article or book - as long as credit is given to the Stanford Computer Graphics Laboratory. However, such models or images are not to be used for commercial purposes, nor should they appear in a product for sale (with the exception of scholarly journals or books), without our permission. +Please, refer to "dragon_recon/README" file. diff --git a/tests/resources/Engine/Graphics/dragon_recon/README b/tests/resources/Engine/Graphics/dragon_recon/README new file mode 100644 index 000000000..af64a50fe --- /dev/null +++ b/tests/resources/Engine/Graphics/dragon_recon/README @@ -0,0 +1,27 @@ + Surface Reconstructions + + Stanford Range Repository + Computer Graphics Laboratory + Stanford University + + August 4, 1996 + + +These files are the result of reconstructing a set of range images +using the "vrip" program. The first file is the high resolution +result, while the "_res*" files are decimated versions. Note that +these decimations were performed using a crude algorithm that does not +necessarily preserve mesh topology. While they are not beautiful, +they are suitable for interactive rendering. + +Note that this model is a decimated version of the original which was +constructed at the voxel resolution of 0.35 mm. The original model +has no holes in it, however, the decimated model has some holes that +we detected with software, but not by inspection. Apparently, the +decimation software introduced these holes. + +For more information, consult the web pages of the Stanford Graphics +Laboratory: + + http://www-graphics.stanford.edu + From 36c1ef1b97c2631b39f06f0616cb88b1bef5982c Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:22:31 +0200 Subject: [PATCH 093/224] Documentation for module: Network Former-commit-id: 0563349542b717b602d5a6eb7728bd40b2af7e1f --- include/Nazara/Network/AbstractSocket.inl | 31 ++++ include/Nazara/Network/Config.hpp | 15 +- include/Nazara/Network/ConfigCheck.hpp | 4 +- include/Nazara/Network/DebugOff.hpp | 2 +- include/Nazara/Network/IpAddress.inl | 164 ++++++++++++++++++++- include/Nazara/Network/NetPacket.inl | 93 ++++++++++++ include/Nazara/Network/RUdpConnection.inl | 87 ++++++++++- include/Nazara/Network/TcpClient.hpp | 2 +- include/Nazara/Network/TcpClient.inl | 35 +++++ include/Nazara/Network/TcpServer.inl | 31 ++++ include/Nazara/Network/UdpSocket.hpp | 1 - include/Nazara/Network/UdpSocket.inl | 53 ++++++- src/Nazara/Network/AbstractSocket.cpp | 68 +++++++++ src/Nazara/Network/AlgorithmNetwork.cpp | 42 +++++- src/Nazara/Network/IpAddress.cpp | 50 +++++++ src/Nazara/Network/NetPacket.cpp | 70 +++++++++ src/Nazara/Network/Network.cpp | 27 +++- src/Nazara/Network/RUdpConnection.cpp | 157 +++++++++++++++++++- src/Nazara/Network/TcpClient.cpp | 168 ++++++++++++++++++++++ src/Nazara/Network/TcpServer.cpp | 34 +++++ src/Nazara/Network/UdpSocket.cpp | 84 +++++++++++ tests/Engine/Network/IpAddress.cpp | 47 ++++++ tests/Engine/Network/RUdpConnection.cpp | 40 ++++++ tests/Engine/Network/TCP.cpp | 49 +++++++ tests/Engine/Network/UdpSocket.cpp | 39 +++++ 25 files changed, 1368 insertions(+), 25 deletions(-) create mode 100644 tests/Engine/Network/IpAddress.cpp create mode 100644 tests/Engine/Network/RUdpConnection.cpp create mode 100644 tests/Engine/Network/TCP.cpp create mode 100644 tests/Engine/Network/UdpSocket.cpp diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl index 8bebabfdb..5b5174b98 100644 --- a/include/Nazara/Network/AbstractSocket.inl +++ b/include/Nazara/Network/AbstractSocket.inl @@ -6,31 +6,62 @@ namespace Nz { + /*! + * \brief Gets the last error + * \return Socket error + */ + inline SocketError AbstractSocket::GetLastError() const { return m_lastError; } + /*! + * \brief Gets the internal socket handle + * \return Socket handle + */ + inline SocketHandle AbstractSocket::GetNativeHandle() const { return m_handle; } + /*! + * \brief Gets the internal state + * \return Socket state + */ + inline SocketState AbstractSocket::GetState() const { return m_state; } + /*! + * \brief Gets the internal type + * \return Socket type + */ + inline SocketType AbstractSocket::GetType() const { return m_type; } + /*! + * \brief Checks whether the blocking is enabled + * \return true If successful + */ + inline bool AbstractSocket::IsBlockingEnabled() const { return m_isBlockingEnabled; } + /*! + * \brief Updates the state of the socket + * + * \param newState Next state for the socket + */ + inline void AbstractSocket::UpdateState(SocketState newState) { if (m_state != newState) diff --git a/include/Nazara/Network/Config.hpp b/include/Nazara/Network/Config.hpp index 727108061..2d73c26bb 100644 --- a/include/Nazara/Network/Config.hpp +++ b/include/Nazara/Network/Config.hpp @@ -27,17 +27,22 @@ #ifndef NAZARA_CONFIG_NETWORK_HPP #define NAZARA_CONFIG_NETWORK_HPP -/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +/*! +* \defgroup network (NazaraNetwork) Network module +* Network/System module including classes to handle networking elements... +*/ -// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +/// Each modification of a paramater of the module needs a recompilation of the unit + +// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower) #define NAZARA_NETWORK_MANAGE_MEMORY 0 -// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +// Activate the security tests based on the code (Advised for development) #define NAZARA_NETWORK_SAFE 1 -/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code +/// Each modification of a parameter following implies a modification (often minor) of the code -/// Vérification des valeurs et types de certaines constantes +/// Checking the values and types of certain constants #include #if defined(NAZARA_STATIC) diff --git a/include/Nazara/Network/ConfigCheck.hpp b/include/Nazara/Network/ConfigCheck.hpp index 73513ebc9..2f1ba1dc8 100644 --- a/include/Nazara/Network/ConfigCheck.hpp +++ b/include/Nazara/Network/ConfigCheck.hpp @@ -7,11 +7,11 @@ #ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP #define NAZARA_CONFIG_CHECK_NETWORK_HPP -/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp +/// This file is used to check the constant values defined in Config.hpp #include -// On force la valeur de MANAGE_MEMORY en mode debug +// We fore the value of MANAGE_MEMORY in debug #if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY #undef NAZARA_NETWORK_MANAGE_MEMORY #define NAZARA_NETWORK_MANAGE_MEMORY 0 diff --git a/include/Nazara/Network/DebugOff.hpp b/include/Nazara/Network/DebugOff.hpp index dd45ac45c..e9df99f1f 100644 --- a/include/Nazara/Network/DebugOff.hpp +++ b/include/Nazara/Network/DebugOff.hpp @@ -2,7 +2,7 @@ // This file is part of the "Nazara Engine - Network module" // For conditions of distribution and use, see copyright notice in Config.hpp -// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +// We suppose that Debug.hpp is already included, same goes for Config.hpp #if NAZARA_NETWORK_MANAGE_MEMORY #undef delete #undef new diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index 3184bd34d..2fc9ac2bd 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -9,11 +9,22 @@ namespace Nz { + /*! + * \brief Constructs a IpAddress object by default + */ + inline IpAddress::IpAddress() : m_isValid(false) { } + /*! + * \brief Constructs a IpAddress object with an IP and a port + * + * \param ip IPv4 address + * \param port Port of the IP + */ + inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) : m_ipv4(ip), m_protocol(NetProtocol_IPv4), @@ -22,6 +33,13 @@ namespace Nz { } + /*! + * \brief Constructs a IpAddress object with an IP and a port + * + * \param ip IPv6 address + * \param port Port of the IP + */ + inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) : m_ipv6(ip), m_protocol(NetProtocol_IPv6), @@ -30,46 +48,100 @@ namespace Nz { } + /*! + * \brief Constructs a IpAddress object with an IP and a port + * + * \param ip IPv4 address (a.b.c.d) + * \param port Port of the IP + */ + inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) : IpAddress(IPv4{a, b, c, d}, port) { } + /*! + * \brief Constructs a IpAddress object with an IP and a port + * + * \param ip IPv6 address (a.b.c.d.e.f.g.h) + * \param port Port of the IP + */ + inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) : IpAddress(IPv6{a, b, c, d, e, f, g, h}, port) { } + /*! + * Constructs a IpAddress object with a C-string + * + * \param address Hostname or textual IP address + */ + inline IpAddress::IpAddress(const char* address) { BuildFromAddress(address); } + /*! + * Constructs a IpAddress object with a string + * + * \param address Hostname or textual IP address + */ + inline IpAddress::IpAddress(const String& address) { BuildFromAddress(address.GetConstBuffer()); } + /*! + * \brief Gets the port + * \return Port attached to the IP address + */ + inline UInt16 IpAddress::GetPort() const { return m_port; } + /*! + * \brief Gets the net protocol + * \return Protocol attached to the IP address + */ + inline NetProtocol IpAddress::GetProtocol() const { return m_protocol; } + /*! + * \brief Checks whether the IP address is valid + * \return true If successful + */ + inline bool IpAddress::IsValid() const { return m_isValid; } + /*! + * \brief Sets the port + * + * \param port Port attached to the IP address + */ + inline void IpAddress::SetPort(UInt16 port) { m_port = port; } + /*! + * \brief Converts IpAddress to IPv4 + * \return Corresponding IPv4 + * + * \remark Produces a NazaraAssert if net protocol is not IPv4 + */ + inline IpAddress::IPv4 IpAddress::ToIPv4() const { NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); @@ -77,6 +149,13 @@ namespace Nz return m_ipv4; } + /*! + * \brief Converts IpAddress to IPv6 + * \return Corresponding IPv6 + * + * \remark Produces a NazaraAssert if net protocol is not IPv6 + */ + inline IpAddress::IPv6 IpAddress::ToIPv6() const { NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6"); @@ -84,6 +163,13 @@ namespace Nz return m_ipv6; } + /*! + * \brief Converts IpAddress to UInt32 + * \return Corresponding UInt32 + * + * \remark Produces a NazaraAssert if net protocol is not IPv4 + */ + inline UInt32 IpAddress::ToUInt32() const { NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); @@ -94,17 +180,40 @@ namespace Nz UInt32(m_ipv4[3]) << 0; } + /*! + * \brief Converts IpAddress to boolean + * \return true If IpAddress is valid + * + * \see IsValid + */ + inline IpAddress::operator bool() const { return IsValid(); } + /*! + * \brief Output operator + * \return The stream + * + * \param out The stream + * \param address The address to output + */ + inline std::ostream& operator<<(std::ostream& out, const IpAddress& address) { out << "IpAddress(" << address.ToString() << ')'; return out; } + /*! + * \brief Compares the IpAddress to other one + * \return true if the ip addresses are the same + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator==(const IpAddress& first, const IpAddress& second) { // We need to check the validity of each address before comparing them @@ -146,11 +255,27 @@ namespace Nz return true; } + /*! + * \brief Compares the IpAddress to other one + * \return false if the ip addresses are the same + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator!=(const IpAddress& first, const IpAddress& second) { return !operator==(first, second); } + /*! + * \brief Compares the IpAddress to other one + * \return true if this ip address is inferior to the other one + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator<(const IpAddress& first, const IpAddress& second) { // If the second address is invalid, there's no way we're lower than it @@ -196,16 +321,40 @@ namespace Nz return false; //< Same address } + /*! + * \brief Compares the IpAddress to other one + * \return true if this ip address is inferior or equal to the other one + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator<=(const IpAddress& first, const IpAddress& second) { return !operator<(second, first); } + /*! + * \brief Compares the IpAddress to other one + * \return true if this ip address is greather to the other one + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator>(const IpAddress& first, const IpAddress& second) { return second < first; } + /*! + * \brief Compares the IpAddress to other one + * \return true if this ip address is greather or equal to the other one + * + * \param first First ip address to compare + * \param second Second ip address to compare with + */ + inline bool operator>=(const IpAddress& first, const IpAddress& second) { return !operator<(first, second); @@ -217,6 +366,13 @@ namespace std template<> struct hash { + /*! + * \brief Converts IpAddress to hash + * \return Hash of the IpAddress + * + * \param ip IpAddress to hash + */ + size_t operator()(const Nz::IpAddress& ip) const { if (!ip) @@ -224,7 +380,7 @@ namespace std // This is SDBM adapted for IP addresses, tested to generate the least collisions possible // (It doesn't mean it cannot be improved though) - std::size_t h = 0; + std::size_t hash = 0; switch (ip.GetProtocol()) { case Nz::NetProtocol_Any: @@ -233,20 +389,20 @@ namespace std case Nz::NetProtocol_IPv4: { - h = ip.ToUInt32() + (h << 6) + (h << 16) - h; + hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash; break; } case Nz::NetProtocol_IPv6: { Nz::IpAddress::IPv6 v6 = ip.ToIPv6(); for (std::size_t i = 0; i < v6.size(); i++) - h = v6[i] + (h << 6) + (h << 16) - h; + hash = v6[i] + (hash << 6) + (hash << 16) - hash; break; } } - return ip.GetPort() + (h << 6) + (h << 16) - h; + return ip.GetPort() + (hash << 6) + (hash << 16) - hash; } }; } diff --git a/include/Nazara/Network/NetPacket.inl b/include/Nazara/Network/NetPacket.inl index c9bbed681..e9765c9dc 100644 --- a/include/Nazara/Network/NetPacket.inl +++ b/include/Nazara/Network/NetPacket.inl @@ -9,21 +9,46 @@ namespace Nz { + /*! + * \brief Constructs a NetPacket object by default + */ + inline NetPacket::NetPacket() : m_netCode(NetCode_Invalid) { } + /*! + * \brief Constructs a NetPacket object with a packet number and a minimal capacity + * + * \param netCode Packet number + * \param minCapacity Minimal capacity of the packet + */ + inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity) { Reset(netCode, minCapacity); } + /*! + * \brief Constructs a NetPacket object with a packet number and raw memory + * + * \param netCode Packet number + * \param ptr Raw memory + * \param size Size of the memory + */ + inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) { Reset(netCode, ptr, size); } + /*! + * \brief Constructs a NetPacket object with another one by move semantic + * + * \param packet NetPacket to move into this + */ + inline NetPacket::NetPacket(NetPacket&& packet) : ByteStream(std::move(packet)), m_buffer(std::move(packet.m_buffer)), @@ -35,12 +60,23 @@ namespace Nz SetStream(&m_memoryStream); } + /*! + * \brief Destructs the object + */ + inline NetPacket::~NetPacket() { FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it FreeStream(); } + /*! + * \brief Gets the raw buffer + * \return Constant raw buffer + * + * \remark Produces a NazaraAssert if internal buffer is invalid + */ + inline const UInt8* NetPacket::GetConstData() const { NazaraAssert(m_buffer, "Invalid buffer"); @@ -48,6 +84,13 @@ namespace Nz return m_buffer->GetConstBuffer(); } + /*! + * \brief Gets the raw buffer + * \return Raw buffer + * + * \remark Produces a NazaraAssert if internal buffer is invalid + */ + inline UInt8* NetPacket::GetData() const { NazaraAssert(m_buffer, "Invalid buffer"); @@ -55,6 +98,11 @@ namespace Nz return m_buffer->GetBuffer(); } + /*! + * \brief Gets the size of the data + * \return Size of the data + */ + inline size_t NetPacket::GetDataSize() const { if (m_buffer) @@ -63,22 +111,46 @@ namespace Nz return 0; } + /*! + * \brief Gets the packet number + * \return Packet number + */ + inline UInt16 NetPacket::GetNetCode() const { return m_netCode; } + /*! + * \brief Resets the packet + */ + inline void NetPacket::Reset() { FreeStream(); } + /*! + * \brief Resets the packet with a packet number and a minimal capacity + * + * \param netCode Packet number + * \param minCapacity Minimal capacity of the packet + */ + inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity) { InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite); m_netCode = netCode; } + /*! + * \brief Resets the packet with a packet number and raw memory + * + * \param netCode Packet number + * \param ptr Raw memory + * \param size Size of the memory + */ + inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size) { InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); @@ -88,6 +160,14 @@ namespace Nz m_netCode = netCode; } + /*! + * \brief Resizes the packet + * + * \param newSize Size for the resizing operation + * + * \remark Produces a NazaraAssert if internal buffer is invalid + */ + inline void NetPacket::Resize(std::size_t newSize) { NazaraAssert(m_buffer, "Invalid buffer"); @@ -95,11 +175,24 @@ namespace Nz m_buffer->Resize(newSize); } + /*! + * \brief Sets the packet number + * + * \param netCode Packet number + */ + inline void NetPacket::SetNetCode(UInt16 netCode) { m_netCode = netCode; } + /*! + * \brief Moves the NetPacket into this + * \return A reference to this + * + * \param packet NetPacket to move in this + */ + inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet) { FreeStream(); diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index b2372285d..53e797b59 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -8,31 +8,66 @@ namespace Nz { + /*! + * \brief Closes the connection + */ + inline void RUdpConnection::Close() { m_socket.Close(); } + /*! + * \brief Disconnects the connection + * + * \see Close + */ + inline void RUdpConnection::Disconnect() { Close(); } + /*! + * \brief Gets the bound address + * \return IpAddress we are linked to + */ + inline IpAddress RUdpConnection::GetBoundAddress() const { return m_socket.GetBoundAddress(); } + /*! + * \brief Gets the port of the bound address + * \return Port we are linked to + */ + inline UInt16 RUdpConnection::GetBoundPort() const { return m_socket.GetBoundPort(); } + /*! + * \brief Gets the last error + * \return Socket error + */ + inline SocketError RUdpConnection::GetLastError() const { return m_lastError; } + /*! + * \brief Listens to a socket + * \return true If successfully bound + * + * \param protocol Net protocol to listen to + * \param port Port to listen to + * + * \remark Produces a NazaraAssert if protocol is unknown or any + */ + inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port) { NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO @@ -59,16 +94,36 @@ namespace Nz return Listen(any); } + /*! + * \brief Sets the protocol id + * + * \param protocolId Protocol ID like NNet + */ + inline void RUdpConnection::SetProtocolId(UInt32 protocolId) { m_protocol = protocolId; } + /*! + * \brief Sets the time before ack + * + * \param Time before acking to send many together (in ms) + */ + inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms) { m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling } - + + /*! + * \brief Computes the difference of sequence + * \return Delta between the two sequences + * + * \param sequence First sequence + * \param sequence2 Second sequence + */ + inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2) { unsigned int difference; @@ -80,6 +135,13 @@ namespace Nz return 0; } + /*! + * \brief Checks whether the peer has pending packets + * \return true If it is the case + * + * \param peer Data relative to the peer + */ + inline bool RUdpConnection::HasPendingPackets(PeerData& peer) { for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority) @@ -94,6 +156,14 @@ namespace Nz return false; } + /*! + * \brief Checks whether the ack is more recent + * \return true If it is the case + * + * \param ack First sequence + * \param ack2 Second sequence + */ + inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2) { constexpr SequenceIndex maxDifference = std::numeric_limits::max() / 2; @@ -106,6 +176,13 @@ namespace Nz return false; ///< Same ack } + /*! + * \brief Checks whether the connection is reliable + * \return true If it is the case + * + * \remark Produces a NazaraError if enumeration is invalid + */ + inline bool RUdpConnection::IsReliable(PacketReliability reliability) { switch (reliability) @@ -122,6 +199,14 @@ namespace Nz return false; } + /*! + * \brief Simulates the loss of packets on network + * + * \param packetLoss Ratio of packet loss according to bernoulli distribution + * + * \remark Produces a NazaraAssert if packetLoss is not in between 0.0 and 1.0 + */ + inline void RUdpConnection::SimulateNetwork(double packetLoss) { NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]"); diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index 0fcedcf39..fda4671f9 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -79,8 +79,8 @@ namespace Nz PendingPacket m_pendingPacket; UInt64 m_keepAliveInterval; UInt64 m_keepAliveTime; - bool m_isKeepAliveEnabled; bool m_isLowDelayEnabled; + bool m_isKeepAliveEnabled; }; } diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index da292b982..23f5412da 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -7,6 +7,10 @@ namespace Nz { + /*! + * \brief Constructs a TcpClient object by default + */ + inline TcpClient::TcpClient() : AbstractSocket(SocketType_TCP), Stream(StreamOption_Sequential), @@ -17,31 +21,62 @@ namespace Nz { } + /*! + * \brief Disconnects the connection + * + * \see Close + */ + inline void TcpClient::Disconnect() { Close(); } + /*! + * \brief Gets the interval between two keep alive pings + * \return Interval in milliseconds between two pings + */ + inline UInt64 TcpClient::GetKeepAliveInterval() const { return m_keepAliveInterval; } + /*! + * \brief Gets the time before expiration of connection + * \return Time in milliseconds before expiration + */ + inline UInt64 TcpClient::GetKeepAliveTime() const { return m_keepAliveTime; } + /*! + * \brief Gets the remote address + * \return Address of peer + */ + inline IpAddress TcpClient::GetRemoteAddress() const { return m_peerAddress; } + /*! + * \brief Checks whether low delay is enabled + * \return true If it is the case + */ + inline bool TcpClient::IsLowDelayEnabled() const { return m_isLowDelayEnabled; } + /*! + * \brief Checks whether the keep alive flag is enabled + * \return true If it is the case + */ + inline bool TcpClient::IsKeepAliveEnabled() const { return m_isKeepAliveEnabled; diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index 5350a58ee..1fcb4eb32 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -7,27 +7,58 @@ namespace Nz { + /*! + * \brief Constructs a TcpServer object by default + */ + inline TcpServer::TcpServer() : AbstractSocket(SocketType_TCP) { } + /*! + * \brief Constructs a TcpServer object with another one by move semantic + * + * \param tcpServer TcpServer to move into this + */ + inline TcpServer::TcpServer(TcpServer&& tcpServer) : AbstractSocket(std::move(tcpServer)), m_boundAddress(std::move(tcpServer.m_boundAddress)) { } + /*! + * \brief Gets the bound address + * \return IpAddress we are linked to + */ + inline IpAddress TcpServer::GetBoundAddress() const { return m_boundAddress; } + /*! + * \brief Gets the port of the bound address + * \return Port we are linked to + */ + inline UInt16 TcpServer::GetBoundPort() const { return m_boundAddress.GetPort(); } + /*! + * \brief Listens to a socket + * \return State of the socket + * + * \param protocol Net protocol to listen to + * \param port Port to listen to + * \param queueSize Size of the queue + * + * \remark Produces a NazaraAssert if protocol is unknown or any + */ + inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) { NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 96c391436..2aac124af 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -49,7 +49,6 @@ namespace Nz void OnOpened() override; IpAddress m_boundAddress; - SocketState m_state; bool m_isBroadCastingEnabled; }; } diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index 9ad4d067b..4096d8c04 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -6,24 +6,46 @@ namespace Nz { + /*! + * \brief Constructs a UdpSocket object by default + */ + inline UdpSocket::UdpSocket() : AbstractSocket(SocketType_UDP) { } + /*! + * \brief Constructs a UdpSocket object with a net protocol + * + * \param protocol Net protocol to use + */ + inline UdpSocket::UdpSocket(NetProtocol protocol) : UdpSocket() { Create(protocol); } + /*! + * \brief Constructs a UdpSocket object with another one by move semantic + * + * \param udpSocket UdpSocket to move into this + */ + inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) : AbstractSocket(std::move(udpSocket)), - m_boundAddress(std::move(udpSocket.m_boundAddress)), - m_state(udpSocket.m_state) + m_boundAddress(std::move(udpSocket.m_boundAddress)) { } + /*! + * \brief Binds a specific port + * \return State of the socket + * + * \param port Port to bind + */ + inline SocketState UdpSocket::Bind(UInt16 port) { IpAddress any; @@ -47,6 +69,13 @@ namespace Nz return Bind(any); } + /*! + * \brief Creates a UDP socket + * \return true If successful + * + * \param protocol Net protocol to use + */ + bool UdpSocket::Create(NetProtocol protocol) { NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); @@ -54,21 +83,41 @@ namespace Nz return Open(protocol); } + /*! + * \brief Gets the bound address + * \return IpAddress we are linked to + */ + inline IpAddress UdpSocket::GetBoundAddress() const { return m_boundAddress; } + /*! + * \brief Gets the port of the bound address + * \return Port we are linked to + */ + inline UInt16 UdpSocket::GetBoundPort() const { return m_boundAddress.GetPort(); } + /*! + * \brief Gets the state of the socket + * \return State of the socket + */ + inline SocketState UdpSocket::GetState() const { return m_state; } + /*! + * \brief Checks whether the broadcasting is enabled + * \return true If it is the case + */ + inline bool UdpSocket::IsBroadcastingEnabled() const { return m_isBroadCastingEnabled; diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index e46a5906a..516364373 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -17,6 +17,18 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::AbstractSocket + * \brief Network class that represents the base of socket + * + * \remark This class is abstract + */ + + /*! + * \brief Constructs a AbstractSocket object with a type + */ + AbstractSocket::AbstractSocket(SocketType type) : m_lastError(SocketError_NoError), m_handle(SocketImpl::InvalidHandle), @@ -26,6 +38,12 @@ namespace Nz { } + /*! + * \brief Constructs a AbstractSocket object with another one by move semantic + * + * \param abstractSocket AbstractSocket to move into this + */ + AbstractSocket::AbstractSocket(AbstractSocket&& abstractSocket) : m_protocol(abstractSocket.m_protocol), m_lastError(abstractSocket.m_lastError), @@ -37,11 +55,21 @@ namespace Nz abstractSocket.m_handle = SocketImpl::InvalidHandle; } + /*! + * \brief Destructs the object and calls Close + * + * \see Close + */ + AbstractSocket::~AbstractSocket() { Close(); } + /*! + * \brief Closes the socket + */ + void AbstractSocket::Close() { if (m_handle != SocketImpl::InvalidHandle) @@ -53,6 +81,12 @@ namespace Nz } } + /*! + * \brief Enables blocking + * + * \param blocking Should the read block + */ + void AbstractSocket::EnableBlocking(bool blocking) { if (m_isBlockingEnabled != blocking) @@ -64,6 +98,11 @@ namespace Nz } } + /*! + * \brief Queries the available bytes + * \return Number of bytes which can be read + */ + std::size_t AbstractSocket::QueryAvailableBytes() const { if (m_handle == SocketImpl::InvalidHandle) @@ -72,11 +111,21 @@ namespace Nz return SocketImpl::QueryAvailableBytes(m_handle); } + /*! + * \brief Operation to do when closing socket + */ + void AbstractSocket::OnClose() { UpdateState(SocketState_NotConnected); } + /*! + * \brief Operation to do when opening socket + * + * \remark Produces a NazaraWarning if blocking failed + */ + void AbstractSocket::OnOpened() { SocketError errorCode; @@ -84,6 +133,11 @@ namespace Nz NazaraWarning("Failed to set socket blocking mode (0x" + String::Number(errorCode, 16) + ')'); } + /*! + * \brief Opens the socket according to a net protocol + * \return true If successful + */ + bool AbstractSocket::Open(NetProtocol protocol) { if (m_handle == SocketImpl::InvalidHandle || m_protocol != protocol) @@ -99,6 +153,13 @@ namespace Nz return true; } + /*! + * \brief Opens the socket according to a socket handle + * \return true If successful + * + * \remark Produces a NazaraAssert if handle is invalid + */ + void AbstractSocket::Open(SocketHandle handle) { NazaraAssert(handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -109,6 +170,13 @@ namespace Nz OnOpened(); } + /*! + * \brief Moves the AbstractSocket into this + * \return A reference to this + * + * \param abstractSocket AbstractSocket to move in this + */ + AbstractSocket& AbstractSocket::operator=(AbstractSocket&& abstractSocket) { Close(); diff --git a/src/Nazara/Network/AlgorithmNetwork.cpp b/src/Nazara/Network/AlgorithmNetwork.cpp index 273169005..307ac679a 100644 --- a/src/Nazara/Network/AlgorithmNetwork.cpp +++ b/src/Nazara/Network/AlgorithmNetwork.cpp @@ -11,6 +11,15 @@ namespace Nz { namespace Detail { + /*! + * \brief Parses a decimal number + * \return true If successful + * + * \param str C-string symbolizing the string to parse + * \param number Optional argument to return the number parsed + * \param endOfRead Optional argument to determine where parsing stopped + */ + bool ParseDecimal(const char* str, unsigned int* number, const char** endOfRead) { const char* ptr = str; @@ -35,6 +44,15 @@ namespace Nz return true; } + /*! + * \brief Parses a hexadecimal number + * \return true If successful + * + * \param str C-string symbolizing the string to parse + * \param number Optional argument to return the number parsed + * \param endOfRead Optional argument to determine where parsing stopped + */ + bool ParseHexadecimal(const char* str, unsigned int* number, const char** endOfRead) { const char* ptr = str; @@ -60,10 +78,26 @@ namespace Nz } } - // From http://rosettacode.org/wiki/Parse_an_IP_Address - // Parse a textual IPv4 or IPv6 address, optionally with port, into a binary - // array (for the address, in host order), and an optionally provided port. - // Also, indicate which of those forms (4 or 6) was parsed. + /*! + * \ingroup network + * \brief Parse a textual IPv4 or IPv6 address + * \return true If successful + * + * From http://rosettacode.org/wiki/Parse_an_IP_Address + * Parse a textual IPv4 or IPv6 address, optionally with port, into a binary + * array (for the address, in host order), and an optionally provided port. + * Also, indicate which of those forms (4 or 6) was parsed. + * + * \param addressPtr C-string which symbolizes the ip adress + * \param result Byte array to return the result in + * \param port Optional argument to resolve according to a specific port + * \param isIPv6 Optional argument to determine if the address is IPv6 + * \param endOfRead Optional argument to determine where parsing stopped + * + * \remark Produces a NazaraAssert if addressPtr is invalid + * \remark Produces a NazaraAssert if result is invalid + */ + bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port, bool* isIPv6, const char** endOfRead) { NazaraAssert(addressPtr, "Invalid address string"); diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index d40e2a581..29be756ea 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -22,6 +22,19 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::IpAddress + * \brief Network class that represents an IP address + */ + + /*! + * \brief Builds the IP from a hostname + * \return true If successful + * + * \remark address C-string symbolizing the IP address or hostname + */ + bool IpAddress::BuildFromAddress(const char* address) { m_isValid = false; @@ -50,6 +63,13 @@ namespace Nz return true; } + /*! + * \brief Checks whether the IP address is loopback + * \return true If it is the case + * + * \remark Produces a NazaraAssert if internal protocol is invalid (should never happen) + */ + bool IpAddress::IsLoopback() const { if (!m_isValid) @@ -73,6 +93,13 @@ namespace Nz return false; } + /*! + * \brief Gives a string representation + * \return A string representation of the object + * + * \remark Produces a NazaraAssert if internal protocol is invalid (should never happen) + */ + String IpAddress::ToString() const { StringStream stream; @@ -153,6 +180,17 @@ namespace Nz return stream; } + /*! + * \brief Resolves the address based on the IP + * \return Hostname of the address + * + * \param address IP address to resolve + * \param service Optional argument to specify the protocol used + * \param error Optional argument to get the error + * + * \remark Produces a NazaraAssert if address is invalid + */ + String IpAddress::ResolveAddress(const IpAddress& address, String* service, ResolveError* error) { NazaraAssert(address.IsValid(), "Invalid address"); @@ -163,6 +201,18 @@ namespace Nz return hostname; } + /*! + * \brief Resolves the address based on the hostname + * \return Informations about the host: IP(s) of the address, names, ... + * + * \param protocol Net protocol to use + * \param hostname Hostname to resolve + * \param service Specify the service used (http, ...) + * \param error Optional argument to get the error + * + * \remark Produces a NazaraAssert if net protocol is set to unknown + */ + std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service, ResolveError* error) { NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); diff --git a/src/Nazara/Network/NetPacket.cpp b/src/Nazara/Network/NetPacket.cpp index 7a1c0d7f5..0823f5258 100644 --- a/src/Nazara/Network/NetPacket.cpp +++ b/src/Nazara/Network/NetPacket.cpp @@ -9,11 +9,36 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::NetPacket + * \brief Network class that represents a packet + */ + + /*! + * \brief Operation to do when receiving data + * + * \param netCode Packet number + * \param data Raw memory + * \param size Size of the memory + */ + void NetPacket::OnReceive(UInt16 netCode, const void* data, std::size_t size) { Reset(netCode, data, size); } + /*! + * \brief Operation to do when sending data + * \return Beggining of the raw memory + * + * \param newSize Size of the memory to send + * + * \remark Produces a NazaraAssert if newSize is invalid + * \remark Produces a NazaraAssert if net code is invalid + * \remark Produces a NazaraError if header could not be encoded + */ + const void* NetPacket::OnSend(std::size_t* newSize) const { NazaraAssert(newSize, "Invalid size pointer"); @@ -30,6 +55,15 @@ namespace Nz return m_buffer->GetBuffer(); } + /*! + * \brief Decodes the header of the packet + * \return true If successful + * + * \param data Raw memory + * \param packetSize Size of the packet + * \param netCode Packet number + */ + bool NetPacket::DecodeHeader(const void* data, UInt16* packetSize, UInt16* netCode) { MemoryView stream(data, HeaderSize); @@ -40,6 +74,15 @@ namespace Nz return Unserialize(context, packetSize) && Unserialize(context, netCode); } + /*! + * \brief Encodes the header of the packet + * \return true If successful + * + * \param data Raw memory + * \param packetSize Size of the packet + * \param netCode Packet number + */ + bool NetPacket::EncodeHeader(void* data, UInt16 packetSize, UInt16 netCode) { MemoryView stream(data, HeaderSize); @@ -50,11 +93,19 @@ namespace Nz return Serialize(context, packetSize) && Serialize(context, netCode); } + /*! + * \brief Operation to do when stream is empty + */ + void NetPacket::OnEmptyStream() { Reset(0); } + /*! + * \brief Frees the stream + */ + void NetPacket::FreeStream() { if (!m_buffer) @@ -66,6 +117,16 @@ namespace Nz s_availableBuffers.emplace_back(std::make_pair(size, std::move(m_buffer))); } + /*! + * \brief Inits the internal stream + * + * \param minCapacity Minimal capacity of the stream + * \param cursorPos Position of the cursor in the stream + * \param openMode Flag of the stream + * + * \remark Produces a NazaraAssert if cursor position is greather than the capacity + */ + void NetPacket::InitStream(std::size_t minCapacity, UInt64 cursorPos, UInt32 openMode) { NazaraAssert(minCapacity >= cursorPos, "Cannot init stream with a smaller capacity than wanted cursor pos"); @@ -92,12 +153,21 @@ namespace Nz SetStream(&m_memoryStream); } + /*! + * \brief Initializes the NetPacket class + * \return true If initialization is successful + */ + bool NetPacket::Initialize() { s_availableBuffersMutex = std::make_unique(); return true; } + /*! + * \brief Uninitializes the NetPacket class + */ + void NetPacket::Uninitialize() { s_availableBuffers.clear(); diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp index 41868b79b..fa3813dd4 100644 --- a/src/Nazara/Network/Network.cpp +++ b/src/Nazara/Network/Network.cpp @@ -24,9 +24,23 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::Network + * \brief Network class that represents the module initializer of Network + */ + + /*! + * \brief Initializes the Network module + * \return true if initialization is successful + * + * \remark Produces a NazaraNotice + * \remark Produces a NazaraError if one submodule failed + */ + bool Network::Initialize() { - if (s_moduleReferenceCounter > 0) + if (IsInitialized()) { s_moduleReferenceCounter++; return true; // Already initialized @@ -68,11 +82,22 @@ namespace Nz return true; } + /*! + * \brief Checks whether the module is initialized + * \return true if module is initialized + */ + bool Network::IsInitialized() { return s_moduleReferenceCounter != 0; } + /*! + * \brief Uninitializes the Core module + * + * \remark Produces a NazaraNotice + */ + void Network::Uninitialize() { if (s_moduleReferenceCounter != 1) diff --git a/src/Nazara/Network/RUdpConnection.cpp b/src/Nazara/Network/RUdpConnection.cpp index 451d08f1e..1b374d604 100644 --- a/src/Nazara/Network/RUdpConnection.cpp +++ b/src/Nazara/Network/RUdpConnection.cpp @@ -10,6 +10,16 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::RUdpConnection + * \brief Network class that represents a reliable UDP connection + */ + + /*! + * \brief Constructs a RUdpConnection object by default + */ + RUdpConnection::RUdpConnection() : m_peerIterator(0), m_forceAckSendTime(10'000), //< 10ms @@ -23,9 +33,20 @@ namespace Nz { } + /*! + * \brief Connects to the IpAddress + * \return true + * + * \param remoteAddress Address to connect to + * + * \remark Produces a NazaraAssert if socket is not bound + * \remark Produces a NazaraAssert if remote is invalid + * \remark Produces a NazaraAssert if port is not specified + */ + bool RUdpConnection::Connect(const IpAddress& remoteAddress) { - NazaraAssert(m_socket.GetState() != SocketState_Bound, "Socket must be bound first"); + NazaraAssert(m_socket.GetState() == SocketState_Bound, "Socket must be bound first"); NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); @@ -39,6 +60,16 @@ namespace Nz return true; } + /*! + * \brief Connects to the hostname + * \return true If successful + * + * \param hostName Hostname of the remote + * \param protocol Net protocol to use + * \param service Specify the protocol used + * \param error Optional argument to get the error + */ + bool RUdpConnection::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) { std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); @@ -64,6 +95,13 @@ namespace Nz return Connect(hostnameAddress); } + /*! + * \brief Listens to a socket + * \return true If successfully bound + * + * \param remoteAddress Address to listen to + */ + bool RUdpConnection::Listen(const IpAddress& address) { if (!InitSocket(address.GetProtocol())) @@ -72,8 +110,19 @@ namespace Nz return m_socket.Bind(address) == SocketState_Bound; } + /*! + * \brief Polls the message + * \return true If there is a message + * + * \param message Message to poll + * + * \remark Produces a NazaraAssert if message is invalid + */ + bool RUdpConnection::PollMessage(RUdpMessage* message) { + NazaraAssert(message, "Invalid message"); + if (m_receivedMessages.empty()) return false; @@ -82,6 +131,16 @@ namespace Nz return true; } + /*! + * \brief Sends the packet to a peer + * \return true If peer exists (false may result from disconnected client) + * + * \param peerIp IpAddress of the peer + * \param priority Priority of the packet + * \param reliability Policy of reliability of the packet + * \param packet Packet to send + */ + bool RUdpConnection::Send(const IpAddress& peerIp, PacketPriority priority, PacketReliability reliability, const NetPacket& packet) { auto it = m_peerByIP.find(peerIp); @@ -92,6 +151,10 @@ namespace Nz return true; } + /*! + * \brief Updates the reliable connection + */ + void RUdpConnection::Update() { m_currentTime = m_clock.GetMicroseconds(); @@ -156,6 +219,14 @@ namespace Nz //m_activeClients.Reset(); } + /*! + * \brief Disconnects a peer + * + * \param peerIndex Index of the peer + * + * \remark Produces a NazaraNotice + */ + void RUdpConnection::DisconnectPeer(std::size_t peerIndex) { PeerData& peer = m_peers[peerIndex]; @@ -193,6 +264,15 @@ namespace Nz m_peers.pop_back(); } + /*! + * \brief Enqueues a packet in the sending list + * + * \param peer Data relative to the peer + * \param priority Priority of the packet + * \param reliability Policy of reliability of the packet + * \param packet Packet to send + */ + void RUdpConnection::EnqueuePacket(PeerData& peer, PacketPriority priority, PacketReliability reliability, const NetPacket& packet) { UInt16 protocolBegin = static_cast(m_protocol & 0xFFFF); @@ -208,6 +288,15 @@ namespace Nz EnqueuePacketInternal(peer, priority, reliability, std::move(data)); } + /*! + * \brief Enqueues internally a packet in the sending list + * + * \param peer Data relative to the peer + * \param priority Priority of the packet + * \param reliability Policy of reliability of the packet + * \param packet Packet to send + */ + void RUdpConnection::EnqueuePacketInternal(PeerData& peer, PacketPriority priority, PacketReliability reliability, NetPacket&& data) { PendingPacket pendingPacket; @@ -219,6 +308,13 @@ namespace Nz m_activeClients.UnboundedSet(peer.index); } + /*! + * \brief Inits the internal socket + * \return true If successful + * + * \param protocol Net protocol to use + */ + bool RUdpConnection::InitSocket(NetProtocol protocol) { CallOnExit updateLastError([this] @@ -233,6 +329,14 @@ namespace Nz return true; } + /*! + * \brief Processes the acks + * + * \param peer Data relative to the peer + * \param lastAck Last index of the ack + * \param ackBits Bits for acking + */ + void RUdpConnection::ProcessAcks(PeerData& peer, SequenceIndex lastAck, UInt32 ackBits) { auto it = peer.pendingAckQueue.begin(); @@ -257,6 +361,14 @@ namespace Nz } } + /*! + * \brief Registers a peer + * \return Data relative to the peer + * + * \param address Address of the peer + * \param state Status of the peer + */ + RUdpConnection::PeerData& RUdpConnection::RegisterPeer(const IpAddress& address, PeerState state) { PeerData data; @@ -266,7 +378,7 @@ namespace Nz data.index = m_peers.size(); data.lastPacketTime = m_currentTime; data.lastPingTime = m_currentTime; - data.roundTripTime = 1000000; ///< Okay that's quite a lot + data.roundTripTime = 1'000'000; ///< Okay that's quite a lot data.state = state; m_activeClients.UnboundedSet(data.index); @@ -276,6 +388,14 @@ namespace Nz return m_peers.back(); } + /*! + * \brief Operation to do when client requests a connection + * + * \param address Address of the peer + * \param sequenceId Sequence index for the ack + * \param token Token for connection + */ + void RUdpConnection::OnClientRequestingConnection(const IpAddress& address, SequenceIndex sequenceId, UInt64 token) { // Call hook to check if client should be accepted or not @@ -292,6 +412,13 @@ namespace Nz EnqueuePacket(client, PacketPriority_Immediate, PacketReliability_Reliable, connectionAcceptedPacket); } + /*! + * \brief Operation to do when a packet is lost + * + * \param peer Data relative to the peer + * \param packet Pending packet + */ + void RUdpConnection::OnPacketLost(PeerData& peer, PendingAckPacket&& packet) { //NazaraNotice(m_socket.GetBoundAddress().ToString() + ": Lost packet " + String::Number(packet.sequenceId)); @@ -300,6 +427,14 @@ namespace Nz EnqueuePacketInternal(peer, packet.priority, packet.reliability, std::move(packet.data)); } + /*! + * \brief Operation to do when receiving a packet + * + * \param peerIndex Index of the peer + * + * \remark Produces a NazaraNotice + */ + void RUdpConnection::OnPacketReceived(const IpAddress& peerIp, NetPacket&& packet) { UInt16 protocolBegin; @@ -436,6 +571,13 @@ namespace Nz } } + /*! + * \brief Sends a packet to a peer + * + * \param peer Data relative to the peer + * \param packet Pending packet + */ + void RUdpConnection::SendPacket(PeerData& peer, PendingPacket&& packet) { if (peer.state == PeerState_WillAck) @@ -448,7 +590,7 @@ namespace Nz { if (ack == remoteSequence) continue; - + unsigned int difference = ComputeSequenceDifference(remoteSequence, ack); if (difference <= 32U) previousAcks |= (1U << (difference - 1)); @@ -473,6 +615,11 @@ namespace Nz peer.pendingAckQueue.emplace_back(std::move(pendingAckPacket)); } + /*! + * \brief Initializes the RUdpConnection class + * \return true + */ + bool RUdpConnection::Initialize() { std::random_device device; @@ -481,6 +628,10 @@ namespace Nz return true; } + /*! + * \brief Uninitializes the RUdpConnection class + */ + void RUdpConnection::Uninitialize() { } diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index a134cf870..cf123ff89 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -20,6 +20,22 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::TcpClient + * \brief Network class that represents a client in a TCP connection + */ + + /*! + * \brief Connects to the IpAddress + * \return State of the socket + * + * \param remoteAddress Address to connect to + * + * \remark Produces a NazaraAssert if remote is invalid + * \remark Produces a NazaraAssert if remote's port is not specified + */ + SocketState TcpClient::Connect(const IpAddress& remoteAddress) { NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); @@ -45,6 +61,17 @@ namespace Nz return state; } + + /*! + * \brief Connects to the hostname + * \return State of the socket + * + * \param hostName Hostname of the remote + * \param protocol Net protocol to use + * \param service Specify the protocol used + * \param error Optional argument to get the error + */ + SocketState TcpClient::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) { UpdateState(SocketState_Resolving); @@ -73,6 +100,14 @@ namespace Nz return Connect(hostnameAddress); } + /*! + * \brief Enables low delay in emitting + * + * \param lowDelay Should low delay be used + * + * \remark This may produce lag + */ + void TcpClient::EnableLowDelay(bool lowDelay) { if (m_isLowDelayEnabled != lowDelay) @@ -84,6 +119,14 @@ namespace Nz } } + /*! + * \brief Enables the keep alive flag + * + * \param keepAlive Should the connection be kept alive + * \param msTime Time in milliseconds before expiration + * \param msInterval Interval in milliseconds between two pings + */ + void TcpClient::EnableKeepAlive(bool keepAlive, UInt64 msTime, UInt64 msInterval) { if (m_isKeepAliveEnabled != keepAlive || m_keepAliveTime != msTime || m_keepAliveInterval != msInterval) @@ -97,22 +140,51 @@ namespace Nz } } + /*! + * \brief Checks whether the stream reached the end of the stream + * \return true if there is no more available bytes + */ + bool TcpClient::EndOfStream() const { return QueryAvailableBytes() == 0; } + /*! + * \brief Gets the position of the cursor + * \return 0 + * + * \remark Produces a NazaraError because it is a special stream + */ + UInt64 TcpClient::GetCursorPos() const { NazaraError("GetCursorPos() cannot be used on sequential streams"); return 0; } + /*! + * \brief Gets the size of the raw memory available + * \return Size of the memory available + */ + UInt64 TcpClient::GetSize() const { return QueryAvailableBytes(); } + /*! + * \brief Receives the data available + * \return true If data received + * + * \param buffer Raw memory to write + * \param size Size of the buffer + * \param received Optional argument to get the number of bytes received + * + * \remark Produces a NazaraAssert if socket is invalid + * \remark Produces a NazaraAssert if buffer and its size is invalid + */ + bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -142,6 +214,17 @@ namespace Nz return true; } + /*! + * \brief Receives the packet available + * \return true If packet received + * + * \param packet Packet to receive + * + * \remark Produces a NazaraAssert if packet is invalid + * \remark Produces a NazaraAssert if packet size is inferior to the header size + * \remark Produces a NazaraWarning if packet's header is invalid + */ + bool TcpClient::ReceivePacket(NetPacket* packet) { //TODO: Every packet requires at least two Receive call, using an internal buffer of a fixed size would prevent this @@ -157,6 +240,7 @@ namespace Nz m_pendingPacket.received += received; + //TODO: Should never happen in production ! NazaraAssert(m_pendingPacket.received <= NetPacket::HeaderSize, "Received more data than header size"); if (m_pendingPacket.received >= NetPacket::HeaderSize) { @@ -185,6 +269,7 @@ namespace Nz m_pendingPacket.received += received; + //TODO: Should never happen in production ! NazaraAssert(m_pendingPacket.received <= packetSize, "Received more data than packet size"); if (m_pendingPacket.received >= packetSize) { @@ -202,6 +287,19 @@ namespace Nz return false; } + /*! + * \brief Sends the data available + * \return true If data sended + * + * \param buffer Raw memory to read + * \param size Size of the buffer + * \param sent Optional argument to get the number of bytes sent + * + * \remark Large sending are handled, you do not need to call this multiple time + * \remark Produces a NazaraAssert if socket is invalid + * \remark Produces a NazaraAssert if buffer and its size is invalid + */ + bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -244,6 +342,15 @@ namespace Nz return true; } + /*! + * \brief Sends the packet available + * \return true If packet sent + * + * \param packet Packet to send + * + * \remark Produces a NazaraError if packet could not be prepared for sending + */ + bool TcpClient::SendPacket(const NetPacket& packet) { std::size_t size = 0; @@ -258,12 +365,30 @@ namespace Nz return Send(ptr, size, nullptr); } + /*! + * \brief Sets the position of the cursor + * \return false + * + * \param offset Offset according to the beginning of the stream + * + * \remark Produces a NazaraError because it is a special stream + */ + bool TcpClient::SetCursorPos(UInt64 offset) { NazaraError("SetCursorPos() cannot be used on sequential streams"); return false; } + /*! + * \brief Waits for being connected before time out + * \return true If connection is successful + * + * \param msTimeout Time in milliseconds before time out + * + * \remark Produces a NazaraAssert if socket is invalid + */ + bool TcpClient::WaitForConnected(UInt64 msTimeout) { switch (m_state) @@ -308,10 +433,18 @@ namespace Nz return false; } + /*! + * \brief Flushes the stream + */ + void TcpClient::FlushStream() { } + /*! + * \brief Operation to do when closing socket + */ + void TcpClient::OnClose() { AbstractSocket::OnClose(); @@ -320,6 +453,12 @@ namespace Nz m_peerAddress = IpAddress::Invalid; } + /*! + * \brief Operation to do when opening socket + * + * \remark Produces a NazaraWarning if delay mode or keep alive failed + */ + void TcpClient::OnOpened() { AbstractSocket::OnOpened(); @@ -336,6 +475,16 @@ namespace Nz m_openMode = OpenMode_ReadWrite; } + /*! + * \brief Reads blocks + * \return Number of blocks read + * + * \param buffer Preallocated buffer to contain information read + * \param size Size of the read and thus of the buffer + * + * \remark Produces a NazaraAssert if socket is invalid + */ + std::size_t TcpClient::ReadBlock(void* buffer, std::size_t size) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -357,6 +506,13 @@ namespace Nz return received; } + /*! + * \brief Resets the connection with a new socket and a peer address + * + * \param handle Socket to connect + * \param peerAddress Address to connect to + */ + void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress) { Open(handle); @@ -365,8 +521,20 @@ namespace Nz UpdateState(SocketState_Connected); } + /*! + * \brief Writes blocks + * \return Number of blocks written + * + * \param buffer Preallocated buffer containing information to write + * \param size Size of the writting and thus of the buffer + * + * \remark Produces a NazaraAssert if buffer is nullptr + * \remark Produces a NazaraAssert if socket is invalid + */ + std::size_t TcpClient::WriteBlock(const void* buffer, std::size_t size) { + NazaraAssert(buffer, "Invalid buffer"); NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); CallOnExit restoreBlocking; diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index b5995b6f5..7a33c066b 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -19,6 +19,22 @@ namespace Nz { + /*! + * \ingroup network + * \class Nz::TcpServer + * \brief Network class that represents a server in a TCP connection + */ + + /*! + * \brief Accepts a client + * \return true If client'socket is valid + * + * \param newClient Client connection + * + * \remark Produces a NazaraAssert if socket is invalid + * \remark Produces a NazaraAssert if newClient is invalid + */ + bool TcpServer::AcceptClient(TcpClient* newClient) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Server isn't listening"); @@ -35,6 +51,16 @@ namespace Nz return false; } + /*! + * \brief Listens to a socket + * \return State of the socket + * + * \param address Address to listen to + * \param queueSize Size of the queue + * + * \remark Produces a NazaraAssert if address is invalid + */ + SocketState TcpServer::Listen(const IpAddress& address, unsigned int queueSize) { NazaraAssert(address.IsValid(), "Invalid address"); @@ -49,6 +75,10 @@ namespace Nz return state; } + /*! + * \brief Operation to do when closing socket + */ + void TcpServer::OnClose() { AbstractSocket::OnClose(); @@ -56,6 +86,10 @@ namespace Nz m_boundAddress = IpAddress::Invalid; } + /*! + * \brief Operation to do when opening socket + */ + void TcpServer::OnOpened() { AbstractSocket::OnOpened(); diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index a233881ea..b49aedcf3 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -17,6 +17,16 @@ namespace Nz { + /*! + * \brief Binds a specific IpAddress + * \return State of the socket + * + * \param address Address to bind + * + * \remark Produces a NazaraAssert if socket is invalid + * \remark Produces a NazaraAssert if address is invalid + */ + SocketState UdpSocket::Bind(const IpAddress& address) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); @@ -30,6 +40,14 @@ namespace Nz return state; } + /*! + * \brief Enables broadcasting + * + * \param broadcasting Should the UDP broadcast + * + * \remark Produces a NazaraAssert if socket is invalid + */ + void UdpSocket::EnableBroadcasting(bool broadcasting) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -41,6 +59,13 @@ namespace Nz } } + /*! + * \brief Gets the maximum datagram size allowed + * \return Number of bytes + * + * \remark Produces a NazaraAssert if socket is invalid + */ + std::size_t UdpSocket::QueryMaxDatagramSize() { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); @@ -48,8 +73,22 @@ namespace Nz return SocketImpl::QueryMaxDatagramSize(m_handle, &m_lastError); } + /*! + * \brief Receives the data available + * \return true If data received + * + * \param buffer Raw memory to write + * \param size Size of the buffer + * \param from IpAddress of the peer + * \param received Optional argument to get the number of bytes received + * + * \remark Produces a NazaraAssert if socket is invalid + * \remark Produces a NazaraAssert if buffer and its size is invalid + */ + bool UdpSocket::Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); NazaraAssert(buffer && size > 0, "Invalid buffer"); int read; @@ -62,8 +101,21 @@ namespace Nz return true; } + /*! + * \brief Receives the packet available + * \return true If packet received + * + * \param packet Packet to receive + * \param from IpAddress of the peer + * + * \remark Produces a NazaraAssert if packet is invalid + * \remark Produces a NazaraWarning if packet's header is invalid + */ + bool UdpSocket::ReceivePacket(NetPacket* packet, IpAddress* from) { + NazaraAssert(packet, "Invalid packet"); + // I'm not sure what's the best between having a 65k bytes buffer ready for any datagram size // or querying the next datagram size every time, for now I'll leave it as is packet->Reset(NetCode_Invalid, std::numeric_limits::max()); @@ -97,6 +149,20 @@ namespace Nz return true; } + /*! + * \brief Sends the data available + * \return true If data sended + * + * \param to IpAddress of the peer + * \param buffer Raw memory to read + * \param size Size of the buffer + * \param sent Optional argument to get the number of bytes sent + * + * \remark Produces a NazaraAssert if peer address is invalid + * \remark Produces a NazaraAssert if protocol of communication is not the same than the peer + * \remark Produces a NazaraAssert if buffer and its size is invalid + */ + bool UdpSocket::Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent) { NazaraAssert(to.IsValid(), "Invalid ip address"); @@ -113,6 +179,16 @@ namespace Nz return true; } + /*! + * \brief Sends the packet available + * \return true If packet sent + * + * \param to IpAddress of the peer + * \param packet Packet to send + * + * \remark Produces a NazaraError if packet could not be prepared for sending + */ + bool UdpSocket::SendPacket(const IpAddress& to, const NetPacket& packet) { std::size_t size = 0; @@ -127,6 +203,10 @@ namespace Nz return Send(to, ptr, size, nullptr); } + /*! + * \brief Operation to do when closing socket + */ + void UdpSocket::OnClose() { AbstractSocket::OnClose(); @@ -134,6 +214,10 @@ namespace Nz m_boundAddress = IpAddress::Invalid; } + /*! + * \brief Operation to do when opening socket + */ + void UdpSocket::OnOpened() { AbstractSocket::OnOpened(); diff --git a/tests/Engine/Network/IpAddress.cpp b/tests/Engine/Network/IpAddress.cpp new file mode 100644 index 000000000..8bb3e7d16 --- /dev/null +++ b/tests/Engine/Network/IpAddress.cpp @@ -0,0 +1,47 @@ +#include +#include + +SCENARIO("IpAddress", "[NETWORK][IPADDRESS]") +{ + GIVEN("Two default IpAddress") + { + Nz::IpAddress ipAddressV4; + Nz::IpAddress ipAddressV6; + + WHEN("We parse localhost") + { + Nz::String localhostIPv4 = "127.0.0.1"; + Nz::String localhostIPv6 = "::1"; + REQUIRE(ipAddressV4.BuildFromAddress(localhostIPv4.GetConstBuffer())); + REQUIRE(ipAddressV6.BuildFromAddress(localhostIPv6.GetConstBuffer())); + + THEN("It's the loop back") + { + REQUIRE(ipAddressV4.IsLoopback()); + REQUIRE(ipAddressV6.IsLoopback()); + } + } + } + + GIVEN("No IpAddress") + { + WHEN("We get the IP of Nazara") + { + std::vector hostnameInfos = Nz::IpAddress::ResolveHostname(Nz::NetProtocol_IPv4, "nazara.digitalpulsesoftware.net"); + + THEN("Result is not null") + { + REQUIRE(!hostnameInfos.empty()); + } + } + + WHEN("We convert IP to hostname") + { + Nz::IpAddress google(8, 8, 8, 8); + THEN("Google (DNS) is 8.8.8.8") + { + REQUIRE(Nz::IpAddress::ResolveAddress(google) == "google-public-dns-a.google.com"); + } + } + } +} diff --git a/tests/Engine/Network/RUdpConnection.cpp b/tests/Engine/Network/RUdpConnection.cpp new file mode 100644 index 000000000..a39100e94 --- /dev/null +++ b/tests/Engine/Network/RUdpConnection.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include + +SCENARIO("RUdpConnection", "[NETWORK][RUDPCONNECTION]") +{ + GIVEN("Two RUdpConnection, one client, one server") + { + Nz::UInt16 port = 64266; + Nz::RUdpConnection server; + REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port)); + Nz::IpAddress serverIP = server.GetBoundAddress(); + REQUIRE(serverIP.IsValid()); + Nz::RUdpConnection client; + REQUIRE(client.Listen(Nz::NetProtocol_IPv4, port + 1)); + Nz::IpAddress clientIP = client.GetBoundAddress(); + REQUIRE(client.Connect(serverIP)); + REQUIRE(clientIP.IsValid()); + + WHEN("We send data from client") + { + Nz::NetPacket packet(1); + Nz::Vector3f vector123(1.f, 2.f, 3.f); + packet << vector123; + REQUIRE(client.Send(serverIP, Nz::PacketPriority_Immediate, Nz::PacketReliability_Reliable, packet)); + client.Update(); + + THEN("We should get it on the server") + { + Nz::RUdpMessage rudpMessage; + server.Update(); + REQUIRE(server.PollMessage(&rudpMessage)); + Nz::Vector3f result; + rudpMessage.data >> result; + REQUIRE(result == vector123); + } + } + } +} diff --git a/tests/Engine/Network/TCP.cpp b/tests/Engine/Network/TCP.cpp new file mode 100644 index 000000000..63b4fe2df --- /dev/null +++ b/tests/Engine/Network/TCP.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +#include +#include + +#include + +SCENARIO("TCP", "[NETWORK][TCP]") +{ + GIVEN("Two TCP, one client, one server") + { + // Avoid reusing the same socket + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(1025, 64245); + + Nz::UInt16 port = dis(gen); + Nz::TcpServer server; + REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port) == Nz::SocketState_Bound); + Nz::IpAddress serverIP = server.GetBoundAddress(); + REQUIRE(serverIP.IsValid()); + Nz::TcpClient client; + REQUIRE(client.Connect(serverIP) == Nz::SocketState_Connecting); + Nz::IpAddress clientIP = client.GetRemoteAddress(); + REQUIRE(clientIP.IsValid()); + + Nz::TcpClient serverToClient; + REQUIRE(server.AcceptClient(&serverToClient)); + + WHEN("We send data from client") + { + Nz::NetPacket packet(1); + Nz::Vector3f vector123(1.f, 2.f, 3.f); + packet << vector123; + REQUIRE(client.SendPacket(packet)); + + THEN("We should get it on the server") + { + Nz::NetPacket resultPacket; + REQUIRE(serverToClient.ReceivePacket(&resultPacket)); + Nz::Vector3f result; + resultPacket >> result; + REQUIRE(result == vector123); + } + } + } +} diff --git a/tests/Engine/Network/UdpSocket.cpp b/tests/Engine/Network/UdpSocket.cpp new file mode 100644 index 000000000..3f199f09e --- /dev/null +++ b/tests/Engine/Network/UdpSocket.cpp @@ -0,0 +1,39 @@ +#include +#include + +#include +#include + +SCENARIO("UdpSocket", "[NETWORK][UDPSOCKET]") +{ + GIVEN("Two UdpSocket, one client, one server") + { + Nz::UInt16 port = 64256; + Nz::UdpSocket server(Nz::NetProtocol_IPv4); + REQUIRE(server.Bind(port) == Nz::SocketState_Bound); + Nz::IpAddress serverIP = server.GetBoundAddress(); + REQUIRE(serverIP.IsValid()); + Nz::UdpSocket client(Nz::NetProtocol_IPv4); + REQUIRE(client.Bind(port + 1) == Nz::SocketState_Bound); + Nz::IpAddress clientIP = client.GetBoundAddress(); + REQUIRE(clientIP.IsValid()); + + WHEN("We send data from client") + { + Nz::NetPacket packet(1); + Nz::Vector3f vector123(1.f, 2.f, 3.f); + packet << vector123; + REQUIRE(client.SendPacket(serverIP, packet)); + + THEN("We should get it on the server") + { + Nz::NetPacket resultPacket; + Nz::IpAddress fromIp; + REQUIRE(server.ReceivePacket(&resultPacket, &fromIp)); + Nz::Vector3f result; + resultPacket >> result; + REQUIRE(result == vector123); + } + } + } +} From c3d3ad20ac6bbb3d9bdf5fd17824bbef646d43b9 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:26:32 +0200 Subject: [PATCH 094/224] Fix loading of MD5 Former-commit-id: 169cc42b3cd41e62ccdd4095acc8383f15df2de9 --- src/Nazara/Utility/Animation.cpp | 2 ++ src/Nazara/Utility/Formats/MD5AnimParser.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index bbd57b1df..62591344b 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -37,6 +37,8 @@ namespace Nz Animation::~Animation() { OnAnimationRelease(this); + + Destroy(); } bool Animation::AddSequence(const Sequence& sequence) diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index 321ee8692..9cd930c2e 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -285,7 +285,8 @@ namespace Nz if (!Advance()) return false; - if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, + // Space is important for the buffer of \n + if (std::sscanf(&m_currentLine[0], " ( %f %f %f ) ( %f %f %f )", &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, &m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 6) { UnrecognizedLine(true); @@ -324,7 +325,8 @@ namespace Nz return false; Vector3f min, max; - if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &min.x, &min.y, &min.z, &max.x, &max.y, &max.z) != 6) + // Space is important for the buffer of \n + if (std::sscanf(&m_currentLine[0], " ( %f %f %f ) ( %f %f %f )", &min.x, &min.y, &min.z, &max.x, &max.y, &max.z) != 6) { UnrecognizedLine(true); return false; From 4e2072afee6e655df75a3709764b48e63e467557 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:27:07 +0200 Subject: [PATCH 095/224] Slightly faster (about 5%) Former-commit-id: a9f7b38d9333fecb6e6a02886b852e257c01554b --- src/Nazara/Utility/AlgorithmUtility.cpp | 33 ++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index 7f4dbaf44..c13d393dd 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -105,9 +105,9 @@ namespace Nz for (unsigned int i = 0; i < recursionLevel; ++i) { std::size_t triangleCount = triangles.size(); - for (std::size_t j = 0; j < triangleCount; ++j) + for (std::size_t i = 0; i < triangleCount; ++i) { - Vector3ui& triangle = triangles[j]; + Vector3ui& triangle = triangles[i]; unsigned int a = GetMiddleVertex(triangle.x, triangle.y); unsigned int b = GetMiddleVertex(triangle.y, triangle.z); @@ -333,21 +333,20 @@ namespace Nz } private: - float CalculateVertexScore(unsigned int vertex) const + float CalculateVertexScore(VertexCacheData& vertex) const { - const VertexCacheData* v = &m_vertices[vertex]; - if (v->remaining_valence <= 0) + if (vertex.remaining_valence <= 0) // No tri needs this vertex! return -1.0f; float ret = 0.0f; - if (v->position_in_cache < 0) + if (vertex.position_in_cache < 0) { // Vertex is not in FIFO cache - no score. } else { - if (v->position_in_cache < 3) + if (vertex.position_in_cache < 3) { // This vertex was used in the last triangle, // so it has a fixed score, whichever of the three @@ -360,14 +359,14 @@ namespace Nz { // Points for being high in the cache. const float Scaler = 1.0f / (32 - 3); - ret = 1.0f - (v->position_in_cache - 3) * Scaler; + ret = 1.0f - (vertex.position_in_cache - 3) * Scaler; ret = std::pow(ret, m_cacheDecayPower); } } // Bonus points for having a low number of tris still to // use the vert, so we get rid of lone verts quickly. - float valence_boost = std::pow(static_cast(v->remaining_valence), -m_valenceBoostPower); + float valence_boost = std::pow(static_cast(vertex.remaining_valence), -m_valenceBoostPower); ret += m_valenceBoostScale * valence_boost; return ret; @@ -378,8 +377,8 @@ namespace Nz int FullScoreRecalculation() { // calculate score for all vertices - for (unsigned int i = 0; i < m_vertices.size(); ++i) - m_vertices[i].current_score = CalculateVertexScore(i); + for (VertexCacheData& vertex : m_vertices) + vertex.current_score = CalculateVertexScore(vertex); // calculate scores for all active triangles float max_score = std::numeric_limits::lowest(); @@ -548,13 +547,13 @@ namespace Nz float sum = 0.f; for (unsigned int i = 0; i < 3; ++i) { - VertexCacheData* v = &m_vertices[t->verts[i]]; - float sc = v->current_score; - if (!v->calculated) - sc = CalculateVertexScore(t->verts[i]); + VertexCacheData& v = m_vertices[t->verts[i]]; + float sc = v.current_score; + if (!v.calculated) + sc = CalculateVertexScore(v); - v->current_score = sc; - v->calculated = true; + v.current_score = sc; + v.calculated = true; sum += sc; } From a2c0963fe4fbd3acb0273d4b2c29a2445d1edfed Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 14:27:31 +0200 Subject: [PATCH 096/224] Default behaviour without precision on name Former-commit-id: 984e99a8ce5380eb54aa48e206a62186a08cce23 --- src/Nazara/Graphics/Formats/MeshLoader.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index ffd2b423e..6769072bb 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -27,6 +27,12 @@ namespace Nz String filePath; if (matData.GetStringParameter(MaterialData::FilePath, &filePath)) { + if (!File::Exists(filePath)) + { + NazaraWarning("Shader name does not refer to an existing file, \".tga\" is used by default"); + filePath += ".tga"; + } + MaterialRef material = Material::New(); if (material->LoadFromFile(filePath, parameters.material)) model->SetMaterial(i, std::move(material)); From 43e6424969d8f2e762c6e1ace9504401dc46a22d Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Mon, 30 May 2016 20:43:27 +0200 Subject: [PATCH 097/224] Fail in copy-paste Former-commit-id: ac1ff8c19a3fdbb8961b911c718e51be9b5a73a4 --- src/Nazara/Utility/AlgorithmUtility.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/AlgorithmUtility.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp index c13d393dd..d82af98af 100644 --- a/src/Nazara/Utility/AlgorithmUtility.cpp +++ b/src/Nazara/Utility/AlgorithmUtility.cpp @@ -105,9 +105,9 @@ namespace Nz for (unsigned int i = 0; i < recursionLevel; ++i) { std::size_t triangleCount = triangles.size(); - for (std::size_t i = 0; i < triangleCount; ++i) + for (std::size_t j = 0; j < triangleCount; ++j) { - Vector3ui& triangle = triangles[i]; + Vector3ui& triangle = triangles[j]; unsigned int a = GetMiddleVertex(triangle.x, triangle.y); unsigned int b = GetMiddleVertex(triangle.y, triangle.z); From b6ba99ae23836b755a56f602cf45deabca2f68a1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 31 May 2016 09:02:35 +0200 Subject: [PATCH 098/224] Physics: Upgrade Newton to 3.13 Former-commit-id: 0744442f892fd7f53d9497669975b381b7bc1369 --- include/Nazara/Physics/Geom.hpp | 2 +- include/Nazara/Physics/PhysObject.hpp | 2 +- include/Nazara/Physics/PhysWorld.hpp | 2 +- src/Nazara/Physics/PhysObject.cpp | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 34b6c58ba..23a02c72b 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -20,7 +20,7 @@ #include #include -struct NewtonCollision; +class NewtonCollision; namespace Nz { diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index 7df72b1d1..d4d9c61b7 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -15,7 +15,7 @@ #include #include -struct NewtonBody; +class NewtonBody; namespace Nz { diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp index b6fd7eae3..0300048b5 100644 --- a/include/Nazara/Physics/PhysWorld.hpp +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -12,7 +12,7 @@ #include #include -struct NewtonWorld; +class NewtonWorld; namespace Nz { diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 1b4816ee6..1ee4a44d5 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -68,7 +68,7 @@ namespace Nz PhysObject::~PhysObject() { if (m_body) - NewtonDestroyBody(m_world->GetHandle(), m_body); + NewtonDestroyBody(m_body); } void PhysObject::AddForce(const Vector3f& force, CoordSys coordSys) @@ -304,11 +304,13 @@ namespace Nz Vector3f min, max; NewtonBodyGetAABB(m_body, min, max); - NewtonWorldForEachBodyInAABBDo(m_world->GetHandle(), min, max, [](const NewtonBody* const body, void* const userData) + NewtonWorldForEachBodyInAABBDo(m_world->GetHandle(), min, max, [](const NewtonBody* const body, void* const userData) -> int { NazaraUnused(userData); NewtonBodySetSleepState(body, 0); - }, nullptr); + return 1; + }, + nullptr); } /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) (*it)->PhysObjectOnUpdate(this);*/ @@ -317,7 +319,7 @@ namespace Nz PhysObject& PhysObject::operator=(PhysObject&& object) { if (m_body) - NewtonDestroyBody(m_world->GetHandle(), m_body); + NewtonDestroyBody(m_body); m_body = object.m_body; m_forceAccumulator = std::move(object.m_forceAccumulator); From f19117e84f94ec411cc32b79fc0c64cb2981eb45 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 31 May 2016 09:06:24 +0200 Subject: [PATCH 099/224] Physics: Add new libraries for Windows Former-commit-id: 55870046787c3c3ae067f09d1ab1c8cb2114f2ca --- build/scripts/modules/physics.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/modules/physics.lua b/build/scripts/modules/physics.lua index fbf6f39c8..f6d485a67 100644 --- a/build/scripts/modules/physics.lua +++ b/build/scripts/modules/physics.lua @@ -2,5 +2,5 @@ MODULE.Name = "Physics" MODULE.Libraries = { "NazaraCore", - "newton" + "Newton" } From abb5ab359655de9d5dae994a722760dcf85ab249 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Tue, 31 May 2016 21:50:31 +0200 Subject: [PATCH 102/224] Fix for problems signaled by clang static analyzer Former-commit-id: 2ad296acdc783054198a7b2f2f34c36d9cc22958 --- include/Nazara/Network/RUdpConnection.inl | 2 +- src/Nazara/Core/Posix/FileImpl.cpp | 13 +++++++- src/Nazara/Core/String.cpp | 31 ++++++-------------- src/Nazara/Graphics/DepthRenderTechnique.cpp | 3 +- tests/Engine/Core/String.cpp | 20 +++++++++++++ 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index 53e797b59..48173bd77 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -132,7 +132,7 @@ namespace Nz else difference = sequence - sequence2; - return 0; + return difference; } /*! diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index f6e8b3bcc..b9a6b0a31 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -143,7 +143,18 @@ namespace Nz return false; } - mode_t permissions; // TODO : get permission from first file + mode_t permissions; + struct stat sb; + if (fstat(fd1, &sb) == -1) // get permission from first file + { + NazaraWarning("Could not get permissions of source file"); + permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + } + else + { + permissions = sb.st_mode & ~S_IFMT; // S_IFMT: bit mask for the file type bit field -> ~S_IFMT: general permissions + } + int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions); if (fd2 == -1) { diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index a57d89861..20d1c1897 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -2827,21 +2827,15 @@ namespace Nz { const char* c = oldCharacters; char character = Detail::ToLower(*ptr); - bool found = false; + + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); + EnsureOwnership(); + ptr = &m_sharedString->string[offset]; + do { if (character == Detail::ToLower(*c)) { - if (!found) - { - std::ptrdiff_t offset = ptr - m_sharedString->string.get(); - - EnsureOwnership(); - - ptr = &m_sharedString->string[offset]; - found = true; - } - *ptr = replaceCharacter; ++count; break; @@ -2853,19 +2847,12 @@ namespace Nz } else { - bool found = false; + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); + EnsureOwnership(); + ptr = &m_sharedString->string[offset]; + while ((ptr = std::strpbrk(ptr, oldCharacters)) != nullptr) { - if (!found) - { - std::ptrdiff_t offset = ptr - m_sharedString->string.get(); - - EnsureOwnership(); - - ptr = &m_sharedString->string[offset]; - found = true; - } - *ptr++ = replaceCharacter; ++count; } diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 233eb9c72..8badefcc9 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -464,7 +464,6 @@ namespace Nz void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { const Shader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; for (auto& matIt : layer.opaqueModels) { @@ -488,7 +487,7 @@ namespace Nz if (shader != lastShader) { // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); + GetShaderUniforms(shader); lastShader = shader; } diff --git a/tests/Engine/Core/String.cpp b/tests/Engine/Core/String.cpp index eac5eaef6..fe9c80c30 100644 --- a/tests/Engine/Core/String.cpp +++ b/tests/Engine/Core/String.cpp @@ -122,5 +122,25 @@ SCENARIO("String", "[CORE][STRING]") } } }*/ + + GIVEN("A string") + { + Nz::String replaceAny("abapeilomuky"); + Nz::String replaceAnyWithCase("abapEilOmuky"); + + WHEN("We replace any of vowels after character 3") + { + unsigned int nbrOfChanges = replaceAny.ReplaceAny("aeiouy", '$', 3); + unsigned int nbrOfChangesWithCase = replaceAnyWithCase.ReplaceAny("AEIOUY", '$', 3); + + THEN("These results are expected") + { + REQUIRE(replaceAny == "abap$$l$m$k$"); + REQUIRE(nbrOfChanges == 5); + REQUIRE(replaceAnyWithCase == "abap$il$muky"); + REQUIRE(nbrOfChangesWithCase == 2); + } + } + } } From 94ff113930065b79437a241579f3fd98c10fbe3d Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 08:34:44 +0200 Subject: [PATCH 103/224] Sdk: Fix uninitialization of components and systems Former-commit-id: 143a252c13269402f6c69c8831f7f1aef0c89c0c [formerly 2cd2160a2cd6da2c0763ca97157dd1349ec28233] Former-commit-id: 1b1fbb0770b993babde90c789250da0bcc8fbcb4 --- SDK/src/NDK/Sdk.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 21bfd236f..7f29bb18e 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -112,6 +112,12 @@ namespace Ndk // Uninitialize the SDK s_referenceCounter = 0; + // Components + BaseComponent::Uninitialize(); + + // Systems + BaseSystem::Uninitialize(); + // Uninitialize the engine #ifndef NDK_SERVER From 8d13b0ae0bf17e76a608fa214d51426bda10c5ce Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 09:34:42 +0200 Subject: [PATCH 104/224] Remove Visual Studio 2015 database file Former-commit-id: 226c236bf00b16ed560ed977663fe28175da5d82 [formerly 11db0f829d9edc279600b9d921c96753da809d70] Former-commit-id: 14e19aa18248ad6e87017df04a299cfb3bc5ea5d --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 258594792..f3b8b2bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ build/**/*.vcxprojResolveAssemblyReference.cache build/**/*.nativecodeanalysis.all.xml build/**/*.nativecodeanalysis.xml build/**/*.VC.opendb +build/**/*.VC.db # Compiled Object files build/**/*.slo From 2e26509f1cda3f011f72a67059e2d20cc468d014 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 09:36:01 +0200 Subject: [PATCH 105/224] Build/Vulkan: Fix compilation under Linux Former-commit-id: db46f107c70d50eac8f84bc7fdecac163325569d [formerly c3c6b1938470eab0199d2740d4546606830cc4e2] Former-commit-id: 33457d04147c6ac16211b3d854a266d071306744 --- build/scripts/modules/vulkan.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua index a8e674d03..760a4e58c 100644 --- a/build/scripts/modules/vulkan.lua +++ b/build/scripts/modules/vulkan.lua @@ -10,10 +10,10 @@ MODULE.Libraries = { } MODULE.OsDefines.Linux = { - "VK_USE_PLATFORM_MIR_KHR", - "VK_USE_PLATFORM_XCB_KHR", - "VK_USE_PLATFORM_XLIB_KHR", - "VK_USE_PLATFORM_WAYLAND_KHR" +-- "VK_USE_PLATFORM_MIR_KHR", + "VK_USE_PLATFORM_XCB_KHR" +-- "VK_USE_PLATFORM_XLIB_KHR", +-- "VK_USE_PLATFORM_WAYLAND_KHR" } MODULE.OsDefines.BSD = MODULE.OsDefines.Linux From fdefa1a3501aabb5c7add4377a20dfb0181825d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 13:06:32 +0200 Subject: [PATCH 106/224] Vulkan/Surface: Fix compilation under Linux Former-commit-id: bc978a47159d5242cc4ef0d15e5118d5992a8199 [formerly 1bd17a6b57f2fffd5e143b89d2a14567b49b1413] Former-commit-id: 0d1059e57c99df00f293621914486bf86c5fe7ba --- include/Nazara/Vulkan/VkSurface.inl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl index b6cb3a28f..f64c24af0 100644 --- a/include/Nazara/Vulkan/VkSurface.inl +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -34,7 +34,7 @@ namespace Nz #ifdef VK_USE_PLATFORM_ANDROID_KHR inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) { - m_lastErrorCode = m_instance.PFN_vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + m_lastErrorCode = m_instance.vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); return Create(allocator); } @@ -55,7 +55,7 @@ namespace Nz #ifdef VK_USE_PLATFORM_MIR_KHR inline bool Surface::Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) { - m_lastErrorCode = m_instance.PFN_vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + m_lastErrorCode = m_instance.vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); return Create(allocator); } @@ -77,7 +77,7 @@ namespace Nz #ifdef VK_USE_PLATFORM_XCB_KHR inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) { - m_lastErrorCode = m_instance.PFN_vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + m_lastErrorCode = m_instance.vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); return Create(allocator); } @@ -99,7 +99,7 @@ namespace Nz #ifdef VK_USE_PLATFORM_XLIB_KHR inline bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) { - m_lastErrorCode = m_instance.PFN_vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + m_lastErrorCode = m_instance.vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); return Create(allocator); } From b4d9eb58c18c6e9e99ac637cd293aaf21d9b7dbf Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 13:08:13 +0200 Subject: [PATCH 107/224] Vulkan/CommandBuffer: Fix warning for GCC Former-commit-id: f789c93664237f951dfc18cb7c5e97cb0816c4e6 [formerly dca55e27aa6a898f65a1f24b936c0521d1eab6c0] Former-commit-id: 992469ac784ee3d48180b2e8e5d2e67ba9ad7d0c --- include/Nazara/Vulkan/VkCommandBuffer.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Vulkan/VkCommandBuffer.inl b/include/Nazara/Vulkan/VkCommandBuffer.inl index d9944e33b..d2d6f50d7 100644 --- a/include/Nazara/Vulkan/VkCommandBuffer.inl +++ b/include/Nazara/Vulkan/VkCommandBuffer.inl @@ -77,7 +77,7 @@ namespace Nz renderPass, subpass, framebuffer, - (occlusionQueryEnable) ? VK_TRUE : VK_FALSE, + VkBool32((occlusionQueryEnable) ? VK_TRUE : VK_FALSE), queryFlags, pipelineStatistics }; @@ -102,7 +102,7 @@ namespace Nz VK_NULL_HANDLE, 0, VK_NULL_HANDLE, - (occlusionQueryEnable) ? VK_TRUE : VK_FALSE, + VkBool32((occlusionQueryEnable) ? VK_TRUE : VK_FALSE), queryFlags, pipelineStatistics }; From 7626f9c5e35c03ac6d018c43fb59ce4d20816cfa Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 13:51:32 +0200 Subject: [PATCH 108/224] Build: Add server option, allows to compile only the server-side part of Nazara Former-commit-id: 60be2c3eb2835984714192a55faebf8c769fd127 [formerly f3dcb15e44dfab997d4c10c97aa34270f5c884bf] Former-commit-id: 6f11439b3e53a812c5adf28413ea084fb2964f21 --- SDK/include/NDK/Components.hpp | 13 ++--- .../NDK/Components/CameraComponent.hpp | 2 + .../NDK/Components/GraphicsComponent.hpp | 2 + SDK/include/NDK/Components/LightComponent.hpp | 2 + .../NDK/Components/ListenerComponent.hpp | 2 + SDK/include/NDK/Systems.hpp | 9 +-- SDK/include/NDK/Systems/ListenerSystem.hpp | 2 + SDK/include/NDK/Systems/RenderSystem.hpp | 2 + build/scripts/common.lua | 57 +++++++++++++++---- build/scripts/modules/audio.lua | 2 + build/scripts/modules/renderer.lua | 2 + build/scripts/modules/vulkan.lua | 2 + build/scripts/tools/ndk.lua | 19 +++---- build/scripts/tools/ndk_server.lua | 19 ++++--- 14 files changed, 92 insertions(+), 43 deletions(-) diff --git a/SDK/include/NDK/Components.hpp b/SDK/include/NDK/Components.hpp index 46392ab7c..ca993b5b6 100644 --- a/SDK/include/NDK/Components.hpp +++ b/SDK/include/NDK/Components.hpp @@ -1,20 +1,17 @@ -// This file was automatically generated on 03 Mar 2016 at 14:09:12 +// This file was automatically generated on 01 Jun 2016 at 13:11:09 #pragma once #ifndef NDK_COMPONENTS_GLOBAL_HPP #define NDK_COMPONENTS_GLOBAL_HPP +#include #include +#include +#include +#include #include #include #include -#ifndef NDK_SERVER -#include -#include -#include -#include -#endif - #endif // NDK_COMPONENTS_GLOBAL_HPP diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index d5951109b..af2245b11 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_COMPONENTS_CAMERACOMPONENT_HPP #define NDK_COMPONENTS_CAMERACOMPONENT_HPP @@ -108,3 +109,4 @@ namespace Ndk #include #endif // NDK_COMPONENTS_CAMERACOMPONENT_HPP +#endif // NDK_SERVER diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index f8fa2bf66..86cefb782 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP #define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP @@ -80,3 +81,4 @@ namespace Ndk #include #endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP +#endif // NDK_SERVER \ No newline at end of file diff --git a/SDK/include/NDK/Components/LightComponent.hpp b/SDK/include/NDK/Components/LightComponent.hpp index c55ae57bb..80f84a759 100644 --- a/SDK/include/NDK/Components/LightComponent.hpp +++ b/SDK/include/NDK/Components/LightComponent.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_COMPONENTS_LIGHTCOMPONENT_HPP #define NDK_COMPONENTS_LIGHTCOMPONENT_HPP @@ -28,3 +29,4 @@ namespace Ndk #include #endif // NDK_COMPONENTS_LIGHTCOMPONENT_HPP +#endif // NDK_SERVER diff --git a/SDK/include/NDK/Components/ListenerComponent.hpp b/SDK/include/NDK/Components/ListenerComponent.hpp index bee1ac14a..3d472bed3 100644 --- a/SDK/include/NDK/Components/ListenerComponent.hpp +++ b/SDK/include/NDK/Components/ListenerComponent.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_COMPONENTS_LISTENERCOMPONENT_HPP #define NDK_COMPONENTS_LISTENERCOMPONENT_HPP @@ -30,3 +31,4 @@ namespace Ndk #include #endif // NDK_COMPONENTS_LISTENERCOMPONENT_HPP +#endif // NDK_SERVER \ No newline at end of file diff --git a/SDK/include/NDK/Systems.hpp b/SDK/include/NDK/Systems.hpp index 193438b5e..176a956ee 100644 --- a/SDK/include/NDK/Systems.hpp +++ b/SDK/include/NDK/Systems.hpp @@ -1,16 +1,13 @@ -// This file was automatically generated on 03 Mar 2016 at 14:09:12 +// This file was automatically generated on 01 Jun 2016 at 13:11:09 #pragma once #ifndef NDK_SYSTEMS_GLOBAL_HPP #define NDK_SYSTEMS_GLOBAL_HPP +#include #include +#include #include -#ifndef NDK_SERVER -#include -#include -#endif - #endif // NDK_SYSTEMS_GLOBAL_HPP diff --git a/SDK/include/NDK/Systems/ListenerSystem.hpp b/SDK/include/NDK/Systems/ListenerSystem.hpp index 6f40fcdf9..bb166a4c1 100644 --- a/SDK/include/NDK/Systems/ListenerSystem.hpp +++ b/SDK/include/NDK/Systems/ListenerSystem.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_SYSTEMS_LISTENERSYSTEM_HPP #define NDK_SYSTEMS_LISTENERSYSTEM_HPP @@ -27,3 +28,4 @@ namespace Ndk #include #endif // NDK_SYSTEMS_LISTENERSYSTEM_HPP +#endif // NDK_SERVER diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 72aa1efb1..f2fbc7a65 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -4,6 +4,7 @@ #pragma once +#ifndef NDK_SERVER #ifndef NDK_SYSTEMS_RENDERSYSTEM_HPP #define NDK_SYSTEMS_RENDERSYSTEM_HPP @@ -70,3 +71,4 @@ namespace Ndk #include #endif // NDK_SYSTEMS_RENDERSYSTEM_HPP +#endif // NDK_SERVER diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 822067ea2..6cf0025ba 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -196,9 +196,7 @@ function NazaraBuild:Execute() targetdir("../lib/" .. makeLibDir .. "/x64") -- Copy the module binaries to the example folder - if (os.is("windows")) then - self:MakeCopyAfterBuild(moduleTable) - end + self:MakeCopyAfterBuild(moduleTable) configuration({"vs*", "x86"}) libdirs("../extlibs/lib/msvc/x86") @@ -310,7 +308,7 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") end - -- Copy the module binaries to the example folder + -- Copy the tool binaries to the example folder if (toolTable.CopyTargetToExampleDir) then self:MakeCopyAfterBuild(toolTable) end @@ -450,6 +448,11 @@ end function NazaraBuild:Initialize() -- Commençons par les options + newoption({ + trigger = "server", + description = "Excludes client-only modules/tools/examples" + }) + newoption({ trigger = "united", description = "Builds all the modules as one united library" @@ -605,13 +608,20 @@ function NazaraBuild:Initialize() self.OrderedExtLibs = {} self.OrderedModules = {} self.OrderedTools = {} - local tables = {self.Examples, self.ExtLibs, self.Modules, self.Tools} - local orderedTables = {self.OrderedExamples, self.OrderedExtLibs, self.OrderedModules, self.OrderedTools} + local tables = {self.ExtLibs, self.Modules, self.Tools, self.Examples} + local orderedTables = {self.OrderedExtLibs, self.OrderedModules, self.OrderedTools, self.OrderedExamples} for k,projects in ipairs(tables) do + -- Begin by resolving every project (because of dependencies in the same category) for projectId,projectTable in pairs(projects) do - self:Process(projectTable) - - table.insert(orderedTables[k], projectTable) + self:Resolve(projectTable) + end + + for projectId,projectTable in pairs(projects) do + if (self:Process(projectTable)) then + table.insert(orderedTables[k], projectTable) + else + print("Rejected client-only " .. projectTable.Name .. " " .. projectTable.Type) + end end table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end) @@ -772,13 +782,22 @@ local PosixOSes = { } function NazaraBuild:Process(infoTable) - local libraries = {} + if (infoTable.ClientOnly and _OPTIONS["server"]) then + return false + end + + local libraries = {} for k, library in pairs(infoTable.Libraries) do local moduleName = library:match("Nazara(%w+)") local moduleTable = moduleName and self.Modules[moduleName:lower()] local toolTable = moduleName and self.Tools[moduleName:lower()] if (moduleTable) then + if (moduleTable.ClientOnly and _OPTIONS["server"]) then + infoTable.ClientOnly = true + return false -- We depend on a client-only library + end + if (_OPTIONS["united"]) then library = "NazaraEngine" else @@ -794,6 +813,11 @@ function NazaraBuild:Process(infoTable) else local extLibTable = self.ExtLibs[library:lower()] if (extLibTable) then + if (extLibTable.ClientOnly and _OPTIONS["server"]) then + infoTable.ClientOnly = true + return false -- We depend on a client-only library + end + library = extLibTable.Name table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") @@ -802,6 +826,11 @@ function NazaraBuild:Process(infoTable) table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") else if (toolTable and toolTable.Kind == "library") then + if (toolTable.ClientOnly and _OPTIONS["server"]) then + infoTable.ClientOnly = true + return false -- We depend on a client-only library + end + library = "Nazara" .. toolTable.Name -- Import tools includes @@ -862,6 +891,14 @@ function NazaraBuild:Process(infoTable) end end end + + return true +end + +function NazaraBuild:Resolve(infoTable) + if (type(infoTable.Libraries) == "function") then + infoTable.Libraries = infoTable.Libraries() + end end function NazaraBuild:MakeCopyAfterBuild(infoTable) diff --git a/build/scripts/modules/audio.lua b/build/scripts/modules/audio.lua index 27e49a08c..509972dc3 100644 --- a/build/scripts/modules/audio.lua +++ b/build/scripts/modules/audio.lua @@ -1,5 +1,7 @@ MODULE.Name = "Audio" +MODULE.ClientOnly = true + MODULE.Defines = { "NAZARA_AUDIO_OPENAL" } diff --git a/build/scripts/modules/renderer.lua b/build/scripts/modules/renderer.lua index 7e3edadbe..bbc472b75 100644 --- a/build/scripts/modules/renderer.lua +++ b/build/scripts/modules/renderer.lua @@ -1,5 +1,7 @@ MODULE.Name = "Renderer" +MODULE.ClientOnly = true + MODULE.Defines = { "NAZARA_RENDERER_OPENGL" } diff --git a/build/scripts/modules/vulkan.lua b/build/scripts/modules/vulkan.lua index 760a4e58c..62a00a745 100644 --- a/build/scripts/modules/vulkan.lua +++ b/build/scripts/modules/vulkan.lua @@ -1,5 +1,7 @@ MODULE.Name = "Vulkan" +MODULE.ClientOnly = true + MODULE.Defines = { "VK_NO_PROTOTYPES" } diff --git a/build/scripts/tools/ndk.lua b/build/scripts/tools/ndk.lua index 5a1084f48..961fa6d7f 100644 --- a/build/scripts/tools/ndk.lua +++ b/build/scripts/tools/ndk.lua @@ -22,14 +22,11 @@ TOOL.Files = { "../SDK/src/NDK/**.cpp" } -TOOL.Libraries = { - "NazaraCore", - "NazaraAudio", - "NazaraLua", - "NazaraNetwork", - "NazaraNoise", - "NazaraPhysics", - "NazaraUtility", - "NazaraRenderer", - "NazaraGraphics" -} +TOOL.Libraries = function() + local libraries = {} + for k,v in pairs(NazaraBuild.Modules) do + table.insert(libraries, "Nazara" .. v.Name) + end + + return libraries +end \ No newline at end of file diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index 978d620be..b1a71453e 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -37,11 +37,14 @@ TOOL.FilesExcluded = { "../SDK/**/LuaBinding_Renderer.*" } -TOOL.Libraries = { - "NazaraCore", - "NazaraLua", - "NazaraNetwork", - "NazaraNoise", - "NazaraPhysics", - "NazaraUtility" -} + +TOOL.Libraries = function() + local libraries = {} + for k,v in pairs(NazaraBuild.Modules) do + if (not v.ClientOnly) then + table.insert(libraries, "Nazara" .. v.Name) + end + end + + return libraries +end From 26ccf59ddd0620b397f7dcc49e619694a6e26212 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 13:52:59 +0200 Subject: [PATCH 109/224] Build: Fix with-extlibs option being required for compilation Former-commit-id: d6045b270db38412f5f323f025afb3fb85f703aa [formerly e5d7be10ada92f2351a4349b57c59b637108c4a3] Former-commit-id: 93146150699c9d9c7ad524eeccb126ea66257f26 --- build/scripts/common.lua | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 6cf0025ba..7e3cb2c33 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -15,7 +15,7 @@ function NazaraBuild:Execute() if (self.Actions[_ACTION] == nil) then local makeLibDir = os.is("windows") and "mingw" or "gmake" - if (#self.OrderedExtLibs > 0) then + if (_OPTIONS["with-extlibs"]) then workspace("NazaraExtlibs") platforms(platformData) @@ -494,26 +494,24 @@ function NazaraBuild:Initialize() ACTION = nil -- Extern libraries - if (_OPTIONS["with-extlibs"]) then - local extlibs = os.matchfiles("../extlibs/build/*.lua") - for k,v in pairs(extlibs) do - local f, err = loadfile(v) - if (f) then - LIBRARY = {} - self:SetupInfoTable(LIBRARY) + local extlibs = os.matchfiles("../extlibs/build/*.lua") + for k,v in pairs(extlibs) do + local f, err = loadfile(v) + if (f) then + LIBRARY = {} + self:SetupInfoTable(LIBRARY) - f() + f() - local succeed, err = self:RegisterExternLibrary(LIBRARY) - if (not succeed) then - print("Unable to register extern library: " .. err) - end - else - print("Unable to load extern library file: " .. err) - end - end - LIBRARY = nil - end + local succeed, err = self:RegisterExternLibrary(LIBRARY) + if (not succeed) then + print("Unable to register extern library: " .. err) + end + else + print("Unable to load extern library file: " .. err) + end + end + LIBRARY = nil -- Then the modules local modules = os.matchfiles("scripts/modules/*.lua") From 5cac6cbe3db30ce55dd559724b7369c09cc6b540 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 14:11:58 +0200 Subject: [PATCH 110/224] Sdk/World: Fix compilation error when submitting arguments on system creation Former-commit-id: ed94334556b84d66c8282c28588fb8f032f5fc02 [formerly f84ddbecb465c96127433b29d1e7cbdb54709324] Former-commit-id: d72da83595df8de5533aec84cdb14433d869744d --- SDK/include/NDK/World.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index 91ebc3922..ba2b33bd4 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -44,7 +44,7 @@ namespace Ndk static_assert(std::is_base_of::value, "SystemType is not a component"); // Allocation et affectation du component - std::unique_ptr ptr(new SystemType(std::forward(args)...)); + std::unique_ptr ptr(new SystemType(std::forward(args)...)); return static_cast(AddSystem(std::move(ptr))); } From ce90bd43d6e1f5f1f05bb4e5acc77bfaa5dda3d0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jun 2016 13:49:30 +0200 Subject: [PATCH 111/224] Graphics: Prevent shadow-mapping code to compile without shadow-mapping Temporary fix for OpenGL 3.3 Former-commit-id: 50b368b62fc0eba5507e4bf3c4f825eedf35cc8b [formerly 6a5258a1ecd4991937a4446684043f52bc60215c] Former-commit-id: 70f890125f05d0c4e16f38535a3ca9c6848bf35b --- src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h | 2 +- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag | 2 ++ src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h | 2 +- src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h index 993c7291b..7c3081f31 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,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 +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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 94184d6ab..61ed69632 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -94,6 +94,7 @@ float VectorToDepthValue(vec3 vec, float zNear, float zFar) return (normZ + 1.0) * 0.5; } +#if SHADOW_MAPPING float CalculateDirectionalShadowFactor(int lightIndex) { vec4 lightSpacePos = vLightSpacePos[lightIndex]; @@ -119,6 +120,7 @@ float CalculateSpotShadowFactor(int lightIndex) return visibility; } +#endif void main() { diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index b3c3f2c63..6f1495308 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,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 +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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,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,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,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,13,10,123,13,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,13,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,13,10,13,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,13,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,13,10,125,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,123,13,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,13,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,13,10,125,13,10,13,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,13,10,123,13,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,13,10,125,13,10,13,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,13,10,123,13,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,13,10,13,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,13,10,9,102,108,111,97,116,32,120,44,121,59,13,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,13,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,13,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,13,10,13,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,13,10,9,13,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,13,10,125,13,10,35,101,110,100,105,102,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index fbdd39607..c1611105a 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,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 +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,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,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,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,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,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,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,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,109,97,116,52,32,73,110,118,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,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,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,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,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,13,10,35,105,102,32,76,73,71,72,84,73,78,71,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,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,13,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,13,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,13,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,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,13,10,35,101,110,100,105,102,13,10,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,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,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,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,13,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,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,33,70,76,65,71,95,68,69,70,69,82,82,69,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file From f3700128902ae1b3fd181e2d77a982619d7af814 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 2 Jun 2016 19:10:33 +0200 Subject: [PATCH 112/224] Utility/PixelFormat: Fix ComputeSize for DXT formats Former-commit-id: c8a5ef0da9f87e944c0085e196b02f10fc3dd7d0 [formerly 957bd2cc1c8d8f5eac590e82f408d863975ecf55] Former-commit-id: c9b2436d570ea44e5317de177ab6696ee3994e68 --- include/Nazara/Utility/PixelFormat.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index e30701d3d..e384d8574 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -156,7 +156,7 @@ namespace Nz case PixelFormatType_DXT1: case PixelFormatType_DXT3: case PixelFormatType_DXT5: - return (((width + 3) / 4) * ((height + 3) / 4) * (format == PixelFormatType_DXT1) ? 8 : 16) * depth; + return (((width + 3) / 4) * ((height + 3) / 4) * ((format == PixelFormatType_DXT1) ? 8 : 16)) * depth; default: NazaraError("Unsupported format"); From 9d02e5ba02481fccc1a01b7b7875b865da31b1f3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 8 Jun 2016 12:58:04 +0200 Subject: [PATCH 115/224] Network/Windows: Fix build on compilers with outdated windows.h Former-commit-id: f51eb50d9cd087402cb8610116d191288e219b1f [formerly 999be5e2e68e5af5783703cbc9f0132e739d9534] Former-commit-id: 01e6012c3c7b7a8cf79591834584873728783309 --- src/Nazara/Network/Win32/IpAddressImpl.cpp | 2 ++ src/Nazara/Network/Win32/IpAddressImpl.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 9f3918574..54d8ee4f5 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -100,6 +100,7 @@ namespace Nz return IpAddress::Invalid; } + #if NAZARA_CORE_WINDOWS_VISTA IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info) { switch (info->ai_family) @@ -121,6 +122,7 @@ namespace Nz return IpAddress::Invalid; } + #endif IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address) { diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index 4b27bef32..960092839 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -17,7 +17,9 @@ namespace Nz ~IpAddressImpl() = delete; static IpAddress FromAddrinfo(const addrinfo* info); + #if NAZARA_CORE_WINDOWS_VISTA static IpAddress FromAddrinfo(const addrinfoW* info); + #endif static IpAddress FromSockAddr(const sockaddr* address); static IpAddress FromSockAddr(const sockaddr_in* addressv4); static IpAddress FromSockAddr(const sockaddr_in6* addressv6); From fdf0c8480d6e2e43454fcbdcb3d12576aa40f193 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 8 Jun 2016 12:58:04 +0200 Subject: [PATCH 116/224] Network/Windows: Fix build on compilers with outdated windows.h (Fixes 63) Former-commit-id: f44bbd435ac7917615d3040489cd0528514c933b [formerly 3eb3a0e73fbefc629d0ee6966a19ba259cacfb79] Former-commit-id: d60d7bfb07651a6345e7ac63e73cbdddc1dd0800 --- src/Nazara/Network/Win32/IpAddressImpl.cpp | 2 ++ src/Nazara/Network/Win32/IpAddressImpl.hpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 9f3918574..54d8ee4f5 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -100,6 +100,7 @@ namespace Nz return IpAddress::Invalid; } + #if NAZARA_CORE_WINDOWS_VISTA IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info) { switch (info->ai_family) @@ -121,6 +122,7 @@ namespace Nz return IpAddress::Invalid; } + #endif IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address) { diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index 4b27bef32..960092839 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -17,7 +17,9 @@ namespace Nz ~IpAddressImpl() = delete; static IpAddress FromAddrinfo(const addrinfo* info); + #if NAZARA_CORE_WINDOWS_VISTA static IpAddress FromAddrinfo(const addrinfoW* info); + #endif static IpAddress FromSockAddr(const sockaddr* address); static IpAddress FromSockAddr(const sockaddr_in* addressv4); static IpAddress FromSockAddr(const sockaddr_in6* addressv6); From 61c6cde4c07b923280b4f68a0bcf13f8dd4f8f0c Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 8 Jun 2016 14:13:19 +0200 Subject: [PATCH 117/224] Revert changes Former-commit-id: 0034c2038ece25081a9975d29f50165e8545eacc [formerly c6e83866ba222715b7f08095494c9f2749fafa8b] Former-commit-id: 66ad8e4a0df7eda465601c1695db5fbd39b792a4 --- src/Nazara/Core/String.cpp | 31 ++++++++++++++------ src/Nazara/Graphics/DepthRenderTechnique.cpp | 3 +- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 20d1c1897..a57d89861 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -2827,15 +2827,21 @@ namespace Nz { const char* c = oldCharacters; char character = Detail::ToLower(*ptr); - - std::ptrdiff_t offset = ptr - m_sharedString->string.get(); - EnsureOwnership(); - ptr = &m_sharedString->string[offset]; - + bool found = false; do { if (character == Detail::ToLower(*c)) { + if (!found) + { + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); + + EnsureOwnership(); + + ptr = &m_sharedString->string[offset]; + found = true; + } + *ptr = replaceCharacter; ++count; break; @@ -2847,12 +2853,19 @@ namespace Nz } else { - std::ptrdiff_t offset = ptr - m_sharedString->string.get(); - EnsureOwnership(); - ptr = &m_sharedString->string[offset]; - + bool found = false; while ((ptr = std::strpbrk(ptr, oldCharacters)) != nullptr) { + if (!found) + { + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); + + EnsureOwnership(); + + ptr = &m_sharedString->string[offset]; + found = true; + } + *ptr++ = replaceCharacter; ++count; } diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 8badefcc9..233eb9c72 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -464,6 +464,7 @@ namespace Nz void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; for (auto& matIt : layer.opaqueModels) { @@ -487,7 +488,7 @@ namespace Nz if (shader != lastShader) { // Index of uniforms in the shader - GetShaderUniforms(shader); + shaderUniforms = GetShaderUniforms(shader); lastShader = shader; } From d274d569ab457b3052964be8511837593b5a4485 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 8 Jun 2016 18:45:56 +0200 Subject: [PATCH 118/224] Network/Windows: Fix build on some plateforms (Hi MinGW) Former-commit-id: d08af3752835ba383672f3e2c26f7167cc4886e0 [formerly 2e32a8d5763f6fcf9ef52ceadcaf0c037f09bbcd] Former-commit-id: 2324a7775727029f0edd6051b2e189116b5ac4e5 --- src/Nazara/Network/Win32/IpAddressImpl.cpp | 29 ++++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 54d8ee4f5..0fd5cd88a 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -84,16 +84,21 @@ namespace Nz { sockaddr_in* ipv4 = reinterpret_cast(info->ai_addr); - auto& rawIpV4 = ipv4->sin_addr.S_un.S_un_b; - return IpAddress(rawIpV4.s_b1, rawIpV4.s_b2, rawIpV4.s_b3, rawIpV4.s_b4, ntohs(ipv4->sin_port)); + auto& rawIpV4 = ipv4->sin_addr; + return IpAddress(rawIpV4.s_net, rawIpV4.s_host, rawIpV4.s_lh, rawIpV4.s_impno, ntohs(ipv4->sin_port)); } case AF_INET6: { sockaddr_in6* ipv6 = reinterpret_cast(info->ai_addr); - auto& rawIpV6 = ipv6->sin6_addr.u.Word; - return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(ipv6->sin6_port)); + auto& rawIpV6 = ipv6->sin6_addr.s6_addr; + + IpAddress::IPv6 structIpV6; + for (unsigned int i = 0; i < 8; ++i) + structIpV6[i] = UInt16(rawIpV6[i * 2]) << 8 | UInt16(rawIpV6[i * 2 + 1]); + + return IpAddress(structIpV6, ntohs(ipv6->sin6_port)); } } @@ -146,8 +151,13 @@ namespace Nz IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in6* addressv6) { - auto& rawIpV6 = addressv6->sin6_addr.u.Word; - return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(addressv6->sin6_port)); + auto& rawIpV6 = addressv6->sin6_addr.s6_addr; + + IpAddress::IPv6 ipv6; + for (unsigned int i = 0; i < 8; ++i) + ipv6[i] = rawIpV6[i*2] << 8 | rawIpV6[i*2+1]; + + return IpAddress(ipv6, ntohs(addressv6->sin6_port)); } bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error) @@ -223,7 +233,7 @@ namespace Nz std::memset(socketAddress, 0, sizeof(sockaddr_in)); socketAddress->sin_family = AF_INET; socketAddress->sin_port = htons(ipAddress.GetPort()); - socketAddress->sin_addr.S_un.S_addr = htonl(ipAddress.ToUInt32()); + socketAddress->sin_addr.s_addr = htonl(ipAddress.ToUInt32()); return sizeof(sockaddr_in); } @@ -238,7 +248,10 @@ namespace Nz IpAddress::IPv6 address = ipAddress.ToIPv6(); for (unsigned int i = 0; i < 8; ++i) - socketAddress->sin6_addr.u.Word[i] = htons(address[i]); + { + socketAddress->sin6_addr.s6_addr[i * 2 + 0] = htons(address[i]) >> 8; + socketAddress->sin6_addr.s6_addr[i * 2 + 1] = htons(address[i]) >> 0; + } return sizeof(sockaddr_in6); } From b0c4bcff6716d1aa6a7a1d78ef3a50aa8d2dbded Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:46:44 +0200 Subject: [PATCH 119/224] Utility/Mesh: Replace scale by transform matrix Former-commit-id: 28cf57d1fe300b78e60c5f9301678a25533df29f [formerly d7b8edd11e99de396d40cf09c58cb94c5e03015c] Former-commit-id: e5915c2a5795900077bdb5229638962fade7f352 --- SDK/include/NDK/LuaAPI.inl | 2 +- include/Nazara/Utility/Mesh.hpp | 4 ++-- plugins/Assimp/Plugin.cpp | 2 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 13 +++++++------ src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 5 +++-- src/Nazara/Utility/Formats/OBJLoader.cpp | 3 +-- src/Nazara/Utility/Mesh.cpp | 6 +++--- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/SDK/include/NDK/LuaAPI.inl b/SDK/include/NDK/LuaAPI.inl index a42479cae..a09d6c459 100644 --- a/SDK/include/NDK/LuaAPI.inl +++ b/SDK/include/NDK/LuaAPI.inl @@ -100,8 +100,8 @@ namespace Nz params->animated = instance.CheckField("Animated", params->animated); params->center = instance.CheckField("Center", params->center); params->flipUVs = instance.CheckField("FlipUVs", params->flipUVs); + //params->matrix = instance.CheckField("Matrix", params->matrix); params->optimizeIndexBuffers = instance.CheckField("OptimizeIndexBuffers", params->optimizeIndexBuffers); - params->scale = instance.CheckField("Scale", params->scale); return 1; } diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index ff11b5d4d..865a228a9 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -29,8 +29,8 @@ namespace Nz { MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) - // La mise à l'échelle éventuelle que subira le mesh - Vector3f scale = Vector3f::Unit(); + // La transformation appliquée à tous les sommets du mesh + Matrix4f matrix = Matrix4f::Identity(); // Si ceci sera le stockage utilisé par les buffers UInt32 storage = DataStorage_Hardware; diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 68c443b29..d571e1ef6 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -209,7 +209,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f); aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); - vertex->position = parameters.scale * Vector3f(position.x, position.y, position.z); + vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z); vertex->normal.Set(normal.x, normal.y, normal.z); vertex->tangent.Set(tangent.x, tangent.y, tangent.z); vertex->uv.Set(uv.x, uv.y); diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index eef4ac63d..126eeaa35 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -188,11 +188,10 @@ namespace Nz SwapBytes(&translate.z, sizeof(float)); #endif - // Un personnage de taille moyenne fait ~50 unités de haut dans Quake 2 - // Avec Nazara, 1 unité = 1 mètre, nous devons donc adapter l'échelle - Vector3f s(parameters.scale/29.f); // 50/29 = 1.72 (Soit 1.72 mètre, proche de la taille moyenne d'un individu) - scale *= s; - translate *= s; + constexpr float ScaleAdjust = 1.f / 27.8f; // Make a 50 Quake 2 units character a 1.8 unit long + + scale *= ScaleAdjust; + translate *= ScaleAdjust; BufferMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); MeshVertex* vertex = static_cast(vertexMapper.GetPointer()); @@ -215,11 +214,13 @@ namespace Nz /// Chargement des positions // Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f); + Nz::Matrix4f matrix = Matrix4f::Transform(translate, rotationQuat, scale); + matrix *= parameters.matrix; for (unsigned int v = 0; v < header.num_vertices; ++v) { const MD2_Vertex& vert = vertices[v]; - Vector3f position = rotationQuat * Vector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z); + Vector3f position = matrix * Vector3f(vert.x, vert.y, vert.z); vertex->position = position; vertex->normal = rotationQuat * md2Normals[vert.n]; diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index cda183313..ce56b136a 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -48,7 +48,8 @@ namespace Nz // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres // Nous réduisons donc la taille générale des fichiers MD5 de 1/40 - Vector3f scale(parameters.scale/40.f); + Matrix4f matrix = Matrix4f::Transform(Nz::Vector3f::Zero(), rotationQuat, Vector3f(1.f / 40.f)); + matrix *= parameters.matrix; const MD5MeshParser::Joint* joints = parser.GetJoints(); const MD5MeshParser::Mesh* meshes = parser.GetMeshes(); @@ -267,7 +268,7 @@ namespace Nz } // On retourne le modèle dans le bon sens - vertex->position = scale * (rotationQuat * finalPos); + vertex->position = matrix * finalPos; vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé vertex++; } diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 75b5ba22f..05b39f81f 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -234,8 +234,7 @@ namespace Nz MeshVertex& vertex = meshVertices[index]; const Vector4f& vec = positions[vertexIndices.position]; - vertex.position.Set(vec.x, vec.y, vec.z); - vertex.position *= parameters.scale/vec.w; + vertex.position = Vector3f(parameters.matrix * vec); if (vertexIndices.normal >= 0) vertex.normal = normals[vertexIndices.normal]; diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index fca38e415..f41f67440 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -39,9 +39,9 @@ namespace Nz return false; } - if (scale == Vector3f::Zero()) + if (matrix == Matrix4f::Zero()) { - NazaraError("Invalid scale"); + NazaraError("Invalid matrix"); return false; } @@ -111,7 +111,7 @@ namespace Nz VertexBufferRef vertexBuffer; Matrix4f matrix(primitive.matrix); - matrix.ApplyScale(params.scale); + matrix *= params.matrix; VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent); From eadd21c52abc72463a85f7dc6682c35224d86cb0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:47:08 +0200 Subject: [PATCH 120/224] Utility/MaterialData: Add Material name information Former-commit-id: ac5a76bc840c2a826af196a9c55c4c390b17770b [formerly 74fa853856dc4720d97b4f66b60dda49d81047a9] Former-commit-id: 83bc618ad6cb7ee4fe420d8acffe496cd3157742 --- include/Nazara/Utility/MaterialData.hpp | 1 + plugins/Assimp/Plugin.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp index 0f69c9846..ea8ffd0f5 100644 --- a/include/Nazara/Utility/MaterialData.hpp +++ b/include/Nazara/Utility/MaterialData.hpp @@ -41,6 +41,7 @@ namespace Nz static constexpr const char* HeightTexturePath = "MatHeightTexturePath"; static constexpr const char* Lighting = "MatLighting"; static constexpr const char* LineWidth = "MatLineWidth"; + static constexpr const char* Name = "MatName"; static constexpr const char* NormalTexturePath = "MatNormalTexturePath"; static constexpr const char* PointSize = "MatPointSize"; static constexpr const char* ScissorTest = "MatScissorTest"; diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index d571e1ef6..f82d51f7b 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -291,6 +291,10 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) ConvertTexture(aiTextureType_OPACITY, MaterialData::AlphaTexturePath); ConvertTexture(aiTextureType_SPECULAR, MaterialData::SpecularTexturePath, MaterialData::SpecularWrap); + aiString name; + if (aiGetMaterialString(aiMat, AI_MATKEY_NAME, &name) == aiReturn_SUCCESS) + matData.SetParameter(MaterialData::Name, String(name.data, name.length)); + int iValue; if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue)) matData.SetParameter(MaterialData::FaceCulling, !iValue); From e43773f2aef19e86183ab752b4ed7c7b5dc3ee79 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:47:43 +0200 Subject: [PATCH 121/224] Plugins/Assimp: Fix FaceCulling parameter retrieval Former-commit-id: ecee810d06d9a75a9a270efc2becf0c879a8e0ab [formerly 30686c841913edaea70d1dfdc8fae7eb94c7cfc0] Former-commit-id: b0a0f965b1c4ca411a400ffa56bfa392297b71b4 --- plugins/Assimp/Plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index f82d51f7b..312bbf48e 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -296,7 +296,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) matData.SetParameter(MaterialData::Name, String(name.data, name.length)); int iValue; - if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue)) + if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue) == aiReturn_SUCCESS) matData.SetParameter(MaterialData::FaceCulling, !iValue); matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first; From 296be70a5c29f9b5cc27f965c9ea8d126bedb17b Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:48:04 +0200 Subject: [PATCH 122/224] Graphics/Material: Ugly spaces to tabs Former-commit-id: fe691ce50ec143681c8a916bab2f85270cedec06 [formerly c45aba3d7b6d8b47a90e5f8120c278785d68773b] Former-commit-id: 04596ea0ca1bb7f1575a4db6a5ef309328922938 --- src/Nazara/Graphics/Material.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 44ec0310d..0b4b887c3 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -442,22 +442,22 @@ namespace Nz s_defaultMaterial->SetFaceFilling(FaceFilling_Line); MaterialLibrary::Register("Default", s_defaultMaterial); - MaterialRef mat; + 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_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)); + 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; } From 18eab1045d82524d63a93dfdcfcf98872520e6d8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:48:35 +0200 Subject: [PATCH 123/224] Sdk/Application: Add MakeExitOnLastWindowClosed At least it's explicit Former-commit-id: 9118daeb3b33768697d502113e80b97c883ff9f5 [formerly aebc375bf0865d94103a16e7cb9540f7c54cfc88] Former-commit-id: 8a8ef252c1ddbc0838b6d5cbf1d48917bf0d5b50 --- SDK/include/NDK/Application.hpp | 4 ++++ SDK/include/NDK/Application.inl | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/SDK/include/NDK/Application.hpp b/SDK/include/NDK/Application.hpp index 5d918ef8e..6a375776c 100644 --- a/SDK/include/NDK/Application.hpp +++ b/SDK/include/NDK/Application.hpp @@ -33,6 +33,10 @@ namespace Ndk bool Run(); + #ifndef NDK_SERVER + inline void MakeExitOnLastWindowClosed(bool exitOnClosedWindows); + #endif + inline void Quit(); Application& operator=(const Application&) = delete; diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index f44ff9e8c..96e8768ce 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -61,6 +61,13 @@ namespace Ndk return m_updateTime; } + #ifndef NDK_SERVER + inline void Application::MakeExitOnLastWindowClosed(bool exitOnClosedWindows) + { + m_exitOnClosedWindows = exitOnClosedWindows; + } + #endif + inline void Application::Quit() { m_shouldQuit = true; From 2ace255d170404eccd4830813fa88df36173574a Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 08:49:01 +0200 Subject: [PATCH 124/224] Graphics/Material: Add errors when failed to query texture Former-commit-id: a28cd9537b7155f461a0e0dc761225c5e8758c77 [formerly e9c6cf2e48766eb3ef99c4711567d4da2e4e30ce] Former-commit-id: d00448a69f391c0e9b17fcce85e48f968b0de143 --- include/Nazara/Graphics/Material.inl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index c8559e11f..d348d7581 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -289,7 +289,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get alpha map \"" + textureName + "\""); return false; + } } SetAlphaMap(std::move(texture)); @@ -335,7 +338,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get diffuse map \"" + textureName + "\""); return false; + } } SetDiffuseMap(std::move(texture)); @@ -366,7 +372,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get emissive map \"" + textureName + "\""); return false; + } } SetEmissiveMap(std::move(texture)); @@ -397,7 +406,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get height map \"" + textureName + "\""); return false; + } } SetHeightMap(std::move(texture)); @@ -418,7 +430,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get normal map \"" + textureName + "\""); return false; + } } SetNormalMap(std::move(texture)); @@ -471,7 +486,10 @@ namespace Nz { texture = TextureManager::Get(textureName); if (!texture) + { + NazaraError("Failed to get specular map \"" + textureName + "\""); return false; + } } SetSpecularMap(std::move(texture)); From 5fb16724e6f68273762f692f47245773a820f352 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 12:32:04 +0200 Subject: [PATCH 125/224] Build: Fix build on Premake4 Former-commit-id: e4b767d8f806cf4350145d4b89fc875efb6c5c38 [formerly 342808bdd0ca5aa81301db4e5aa7656716a7323c] Former-commit-id: ba1724ff6d933ca7b101873857d489a9d51092ff --- build/scripts/common.lua | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 7e3cb2c33..5124dcace 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -7,9 +7,9 @@ function NazaraBuild:Execute() local platformData if (os.is64bit()) then - platformData = {"x64", "x86"} + platformData = {"x64", "x32"} else - platformData = {"x86", "x64"} + platformData = {"x32", "x64"} end if (self.Actions[_ACTION] == nil) then @@ -30,13 +30,13 @@ function NazaraBuild:Execute() location(_ACTION) kind("StaticLib") - configuration("x86") + configuration("x32") libdirs("../extlibs/lib/common/x86") configuration("x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x86"}) + configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") @@ -47,7 +47,7 @@ function NazaraBuild:Execute() configuration("vs*") buildoptions("/MP") - configuration({"vs*", "x86"}) + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") targetdir("../extlibs/lib/msvc/x86") @@ -55,7 +55,7 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/msvc/x64") targetdir("../extlibs/lib/msvc/x64") - configuration({"xcode3 or xcode4", "x86"}) + configuration({"xcode3 or xcode4", "x32"}) libdirs("../extlibs/lib/xcode/x86") targetdir("../extlibs/lib/xcode/x86") @@ -178,14 +178,14 @@ function NazaraBuild:Execute() libdirs("../lib") libdirs("../extlibs/lib/common") - configuration("x86") + configuration("x32") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x86"}) + configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86") targetdir("../lib/" .. makeLibDir .. "/x86") @@ -198,7 +198,7 @@ function NazaraBuild:Execute() -- Copy the module binaries to the example folder self:MakeCopyAfterBuild(moduleTable) - configuration({"vs*", "x86"}) + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") targetdir("../lib/msvc/x86") @@ -208,7 +208,7 @@ function NazaraBuild:Execute() libdirs("../lib/msvc/x64") targetdir("../lib/msvc/x64") - configuration({"xcode3 or xcode4", "x86"}) + configuration({"xcode3 or xcode4", "x32"}) libdirs("../extlibs/lib/xcode/x86") libdirs("../lib/xcode/x86") targetdir("../lib/xcode/x86") @@ -283,14 +283,14 @@ function NazaraBuild:Execute() libdirs("../lib") libdirs("../extlibs/lib/common") - configuration("x86") + configuration("x32") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x86"}) + configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86") if (toolTable.Kind == "library") then @@ -313,7 +313,7 @@ function NazaraBuild:Execute() self:MakeCopyAfterBuild(toolTable) end - configuration({"vs*", "x86"}) + configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") if (toolTable.Kind == "library") then @@ -331,7 +331,7 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x64") end - configuration({"xcode3 or xcode4", "x86"}) + configuration({"xcode3 or xcode4", "x32"}) libdirs("../extlibs/lib/xcode/x86") libdirs("../lib/xcode/x86") if (toolTable.Kind == "library") then @@ -411,26 +411,26 @@ function NazaraBuild:Execute() includedirs(exampleTable.Includes) links(exampleTable.Libraries) - configuration("x86") + configuration("x32") libdirs("../extlibs/lib/common/x86") configuration("x64") defines("NAZARA_PLATFORM_x64") libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x86"}) + configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../lib/" .. makeLibDir .. "/x86") configuration({"codeblocks or codelite or gmake", "x64"}) libdirs("../lib/" .. makeLibDir .. "/x64") - configuration({"vs*", "x86"}) + configuration({"vs*", "x32"}) libdirs("../lib/msvc/x86") configuration({"vs*", "x64"}) libdirs("../lib/msvc/x64") - configuration({"xcode3 or xcode4", "x86"}) + configuration({"xcode3 or xcode4", "x32"}) libdirs("../lib/xcode/x86") configuration({"xcode3 or xcode4", "x64"}) @@ -906,8 +906,8 @@ function NazaraBuild:MakeCopyAfterBuild(infoTable) for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do local paths = {} - table.insert(paths, {"x86", "../extlibs/lib/common/x86/" .. v .. ".dll"}) - table.insert(paths, {"x86", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) + table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) + table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) From f74f1800445986117a5077c5d8c53395e1c48e73 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 9 Jun 2016 13:02:02 +0200 Subject: [PATCH 126/224] Fix compilation for CodeBlocks 16.01 ! (Fixes #65) Former-commit-id: f49f9b662c6e105d1249f7f7839f8a711be87640 [formerly ab9e2158aebc0583790b52d6397015fe470c0a31] Former-commit-id: d68b86c1319bdfd956b226865831e7c2d0a5ea42 --- build/scripts/common.lua | 6 +++++- src/Nazara/Network/Win32/SocketImpl.cpp | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 5124dcace..f08828e3b 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -83,7 +83,7 @@ function NazaraBuild:Execute() targetsuffix("-s") configuration("codeblocks or codelite or gmake or xcode3 or xcode4") - buildoptions({"-fPIC", "-std=c++14"}) + buildoptions({"-fPIC", "-std=c++14", "-U__STRICT_ANSI__"}) for k, libTable in ipairs(self.OrderedExtLibs) do project(libTable.Name) @@ -900,6 +900,10 @@ function NazaraBuild:Resolve(infoTable) end function NazaraBuild:MakeCopyAfterBuild(infoTable) + if (PremakeVersion < 50) then + return + end + if (os.is("windows")) then configuration({}) postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 35d4b2371..9e5846471 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -6,7 +6,22 @@ #include #include #include -#include + +#include +#ifdef NAZARA_COMPILER_MINGW +// MinGW is lacking Mstcpip.h and that's too bad +struct tcp_keepalive +{ + u_long onoff; + u_long keepalivetime; + u_long keepaliveinterval; +}; + +#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) +#else + #include +#endif // NAZARA_COMPILER_MINGW + #include namespace Nz @@ -93,7 +108,7 @@ namespace Nz IpAddressImpl::SockAddrBuffer nameBuffer; int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); - + if (error) *error = SocketError_NoError; @@ -365,7 +380,7 @@ namespace Nz return IpAddress(); } - + if (error) *error = SocketError_NoError; @@ -566,7 +581,7 @@ namespace Nz return true; } - + bool SocketImpl::SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); From f7eeda0a1f11d050556838585c0bd5c80be75eaa Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 10 Jun 2016 12:40:31 +0200 Subject: [PATCH 127/224] Network/RUdpConnection: Remove useless line Former-commit-id: 03abb4d33dbf11efe2088ae9d403fbcd74217c4d [formerly 3672d0f6c5848d1fbe493f79ca9dc79fca45b34d] Former-commit-id: d9c9067cf538507bfd75c7d7e25051fecc96dab2 --- include/Nazara/Network/RUdpConnection.inl | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/Nazara/Network/RUdpConnection.inl b/include/Nazara/Network/RUdpConnection.inl index 48173bd77..2960cbced 100644 --- a/include/Nazara/Network/RUdpConnection.inl +++ b/include/Nazara/Network/RUdpConnection.inl @@ -149,8 +149,6 @@ namespace Nz std::vector& pendingPackets = peer.pendingPackets[priority]; if (!pendingPackets.empty()) return true; - - pendingPackets.clear(); } return false; From 6f38f42e8d7b903b38efb34067f3f39606f8ffdf Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 11 Jun 2016 13:13:53 +0200 Subject: [PATCH 128/224] Math/Algorithm: Fix IntegralLog2Pot case with sizeof(T) > 4 and %32 bits Former-commit-id: 08c6f806104a3956eb7d6eae82d7a872c8939d19 [formerly f1f7afc79b2f2670a3b1c81b291cc7d8e6a0f933] Former-commit-id: 5edb7cceefaaa87ac23e40563275165cd10bdfad --- include/Nazara/Math/Algorithm.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index e7e205e45..524f0bd4c 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -90,7 +90,7 @@ namespace Nz // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse unsigned int log2 = IntegralLog2Pot(val); - if (log2) + if (log2 || val == 1) return log2 + i*8; } From 6819d4a26cbd538b4becdab720b5888b678b5ea0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 10:03:05 +0200 Subject: [PATCH 129/224] Build: Remake exclusion system Allows to excludes pretty much everything and now also excludes projects relying on an excluded dependency Former-commit-id: 5260c724bd0b7ee82e58abdd16c99d0b78772c08 [formerly 3b107d86de1501964ea8f5babcdac4488759282b] Former-commit-id: 00b7cbc69751720da768efd56beca9ba6143cd32 --- build/scripts/common.lua | 110 +++++++++++++++++---------------- build/scripts/modules/core.lua | 3 +- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index f08828e3b..a6de8fca7 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -519,28 +519,19 @@ function NazaraBuild:Initialize() local moduleName = v:match(".*/(.*).lua") local moduleNameLower = moduleName:lower() - if (moduleNameLower ~= "core") then -- exclure le noyau n'aurait aucun sens - newoption({ - trigger = "exclude-" .. moduleNameLower, - description = "Exclude the " .. moduleName .. " module from the build system" - }) - end + local f, err = loadfile(v) + if (f) then + MODULE = {} + self:SetupInfoTable(MODULE) - if (not _OPTIONS["exclude-" .. moduleNameLower]) then - local f, err = loadfile(v) - if (f) then - MODULE = {} - self:SetupInfoTable(MODULE) + f() - f() - - local succeed, err = self:RegisterModule(MODULE) - if (not succeed) then - print("Unable to register module: " .. err) - end - else - print("Unable to load module file: " .. err) + local succeed, err = self:RegisterModule(MODULE) + if (not succeed) then + print("Unable to register module: " .. err) end + else + print("Unable to load module file: " .. err) end end MODULE = nil @@ -551,26 +542,19 @@ function NazaraBuild:Initialize() local toolName = v:match(".*/(.*).lua") local toolNameLower = toolName:lower() - newoption({ - trigger = "exclude-" .. toolNameLower, - description = "Exclude the " .. toolName .. " tool from the build system" - }) + local f, err = loadfile(v) + if (f) then + TOOL = {} + self:SetupInfoTable(TOOL) - if (not _OPTIONS["exclude-" .. toolNameLower]) then - local f, err = loadfile(v) - if (f) then - TOOL = {} - self:SetupInfoTable(TOOL) + f() - f() - - local succeed, err = self:RegisterTool(TOOL) - if (not succeed) then - print("Unable to register tool: " .. err) - end - else - print("Unable to load tool file: " .. err) + local succeed, err = self:RegisterTool(TOOL) + if (not succeed) then + print("Unable to register tool: " .. err) end + else + print("Unable to load tool file: " .. err) end end TOOL = nil @@ -616,9 +600,9 @@ function NazaraBuild:Initialize() for projectId,projectTable in pairs(projects) do if (self:Process(projectTable)) then - table.insert(orderedTables[k], projectTable) + table.insert(orderedTables[k], projectTable) else - print("Rejected client-only " .. projectTable.Name .. " " .. projectTable.Type) + print("Rejected " .. projectTable.Name .. " " .. string.lower(projectTable.Type) .. ": " .. projectTable.ExcludeReason) end end @@ -780,20 +764,17 @@ local PosixOSes = { } function NazaraBuild:Process(infoTable) - if (infoTable.ClientOnly and _OPTIONS["server"]) then - return false - end - local libraries = {} for k, library in pairs(infoTable.Libraries) do - local moduleName = library:match("Nazara(%w+)") - local moduleTable = moduleName and self.Modules[moduleName:lower()] - local toolTable = moduleName and self.Tools[moduleName:lower()] + local projectName = library:match("Nazara(%w+)") + local moduleTable = projectName and self.Modules[projectName:lower()] + local toolTable = projectName and self.Tools[projectName:lower()] if (moduleTable) then - if (moduleTable.ClientOnly and _OPTIONS["server"]) then - infoTable.ClientOnly = true - return false -- We depend on a client-only library + if (moduleTable.Excluded) then + infoTable.Excluded = true + infoTable.ExcludeReason = "depends on excluded " .. projectName .. " module" + return false end if (_OPTIONS["united"]) then @@ -811,9 +792,10 @@ function NazaraBuild:Process(infoTable) else local extLibTable = self.ExtLibs[library:lower()] if (extLibTable) then - if (extLibTable.ClientOnly and _OPTIONS["server"]) then - infoTable.ClientOnly = true - return false -- We depend on a client-only library + if (extLibTable.Excluded) then + infoTable.Excluded = true + infoTable.ExcludeReason = "depends on excluded " .. extLibTable.Name .. " external library" + return false end library = extLibTable.Name @@ -824,9 +806,10 @@ function NazaraBuild:Process(infoTable) table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") else if (toolTable and toolTable.Kind == "library") then - if (toolTable.ClientOnly and _OPTIONS["server"]) then - infoTable.ClientOnly = true - return false -- We depend on a client-only library + if (toolTable.Excluded) then + infoTable.Excluded = true + infoTable.ExcludeReason = "depends on excluded " .. toolTable.Name .. " tool" + return false end library = "Nazara" .. toolTable.Name @@ -894,6 +877,24 @@ function NazaraBuild:Process(infoTable) end function NazaraBuild:Resolve(infoTable) + if (infoTable.ClientOnly and _OPTIONS["server"]) then + infoTable.Excluded = true + infoTable.ExcludeReason = "excluded by command-line options (client-only)" + end + + if (infoTable.Excludable) then + local optionName = "excludes-" .. string.lower(infoTable.Type .. "-" .. infoTable.Name) + newoption({ + trigger = optionName, + description = "Excludes the " .. infoTable.Name .. " " .. string.lower(infoTable.Type) .. " and projects relying on it" + }) + + if (_OPTIONS[optionName]) then + infoTable.Excluded = true + infoTable.ExcludeReason = "excluded by command-line options" + end + end + if (type(infoTable.Libraries) == "function") then infoTable.Libraries = infoTable.Libraries() end @@ -932,6 +933,7 @@ function NazaraBuild:MakeCopyAfterBuild(infoTable) end function NazaraBuild:SetupInfoTable(infoTable) + infoTable.Excludable = true infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries.DebugStatic = {} infoTable.ConfigurationLibraries.ReleaseStatic = {} diff --git a/build/scripts/modules/core.lua b/build/scripts/modules/core.lua index 7156ef2f6..b33c0b61f 100644 --- a/build/scripts/modules/core.lua +++ b/build/scripts/modules/core.lua @@ -1,6 +1,7 @@ MODULE.Name = "Core" +MODULE.Excludable = false -- Excluding the core makes no sense as everything relies on it -MODULE.Files = { -- Les autres fichiers seront ajoutés automatiquement +MODULE.Files = { -- Other files will be automatically added "../include/Nazara/Prerequesites.hpp", "../include/Nazara/Math/**.hpp", "../include/Nazara/Math/**.inl", From 926cbbea98e00662cb4054a478f31583144ad2aa Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 10:03:39 +0200 Subject: [PATCH 130/224] Build: Remove -fPIC on Windows Former-commit-id: 76c37366073ebdb5ff1ecb0ad61ee746806195ed [formerly 920a28d07dabee120584c778271d95e863a39fa1] Former-commit-id: 2f8dbf0c075f6e2638da31e9ca69cbef1b832912 --- build/scripts/common.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index a6de8fca7..056f5c022 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -82,8 +82,11 @@ function NazaraBuild:Execute() configuration("ReleaseStatic") targetsuffix("-s") + configuration({"not windows", "codeblocks or codelite or gmake or xcode3 or xcode4"}) + buildoptions("-fPIC") + configuration("codeblocks or codelite or gmake or xcode3 or xcode4") - buildoptions({"-fPIC", "-std=c++14", "-U__STRICT_ANSI__"}) + buildoptions({"-std=c++14", "-U__STRICT_ANSI__"}) for k, libTable in ipairs(self.OrderedExtLibs) do project(libTable.Name) From 92f796105643846271889354bcef37ebf3d26cfc Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 10:06:27 +0200 Subject: [PATCH 131/224] Build: Convert spaces to tabs Former-commit-id: e0e4844838f16f006941d7152883cbfa04ea9913 [formerly d65a47fe81387c65a7ae32b9b38ad9a8fc4c2713] Former-commit-id: a97e57d33ba27c7b9f3e97d0ff86736b75211df9 --- build/scripts/common.lua | 142 +++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 056f5c022..e51729268 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -11,11 +11,11 @@ function NazaraBuild:Execute() else platformData = {"x32", "x64"} end - + if (self.Actions[_ACTION] == nil) then local makeLibDir = os.is("windows") and "mingw" or "gmake" - - if (_OPTIONS["with-extlibs"]) then + + if (_OPTIONS["with-extlibs"]) then workspace("NazaraExtlibs") platforms(platformData) @@ -68,9 +68,9 @@ function NazaraBuild:Execute() configuration("Release*") flags("NoFramePointer") - optimize("Speed") - rtti("Off") - vectorextensions("SSE2") + optimize("Speed") + rtti("Off") + vectorextensions("SSE2") configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants @@ -82,7 +82,7 @@ function NazaraBuild:Execute() configuration("ReleaseStatic") targetsuffix("-s") - configuration({"not windows", "codeblocks or codelite or gmake or xcode3 or xcode4"}) + configuration({"not windows", "codeblocks or codelite or gmake or xcode3 or xcode4"}) buildoptions("-fPIC") configuration("codeblocks or codelite or gmake or xcode3 or xcode4") @@ -90,7 +90,7 @@ function NazaraBuild:Execute() for k, libTable in ipairs(self.OrderedExtLibs) do project(libTable.Name) - + language(libTable.Language) location(_ACTION .. "/extlibs") @@ -106,7 +106,7 @@ function NazaraBuild:Execute() configuration(k) links(v) end - + configuration({}) end end @@ -130,10 +130,10 @@ function NazaraBuild:Execute() flags("Symbols") configuration("Release*") - flags("NoFramePointer") - optimize("Speed") - rtti("Off") - vectorextensions("SSE2") + flags("NoFramePointer") + optimize("Speed") + rtti("Off") + vectorextensions("SSE2") configuration({"Release*", "codeblocks or codelite or gmake or xcode3 or xcode4"}) buildoptions("-mfpmath=sse") -- Utilisation du SSE pour les calculs flottants @@ -250,17 +250,17 @@ function NazaraBuild:Execute() configuration(k) links(v) end - + configuration({}) end - + -- Tools for k, toolTable in ipairs(self.OrderedTools) do local prefix = "Nazara" if (toolTable.Kind == "plugin") then prefix = "Plugin" end - + project(prefix .. toolTable.Name) location(_ACTION .. "/tools") @@ -358,7 +358,7 @@ function NazaraBuild:Execute() configuration("*Dynamic") kind("SharedLib") - + configuration("DebugStatic") targetsuffix("-s-d") @@ -443,7 +443,7 @@ function NazaraBuild:Execute() configuration(k) links(v) end - + configuration({}) end end @@ -497,24 +497,24 @@ function NazaraBuild:Initialize() ACTION = nil -- Extern libraries - local extlibs = os.matchfiles("../extlibs/build/*.lua") - for k,v in pairs(extlibs) do - local f, err = loadfile(v) - if (f) then - LIBRARY = {} - self:SetupInfoTable(LIBRARY) + local extlibs = os.matchfiles("../extlibs/build/*.lua") + for k,v in pairs(extlibs) do + local f, err = loadfile(v) + if (f) then + LIBRARY = {} + self:SetupInfoTable(LIBRARY) - f() + f() - local succeed, err = self:RegisterExternLibrary(LIBRARY) - if (not succeed) then - print("Unable to register extern library: " .. err) - end - else - print("Unable to load extern library file: " .. err) - end - end - LIBRARY = nil + local succeed, err = self:RegisterExternLibrary(LIBRARY) + if (not succeed) then + print("Unable to register extern library: " .. err) + end + else + print("Unable to load extern library file: " .. err) + end + end + LIBRARY = nil -- Then the modules local modules = os.matchfiles("scripts/modules/*.lua") @@ -587,7 +587,7 @@ function NazaraBuild:Initialize() end EXAMPLE = nil end - + -- Once everything is registred, let's process all the tables self.OrderedExamples = {} self.OrderedExtLibs = {} @@ -596,19 +596,19 @@ function NazaraBuild:Initialize() local tables = {self.ExtLibs, self.Modules, self.Tools, self.Examples} local orderedTables = {self.OrderedExtLibs, self.OrderedModules, self.OrderedTools, self.OrderedExamples} for k,projects in ipairs(tables) do - -- Begin by resolving every project (because of dependencies in the same category) + -- Begin by resolving every project (because of dependencies in the same category) for projectId,projectTable in pairs(projects) do - self:Resolve(projectTable) - end + self:Resolve(projectTable) + end for projectId,projectTable in pairs(projects) do if (self:Process(projectTable)) then table.insert(orderedTables[k], projectTable) - else - print("Rejected " .. projectTable.Name .. " " .. string.lower(projectTable.Type) .. ": " .. projectTable.ExcludeReason) - end + else + print("Rejected " .. projectTable.Name .. " " .. string.lower(projectTable.Type) .. ": " .. projectTable.ExcludeReason) + end end - + table.sort(orderedTables[k], function (a, b) return a.Name < b.Name end) end end @@ -668,13 +668,13 @@ function NazaraBuild:RegisterExample(exampleTable) if (#exampleTable.Files == 0) then return false, "This example has no files" end - + local files = {} for k, file in ipairs(exampleTable.Files) do table.insert(files, "../examples/" .. exampleTable.Directory .. "/" .. file) end exampleTable.Files = files - + exampleTable.Type = "Example" self.Examples[lowerCaseName] = exampleTable return true @@ -719,7 +719,7 @@ function NazaraBuild:RegisterModule(moduleTable) table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.hpp") table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl") table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp") - + if (_OPTIONS["united"] and lowerCaseName ~= "core") then table.insert(moduleTable.FilesExcluded, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp") end @@ -767,18 +767,18 @@ local PosixOSes = { } function NazaraBuild:Process(infoTable) - local libraries = {} + local libraries = {} for k, library in pairs(infoTable.Libraries) do local projectName = library:match("Nazara(%w+)") local moduleTable = projectName and self.Modules[projectName:lower()] local toolTable = projectName and self.Tools[projectName:lower()] - + if (moduleTable) then - if (moduleTable.Excluded) then + if (moduleTable.Excluded) then infoTable.Excluded = true infoTable.ExcludeReason = "depends on excluded " .. projectName .. " module" - return false - end + return false + end if (_OPTIONS["united"]) then library = "NazaraEngine" @@ -795,38 +795,38 @@ function NazaraBuild:Process(infoTable) else local extLibTable = self.ExtLibs[library:lower()] if (extLibTable) then - if (extLibTable.Excluded) then + if (extLibTable.Excluded) then infoTable.Excluded = true infoTable.ExcludeReason = "depends on excluded " .. extLibTable.Name .. " external library" - return false - end + return false + end library = extLibTable.Name - + table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") else if (toolTable and toolTable.Kind == "library") then - if (toolTable.Excluded) then + if (toolTable.Excluded) then infoTable.Excluded = true infoTable.ExcludeReason = "depends on excluded " .. toolTable.Name .. " tool" - return false - end + return false + end library = "Nazara" .. toolTable.Name - + -- Import tools includes for k,v in ipairs(toolTable.Includes) do table.insert(infoTable.Includes, v) end - + -- And libraries for k, v in pairs(toolTable.Libraries) do table.insert(infoTable.Libraries, v) end - + for config, libs in pairs(toolTable.ConfigurationLibraries) do for k,v in pairs(libs) do table.insert(infoTable.ConfigurationLibraries[config], v) @@ -876,14 +876,14 @@ function NazaraBuild:Process(infoTable) end end - return true + return true end function NazaraBuild:Resolve(infoTable) - if (infoTable.ClientOnly and _OPTIONS["server"]) then + if (infoTable.ClientOnly and _OPTIONS["server"]) then infoTable.Excluded = true infoTable.ExcludeReason = "excluded by command-line options (client-only)" - end + end if (infoTable.Excludable) then local optionName = "excludes-" .. string.lower(infoTable.Type .. "-" .. infoTable.Name) @@ -891,22 +891,22 @@ function NazaraBuild:Resolve(infoTable) trigger = optionName, description = "Excludes the " .. infoTable.Name .. " " .. string.lower(infoTable.Type) .. " and projects relying on it" }) - + if (_OPTIONS[optionName]) then infoTable.Excluded = true infoTable.ExcludeReason = "excluded by command-line options" end end - if (type(infoTable.Libraries) == "function") then - infoTable.Libraries = infoTable.Libraries() - end + if (type(infoTable.Libraries) == "function") then + infoTable.Libraries = infoTable.Libraries() + end end function NazaraBuild:MakeCopyAfterBuild(infoTable) - if (PremakeVersion < 50) then - return - end + if (PremakeVersion < 50) then + return + end if (os.is("windows")) then configuration({}) @@ -942,7 +942,7 @@ function NazaraBuild:SetupInfoTable(infoTable) infoTable.ConfigurationLibraries.ReleaseStatic = {} infoTable.ConfigurationLibraries.DebugDynamic = {} infoTable.ConfigurationLibraries.ReleaseDynamic = {} - + local infos = {"Defines", "DynLib", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"} for k,v in ipairs(infos) do infoTable[v] = {} From d42ae34c4feaeab1261c19dba108b3b86a7b2d2b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 10:14:36 +0200 Subject: [PATCH 132/224] Build: Remove duplicate Former-commit-id: beac603acc691f30a232da2ae1def9e588f79b5d [formerly 5ca9b1d0c8df0562ad7a016c8c7b3fab136a9959] Former-commit-id: 14269fa79790ecf6a4f01b276aa153c5dad4148b --- build/scripts/common.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index e51729268..c359a60c4 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -148,9 +148,6 @@ function NazaraBuild:Execute() configuration({"linux or bsd or macosx", "gmake"}) buildoptions("-fvisibility=hidden") - configuration({"linux or bsd or macosx", "gmake"}) - buildoptions("-fvisibility=hidden") - configuration("vs*") buildoptions("/MP") -- Multiprocessus build flags("NoMinimalRebuild") From 49650a94f346c061ab96dc04382ec47cc3f90591 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 11:39:31 +0200 Subject: [PATCH 133/224] Build: Remake install system Former-commit-id: 5103cd29d3959802747d7d06bc9b90bc272215d4 [formerly 7c3ea867b6439d721f255306d812b5d10a3efe1a] Former-commit-id: 5b5ab11770402db34a14df80b9ad6c1ce3fecaca --- build/scripts/common.lua | 122 ++++++++++++++++++++++------- build/scripts/tools/assimp.lua | 2 - build/scripts/tools/ndk.lua | 2 - build/scripts/tools/ndk_server.lua | 4 +- build/scripts/tools/unittests.lua | 3 +- examples/DopplerEffect/build.lua | 2 +- examples/FirstScene/build.lua | 2 +- examples/MeshInfos/build.lua | 2 +- examples/Tut00/build.lua | 2 +- examples/Tut01/build.lua | 2 +- 10 files changed, 102 insertions(+), 41 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index c359a60c4..e7d4929c5 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -1,5 +1,14 @@ NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table +function NazaraBuild:AddExecutablePath(path) + self.ExecutableDir[path] = true + self.InstallDir[path] = true +end + +function NazaraBuild:AddInstallPath(path) + self.InstallDir[path] = true +end + function NazaraBuild:Execute() if (_ACTION == nil) then -- Si aucune action n'est spécifiée return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien @@ -196,7 +205,7 @@ function NazaraBuild:Execute() targetdir("../lib/" .. makeLibDir .. "/x64") -- Copy the module binaries to the example folder - self:MakeCopyAfterBuild(moduleTable) + self:MakeInstallCommands(moduleTable) configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") @@ -265,12 +274,16 @@ function NazaraBuild:Execute() if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then kind("SharedLib") - elseif (toolTable.Kind == "consoleapp") then + + -- Copy the tool binaries to the example folder + self:MakeInstallCommands(toolTable) + elseif (toolTable.Kind == "application") then debugdir(toolTable.Directory) - kind("ConsoleApp") - elseif (toolTable.Kind == "windowapp") then - debugdir(toolTable.Directory) - kind("WindowedApp") + if (toolTable.EnableConsole) then + kind("ConsoleApp") + else + kind("WindowedApp") + end else assert(false, "Invalid tool Kind") end @@ -308,11 +321,6 @@ function NazaraBuild:Execute() targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") end - -- Copy the tool binaries to the example folder - if (toolTable.CopyTargetToExampleDir) then - self:MakeCopyAfterBuild(toolTable) - end - configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") libdirs("../lib/msvc/x86") @@ -385,23 +393,34 @@ function NazaraBuild:Execute() end for k, exampleTable in ipairs(self.OrderedExamples) do + local destPath = "../examples/bin" + project("Demo" .. exampleTable.Name) location(_ACTION .. "/examples") - if (exampleTable.Console) then - kind("ConsoleApp") + if (exampleTable.Kind == "plugin" or exampleTable.Kind == "library") then + kind("SharedLib") + + self:MakeInstallCommands(toolTable) + elseif (exampleTable.Kind == "application") then + debugdir(exampleTable.Directory) + if (exampleTable.EnableConsole) then + kind("ConsoleApp") + else + kind("WindowedApp") + end else - kind("Window") + assert(false, "Invalid tool Kind") end - debugdir("../examples/bin") + debugdir(destPath) includedirs({ "../include", "../extlibs/include" }) libdirs("../lib") - targetdir("../examples/bin") + targetdir(destPath) files(exampleTable.Files) excludes(exampleTable.FilesExcluded) @@ -448,6 +467,11 @@ end function NazaraBuild:Initialize() -- Commençons par les options + newoption({ + trigger = "install-path", + description = "Setup additionnals install directories (library binaries will be copied there)" + }) + newoption({ trigger = "server", description = "Excludes client-only modules/tools/examples" @@ -470,9 +494,18 @@ function NazaraBuild:Initialize() self.Actions = {} self.Examples = {} + self.ExecutableDir = {} self.ExtLibs = {} + self.InstallDir = {} self.Modules = {} self.Tools = {} + + if (_OPTIONS["install-path"]) then + local paths = string.explode(_OPTIONS["install-path"], ";") + for k,v in pairs(paths) do + self:AddInstallPath(v) + end + end -- Actions modules = os.matchfiles("scripts/actions/*.lua") @@ -499,7 +532,7 @@ function NazaraBuild:Initialize() local f, err = loadfile(v) if (f) then LIBRARY = {} - self:SetupInfoTable(LIBRARY) + self:SetupExtlibTable(LIBRARY) f() @@ -522,7 +555,7 @@ function NazaraBuild:Initialize() local f, err = loadfile(v) if (f) then MODULE = {} - self:SetupInfoTable(MODULE) + self:SetupModuleTable(MODULE) f() @@ -545,7 +578,7 @@ function NazaraBuild:Initialize() local f, err = loadfile(v) if (f) then TOOL = {} - self:SetupInfoTable(TOOL) + self:SetupToolTable(TOOL) f() @@ -569,7 +602,7 @@ function NazaraBuild:Initialize() if (f) then EXAMPLE = {} EXAMPLE.Directory = dirName - self:SetupInfoTable(EXAMPLE) + self:SetupExampleTable(EXAMPLE) f() @@ -745,7 +778,7 @@ function NazaraBuild:RegisterTool(toolTable) end local lowerCaseKind = toolTable.Kind:lower() - if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "consoleapp" or lowerCaseKind == "windowapp") then + if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "application") then toolTable.Kind = lowerCaseKind else return false, "Invalid tool type" @@ -873,6 +906,10 @@ function NazaraBuild:Process(infoTable) end end + if (infoTable.Kind == "application") then + self:AddExecutablePath(infoTable.Directory) + end + return true end @@ -900,14 +937,18 @@ function NazaraBuild:Resolve(infoTable) end end -function NazaraBuild:MakeCopyAfterBuild(infoTable) +function NazaraBuild:MakeInstallCommands(infoTable) if (PremakeVersion < 50) then return end if (os.is("windows")) then configuration({}) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]}) + + for k,v in pairs(self.InstallDir) do + local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "]] .. destPath .. [[\" /E /Y]]}) + end for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do local paths = {} @@ -918,14 +959,18 @@ function NazaraBuild:MakeCopyAfterBuild(infoTable) for k,v in pairs(paths) do local config = v[1] - local path = v[2] - if (os.isfile(path)) then + local srcPath = v[2] + if (os.isfile(srcPath)) then if (infoTable.Kind == "plugin") then - path = "../../" .. path + srcPath = "../../" .. srcPath end configuration(config) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. path .. [[")}" "..\..\..\examples\bin\" /E /Y]]}) + + for k,v in pairs(self.ExecutableDir) do + local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. srcPath .. [[")}" "]] .. destPath .. [[\" /E /Y]]}) + end end end end @@ -945,4 +990,25 @@ function NazaraBuild:SetupInfoTable(infoTable) infoTable[v] = {} infoTable["Os" .. v] = {} end -end \ No newline at end of file +end + +function NazaraBuild:SetupExampleTable(infoTable) + self:SetupInfoTable(infoTable) + + infoTable.Directory = "../example/bin" + infoTable.Kind = "application" +end + +function NazaraBuild:SetupExtlibTable(infoTable) + self:SetupInfoTable(infoTable) + + infoTable.Kind = "library" +end + +function NazaraBuild:SetupModuleTable(infoTable) + self:SetupInfoTable(infoTable) + + infoTable.Kind = "library" +end + +NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable \ No newline at end of file diff --git a/build/scripts/tools/assimp.lua b/build/scripts/tools/assimp.lua index 3a1ca093b..0eecbcd54 100644 --- a/build/scripts/tools/assimp.lua +++ b/build/scripts/tools/assimp.lua @@ -3,8 +3,6 @@ TOOL.Name = "Assimp" TOOL.Directory = "../SDK/lib" TOOL.Kind = "Plugin" -TOOL.CopyTargetToExampleDir = true - TOOL.Includes = { "../include", "../plugins/Assimp" diff --git a/build/scripts/tools/ndk.lua b/build/scripts/tools/ndk.lua index 961fa6d7f..d2038342b 100644 --- a/build/scripts/tools/ndk.lua +++ b/build/scripts/tools/ndk.lua @@ -1,7 +1,5 @@ TOOL.Name = "SDK" -TOOL.CopyTargetToExampleDir = true - TOOL.Directory = "../SDK/lib" TOOL.Kind = "Library" diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index b1a71453e..91a0fd170 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -1,7 +1,5 @@ TOOL.Name = "SDKServer" -TOOL.CopyTargetToExampleDir = true - TOOL.Directory = "../SDK/lib" TOOL.Kind = "Library" @@ -23,7 +21,7 @@ TOOL.Files = { "../SDK/src/NDK/**.cpp" } --- Exlude client-only files +-- Excludes client-only files TOOL.FilesExcluded = { "../SDK/**/CameraComponent.*", "../SDK/**/Console.*", diff --git a/build/scripts/tools/unittests.lua b/build/scripts/tools/unittests.lua index cc6051297..349932cb6 100644 --- a/build/scripts/tools/unittests.lua +++ b/build/scripts/tools/unittests.lua @@ -1,7 +1,8 @@ TOOL.Name = "UnitTests" TOOL.Directory = "../tests" -TOOL.Kind = "ConsoleApp" +TOOL.EnableConsole = true +TOOL.Kind = "Application" TOOL.Defines = { } diff --git a/examples/DopplerEffect/build.lua b/examples/DopplerEffect/build.lua index 8298ef526..302011b81 100644 --- a/examples/DopplerEffect/build.lua +++ b/examples/DopplerEffect/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "DopplerEffect" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Files = { "main.cpp" diff --git a/examples/FirstScene/build.lua b/examples/FirstScene/build.lua index 14bf8a42f..612965b5a 100644 --- a/examples/FirstScene/build.lua +++ b/examples/FirstScene/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "FirstScene" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Files = { "main.cpp" diff --git a/examples/MeshInfos/build.lua b/examples/MeshInfos/build.lua index 9372ef5c1..4e26f318b 100644 --- a/examples/MeshInfos/build.lua +++ b/examples/MeshInfos/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "MeshInfos" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Files = { "main.cpp" diff --git a/examples/Tut00/build.lua b/examples/Tut00/build.lua index d0c499df6..ed5ea5995 100644 --- a/examples/Tut00/build.lua +++ b/examples/Tut00/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "Tut00_EmptyProject" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Files = { "main.cpp" diff --git a/examples/Tut01/build.lua b/examples/Tut01/build.lua index c12dc35b5..c195cbc1b 100644 --- a/examples/Tut01/build.lua +++ b/examples/Tut01/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "Tut01_HelloWorld" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Files = { "main.cpp" From 002a3666bf057fe3268300c171a6df2b8d36d1de Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 12:46:38 +0200 Subject: [PATCH 134/224] Update .gitignore Former-commit-id: 8f2692032677ec82978048becff61a5fa662bbc6 [formerly b2776b19ded063f59df50d2095325e2d7c13a2fe] Former-commit-id: d67437e4be7a6558d7706cc36fc0bee26b5cc077 --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index f3b8b2bbd..c930343f4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ examples/bin/*.dll examples/bin/*.so tests/*.exe tests/*.pdb +tests/*.dll +tests/*.so lib/* # Feature page From 6eca751ee52d3ea0fccea622e5af4c8c8ce86bcd Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 12 Jun 2016 12:46:56 +0200 Subject: [PATCH 135/224] Build: Fix typo Former-commit-id: 014f7894f5879ffa2cbddfbfe3382b150b9b5e52 [formerly d9ce35fac610af8ffe36ec8fac91f828ee58a9ab] Former-commit-id: c2e8b01db7fed181200243f3a40e8e2c8f5ed62d --- build/scripts/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index e7d4929c5..66aa12513 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -995,7 +995,7 @@ end function NazaraBuild:SetupExampleTable(infoTable) self:SetupInfoTable(infoTable) - infoTable.Directory = "../example/bin" + infoTable.Directory = "../examples/bin" infoTable.Kind = "application" end From c528640d80e47cecc61bb7f398a86b8e9129895f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 13 Jun 2016 21:09:55 +0200 Subject: [PATCH 136/224] Fix a shitload of warnings in 64 bits mode Former-commit-id: 5bc0c622c20eae45df51bb1ee62e5ed566e58a1b [formerly a8befbed30cb897ce876fd3b46a3585e1b70613e] Former-commit-id: 999225e414c0d6a3e9c6868f040b68045b2ba724 --- SDK/include/NDK/BaseComponent.inl | 2 +- .../NDK/Components/GraphicsComponent.hpp | 2 +- SDK/src/NDK/Components/GraphicsComponent.cpp | 2 +- build/scripts/common.lua | 4 +- include/Nazara/Core/Bitset.hpp | 50 ++++---- include/Nazara/Core/Bitset.inl | 114 +++++++++--------- include/Nazara/Core/Endianness.inl | 4 +- include/Nazara/Core/ResourceLoader.hpp | 2 +- include/Nazara/Core/ResourceLoader.inl | 2 +- include/Nazara/Lua/LuaInstance.hpp | 12 +- include/Nazara/Renderer/Texture.hpp | 4 +- include/Nazara/Utility/AbstractAtlas.hpp | 2 +- include/Nazara/Utility/AbstractImage.hpp | 4 +- include/Nazara/Utility/AbstractTextDrawer.hpp | 8 +- include/Nazara/Utility/Font.hpp | 4 +- .../Nazara/Utility/Formats/MD5AnimParser.hpp | 8 +- .../Nazara/Utility/Formats/MD5MeshParser.hpp | 4 +- .../Nazara/Utility/GuillotineImageAtlas.hpp | 13 +- include/Nazara/Utility/Image.hpp | 4 +- include/Nazara/Utility/PixelFormat.inl | 4 +- include/Nazara/Utility/SimpleTextDrawer.hpp | 8 +- src/Nazara/Core/Win32/FileImpl.cpp | 8 +- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 8 +- src/Nazara/Core/Win32/TaskSchedulerImpl.hpp | 2 +- src/Nazara/Graphics/TextSprite.cpp | 8 +- src/Nazara/Lua/LuaInstance.cpp | 16 +-- src/Nazara/Network/Win32/IpAddressImpl.cpp | 2 +- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 6 +- src/Nazara/Renderer/Texture.cpp | 4 +- src/Nazara/Utility/Font.cpp | 6 +- src/Nazara/Utility/Formats/MD5AnimLoader.cpp | 10 +- src/Nazara/Utility/Formats/MD5AnimParser.cpp | 8 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 18 +-- src/Nazara/Utility/Formats/MD5MeshParser.cpp | 4 +- src/Nazara/Utility/GuillotineImageAtlas.cpp | 2 +- src/Nazara/Utility/Image.cpp | 4 +- src/Nazara/Utility/SimpleTextDrawer.cpp | 8 +- src/Nazara/Utility/Win32/WindowImpl.cpp | 6 +- 39 files changed, 191 insertions(+), 188 deletions(-) diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 71f8ee2c1..341ddb651 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -26,7 +26,7 @@ namespace Ndk inline ComponentIndex BaseComponent::RegisterComponent(ComponentId id, Factory factoryFunc) { // Nous allons rajouter notre composant à la fin - ComponentIndex index = s_entries.size(); + ComponentIndex index = static_cast(s_entries.size()); s_entries.resize(index + 1); // On récupère et on affecte diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 86cefb782..c94cec4ab 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -40,7 +40,7 @@ namespace Ndk private: inline void InvalidateBoundingVolume(); - void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index); + void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index); inline void InvalidateRenderables(); inline void InvalidateTransformMatrix(); diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index e345bdb85..88ccd4ca1 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -9,7 +9,7 @@ namespace Ndk { - void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index) + void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index) { NazaraAssert(index < m_renderables.size(), "Invalid renderable index"); NazaraUnused(renderable); diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 66aa12513..12aa13d70 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -54,7 +54,7 @@ function NazaraBuild:Execute() targetdir("../extlibs/lib/" .. makeLibDir .. "/x64") configuration("vs*") - buildoptions("/MP") + buildoptions({"/MP", "/bigobj"}) -- Multiprocessus build and big .obj configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") @@ -158,7 +158,7 @@ function NazaraBuild:Execute() buildoptions("-fvisibility=hidden") configuration("vs*") - buildoptions("/MP") -- Multiprocessus build + buildoptions({"/MP", "/bigobj"}) -- Multiprocessus build and big .obj flags("NoMinimalRebuild") defines("_CRT_SECURE_NO_WARNINGS") defines("_SCL_SECURE_NO_WARNINGS") diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index 3b440278c..e4e2d8042 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -26,9 +26,9 @@ namespace Nz class Bit; Bitset(); - explicit Bitset(unsigned int bitCount, bool val); + explicit Bitset(std::size_t bitCount, bool val); explicit Bitset(const char* bits); - Bitset(const char* bits, unsigned int bitCount); + Bitset(const char* bits, std::size_t bitCount); Bitset(const Bitset& bitset) = default; explicit Bitset(const String& bits); template Bitset(T value); @@ -36,16 +36,16 @@ namespace Nz ~Bitset() noexcept = default; void Clear() noexcept; - unsigned int Count() const; + std::size_t Count() const; void Flip(); - unsigned int FindFirst() const; - unsigned int FindNext(unsigned int bit) const; + std::size_t FindFirst() const; + std::size_t FindNext(std::size_t bit) const; - Block GetBlock(unsigned int i) const; - unsigned int GetBlockCount() const; - unsigned int GetCapacity() const; - unsigned int GetSize() const; + Block GetBlock(std::size_t i) const; + std::size_t GetBlockCount() const; + std::size_t GetCapacity() const; + std::size_t GetSize() const; void PerformsAND(const Bitset& a, const Bitset& b); void PerformsNOT(const Bitset& a); @@ -54,19 +54,19 @@ namespace Nz bool Intersects(const Bitset& bitset) const; - void Reserve(unsigned int bitCount); - void Resize(unsigned int bitCount, bool defaultVal = false); + void Reserve(std::size_t bitCount); + void Resize(std::size_t bitCount, bool defaultVal = false); void Reset(); - void Reset(unsigned int bit); + void Reset(std::size_t bit); void Set(bool val = true); - void Set(unsigned int bit, bool val = true); - void SetBlock(unsigned int i, Block block); + void Set(std::size_t bit, bool val = true); + void SetBlock(std::size_t i, Block block); void Swap(Bitset& bitset); - bool Test(unsigned int bit) const; + bool Test(std::size_t bit) const; bool TestAll() const; bool TestAny() const; bool TestNone() const; @@ -74,9 +74,9 @@ namespace Nz template T To() const; String ToString() const; - void UnboundedReset(unsigned int bit); - void UnboundedSet(unsigned int bit, bool val = true); - bool UnboundedTest(unsigned int bit) const; + void UnboundedReset(std::size_t bit); + void UnboundedSet(std::size_t bit, bool val = true); + bool UnboundedTest(std::size_t bit) const; Bit operator[](int index); bool operator[](int index) const; @@ -93,20 +93,20 @@ namespace Nz Bitset& operator^=(const Bitset& bitset); static constexpr Block fullBitMask = std::numeric_limits::max(); - static constexpr unsigned int bitsPerBlock = std::numeric_limits::digits; - static constexpr unsigned int npos = std::numeric_limits::max(); + static constexpr std::size_t bitsPerBlock = std::numeric_limits::digits; + static constexpr std::size_t npos = std::numeric_limits::max(); private: - unsigned int FindFirstFrom(unsigned int blockIndex) const; + std::size_t FindFirstFrom(std::size_t blockIndex) const; Block GetLastBlockMask() const; void ResetExtraBits(); - static unsigned int ComputeBlockCount(unsigned int bitCount); - static unsigned int GetBitIndex(unsigned int bit); - static unsigned int GetBlockIndex(unsigned int bit); + static std::size_t ComputeBlockCount(std::size_t bitCount); + static std::size_t GetBitIndex(std::size_t bit); + static std::size_t GetBlockIndex(std::size_t bit); std::vector m_blocks; - unsigned int m_bitCount; + std::size_t m_bitCount; }; template diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index f7256bdbb..21457d7c7 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -42,7 +42,7 @@ namespace Nz */ template - Bitset::Bitset(unsigned int bitCount, bool val) : + Bitset::Bitset(std::size_t bitCount, bool val) : Bitset() { Resize(bitCount, val); @@ -72,11 +72,11 @@ namespace Nz */ template - Bitset::Bitset(const char* bits, unsigned int bitCount) : + Bitset::Bitset(const char* bits, std::size_t bitCount) : m_blocks(ComputeBlockCount(bitCount), 0U), m_bitCount(bitCount) { - for (unsigned int i = 0; i < bitCount; ++i) + for (std::size_t i = 0; i < bitCount; ++i) { switch (*bits++) { @@ -126,7 +126,7 @@ namespace Nz else { // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits - for (unsigned int bitPos = 0; bitPos < std::numeric_limits::digits; bitPos++) + for (std::size_t bitPos = 0; bitPos < std::numeric_limits::digits; bitPos++) { if (value & (T(1U) << bitPos)) UnboundedSet(bitPos, true); @@ -153,13 +153,13 @@ namespace Nz */ template - unsigned int Bitset::Count() const + std::size_t Bitset::Count() const { if (m_blocks.empty()) return 0; - unsigned int count = 0; - for (unsigned int i = 0; i < m_blocks.size(); ++i) + std::size_t count = 0; + for (std::size_t i = 0; i < m_blocks.size(); ++i) count += CountBits(m_blocks[i]); return count; @@ -184,7 +184,7 @@ namespace Nz */ template - unsigned int Bitset::FindFirst() const + std::size_t Bitset::FindFirst() const { return FindFirstFrom(0); } @@ -199,7 +199,7 @@ namespace Nz */ template - unsigned int Bitset::FindNext(unsigned int bit) const + std::size_t Bitset::FindNext(std::size_t bit) const { NazaraAssert(bit < m_bitCount, "Bit index out of range"); @@ -207,8 +207,8 @@ namespace Nz return npos; // The block of the bit and its index - unsigned int blockIndex = GetBlockIndex(bit); - unsigned int bitIndex = GetBitIndex(bit); + std::size_t blockIndex = GetBlockIndex(bit); + std::size_t bitIndex = GetBitIndex(bit); // We get the block Block block = m_blocks[blockIndex]; @@ -233,7 +233,7 @@ namespace Nz */ template - Block Bitset::GetBlock(unsigned int i) const + Block Bitset::GetBlock(std::size_t i) const { NazaraAssert(i < m_blocks.size(), "Block index out of range"); @@ -246,7 +246,7 @@ namespace Nz */ template - unsigned int Bitset::GetBlockCount() const + std::size_t Bitset::GetBlockCount() const { return m_blocks.size(); } @@ -257,7 +257,7 @@ namespace Nz */ template - unsigned int Bitset::GetCapacity() const + std::size_t Bitset::GetCapacity() const { return m_blocks.capacity()*bitsPerBlock; } @@ -268,7 +268,7 @@ namespace Nz */ template - unsigned int Bitset::GetSize() const + std::size_t Bitset::GetSize() const { return m_bitCount; } @@ -285,7 +285,7 @@ namespace Nz template void Bitset::PerformsAND(const Bitset& a, const Bitset& b) { - std::pair minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); + std::pair minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); // We reinitialise our blocks with zero m_blocks.clear(); @@ -293,7 +293,7 @@ namespace Nz m_bitCount = std::max(a.GetSize(), b.GetSize()); // In case of the "AND", we can stop with the smallest size (because x & 0 = 0) - for (unsigned int i = 0; i < minmax.first; ++i) + for (std::size_t i = 0; i < minmax.first; ++i) m_blocks[i] = a.GetBlock(i) & b.GetBlock(i); ResetExtraBits(); @@ -311,7 +311,7 @@ namespace Nz m_blocks.resize(a.GetBlockCount()); m_bitCount = a.GetSize(); - for (unsigned int i = 0; i < m_blocks.size(); ++i) + for (std::size_t i = 0; i < m_blocks.size(); ++i) m_blocks[i] = ~a.GetBlock(i); ResetExtraBits(); @@ -332,15 +332,15 @@ namespace Nz const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b; const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a; - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); + std::size_t maxBlockCount = greater.GetBlockCount(); + std::size_t minBlockCount = lesser.GetBlockCount(); m_blocks.resize(maxBlockCount); m_bitCount = greater.GetSize(); - for (unsigned int i = 0; i < minBlockCount; ++i) + for (std::size_t i = 0; i < minBlockCount; ++i) m_blocks[i] = a.GetBlock(i) | b.GetBlock(i); - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + for (std::size_t i = minBlockCount; i < maxBlockCount; ++i) m_blocks[i] = greater.GetBlock(i); // (x | 0 = x) ResetExtraBits(); @@ -361,15 +361,15 @@ namespace Nz const Bitset& greater = (a.GetSize() > b.GetSize()) ? a : b; const Bitset& lesser = (a.GetSize() > b.GetSize()) ? b : a; - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); + std::size_t maxBlockCount = greater.GetBlockCount(); + std::size_t minBlockCount = lesser.GetBlockCount(); m_blocks.resize(maxBlockCount); m_bitCount = greater.GetSize(); - for (unsigned int i = 0; i < minBlockCount; ++i) + for (std::size_t i = 0; i < minBlockCount; ++i) m_blocks[i] = a.GetBlock(i) ^ b.GetBlock(i); - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + for (std::size_t i = minBlockCount; i < maxBlockCount; ++i) m_blocks[i] = greater.GetBlock(i); // (x ^ 0 = x) ResetExtraBits(); @@ -385,8 +385,8 @@ namespace Nz bool Bitset::Intersects(const Bitset& bitset) const { // We only test the blocks in common - unsigned int sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); - for (unsigned int i = 0; i < sharedBlocks; ++i) + std::size_t sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); + for (std::size_t i = 0; i < sharedBlocks; ++i) { Block a = GetBlock(i); Block b = bitset.GetBlock(i); @@ -404,7 +404,7 @@ namespace Nz */ template - void Bitset::Reserve(unsigned int bitCount) + void Bitset::Reserve(std::size_t bitCount) { m_blocks.reserve(ComputeBlockCount(bitCount)); } @@ -417,13 +417,13 @@ namespace Nz */ template - void Bitset::Resize(unsigned int bitCount, bool defaultVal) + void Bitset::Resize(std::size_t bitCount, bool defaultVal) { // We begin with changing the size of container, with the correct value of initialisation - unsigned int lastBlockIndex = m_blocks.size() - 1; + std::size_t lastBlockIndex = m_blocks.size() - 1; m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U); - unsigned int remainingBits = GetBitIndex(m_bitCount); + std::size_t remainingBits = GetBitIndex(m_bitCount); if (bitCount > m_bitCount && remainingBits > 0 && defaultVal) // Initialisation of unused bits in the last block before the size change m_blocks[lastBlockIndex] |= fullBitMask << remainingBits; @@ -451,7 +451,7 @@ namespace Nz */ template - void Bitset::Reset(unsigned int bit) + void Bitset::Reset(std::size_t bit) { Set(bit, false); } @@ -482,7 +482,7 @@ namespace Nz */ template - void Bitset::Set(unsigned int bit, bool val) + void Bitset::Set(std::size_t bit, bool val) { NazaraAssert(bit < m_bitCount, "Bit index out of range"); @@ -503,7 +503,7 @@ namespace Nz * \remark Produce a NazaraAssert if i is greather than number of blocks in bitset */ template - void Bitset::SetBlock(unsigned int i, Block block) + void Bitset::SetBlock(std::size_t i, Block block) { NazaraAssert(i < m_blocks.size(), "Block index out of range"); @@ -537,7 +537,7 @@ namespace Nz */ template - bool Bitset::Test(unsigned int bit) const + bool Bitset::Test(std::size_t bit) const { NazaraAssert(bit < m_bitCount, "Bit index out of range"); @@ -555,7 +555,7 @@ namespace Nz // Special case for the last block Block lastBlockMask = GetLastBlockMask(); - for (unsigned int i = 0; i < m_blocks.size(); ++i) + for (std::size_t i = 0; i < m_blocks.size(); ++i) { Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; if (m_blocks[i] == mask) // The extra bits are set to zero, thus we can't test without proceeding with a mask @@ -576,7 +576,7 @@ namespace Nz if (m_blocks.empty()) return false; - for (unsigned int i = 0; i < m_blocks.size(); ++i) + for (std::size_t i = 0; i < m_blocks.size(); ++i) { if (m_blocks[i]) return true; @@ -612,7 +612,7 @@ namespace Nz NazaraAssert(m_bitCount <= std::numeric_limits::digits, "Bit count cannot be greater than T bit count"); T value = 0; - for (unsigned int i = 0; i < m_blocks.size(); ++i) + for (std::size_t i = 0; i < m_blocks.size(); ++i) value |= static_cast(m_blocks[i]) << i*bitsPerBlock; return value; @@ -628,7 +628,7 @@ namespace Nz { String str(m_bitCount, '0'); - for (unsigned int i = 0; i < m_bitCount; ++i) + for (std::size_t i = 0; i < m_bitCount; ++i) { if (Test(i)) str[m_bitCount - i - 1] = '1'; // Inversion de l'indice @@ -648,7 +648,7 @@ namespace Nz */ template - void Bitset::UnboundedReset(unsigned int bit) + void Bitset::UnboundedReset(std::size_t bit) { UnboundedSet(bit, false); } @@ -665,7 +665,7 @@ namespace Nz */ template - void Bitset::UnboundedSet(unsigned int bit, bool val) + void Bitset::UnboundedSet(std::size_t bit, bool val) { if (bit < m_bitCount) Set(bit, val); @@ -687,7 +687,7 @@ namespace Nz */ template - bool Bitset::UnboundedTest(unsigned int bit) const + bool Bitset::UnboundedTest(std::size_t bit) const { if (bit < m_bitCount) return Test(bit); @@ -816,13 +816,13 @@ namespace Nz */ template - unsigned int Bitset::FindFirstFrom(unsigned int blockIndex) const + std::size_t Bitset::FindFirstFrom(std::size_t blockIndex) const { if (blockIndex >= m_blocks.size()) return npos; // We are looking for the first non-null block - unsigned int i = blockIndex; + std::size_t i = blockIndex; for (; i < m_blocks.size(); ++i) { if (m_blocks[i]) @@ -868,7 +868,7 @@ namespace Nz */ template - unsigned int Bitset::ComputeBlockCount(unsigned int bitCount) + std::size_t Bitset::ComputeBlockCount(std::size_t bitCount) { return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U); } @@ -879,7 +879,7 @@ namespace Nz */ template - unsigned int Bitset::GetBitIndex(unsigned int bit) + std::size_t Bitset::GetBitIndex(std::size_t bit) { return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock } @@ -890,7 +890,7 @@ namespace Nz */ template - unsigned int Bitset::GetBlockIndex(unsigned int bit) + std::size_t Bitset::GetBlockIndex(std::size_t bit) { return bit / bitsPerBlock; } @@ -1106,18 +1106,18 @@ namespace Nz const Bitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; const Bitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); + std::size_t maxBlockCount = greater.GetBlockCount(); + std::size_t minBlockCount = lesser.GetBlockCount(); // We test the blocks in common to check the equality of bits - for (unsigned int i = 0; i < minBlockCount; ++i) + for (std::size_t i = 0; i < minBlockCount; ++i) { if (lhs.GetBlock(i) != rhs.GetBlock(i)) return false; } // Now we check for the blocks that only the biggest bitset owns, and to be equal, they must be set to '0' - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + for (std::size_t i = minBlockCount; i < maxBlockCount; ++i) if (greater.GetBlock(i)) return false; @@ -1152,20 +1152,20 @@ namespace Nz const Bitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; const Bitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); + std::size_t maxBlockCount = greater.GetBlockCount(); + std::size_t minBlockCount = lesser.GetBlockCount(); // If the greatest bitset has a single bit active in a block outside the lesser bitset range, then it is greater - for (unsigned int i = maxBlockCount; i > minBlockCount; ++i) + for (std::size_t i = maxBlockCount; i > minBlockCount; ++i) { if (greater.GetBlock(i)) return lhs.GetBlockCount() < rhs.GetBlockCount(); } // Compare the common blocks - for (unsigned int i = 0; i < minBlockCount; ++i) + for (std::size_t i = 0; i < minBlockCount; ++i) { - unsigned int index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block + std::size_t index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block if (lhs.GetBlock(index) < rhs.GetBlock(index)) return true; } diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index ee0d094ca..67df87c45 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -33,8 +33,8 @@ namespace Nz inline void SwapBytes(void* buffer, std::size_t size) { UInt8* bytes = static_cast(buffer); - unsigned int i = 0; - unsigned int j = size - 1; + std::size_t i = 0; + std::size_t j = size - 1; while (i < j) std::swap(bytes[i++], bytes[j--]); diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index b0640dcbc..8af3e3cd3 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -39,7 +39,7 @@ namespace Nz static bool IsExtensionSupported(const String& extension); static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters()); - static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); + static bool LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters = Parameters()); static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters()); static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 74e59067d..2ac72c6df 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -160,7 +160,7 @@ namespace Nz * \remark Produces a NazaraError if all loaders failed or no loader was found */ template - bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) + bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, std::size_t size, const Parameters& parameters) { NazaraAssert(resource, "Invalid resource"); NazaraAssert(data, "Invalid data pointer"); diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index b924f6a05..9affe6f87 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -84,7 +84,7 @@ namespace Nz bool Execute(const String& code); bool ExecuteFromFile(const String& filePath); - bool ExecuteFromMemory(const void* data, unsigned int size); + bool ExecuteFromMemory(const void* data, std::size_t size); bool ExecuteFromStream(Stream& stream); int GetAbsIndex(int index) const; @@ -142,10 +142,10 @@ namespace Nz void PushNumber(double value) const; void PushReference(int ref) const; void PushString(const char* str) const; - void PushString(const char* str, unsigned int size) const; + void PushString(const char* str, std::size_t size) const; void PushString(const String& str) const; void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0) const; - void* PushUserdata(unsigned int size) const; + void* PushUserdata(std::size_t size) const; void PushValue(int index) const; void Remove(int index) const; @@ -158,7 +158,7 @@ namespace Nz void SetMetatable(const char* tname) const; void SetMetatable(const String& tname) const; void SetMetatable(int index) const; - void SetMemoryLimit(UInt32 memoryLimit); + void SetMemoryLimit(std::size_t memoryLimit); void SetTable(int index = -3) const; void SetTimeLimit(UInt32 timeLimit); @@ -185,8 +185,8 @@ namespace Nz static int ProxyFunc(lua_State* state); static void TimeLimiter(lua_State* state, lua_Debug* debug); - UInt32 m_memoryLimit; - UInt32 m_memoryUsage; + std::size_t m_memoryLimit; + std::size_t m_memoryUsage; UInt32 m_timeLimit; Clock m_clock; String m_lastError; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 73069aa37..2fd368b53 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -59,8 +59,8 @@ namespace Nz unsigned int GetHeight(UInt8 level = 0) const; UInt8 GetLevelCount() const; UInt8 GetMaxLevel() const; - unsigned int GetMemoryUsage() const; - unsigned int GetMemoryUsage(UInt8 level) const; + std::size_t GetMemoryUsage() const; + std::size_t GetMemoryUsage(UInt8 level) const; Vector3ui GetSize(UInt8 level = 0) const; ImageType GetType() const; unsigned int GetWidth(UInt8 level = 0) const; diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 4d135d465..16d09235f 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -29,7 +29,7 @@ namespace Nz virtual void Clear() = 0; virtual void Free(SparsePtr rects, SparsePtr layers, unsigned int count) = 0; virtual AbstractImage* GetLayer(unsigned int layerIndex) const = 0; - virtual unsigned int GetLayerCount() const = 0; + virtual std::size_t GetLayerCount() const = 0; virtual UInt32 GetStorage() const = 0; virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) = 0; diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp index 3a09f3a06..93821e105 100644 --- a/include/Nazara/Utility/AbstractImage.hpp +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -28,8 +28,8 @@ namespace Nz virtual unsigned int GetHeight(UInt8 level = 0) const = 0; virtual UInt8 GetLevelCount() const = 0; virtual UInt8 GetMaxLevel() const = 0; - virtual unsigned int GetMemoryUsage() const = 0; - virtual unsigned int GetMemoryUsage(UInt8 level) const = 0; + virtual std::size_t GetMemoryUsage() const = 0; + virtual std::size_t GetMemoryUsage(UInt8 level) const = 0; virtual Vector3ui GetSize(UInt8 level = 0) const = 0; virtual ImageType GetType() const = 0; virtual unsigned int GetWidth(UInt8 level = 0) const = 0; diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp index ffd704f6a..9f941b9c9 100644 --- a/include/Nazara/Utility/AbstractTextDrawer.hpp +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -27,10 +27,10 @@ namespace Nz virtual ~AbstractTextDrawer(); 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; - virtual unsigned int GetGlyphCount() const = 0; + virtual Font* GetFont(std::size_t index) const = 0; + virtual std::size_t GetFontCount() const = 0; + virtual const Glyph& GetGlyph(std::size_t index) const = 0; + virtual std::size_t GetGlyphCount() const = 0; struct Glyph { diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 257e91245..9a226d91e 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -61,8 +61,8 @@ namespace Nz bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* glyph) const; const std::shared_ptr& GetAtlas() const; - unsigned int GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const; - unsigned int GetCachedGlyphCount() const; + std::size_t GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const; + std::size_t GetCachedGlyphCount() const; String GetFamilyName() const; int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; const Glyph& GetGlyph(unsigned int characterSize, UInt32 style, char32_t character) const; diff --git a/include/Nazara/Utility/Formats/MD5AnimParser.hpp b/include/Nazara/Utility/Formats/MD5AnimParser.hpp index cfba9fdc4..558608142 100644 --- a/include/Nazara/Utility/Formats/MD5AnimParser.hpp +++ b/include/Nazara/Utility/Formats/MD5AnimParser.hpp @@ -47,12 +47,12 @@ namespace Nz Ternary Check(); - unsigned int GetAnimatedComponentCount() const; + std::size_t GetAnimatedComponentCount() const; const Frame* GetFrames() const; - unsigned int GetFrameCount() const; - unsigned int GetFrameRate() const; + std::size_t GetFrameCount() const; + std::size_t GetFrameRate() const; const Joint* GetJoints() const; - unsigned int GetJointCount() const; + std::size_t GetJointCount() const; bool Parse(); diff --git a/include/Nazara/Utility/Formats/MD5MeshParser.hpp b/include/Nazara/Utility/Formats/MD5MeshParser.hpp index 5d114bdbb..cd2d19309 100644 --- a/include/Nazara/Utility/Formats/MD5MeshParser.hpp +++ b/include/Nazara/Utility/Formats/MD5MeshParser.hpp @@ -58,9 +58,9 @@ namespace Nz Ternary Check(); const Joint* GetJoints() const; - unsigned int GetJointCount() const; + std::size_t GetJointCount() const; const Mesh* GetMeshes() const; - unsigned int GetMeshCount() const; + std::size_t GetMeshCount() const; bool Parse(); diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index f26ae13ea..318b92d6b 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -23,16 +23,17 @@ namespace Nz GuillotineImageAtlas(); virtual ~GuillotineImageAtlas(); - void Clear(); - void Free(SparsePtr rects, SparsePtr layers, unsigned int count); + void Clear() override; + + void Free(SparsePtr rects, SparsePtr layers, unsigned int count) override; GuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const; GuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const; - AbstractImage* GetLayer(unsigned int layerIndex) const; - unsigned int GetLayerCount() const; - UInt32 GetStorage() const; + AbstractImage* GetLayer(unsigned int layerIndex) const override; + std::size_t GetLayerCount() const override; + UInt32 GetStorage() const override; - bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex); + bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) override; void SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic); void SetRectSplitHeuristic(GuillotineBinPack::GuillotineSplitHeuristic heuristic); diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 65c03d6bd..d936ee4d8 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -84,8 +84,8 @@ namespace Nz unsigned int GetHeight(UInt8 level = 0) const; UInt8 GetLevelCount() const; UInt8 GetMaxLevel() const; - unsigned int GetMemoryUsage() const; - unsigned int GetMemoryUsage(UInt8 level) const; + std::size_t GetMemoryUsage() const; + std::size_t GetMemoryUsage(UInt8 level) const; Color GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const; UInt8* GetPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, UInt8 level = 0); Vector3ui GetSize(UInt8 level = 0) const; diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index e384d8574..bf827c4c0 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -100,7 +100,7 @@ namespace Nz counter |= blueMask; counter |= alphaMask; - bitsPerPixel = counter.Count(); + bitsPerPixel = static_cast(counter.Count()); } inline bool PixelFormatInfo::Validate() const @@ -116,7 +116,7 @@ namespace Nz for (unsigned int i = 0; i < 4; ++i) { - unsigned int usedBits = masks[i]->Count(); + UInt8 usedBits = static_cast(masks[i]->Count()); if (usedBits == 0) continue; diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index f5532ca8f..b2f2bf4f9 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -32,10 +32,10 @@ namespace Nz unsigned int GetCharacterSize() const; const Color& GetColor() const; Font* GetFont() const; - Font* GetFont(unsigned int index) const override; - unsigned int GetFontCount() const override; - const Glyph& GetGlyph(unsigned int index) const override; - unsigned int GetGlyphCount() const override; + Font* GetFont(std::size_t index) const override; + std::size_t GetFontCount() const override; + const Glyph& GetGlyph(std::size_t index) const override; + std::size_t GetGlyphCount() const override; UInt32 GetStyle() const; const String& GetText() const; diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index dcce3d29a..5ed051adb 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -96,7 +96,7 @@ namespace Nz //UInt64 oldCursorPos = GetCursorPos(); DWORD read = 0; - if (ReadFile(m_handle, buffer, size, &read, nullptr)) + if (ReadFile(m_handle, buffer, static_cast(size), &read, nullptr)) { m_endOfFile = (read != size); m_endOfFileUpdated = true; @@ -191,9 +191,9 @@ namespace Nz LARGE_INTEGER cursorPos; cursorPos.QuadPart = GetCursorPos(); - LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); - WriteFile(m_handle, buffer, size, &written, nullptr); - UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); + LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, static_cast(size), 0); + WriteFile(m_handle, buffer, static_cast(size), &written, nullptr); + UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, static_cast(size), 0); m_endOfFileUpdated = false; diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index 5b5d7153d..ef83e4b28 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -24,7 +24,7 @@ namespace Nz } #endif - s_workerCount = workerCount; + s_workerCount = static_cast(workerCount); s_doneEvents.reset(new HANDLE[workerCount]); s_workers.reset(new Worker[workerCount]); s_workerThreads.reset(new HANDLE[workerCount]); @@ -64,7 +64,7 @@ namespace Nz // On s'assure que des tâches ne sont pas déjà en cours WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); - std::ldiv_t div = std::ldiv(count, s_workerCount); // Division et modulo en une opération, y'a pas de petit profit + std::lldiv_t div = std::lldiv(count, s_workerCount); // Division et modulo en une opération, y'a pas de petit profit for (std::size_t i = 0; i < s_workerCount; ++i) { // On va maintenant répartir les tâches entre chaque worker et les envoyer dans la queue de chacun @@ -78,7 +78,7 @@ namespace Nz } // On les lance une fois qu'ils sont tous initialisés (pour éviter qu'un worker ne passe en pause détectant une absence de travaux) - for (unsigned int i = 0; i < s_workerCount; ++i) + for (std::size_t i = 0; i < s_workerCount; ++i) { ResetEvent(s_doneEvents[i]); SetEvent(s_workers[i].wakeEvent); @@ -244,5 +244,5 @@ namespace Nz std::unique_ptr TaskSchedulerImpl::s_doneEvents; // Doivent être contigus std::unique_ptr TaskSchedulerImpl::s_workers; std::unique_ptr TaskSchedulerImpl::s_workerThreads; // Doivent être contigus - std::size_t TaskSchedulerImpl::s_workerCount; + DWORD TaskSchedulerImpl::s_workerCount; } diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp index 00fdec634..aabd58b86 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp @@ -44,7 +44,7 @@ namespace Nz static std::unique_ptr s_doneEvents; // Doivent être contigus static std::unique_ptr s_workers; static std::unique_ptr s_workerThreads; // Doivent être contigus - static std::size_t s_workerCount; + static DWORD s_workerCount; }; } diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 3459b22cd..42dba4aaf 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -64,8 +64,8 @@ namespace Nz pair.second.used = false; // ... until they are marked as used by the drawer - unsigned int fontCount = drawer.GetFontCount(); - for (unsigned int i = 0; i < fontCount; ++i) + std::size_t fontCount = drawer.GetFontCount(); + for (std::size_t i = 0; i < fontCount; ++i) { Font* font = drawer.GetFont(i); const AbstractAtlas* atlas = font->GetAtlas().get(); @@ -95,7 +95,7 @@ namespace Nz ++atlasIt; } - unsigned int glyphCount = drawer.GetGlyphCount(); + std::size_t glyphCount = drawer.GetGlyphCount(); m_localVertices.resize(glyphCount * 4); // Reset glyph count for every texture to zero @@ -105,7 +105,7 @@ namespace Nz // Count glyph count for each texture Texture* lastTexture = nullptr; unsigned int* count = nullptr; - for (unsigned int i = 0; i < glyphCount; ++i) + for (std::size_t i = 0; i < glyphCount; ++i) { const AbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 23f852921..0ecf4c063 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -401,7 +401,7 @@ namespace Nz return false; } - unsigned int length = static_cast(file.GetSize()); + std::size_t length = static_cast(file.GetSize()); String source(length, '\0'); @@ -416,7 +416,7 @@ namespace Nz return Execute(source); } - bool LuaInstance::ExecuteFromMemory(const void* data, unsigned int size) + bool LuaInstance::ExecuteFromMemory(const void* data, std::size_t size) { MemoryView stream(data, size); return ExecuteFromStream(stream); @@ -679,7 +679,7 @@ namespace Nz lua_pushstring(m_state, str); } - void LuaInstance::PushString(const char* str, unsigned int size) const + void LuaInstance::PushString(const char* str, std::size_t size) const { lua_pushlstring(m_state, str, size); } @@ -694,7 +694,7 @@ namespace Nz lua_createtable(m_state, sequenceElementCount, arrayElementCount); } - void* LuaInstance::PushUserdata(unsigned int size) const + void* LuaInstance::PushUserdata(std::size_t size) const { return lua_newuserdata(m_state, size); } @@ -749,7 +749,7 @@ namespace Nz lua_setmetatable(m_state, index); } - void LuaInstance::SetMemoryLimit(UInt32 memoryLimit) + void LuaInstance::SetMemoryLimit(std::size_t memoryLimit) { m_memoryLimit = memoryLimit; } @@ -860,8 +860,8 @@ namespace Nz void* LuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize) { LuaInstance* instance = static_cast(ud); - UInt32& memoryLimit = instance->m_memoryLimit; - UInt32& memoryUsage = instance->m_memoryUsage; + std::size_t& memoryLimit = instance->m_memoryLimit; + std::size_t& memoryUsage = instance->m_memoryUsage; if (nsize == 0) { @@ -872,7 +872,7 @@ namespace Nz } else { - UInt32 usage = memoryUsage + nsize; + std::size_t usage = memoryUsage + nsize; if (ptr) usage -= osize; diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 0fd5cd88a..cbcebb83b 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -56,7 +56,7 @@ namespace Nz std::array hostnameBuffer; std::array serviceBuffer; - int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); + int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), static_cast(hostnameBuffer.size()), serviceBuffer.data(), static_cast(serviceBuffer.size()), flags); if (result == 0) { if (hostname) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 9e5846471..ab7ba7fe3 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -328,7 +328,7 @@ namespace Nz return code == TRUE; } - unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) + std::size_t SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) { unsigned int code; int codeLength = sizeof(code); diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 1093f1fd1..e49db2cec 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -227,7 +227,8 @@ namespace Nz } GLenum type; - UInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); + UInt8* offset = nullptr; + offset += s_indexBuffer->GetStartOffset(); if (s_indexBuffer->HasLargeIndices()) { @@ -290,7 +291,8 @@ namespace Nz } GLenum type; - UInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); + UInt8* offset = nullptr; + offset += s_indexBuffer->GetStartOffset(); if (s_indexBuffer->HasLargeIndices()) { diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 835dce85e..b8bed61a0 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -364,7 +364,7 @@ namespace Nz return Image::GetMaxLevel(m_impl->type, m_impl->width, m_impl->height, m_impl->depth); } - unsigned int Texture::GetMemoryUsage() const + std::size_t Texture::GetMemoryUsage() const { #if NAZARA_RENDERER_SAFE if (!m_impl) @@ -399,7 +399,7 @@ namespace Nz return size * PixelFormat::GetBytesPerPixel(m_impl->format); } - unsigned int Texture::GetMemoryUsage(UInt8 level) const + std::size_t Texture::GetMemoryUsage(UInt8 level) const { #if NAZARA_UTILITY_SAFE if (!m_impl) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index a29d28671..b5914aa58 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -127,7 +127,7 @@ namespace Nz return m_atlas; } - unsigned int Font::GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const + std::size_t Font::GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const { UInt64 key = ComputeKey(characterSize, style); auto it = m_glyphes.find(key); @@ -137,9 +137,9 @@ namespace Nz return it->second.size(); } - unsigned int Font::GetCachedGlyphCount() const + std::size_t Font::GetCachedGlyphCount() const { - unsigned int count = 0; + std::size_t count = 0; for (auto& pair : m_glyphes) count += pair.second.size(); diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index d079dc426..e61f6dda2 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -37,10 +37,10 @@ namespace Nz } const MD5AnimParser::Frame* frames = parser.GetFrames(); - unsigned int frameCount = parser.GetFrameCount(); - unsigned int frameRate = parser.GetFrameRate(); + std::size_t frameCount = parser.GetFrameCount(); + std::size_t frameRate = parser.GetFrameRate(); const MD5AnimParser::Joint* joints = parser.GetJoints(); - unsigned int jointCount = parser.GetJointCount(); + std::size_t jointCount = parser.GetJointCount(); // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation animation->CreateSkeletal(frameCount, jointCount); @@ -59,10 +59,10 @@ namespace Nz Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) * Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); - for (unsigned int i = 0; i < jointCount; ++i) + for (std::size_t i = 0; i < jointCount; ++i) { int parent = joints[i].parent; - for (unsigned int j = 0; j < frameCount; ++j) + for (std::size_t j = 0; j < frameCount; ++j) { SequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i]; diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index 9cd930c2e..105944858 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -48,7 +48,7 @@ namespace Nz return Ternary_False; } - unsigned int MD5AnimParser::GetAnimatedComponentCount() const + std::size_t MD5AnimParser::GetAnimatedComponentCount() const { return m_animatedComponents.size(); } @@ -58,12 +58,12 @@ namespace Nz return m_frames.data(); } - unsigned int MD5AnimParser::GetFrameCount() const + std::size_t MD5AnimParser::GetFrameCount() const { return m_frames.size(); } - unsigned int MD5AnimParser::GetFrameRate() const + std::size_t MD5AnimParser::GetFrameRate() const { return m_frameRate; } @@ -73,7 +73,7 @@ namespace Nz return m_joints.data(); } - unsigned int MD5AnimParser::GetJointCount() const + std::size_t MD5AnimParser::GetJointCount() const { return m_joints.size(); } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index ce56b136a..cd8a6813a 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -53,15 +53,15 @@ namespace Nz const MD5MeshParser::Joint* joints = parser.GetJoints(); const MD5MeshParser::Mesh* meshes = parser.GetMeshes(); - unsigned int jointCount = parser.GetJointCount(); - unsigned int meshCount = parser.GetMeshCount(); + std::size_t jointCount = parser.GetJointCount(); + std::size_t meshCount = parser.GetMeshCount(); if (parameters.animated) { mesh->CreateSkeletal(jointCount); Skeleton* skeleton = mesh->GetSkeleton(); - for (unsigned int i = 0; i < jointCount; ++i) + for (std::size_t i = 0; i < jointCount; ++i) { Joint* joint = skeleton->GetJoint(i); @@ -82,12 +82,12 @@ namespace Nz } mesh->SetMaterialCount(meshCount); - for (unsigned int i = 0; i < meshCount; ++i) + for (std::size_t i = 0; i < meshCount; ++i) { const MD5MeshParser::Mesh& md5Mesh = meshes[i]; - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); + std::size_t indexCount = md5Mesh.triangles.size()*3; + std::size_t vertexCount = md5Mesh.vertices.size(); bool largeIndices = (vertexCount > std::numeric_limits::max()); @@ -227,11 +227,11 @@ namespace Nz } mesh->SetMaterialCount(meshCount); - for (unsigned int i = 0; i < meshCount; ++i) + for (std::size_t i = 0; i < meshCount; ++i) { const MD5MeshParser::Mesh& md5Mesh = meshes[i]; - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); + std::size_t indexCount = md5Mesh.triangles.size()*3; + std::size_t vertexCount = md5Mesh.vertices.size(); // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index 56e384bf0..b4fd04a33 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -58,7 +58,7 @@ namespace Nz return m_joints.data(); } - unsigned int MD5MeshParser::GetJointCount() const + std::size_t MD5MeshParser::GetJointCount() const { return m_joints.size(); } @@ -68,7 +68,7 @@ namespace Nz return m_meshes.data(); } - unsigned int MD5MeshParser::GetMeshCount() const + std::size_t MD5MeshParser::GetMeshCount() const { return m_meshes.size(); } diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index 35beab566..b3e630921 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -70,7 +70,7 @@ namespace Nz return layer.image.get(); } - unsigned int GuillotineImageAtlas::GetLayerCount() const + std::size_t GuillotineImageAtlas::GetLayerCount() const { return m_layers.size(); } diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index c8f3e49f1..9e0213cf6 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -666,7 +666,7 @@ namespace Nz return GetMaxLevel(m_sharedImage->type, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); } - unsigned int Image::GetMemoryUsage() const + std::size_t Image::GetMemoryUsage() const { unsigned int width = m_sharedImage->width; unsigned int height = m_sharedImage->height; @@ -693,7 +693,7 @@ namespace Nz return size * PixelFormat::GetBytesPerPixel(m_sharedImage->format); } - unsigned int Image::GetMemoryUsage(UInt8 level) const + std::size_t Image::GetMemoryUsage(UInt8 level) const { return PixelFormat::ComputeSize(m_sharedImage->format, GetLevelSize(m_sharedImage->width, level), GetLevelSize(m_sharedImage->height, level), ((m_sharedImage->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level))); } diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index ae2dc8762..03a95f35a 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -72,19 +72,19 @@ namespace Nz return m_font; } - Font* SimpleTextDrawer::GetFont(unsigned int index) const + Font* SimpleTextDrawer::GetFont(std::size_t index) const { NazaraAssert(index == 0, "Font index out of range"); return m_font; } - unsigned int SimpleTextDrawer::GetFontCount() const + std::size_t SimpleTextDrawer::GetFontCount() const { return 1; } - const AbstractTextDrawer::Glyph& SimpleTextDrawer::GetGlyph(unsigned int index) const + const AbstractTextDrawer::Glyph& SimpleTextDrawer::GetGlyph(std::size_t index) const { if (!m_glyphUpdated) UpdateGlyphs(); @@ -94,7 +94,7 @@ namespace Nz return m_glyphs[index]; } - unsigned int SimpleTextDrawer::GetGlyphCount() const + std::size_t SimpleTextDrawer::GetGlyphCount() const { if (!m_glyphUpdated) UpdateGlyphs(); diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 2bf9c9d02..b494a7789 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -394,7 +394,7 @@ namespace Nz void WindowImpl::SetMaximumSize(int width, int height) { RECT rect = {0, 0, width, height}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); + AdjustWindowRect(&rect, static_cast(GetWindowLongPtr(m_handle, GWL_STYLE)), false); if (width != -1) m_maxSize.x = rect.right-rect.left; @@ -410,7 +410,7 @@ namespace Nz void WindowImpl::SetMinimumSize(int width, int height) { RECT rect = {0, 0, width, height}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); + AdjustWindowRect(&rect, static_cast(GetWindowLongPtr(m_handle, GWL_STYLE)), false); if (width != -1) m_minSize.x = rect.right-rect.left; @@ -432,7 +432,7 @@ namespace Nz { // SetWindowPos demande la taille totale de la fenêtre RECT rect = {0, 0, static_cast(width), static_cast(height)}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); + AdjustWindowRect(&rect, static_cast(GetWindowLongPtr(m_handle, GWL_STYLE)), false); SetWindowPos(m_handle, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER); } From a277e7560fe2cc2fdd2e1a057d9daa0f6b0c8914 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 13 Jun 2016 21:19:12 +0200 Subject: [PATCH 137/224] Build: Fix example path Former-commit-id: 54e56da81ea8c93da5ec276035dca59a62932ed0 [formerly ab7201812c22e7a4dcabbfbf74686a169a67a1b0] Former-commit-id: 48aaf02c04cea375eeb33b64afc09428631ee523 --- build/scripts/common.lua | 12 ++++++------ build/scripts/tools/assimp.lua | 3 ++- build/scripts/tools/ndk.lua | 3 ++- build/scripts/tools/ndk_server.lua | 3 ++- build/scripts/tools/unittests.lua | 1 + 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 12aa13d70..2b4906569 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -270,7 +270,7 @@ function NazaraBuild:Execute() project(prefix .. toolTable.Name) location(_ACTION .. "/tools") - targetdir(toolTable.Directory) + targetdir(toolTable.TargetDirectory) if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then kind("SharedLib") @@ -278,7 +278,7 @@ function NazaraBuild:Execute() -- Copy the tool binaries to the example folder self:MakeInstallCommands(toolTable) elseif (toolTable.Kind == "application") then - debugdir(toolTable.Directory) + debugdir(toolTable.TargetDirectory) if (toolTable.EnableConsole) then kind("ConsoleApp") else @@ -404,7 +404,7 @@ function NazaraBuild:Execute() self:MakeInstallCommands(toolTable) elseif (exampleTable.Kind == "application") then - debugdir(exampleTable.Directory) + debugdir(exampleTable.TargetDirectory) if (exampleTable.EnableConsole) then kind("ConsoleApp") else @@ -769,7 +769,7 @@ function NazaraBuild:RegisterTool(toolTable) return false, "This tool name is already in use" end - if (toolTable.Directory == nil or type(toolTable.Directory) ~= "string" or string.len(toolTable.Directory) == 0) then + if (toolTable.TargetDirectory == nil or type(toolTable.TargetDirectory) ~= "string" or string.len(toolTable.TargetDirectory) == 0) then return false, "Invalid tool directory" end @@ -907,7 +907,7 @@ function NazaraBuild:Process(infoTable) end if (infoTable.Kind == "application") then - self:AddExecutablePath(infoTable.Directory) + self:AddExecutablePath(infoTable.TargetDirectory) end return true @@ -995,8 +995,8 @@ end function NazaraBuild:SetupExampleTable(infoTable) self:SetupInfoTable(infoTable) - infoTable.Directory = "../examples/bin" infoTable.Kind = "application" + infoTable.TargetDirectory = "../examples/bin" end function NazaraBuild:SetupExtlibTable(infoTable) diff --git a/build/scripts/tools/assimp.lua b/build/scripts/tools/assimp.lua index 0eecbcd54..08688ef72 100644 --- a/build/scripts/tools/assimp.lua +++ b/build/scripts/tools/assimp.lua @@ -1,7 +1,8 @@ TOOL.Name = "Assimp" -TOOL.Directory = "../SDK/lib" +TOOL.Directory = "../plugins/Assimp" TOOL.Kind = "Plugin" +TOOL.TargetDirectory = "../SDK/lib" TOOL.Includes = { "../include", diff --git a/build/scripts/tools/ndk.lua b/build/scripts/tools/ndk.lua index d2038342b..8a40ea170 100644 --- a/build/scripts/tools/ndk.lua +++ b/build/scripts/tools/ndk.lua @@ -1,7 +1,8 @@ TOOL.Name = "SDK" -TOOL.Directory = "../SDK/lib" +TOOL.Directory = "../SDK" TOOL.Kind = "Library" +TOOL.TargetDirectory = "../SDK/lib" TOOL.Defines = { "NDK_BUILD" diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index 91a0fd170..2881c56fc 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -1,7 +1,8 @@ TOOL.Name = "SDKServer" -TOOL.Directory = "../SDK/lib" +TOOL.Directory = "../SDK" TOOL.Kind = "Library" +TOOL.TargetDirectory = "../SDK/lib" TOOL.Defines = { "NDK_BUILD", diff --git a/build/scripts/tools/unittests.lua b/build/scripts/tools/unittests.lua index 349932cb6..fc0f4bad6 100644 --- a/build/scripts/tools/unittests.lua +++ b/build/scripts/tools/unittests.lua @@ -3,6 +3,7 @@ TOOL.Name = "UnitTests" TOOL.Directory = "../tests" TOOL.EnableConsole = true TOOL.Kind = "Application" +TOOL.TargetDirectory = TOOL.Directory TOOL.Defines = { } From 01428dcde398f609cba8256382a846c4c8098b9c Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 17 Jun 2016 22:30:29 +0200 Subject: [PATCH 138/224] Fix some more warnings Former-commit-id: 3ce21e64373163c1ae9f7803760c897e5334b726 [formerly f1e054d5acd1e19bba6e61fca71d3bb1148bb4bb] Former-commit-id: 9a2bded15c3c34c3c8a96aa45ec53ff1c500e740 --- SDK/src/NDK/Entity.cpp | 10 +++++----- SDK/src/NDK/World.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 17730a234..f037e5f9a 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -51,7 +51,7 @@ namespace Ndk BaseComponent& component = *m_components[index].get(); component.SetEntity(this); - for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) { if (i != index) m_components[i]->OnComponentAttached(component); @@ -73,8 +73,8 @@ namespace Ndk void Entity::RemoveAllComponents() { - for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) - RemoveComponent(i); + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + RemoveComponent(static_cast(i)); NazaraAssert(m_componentBits.TestNone(), "All components should be gone"); @@ -90,7 +90,7 @@ namespace Ndk { // On récupère le component et on informe les composants du détachement BaseComponent& component = *m_components[index].get(); - for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) { if (i != index) m_components[i]->OnComponentDetached(component); @@ -114,7 +114,7 @@ namespace Ndk void Entity::Destroy() { // On informe chaque système - for (SystemIndex index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) + for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) { if (m_world->HasSystem(index)) { diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index fc53143dd..e95785896 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -94,7 +94,7 @@ namespace Ndk void World::Update() { // Gestion des entités tuées depuis le dernier appel - for (unsigned int i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i)) + for (std::size_t i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i)) { EntityBlock& block = m_entities[i]; Entity& entity = block.entity; @@ -127,7 +127,7 @@ namespace Ndk m_killedEntities.Reset(); // Gestion des entités nécessitant une mise à jour de leurs systèmes - for (unsigned int i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i)) + for (std::size_t i = m_dirtyEntities.FindFirst(); i != m_dirtyEntities.npos; i = m_dirtyEntities.FindNext(i)) { NazaraAssert(i < m_entities.size(), "Entity index out of range"); From a66db53057be8138b6094f1139a8a51b6cbfa32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 18 Jun 2016 07:04:15 +0200 Subject: [PATCH 139/224] Examples: Fix compilation of FirstScene Former-commit-id: ee50f2617a3e35ea5355f4b5b9615cfcb512a539 [formerly 14d411c4eb64a9dd2cac24da6365fbfbab34e021] Former-commit-id: 393cb9925049b92f084d4a7eb5a20fc86956f185 --- examples/FirstScene/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 24fef574f..385b054e0 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -29,7 +29,7 @@ Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& ta int main() { - // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, + // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, // les composants, systèmes, etc. // NzInitializer est une classe RAII appelant Initialize dans son constructeur et Uninitialize dans son destructeur. // Autrement dit, une fois ceci fait nous n'avons plus à nous soucier de la libération du moteur. @@ -101,7 +101,7 @@ int main() // Le format OBJ ne précise aucune échelle pour ses données, contrairement à Nazara (une unité = un mètre en 3D). // Comme le vaisseau est très grand (Des centaines de mètres de long), nous allons le rendre plus petit pour les besoins de la démo. // Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle. - params.mesh.scale.Set(0.01f); // Un centième de la taille originelle + params.mesh.matrix.MakeScale(Nz::Vector3f(0.01f)); // Un centième de la taille originelle // Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend (haut-gauche) // Nous devons donc indiquer au moteur de les retourner lors du chargement @@ -156,7 +156,7 @@ int main() // Nous devons donc lui rajouter les composants que nous voulons. // Un NodeComponent donne à notre entité une position, rotation, échelle, et nous permet de l'attacher à d'autres entités (ce que nous ne ferons pas ici). - // Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient, + // Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient, // nous n'avons pas besoin d'agir sur le composant créé. spaceship->AddComponent(); From 33f2241d95f6558381383473a24856ddb28172f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 18 Jun 2016 07:52:33 +0200 Subject: [PATCH 140/224] Noise: Refresh module using ZNoise https://github.com/Overdrivr/ZNoise Former-commit-id: ea7bbeb58a7147934523e2f600b1bd02f1cae5ed [formerly 581ab53941abbda68e00417592240f52ebd482e6] Former-commit-id: e948aca78eb101292f0458365cfa39e6564d0462 --- include/Nazara/Noise/Abstract2DNoise.hpp | 26 - include/Nazara/Noise/Abstract3DNoise.hpp | 26 - include/Nazara/Noise/Abstract4DNoise.hpp | 26 - include/Nazara/Noise/ComplexNoiseBase.hpp | 41 -- include/Nazara/Noise/Config.hpp | 2 +- include/Nazara/Noise/ConfigCheck.hpp | 2 +- include/Nazara/Noise/Debug.hpp | 2 +- include/Nazara/Noise/DebugOff.hpp | 2 +- include/Nazara/Noise/Enums.hpp | 18 + include/Nazara/Noise/FBM.hpp | 30 ++ include/Nazara/Noise/FBM2D.hpp | 31 -- include/Nazara/Noise/FBM3D.hpp | 32 -- include/Nazara/Noise/FBM4D.hpp | 32 -- include/Nazara/Noise/HybridMultiFractal.hpp | 34 ++ include/Nazara/Noise/HybridMultiFractal2D.hpp | 36 -- include/Nazara/Noise/HybridMultiFractal3D.hpp | 36 -- include/Nazara/Noise/HybridMultiFractal4D.hpp | 36 -- include/Nazara/Noise/MappedNoiseBase.hpp | 35 -- include/Nazara/Noise/MixerBase.hpp | 38 ++ include/Nazara/Noise/Noise.hpp | 2 +- include/Nazara/Noise/NoiseBase.hpp | 36 +- include/Nazara/Noise/NoiseTools.hpp | 14 + include/Nazara/Noise/Perlin.hpp | 36 ++ include/Nazara/Noise/Perlin2D.hpp | 39 -- include/Nazara/Noise/Perlin3D.hpp | 40 -- include/Nazara/Noise/Perlin4D.hpp | 39 -- include/Nazara/Noise/Simplex.hpp | 43 ++ include/Nazara/Noise/Simplex2D.hpp | 42 -- include/Nazara/Noise/Simplex3D.hpp | 42 -- include/Nazara/Noise/Simplex4D.hpp | 44 -- include/Nazara/Noise/Worley.hpp | 41 ++ src/Nazara/Noise/Abstract2DNoise.cpp | 24 - src/Nazara/Noise/Abstract3DNoise.cpp | 24 - src/Nazara/Noise/Abstract4DNoise.cpp | 24 - src/Nazara/Noise/ComplexNoiseBase.cpp | 83 ---- src/Nazara/Noise/FBM.cpp | 31 ++ src/Nazara/Noise/FBM2D.cpp | 54 --- src/Nazara/Noise/FBM3D.cpp | 54 --- src/Nazara/Noise/FBM4D.cpp | 54 --- src/Nazara/Noise/HybridMultiFractal.cpp | 42 ++ src/Nazara/Noise/HybridMultiFractal3D.cpp | 67 --- src/Nazara/Noise/HybridMultiFractal4D.cpp | 67 --- src/Nazara/Noise/HybridMultifractal2D.cpp | 67 --- src/Nazara/Noise/MappedNoiseBase.cpp | 56 --- src/Nazara/Noise/MixerBase.cpp | 56 +++ src/Nazara/Noise/NoiseBase.cpp | 68 +-- src/Nazara/Noise/NoiseTools.cpp | 28 ++ src/Nazara/Noise/Perlin.cpp | 325 +++++++++++++ src/Nazara/Noise/Perlin2D.cpp | 75 --- src/Nazara/Noise/Perlin3D.cpp | 98 ---- src/Nazara/Noise/Perlin4D.cpp | 156 ------ src/Nazara/Noise/Simplex.cpp | 459 ++++++++++++++++++ src/Nazara/Noise/Simplex2D.cpp | 94 ---- src/Nazara/Noise/Simplex3D.cpp | 176 ------- src/Nazara/Noise/Simplex4D.cpp | 169 ------- src/Nazara/Noise/Worley.cpp | 171 +++++++ 56 files changed, 1408 insertions(+), 2017 deletions(-) delete mode 100644 include/Nazara/Noise/Abstract2DNoise.hpp delete mode 100644 include/Nazara/Noise/Abstract3DNoise.hpp delete mode 100644 include/Nazara/Noise/Abstract4DNoise.hpp delete mode 100644 include/Nazara/Noise/ComplexNoiseBase.hpp create mode 100644 include/Nazara/Noise/Enums.hpp create mode 100644 include/Nazara/Noise/FBM.hpp delete mode 100644 include/Nazara/Noise/FBM2D.hpp delete mode 100644 include/Nazara/Noise/FBM3D.hpp delete mode 100644 include/Nazara/Noise/FBM4D.hpp create mode 100644 include/Nazara/Noise/HybridMultiFractal.hpp delete mode 100644 include/Nazara/Noise/HybridMultiFractal2D.hpp delete mode 100644 include/Nazara/Noise/HybridMultiFractal3D.hpp delete mode 100644 include/Nazara/Noise/HybridMultiFractal4D.hpp delete mode 100644 include/Nazara/Noise/MappedNoiseBase.hpp create mode 100644 include/Nazara/Noise/MixerBase.hpp create mode 100644 include/Nazara/Noise/NoiseTools.hpp create mode 100644 include/Nazara/Noise/Perlin.hpp delete mode 100644 include/Nazara/Noise/Perlin2D.hpp delete mode 100644 include/Nazara/Noise/Perlin3D.hpp delete mode 100644 include/Nazara/Noise/Perlin4D.hpp create mode 100644 include/Nazara/Noise/Simplex.hpp delete mode 100644 include/Nazara/Noise/Simplex2D.hpp delete mode 100644 include/Nazara/Noise/Simplex3D.hpp delete mode 100644 include/Nazara/Noise/Simplex4D.hpp create mode 100644 include/Nazara/Noise/Worley.hpp delete mode 100644 src/Nazara/Noise/Abstract2DNoise.cpp delete mode 100644 src/Nazara/Noise/Abstract3DNoise.cpp delete mode 100644 src/Nazara/Noise/Abstract4DNoise.cpp delete mode 100644 src/Nazara/Noise/ComplexNoiseBase.cpp create mode 100644 src/Nazara/Noise/FBM.cpp delete mode 100644 src/Nazara/Noise/FBM2D.cpp delete mode 100644 src/Nazara/Noise/FBM3D.cpp delete mode 100644 src/Nazara/Noise/FBM4D.cpp create mode 100644 src/Nazara/Noise/HybridMultiFractal.cpp delete mode 100644 src/Nazara/Noise/HybridMultiFractal3D.cpp delete mode 100644 src/Nazara/Noise/HybridMultiFractal4D.cpp delete mode 100644 src/Nazara/Noise/HybridMultifractal2D.cpp delete mode 100644 src/Nazara/Noise/MappedNoiseBase.cpp create mode 100644 src/Nazara/Noise/MixerBase.cpp create mode 100644 src/Nazara/Noise/NoiseTools.cpp create mode 100644 src/Nazara/Noise/Perlin.cpp delete mode 100644 src/Nazara/Noise/Perlin2D.cpp delete mode 100644 src/Nazara/Noise/Perlin3D.cpp delete mode 100644 src/Nazara/Noise/Perlin4D.cpp create mode 100644 src/Nazara/Noise/Simplex.cpp delete mode 100644 src/Nazara/Noise/Simplex2D.cpp delete mode 100644 src/Nazara/Noise/Simplex3D.cpp delete mode 100644 src/Nazara/Noise/Simplex4D.cpp create mode 100644 src/Nazara/Noise/Worley.cpp diff --git a/include/Nazara/Noise/Abstract2DNoise.hpp b/include/Nazara/Noise/Abstract2DNoise.hpp deleted file mode 100644 index 0eb5c23e5..000000000 --- a/include/Nazara/Noise/Abstract2DNoise.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_ABSTRACT2DNOISE_HPP -#define NAZARA_ABSTRACT2DNOISE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Abstract2DNoise : public MappedNoiseBase - { - public: - virtual ~Abstract2DNoise(); - - float GetBasicValue(float x, float y); - float GetMappedValue(float x, float y); - virtual float GetValue(float x, float y, float resolution) = 0; - }; -} - -#endif // NAZARA_ABSTRACT2DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract3DNoise.hpp b/include/Nazara/Noise/Abstract3DNoise.hpp deleted file mode 100644 index 19a0c765c..000000000 --- a/include/Nazara/Noise/Abstract3DNoise.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_ABSTRACT3DNOISE_HPP -#define NAZARA_ABSTRACT3DNOISE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Abstract3DNoise : public MappedNoiseBase - { - public: - virtual ~Abstract3DNoise(); - - float GetBasicValue(float x, float y, float z); - float GetMappedValue(float x, float y, float z); - virtual float GetValue(float x, float y, float z, float resolution) = 0; - }; -} - -#endif // NAZARA_ABSTRACT3DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract4DNoise.hpp b/include/Nazara/Noise/Abstract4DNoise.hpp deleted file mode 100644 index 631228020..000000000 --- a/include/Nazara/Noise/Abstract4DNoise.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_ABSTRACT4DNOISE_HPP -#define NAZARA_ABSTRACT4DNOISE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Abstract4DNoise : public MappedNoiseBase - { - public: - virtual ~Abstract4DNoise(); - - float GetBasicValue(float x, float y, float z, float w); - float GetMappedValue(float x, float y, float z, float w); - virtual float GetValue(float x, float y, float z, float w, float resolution) = 0; - }; -} - -#endif // NAZARA_ABSTRACT4DNOISE_HPP diff --git a/include/Nazara/Noise/ComplexNoiseBase.hpp b/include/Nazara/Noise/ComplexNoiseBase.hpp deleted file mode 100644 index 6be8667a5..000000000 --- a/include/Nazara/Noise/ComplexNoiseBase.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef COMPLEXNOISEBASE_HPP -#define COMPLEXNOISEBASE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API ComplexNoiseBase - { - public: - ComplexNoiseBase(); - ~ComplexNoiseBase() = default; - - float GetHurstParameter() const; - float GetLacunarity() const; - float GetOctaveNumber() const; - void SetHurstParameter(float h); - void SetLacunarity(float lacunarity); - void SetOctavesNumber(float octaves); - void RecomputeExponentArray(); - - protected: - float m_lacunarity; - float m_hurst; - float m_octaves; - std::array m_exponent_array; - float m_sum; - - private: - bool m_parametersModified; - }; -} - -#endif // COMPLEXNOISEBASE_HPP diff --git a/include/Nazara/Noise/Config.hpp b/include/Nazara/Noise/Config.hpp index 5df2d6dc4..afe6d577e 100644 --- a/include/Nazara/Noise/Config.hpp +++ b/include/Nazara/Noise/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Noise module - Copyright (C) 2015 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) + Copyright (C) 2016 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Noise/ConfigCheck.hpp b/include/Nazara/Noise/ConfigCheck.hpp index f7682bd28..9c6df7851 100644 --- a/include/Nazara/Noise/ConfigCheck.hpp +++ b/include/Nazara/Noise/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Jérôme Leclercq +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Debug.hpp b/include/Nazara/Noise/Debug.hpp index 377ae7b1c..4696c79b9 100644 --- a/include/Nazara/Noise/Debug.hpp +++ b/include/Nazara/Noise/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/DebugOff.hpp b/include/Nazara/Noise/DebugOff.hpp index 75903b6cc..4b368b6ea 100644 --- a/include/Nazara/Noise/DebugOff.hpp +++ b/include/Nazara/Noise/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Enums.hpp b/include/Nazara/Noise/Enums.hpp new file mode 100644 index 000000000..7962d8415 --- /dev/null +++ b/include/Nazara/Noise/Enums.hpp @@ -0,0 +1,18 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_ENUMS_NOISE_HPP +#define NAZARA_ENUMS_NOISE_HPP + +namespace Nz +{ + enum WorleyFunction + { + WorleyFunction_F1 = 0, + WorleyFunction_F2 = 1, + WorleyFunction_F3 = 2, + WorleyFunction_F4 = 3 + }; +} +#endif // NAZARA_ENUMS_NOISE_HPP diff --git a/include/Nazara/Noise/FBM.hpp b/include/Nazara/Noise/FBM.hpp new file mode 100644 index 000000000..ded4aa069 --- /dev/null +++ b/include/Nazara/Noise/FBM.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_FBM_HPP +#define NAZARA_FBM_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API FBM : public MixerBase + { + public: + FBM(const NoiseBase& source); + FBM(const FBM&) = delete; + ~FBM() = default; + + float Get(std::initializer_list coordinates, float scale) const; + + FBM& operator=(const FBM&) = delete; + + private: + const NoiseBase& m_source; + }; +} + +#endif // NAZARA_FBM_HPP diff --git a/include/Nazara/Noise/FBM2D.hpp b/include/Nazara/Noise/FBM2D.hpp deleted file mode 100644 index 9b456de0a..000000000 --- a/include/Nazara/Noise/FBM2D.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef FBM2D_HPP -#define FBM2D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API FBM2D : public Abstract2DNoise, public ComplexNoiseBase - { - public: - FBM2D(NoiseType source, unsigned int seed); - float GetValue(float x, float y, float resolution); - ~FBM2D(); - - private: - Abstract2DNoise* m_source; - float m_value; - float m_remainder; - NoiseType m_noiseType; - }; -} - -#endif // FBM2D_HPP diff --git a/include/Nazara/Noise/FBM3D.hpp b/include/Nazara/Noise/FBM3D.hpp deleted file mode 100644 index 722ad843d..000000000 --- a/include/Nazara/Noise/FBM3D.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef FBM3D_HPP -#define FBM3D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API FBM3D : public Abstract3DNoise, public ComplexNoiseBase - { - public: - FBM3D(NoiseType source, unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~FBM3D(); - - private: - Abstract3DNoise* m_source; - float m_value; - float m_remainder; - NoiseType m_noiseType; - }; -} - -#endif // FBM3D_HPP - diff --git a/include/Nazara/Noise/FBM4D.hpp b/include/Nazara/Noise/FBM4D.hpp deleted file mode 100644 index e18c93111..000000000 --- a/include/Nazara/Noise/FBM4D.hpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef FBM4D_HPP -#define FBM4D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API FBM4D : public Abstract4DNoise, public ComplexNoiseBase - { - public: - FBM4D(NoiseType source, unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~FBM4D(); - - private: - Abstract4DNoise* m_source; - float m_value; - float m_remainder; - NoiseType m_noiseType; - }; -} - -#endif // FBM4D_HPP - diff --git a/include/Nazara/Noise/HybridMultiFractal.hpp b/include/Nazara/Noise/HybridMultiFractal.hpp new file mode 100644 index 000000000..a211a4767 --- /dev/null +++ b/include/Nazara/Noise/HybridMultiFractal.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_HYBRIDMULTIFRACTAL_HPP +#define NAZARA_HYBRIDMULTIFRACTAL_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API HybridMultiFractal : public MixerBase + { + public: + HybridMultiFractal(const NoiseBase & source); + HybridMultiFractal(const HybridMultiFractal&) = delete; + ~HybridMultiFractal() = default; + + float Get(std::initializer_list coordinates, float scale) const; + + HybridMultiFractal& operator=(const HybridMultiFractal&) = delete; + + private: + const NoiseBase& m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + }; +} + +#endif // NAZARA_HYBRIDMULTIFRACTAL_HPP diff --git a/include/Nazara/Noise/HybridMultiFractal2D.hpp b/include/Nazara/Noise/HybridMultiFractal2D.hpp deleted file mode 100644 index 4b0ad9bc6..000000000 --- a/include/Nazara/Noise/HybridMultiFractal2D.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef HYBRIDMULTIFRACTAL2D_HPP -#define HYBRIDMULTIFRACTAL2D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API HybridMultiFractal2D : public Abstract2DNoise, public ComplexNoiseBase - { - public: - HybridMultiFractal2D(NoiseType source, unsigned int seed); - ~HybridMultiFractal2D(); - - float GetValue(float x, float y, float resolution); - - private: - Abstract2DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - NoiseType m_noiseType; - }; -} - -#endif // HYBRIDMULTIFRACTAL2D_HPP - diff --git a/include/Nazara/Noise/HybridMultiFractal3D.hpp b/include/Nazara/Noise/HybridMultiFractal3D.hpp deleted file mode 100644 index 34d554292..000000000 --- a/include/Nazara/Noise/HybridMultiFractal3D.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef HYBRIDMULTIFRACTAL3D_HPP -#define HYBRIDMULTIFRACTAL3D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API HybridMultiFractal3D : public Abstract3DNoise, public ComplexNoiseBase - { - public: - HybridMultiFractal3D(NoiseType source, unsigned int seed); - ~HybridMultiFractal3D(); - - float GetValue(float x, float y, float z, float resolution); - - private: - Abstract3DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - NoiseType m_noiseType; - }; -} - -#endif // HYBRIDMULTIFRACTAL3D_HPP - diff --git a/include/Nazara/Noise/HybridMultiFractal4D.hpp b/include/Nazara/Noise/HybridMultiFractal4D.hpp deleted file mode 100644 index 859ed8087..000000000 --- a/include/Nazara/Noise/HybridMultiFractal4D.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef HYBRIDMULTIFRACTAL4D_HPP -#define HYBRIDMULTIFRACTAL4D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API HybridMultiFractal4D : public Abstract4DNoise, public ComplexNoiseBase - { - public: - HybridMultiFractal4D(NoiseType source, unsigned int seed); - ~HybridMultiFractal4D(); - - float GetValue(float x, float y, float z, float w, float resolution); - - private: - Abstract4DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - NoiseType m_noiseType; - }; -} - -#endif // HYBRIDMULTIFRACTAL4D_HPP - diff --git a/include/Nazara/Noise/MappedNoiseBase.hpp b/include/Nazara/Noise/MappedNoiseBase.hpp deleted file mode 100644 index 7e5106a31..000000000 --- a/include/Nazara/Noise/MappedNoiseBase.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_MAPPEDNOISEBASE_HPP -#define NAZARA_MAPPEDNOISEBASE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API MappedNoiseBase : public NoiseBase - { - public: - MappedNoiseBase(); - ~MappedNoiseBase() = default; - - float GetGain() const; - float GetOffset() const; - float GetResolution() const; - void SetGain(float gain); - void SetOffset(float offset); - void SetResolution(float resolution); - - protected: - float m_gain; - float m_offset; - float m_resolution; - }; -} - -#endif // NAZARA_MAPPEDNOISEBASE_HPP diff --git a/include/Nazara/Noise/MixerBase.hpp b/include/Nazara/Noise/MixerBase.hpp new file mode 100644 index 000000000..3c7a131b0 --- /dev/null +++ b/include/Nazara/Noise/MixerBase.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_MIXERBASE_HPP +#define NAZARA_MIXERBASE_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API MixerBase + { + public: + MixerBase(); + ~MixerBase() = default; + + float GetHurstParameter() const; + float GetLacunarity() const; + float GetOctaveNumber() const; + + void SetParameters(float hurst, float lacunarity, float octaves); + + protected: + float m_hurst; + float m_lacunarity; + float m_octaves; + std::vector m_exponent_array; + float m_sum; + + private: + void Recompute(); + }; +} + +#endif // NAZARA_MIXERBASE_HPP diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index a1e5b7d11..c1ec5b1da 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index bd268ee8c..6a5c5c37f 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -1,48 +1,38 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp -#pragma once - -#ifndef NOISEBASE_HPP -#define NOISEBASE_HPP +#ifndef NAZARA_NOISEBASE_HPP +#define NAZARA_NOISEBASE_HPP #include #include +#include namespace Nz { - enum NoiseType - { - PERLIN, - SIMPLEX, - CELL - }; - class NAZARA_NOISE_API NoiseBase { public: NoiseBase(unsigned int seed = 0); ~NoiseBase() = default; - void SetNewSeed(unsigned int seed); + virtual float Get(std::initializer_list coordinates, float scale) const = 0; + float GetScale(); - void ShufflePermutationTable(); + void SetScale(float scale); + void SetSeed(unsigned int seed); - unsigned int GetUniformRandomValue(); - - int fastfloor(float n); - int JenkinsHash(int a, int b, int c); + void Shuffle(); + void Shuffle(unsigned int amount); protected: unsigned int perm[512]; + float m_scale; private: - unsigned int Ua, Uc, Um; - unsigned int UcurrentSeed; - unsigned int Uprevious, Ulast; - + std::default_random_engine generator; }; } -#endif // NOISEBASE_HPP +#endif // NAZARA_NOISEBASE_HPP diff --git a/include/Nazara/Noise/NoiseTools.hpp b/include/Nazara/Noise/NoiseTools.hpp new file mode 100644 index 000000000..6238caec3 --- /dev/null +++ b/include/Nazara/Noise/NoiseTools.hpp @@ -0,0 +1,14 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_NOISETOOLS_HPP +#define NAZARA_NOISETOOLS_HPP + +namespace Nz +{ + int fastfloor(float n); + int JenkinsHash(int a, int b, int c); +} + +#endif // NAZARA_NOISETOOLS_HPP diff --git a/include/Nazara/Noise/Perlin.hpp b/include/Nazara/Noise/Perlin.hpp new file mode 100644 index 000000000..058a3ada5 --- /dev/null +++ b/include/Nazara/Noise/Perlin.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_PERLIN_HPP +#define NAZARA_PERLIN_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API Perlin : public NoiseBase + { + public: + Perlin(); + Perlin(unsigned int seed); + ~Perlin() = default; + + float Get(std::initializer_list coordinates, float scale) const; + + protected: + float _2D(std::initializer_list coordinates, float scale) const; + float _3D(std::initializer_list coordinates, float scale) const; + float _4D(std::initializer_list coordinates, float scale) const; + + private: + const float gradient2[8][2]; + const float gradient3[16][3]; + const float gradient4[32][4]; + }; +} + +#endif // NAZARA_PERLIN_HPP diff --git a/include/Nazara/Noise/Perlin2D.hpp b/include/Nazara/Noise/Perlin2D.hpp deleted file mode 100644 index 88a98155b..000000000 --- a/include/Nazara/Noise/Perlin2D.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef PERLIN2D_HPP -#define PERLIN2D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Perlin2D : public Abstract2DNoise - { - public: - Perlin2D(); - Perlin2D(unsigned int seed); - ~Perlin2D() = default; - - float GetValue(float x, float y, float resolution); - - private: - int x0, y0; - int gi0,gi1,gi2,gi3; - int ii, jj; - float gradient2[8][2]; - float s,t,u,v; - float Cx,Cy; - float Li1, Li2; - Vector2 temp; - }; -} - -#endif // PERLIN2D_HPP - diff --git a/include/Nazara/Noise/Perlin3D.hpp b/include/Nazara/Noise/Perlin3D.hpp deleted file mode 100644 index 47be7f29b..000000000 --- a/include/Nazara/Noise/Perlin3D.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef PERLIN3D_HPP -#define PERLIN3D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Perlin3D : public Abstract3DNoise - { - public: - Perlin3D(); - Perlin3D(unsigned int seed); - ~Perlin3D() = default; - - float GetValue(float x, float y, float z, float resolution); - - private: - int x0,y0,z0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; - int ii,jj,kk; - float gradient3[16][3]; - float Li1,Li2,Li3,Li4,Li5,Li6; - float s[2],t[2],u[2],v[2]; - float Cx,Cy,Cz; - float nx,ny,nz; - float tmp; - Vector3 temp; - }; -} - -#endif // PERLIN3D_HPP diff --git a/include/Nazara/Noise/Perlin4D.hpp b/include/Nazara/Noise/Perlin4D.hpp deleted file mode 100644 index 66d7a1b7b..000000000 --- a/include/Nazara/Noise/Perlin4D.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef PERLIN4D_HPP -#define PERLIN4D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Perlin4D : public Abstract4DNoise - { - public: - Perlin4D(); - Perlin4D(unsigned int seed); - ~Perlin4D() = default; - - float GetValue(float x, float y, float z, float w, float resolution); - - private: - int x0,y0,z0,w0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; - int ii,jj,kk,ll; - float gradient4[32][4]; - float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; - float s[4],t[4],u[4],v[4]; - float Cx,Cy,Cz,Cw; - float tmp; - Vector4 temp; - }; -} - -#endif // PERLIN4D_HPP diff --git a/include/Nazara/Noise/Simplex.hpp b/include/Nazara/Noise/Simplex.hpp new file mode 100644 index 000000000..f131387b6 --- /dev/null +++ b/include/Nazara/Noise/Simplex.hpp @@ -0,0 +1,43 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef SIMPLEX_HPP +#define SIMPLE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API Simplex : public NoiseBase + { + public: + Simplex(); + Simplex(unsigned int seed); + ~Simplex() = default; + + float Get(std::initializer_list coordinates, float scale) const; + + protected: + float _2D(std::initializer_list coordinates, float scale) const; + float _3D(std::initializer_list coordinates, float scale) const; + float _4D(std::initializer_list coordinates, float scale) const; + + private: + const float gradient2[8][2]; + const float gradient3[16][3]; + const float gradient4[32][4]; + const float UnskewCoeff2D; + const float SkewCoeff2D; + const float UnskewCoeff3D; + const float SkewCoeff3D; + const float UnskewCoeff4D; + const float SkewCoeff4D; + const int lookupTable4D[64][4]; + }; +} + +#endif // SIMPLEX_HPP diff --git a/include/Nazara/Noise/Simplex2D.hpp b/include/Nazara/Noise/Simplex2D.hpp deleted file mode 100644 index 69a73478d..000000000 --- a/include/Nazara/Noise/Simplex2D.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef SIMPLEX2D_HPP -#define SIMPLEX2D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Simplex2D : public Abstract2DNoise - { - public: - Simplex2D(); - Simplex2D(unsigned int seed); - virtual ~Simplex2D() = default; - - float GetValue(float x, float y, float resolution); - - private: - int ii,jj; - int gi0,gi1,gi2; - Vector2i skewedCubeOrigin,off1; - float n1,n2,n3; - float c1,c2,c3; - float gradient2[8][2]; - float UnskewCoeff2D; - float SkewCoeff2D; - float sum; - Vector2 unskewedCubeOrigin, unskewedDistToOrigin; - Vector2 d1,d2,d3; - }; -} - -#endif // SIMPLEX2D_HPP - diff --git a/include/Nazara/Noise/Simplex3D.hpp b/include/Nazara/Noise/Simplex3D.hpp deleted file mode 100644 index ecfc4c2a4..000000000 --- a/include/Nazara/Noise/Simplex3D.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef SIMPLEX3D_HPP -#define SIMPLEX3D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Simplex3D : public Abstract3DNoise - { - public: - Simplex3D(); - Simplex3D(unsigned int seed); - ~Simplex3D() = default; - - float GetValue(float x, float y, float z, float resolution); - - private: - int ii,jj,kk; - int gi0,gi1,gi2,gi3; - Vector3i skewedCubeOrigin,off1,off2; - float n1,n2,n3,n4; - float c1,c2,c3,c4; - float gradient3[12][3]; - float UnskewCoeff3D; - float SkewCoeff3D; - float sum; - Vector3 unskewedCubeOrigin, unskewedDistToOrigin; - Vector3 d1,d2,d3,d4; - }; -} - -#endif // SIMPLEX3D_HPP - diff --git a/include/Nazara/Noise/Simplex4D.hpp b/include/Nazara/Noise/Simplex4D.hpp deleted file mode 100644 index 545c5f290..000000000 --- a/include/Nazara/Noise/Simplex4D.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef SIMPLEX4D_HPP -#define SIMPLEX4D_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API Simplex4D : public Abstract4DNoise - { - public: - Simplex4D(); - Simplex4D(unsigned int seed); - ~Simplex4D() = default; - - float GetValue(float x, float y, float z, float w, float resolution); - - private: - int ii,jj,kk,ll; - int gi0,gi1,gi2,gi3,gi4; - Vector4i skewedCubeOrigin,off1,off2,off3; - int lookupTable4D[64][4]; - int c; - float n1,n2,n3,n4,n5; - float c1,c2,c3,c4,c5,c6; - float gradient4[32][4]; - float UnskewCoeff4D; - float SkewCoeff4D; - float sum; - Vector4 unskewedCubeOrigin, unskewedDistToOrigin; - Vector4 d1,d2,d3,d4,d5; - }; -} - -#endif // SIMPLEX4D_H - diff --git a/include/Nazara/Noise/Worley.hpp b/include/Nazara/Noise/Worley.hpp new file mode 100644 index 000000000..249da999f --- /dev/null +++ b/include/Nazara/Noise/Worley.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifndef NAZARA_WORLEY_HPP +#define NAZARA_WORLEY_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API Worley : public NoiseBase + { + public: + Worley(); + Worley(unsigned int seed); + ~Worley() = default; + + void Set(WorleyFunction func); + + float Get(std::initializer_list coordinates, float scale) const; + + protected: + float _2D(std::initializer_list coordinates, float scale) const; + float _3D(std::initializer_list coordinates, float scale) const; + float _4D(std::initializer_list coordinates, float scale) const; + void _SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const; + + private: + const float scales[4]; + WorleyFunction function; + }; +} + +#endif // NAZARA_WORLEY_HPP diff --git a/src/Nazara/Noise/Abstract2DNoise.cpp b/src/Nazara/Noise/Abstract2DNoise.cpp deleted file mode 100644 index 51cfeddcc..000000000 --- a/src/Nazara/Noise/Abstract2DNoise.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -namespace Nz -{ - Abstract2DNoise::~Abstract2DNoise() = default; - - float Abstract2DNoise::GetBasicValue(float x, float y) - { - return this->GetValue(x,y,m_resolution); - } - - float Abstract2DNoise::GetMappedValue(float x, float y) - { - return (this->GetValue(x,y,m_resolution) + m_offset) * m_gain; - } -} diff --git a/src/Nazara/Noise/Abstract3DNoise.cpp b/src/Nazara/Noise/Abstract3DNoise.cpp deleted file mode 100644 index 6456babec..000000000 --- a/src/Nazara/Noise/Abstract3DNoise.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -namespace Nz -{ - Abstract3DNoise::~Abstract3DNoise() = default; - - float Abstract3DNoise::GetBasicValue(float x, float y, float z) - { - return this->GetValue(x,y,z,m_resolution); - } - - float Abstract3DNoise::GetMappedValue(float x, float y, float z) - { - return (this->GetValue(x,y,z,m_resolution) + m_offset) * m_gain ; - } -} diff --git a/src/Nazara/Noise/Abstract4DNoise.cpp b/src/Nazara/Noise/Abstract4DNoise.cpp deleted file mode 100644 index 44bde3b0f..000000000 --- a/src/Nazara/Noise/Abstract4DNoise.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -namespace Nz -{ - Abstract4DNoise::~Abstract4DNoise() = default; - - float Abstract4DNoise::GetBasicValue(float x, float y, float z, float w) - { - return this->GetValue(x,y,z,w,m_resolution); - } - - float Abstract4DNoise::GetMappedValue(float x, float y, float z, float w) - { - return (this->GetValue(x,y,z,w,m_resolution) + m_offset) * m_gain ; - } -} diff --git a/src/Nazara/Noise/ComplexNoiseBase.cpp b/src/Nazara/Noise/ComplexNoiseBase.cpp deleted file mode 100644 index c62ad8a8f..000000000 --- a/src/Nazara/Noise/ComplexNoiseBase.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -namespace Nz -{ - ComplexNoiseBase::ComplexNoiseBase() - { - m_parametersModified = true; - m_lacunarity = 5.0f; - m_hurst = 1.2f; - m_octaves = 3.0f; - - for (int i(0) ; i < m_octaves; ++i) - { - m_exponent_array[i] = 0; - } - } - - float ComplexNoiseBase::GetLacunarity() const - { - - return m_lacunarity; - } - - float ComplexNoiseBase::GetHurstParameter() const - { - return m_hurst; - } - - float ComplexNoiseBase::GetOctaveNumber() const - { - return m_octaves; - } - - void ComplexNoiseBase::SetLacunarity(float lacunarity) - { - m_lacunarity = lacunarity; - m_parametersModified = true; - - } - - void ComplexNoiseBase::SetHurstParameter(float h) - { - m_hurst = h; - m_parametersModified = true; - } - - void ComplexNoiseBase::SetOctavesNumber(float octaves) - { - if(octaves <= 30.0f) - m_octaves = octaves; - else - m_octaves = 30.0f; - - m_parametersModified = true; - } - - void ComplexNoiseBase::RecomputeExponentArray() - { - if(m_parametersModified) - { - float frequency = 1.0; - m_sum = 0.f; - for (int i(0) ; i < static_cast(m_octaves) ; ++i) - { - - m_exponent_array[i] = std::pow( frequency, -m_hurst ); - frequency *= m_lacunarity; - - m_sum += m_exponent_array[i]; - - } - m_parametersModified = false; - } - } -} diff --git a/src/Nazara/Noise/FBM.cpp b/src/Nazara/Noise/FBM.cpp new file mode 100644 index 000000000..f61bf8f44 --- /dev/null +++ b/src/Nazara/Noise/FBM.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + FBM::FBM(const NoiseBase & source): m_source(source) + { + } + + float FBM::Get(std::initializer_list coordinates, float scale) const + { + float value = 0.0; + + for(int i(0); i < m_octaves; ++i) + { + value += m_source.Get(coordinates,scale) * m_exponent_array.at(i); + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if(std::fabs(remainder) > 0.01f) + value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum; + } +} diff --git a/src/Nazara/Noise/FBM2D.cpp b/src/Nazara/Noise/FBM2D.cpp deleted file mode 100644 index 5a4670b80..000000000 --- a/src/Nazara/Noise/FBM2D.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - FBM2D::FBM2D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin2D(); - break; - - default: - m_source = new Simplex2D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float FBM2D::GetValue(float x, float y, float resolution) - { - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); - - if(!NumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; - } - - FBM2D::~FBM2D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/FBM3D.cpp b/src/Nazara/Noise/FBM3D.cpp deleted file mode 100644 index f0ee6143e..000000000 --- a/src/Nazara/Noise/FBM3D.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - FBM3D::FBM3D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin3D(); - break; - - default: - m_source = new Simplex3D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float FBM3D::GetValue(float x, float y, float z, float resolution) - { - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,z,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); - - if(!NumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; - } - - FBM3D::~FBM3D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/FBM4D.cpp b/src/Nazara/Noise/FBM4D.cpp deleted file mode 100644 index dace704d7..000000000 --- a/src/Nazara/Noise/FBM4D.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - FBM4D::FBM4D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin4D(); - break; - - default: - m_source = new Simplex4D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float FBM4D::GetValue(float x, float y, float z, float w, float resolution) - { - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); - - if(!NumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; - } - - FBM4D::~FBM4D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/HybridMultiFractal.cpp b/src/Nazara/Noise/HybridMultiFractal.cpp new file mode 100644 index 000000000..3f20809d3 --- /dev/null +++ b/src/Nazara/Noise/HybridMultiFractal.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + HybridMultiFractal::HybridMultiFractal(const NoiseBase & source) : + m_source(source) + { + } + + float HybridMultiFractal::Get(std::initializer_list coordinates, float scale) const + { + float offset = 1.0f; + float value = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(0); + float weight = value; + float signal = 0.f; + + scale *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (weight > 1.f) + weight = 1.f; + + signal = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(i); + value += weight * signal; + weight *= signal; + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if (remainder > 0.f) + value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum - offset; + } +} diff --git a/src/Nazara/Noise/HybridMultiFractal3D.cpp b/src/Nazara/Noise/HybridMultiFractal3D.cpp deleted file mode 100644 index e97ce3497..000000000 --- a/src/Nazara/Noise/HybridMultiFractal3D.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - HybridMultiFractal3D::HybridMultiFractal3D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin3D(); - break; - - default: - m_source = new Simplex3D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float HybridMultiFractal3D::GetValue(float x, float y, float z, float resolution) - { - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; - - m_signal = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; - - m_weight *= m_signal; - - resolution *= m_lacunarity; - } - - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; - } - - HybridMultiFractal3D::~HybridMultiFractal3D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/HybridMultiFractal4D.cpp b/src/Nazara/Noise/HybridMultiFractal4D.cpp deleted file mode 100644 index 06ddf87a1..000000000 --- a/src/Nazara/Noise/HybridMultiFractal4D.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - HybridMultiFractal4D::HybridMultiFractal4D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin4D(); - break; - - default: - m_source = new Simplex4D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float HybridMultiFractal4D::GetValue(float x, float y, float z, float w, float resolution) - { - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; - - m_signal = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; - - m_weight *= m_signal; - - resolution *= m_lacunarity; - } - - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; - } - - HybridMultiFractal4D::~HybridMultiFractal4D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/HybridMultifractal2D.cpp b/src/Nazara/Noise/HybridMultifractal2D.cpp deleted file mode 100644 index 007ff78d0..000000000 --- a/src/Nazara/Noise/HybridMultifractal2D.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - HybridMultiFractal2D::HybridMultiFractal2D(NoiseType source, unsigned int seed) - { - switch(source) - { - case PERLIN: - m_source = new Perlin2D(); - break; - - default: - m_source = new Simplex2D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; - } - - float HybridMultiFractal2D::GetValue(float x, float y, float resolution) - { - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; - - m_signal = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; - - m_weight *= m_signal; - - resolution *= m_lacunarity; - } - - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; - } - - HybridMultiFractal2D::~HybridMultiFractal2D() - { - delete m_source; - } -} diff --git a/src/Nazara/Noise/MappedNoiseBase.cpp b/src/Nazara/Noise/MappedNoiseBase.cpp deleted file mode 100644 index 77d8e0eb3..000000000 --- a/src/Nazara/Noise/MappedNoiseBase.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - MappedNoiseBase::MappedNoiseBase() : m_gain(1.f), m_offset(0.f), m_resolution(30.f) - { - - } - - float MappedNoiseBase::GetGain() const - { - return m_gain; - } - - float MappedNoiseBase::GetOffset() const - { - return m_offset; - } - - float MappedNoiseBase::GetResolution() const - { - return m_resolution; - } - - void MappedNoiseBase::SetGain(float gain) - { - m_gain = gain; - } - - void MappedNoiseBase::SetOffset(float offset) - { - m_offset = offset; - } - - void MappedNoiseBase::SetResolution(float resolution) - { - if (NumberEquals(resolution, 0.f)) - { - StringStream ss; - ss << __FILE__ << ':' << __LINE__ << " : resolution cannot be 0.0f"; - - throw std::domain_error(ss.ToString()); - } - m_resolution = resolution; - } -} diff --git a/src/Nazara/Noise/MixerBase.cpp b/src/Nazara/Noise/MixerBase.cpp new file mode 100644 index 000000000..d3dd82acc --- /dev/null +++ b/src/Nazara/Noise/MixerBase.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + MixerBase::MixerBase() : + m_hurst(1.2f), + m_lacunarity(5.f), + m_octaves(3.f) + { + Recompute(); + } + + float MixerBase::GetHurstParameter() const + { + return m_hurst; + } + + float MixerBase::GetLacunarity() const + { + return m_lacunarity; + } + + float MixerBase::GetOctaveNumber() const + { + return m_octaves; + } + + void MixerBase::SetParameters(float hurst, float lacunarity, float octaves) + { + m_hurst = hurst; + m_lacunarity = lacunarity; + m_octaves = octaves; + + Recompute(); + } + + void MixerBase::Recompute() + { + float frequency = 1.0; + m_sum = 0.f; + m_exponent_array.clear(); + + for (int i(0) ; i < static_cast(m_octaves) ; ++i) + { + m_exponent_array.push_back(std::pow( frequency, -m_hurst )); + frequency *= m_lacunarity; + m_sum += m_exponent_array.at(i); + } + } +} diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 550579227..0cbee9eec 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -1,43 +1,37 @@ -// Copyright (C) 2015 Rémi Bèges +// Copyright (C) 2016 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include #include namespace Nz { NoiseBase::NoiseBase(unsigned int seed) { - Ua = 16807; - Uc = 0; - Um = 2147483647; - UcurrentSeed = 0; - Uprevious = 0; + SetSeed(seed); + m_scale = 0.05f; - SetNewSeed(seed); - - for(int i(0) ; i < 512 ; i++) + for(unsigned int i(0) ; i < 512; ++i) perm[i] = i & 255; - } - void NoiseBase::SetNewSeed(unsigned int seed) + float NoiseBase::GetScale() { - Uprevious = seed; - UcurrentSeed = seed; + return m_scale; } - unsigned int NoiseBase::GetUniformRandomValue() + void NoiseBase::SetScale(float scale) { - Ulast = Ua*Uprevious + Uc%Um; - Uprevious = Ulast; - return Ulast; + m_scale = scale; } - void NoiseBase::ShufflePermutationTable() + void NoiseBase::SetSeed(unsigned int seed) + { + generator.seed(seed); + } + + void NoiseBase::Shuffle() { int xchanger; unsigned int ncase; @@ -45,35 +39,21 @@ namespace Nz for(unsigned int i(0) ; i < 256 ; i++) perm[i] = i; - for(unsigned int j(0) ; j < 20 ; ++j) - for (unsigned int i(0); i < 256 ; ++i) - { - ncase = this->GetUniformRandomValue() & 255; - xchanger = perm[i]; - perm[i] = perm[ncase]; - perm[ncase] = xchanger; - } + for (unsigned int i(0); i < 256 ; ++i) + { + ncase = generator() & 255; + xchanger = perm[i]; + perm[i] = perm[ncase]; + perm[ncase] = xchanger; + } for(unsigned int i(256) ; i < 512; ++i) perm[i] = perm[i & 255]; } - int NoiseBase::fastfloor(float n) + void NoiseBase::Shuffle(unsigned int amount) { - return (n >= 0) ? static_cast(n) : static_cast(n-1); - } - - int NoiseBase::JenkinsHash(int a, int b, int c) - { - a = a-b; a = a - c; a = a^(static_cast(c) >> 13); - b = b-c; b = b - a; b = b^(a << 8); - c = c-a; c = c - b; c = c^(static_cast(b) >> 13); - a = a-b; a = a - c; a = a^(static_cast(c) >> 12); - b = b-c; b = b - a; b = b^(a << 16); - c = c-a; c = c - b; c = c^(static_cast(b) >> 5); - a = a-b; a = a - c; a = a^(static_cast(c) >> 3); - b = b-c; b = b - a; b = b^(a << 10); - c = c-a; c = c - b; c = c^(static_cast(b) >> 15); - return c; + for(unsigned int j(0) ; j < amount ; ++j) + Shuffle(); } } diff --git a/src/Nazara/Noise/NoiseTools.cpp b/src/Nazara/Noise/NoiseTools.cpp new file mode 100644 index 000000000..9cf6efd39 --- /dev/null +++ b/src/Nazara/Noise/NoiseTools.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + int fastfloor(float n) + { + return (n >= 0) ? static_cast(n) : static_cast(n-1); + } + + int JenkinsHash(int a, int b, int c) + { + a = a-b; a = a - c; a = a^(static_cast(c) >> 13); + b = b-c; b = b - a; b = b^(a << 8); + c = c-a; c = c - b; c = c^(static_cast(b) >> 13); + a = a-b; a = a - c; a = a^(static_cast(c) >> 12); + b = b-c; b = b - a; b = b^(a << 16); + c = c-a; c = c - b; c = c^(static_cast(b) >> 5); + a = a-b; a = a - c; a = a^(static_cast(c) >> 3); + b = b-c; b = b - a; b = b^(a << 10); + c = c-a; c = c - b; c = c^(static_cast(b) >> 15); + return c; + } +} diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp new file mode 100644 index 000000000..f184702de --- /dev/null +++ b/src/Nazara/Noise/Perlin.cpp @@ -0,0 +1,325 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + Perlin::Perlin() : + gradient2{ + {1.f,1.f},{-1.f,1.f},{1.f,-1.f},{-1.f,-1.f}, + {1.f,0.f},{-1.f,0.f},{0.f,1.f},{0.f,-1.f} + }, + gradient3{ + {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, + {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, + {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, + {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} + }, + gradient4{ + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + } + { + + } + + Perlin::Perlin(unsigned int seed) : Perlin() + { + SetSeed(seed); + Shuffle(); + } + + float Perlin::Get(std::initializer_list coordinates, float scale) const + { + switch(coordinates.size()) + { + case 2: + return this->_2D(coordinates,scale); + case 3: + return this->_3D(coordinates,scale); + case 4: + return this->_4D(coordinates,scale); + default: + throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); + } + } + + float Perlin::_2D(std::initializer_list coordinates, float scale) const + { + thread_local float xc, yc; + thread_local int x0, y0; + thread_local int gi0,gi1,gi2,gi3; + thread_local int ii, jj; + + thread_local float s,t,u,v; + thread_local float Cx,Cy; + thread_local float Li1, Li2; + thread_local float tempx,tempy; + + std::initializer_list::const_iterator it = coordinates.begin(); + + xc = *(it ) * scale; + yc = *(++it) * scale; + + x0 = fastfloor(xc); + y0 = fastfloor(yc); + + ii = x0 & 255; + jj = y0 & 255; + + gi0 = perm[ii + perm[jj]] & 7; + gi1 = perm[ii + 1 + perm[jj]] & 7; + gi2 = perm[ii + perm[jj + 1]] & 7; + gi3 = perm[ii + 1 + perm[jj + 1]] & 7; + + tempx = xc - x0; + tempy = yc - y0; + + Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10); + Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); + + s = gradient2[gi0][0]*tempx + gradient2[gi0][1]*tempy; + + tempx = xc - (x0 + 1); + t = gradient2[gi1][0]*tempx + gradient2[gi1][1]*tempy; + + tempy = yc - (y0 + 1); + v = gradient2[gi3][0]*tempx + gradient2[gi3][1]*tempy; + + tempx = xc - x0; + u = gradient2[gi2][0]*tempx + gradient2[gi2][1]*tempy; + + Li1 = s + Cx*(t-s); + Li2 = u + Cx*(v-u); + + return Li1 + Cy*(Li2-Li1); + } + + float Perlin::_3D(std::initializer_list coordinates, float scale) const + { + thread_local float xc, yc, zc; + thread_local int x0, y0, z0; + thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; + thread_local int ii, jj, kk; + + thread_local float Li1,Li2,Li3,Li4,Li5,Li6; + thread_local float s[2],t[2],u[2],v[2]; + thread_local float Cx,Cy,Cz; + thread_local float nx,ny,nz; + + thread_local float tmp; + thread_local float tempx,tempy,tempz; + + std::initializer_list::const_iterator it = coordinates.begin(); + + xc = *(it ) * scale; + yc = *(++it) * scale; + zc = *(++it) * scale; + + x0 = fastfloor(xc); + y0 = fastfloor(yc); + z0 = fastfloor(zc); + + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; + + gi0 = perm[ii + perm[jj + perm[kk]]] & 15; + gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; + gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; + + gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; + gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; + + tempx = xc - x0; + tempy = yc - y0; + tempz = zc - z0; + + Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10); + Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); + Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); + + s[0] = gradient3[gi0][0]*tempx + gradient3[gi0][1]*tempy + gradient3[gi0][2]*tempz; + + tempx = xc - (x0 + 1); + t[0] = gradient3[gi1][0]*tempx + gradient3[gi1][1]*tempy + gradient3[gi1][2]*tempz; + + tempy = yc - (y0 + 1); + v[0] = gradient3[gi3][0]*tempx + gradient3[gi3][1]*tempy + gradient3[gi3][2]*tempz; + + tempx = xc - x0; + u[0] = gradient3[gi2][0]*tempx + gradient3[gi2][1]*tempy + gradient3[gi2][2]*tempz; + + tempy = yc - y0; + tempz = zc - (z0 + 1); + s[1] = gradient3[gi4][0]*tempx + gradient3[gi4][1]*tempy + gradient3[gi4][2]*tempz; + + tempx = xc - (x0 + 1); + t[1] = gradient3[gi5][0]*tempx + gradient3[gi5][1]*tempy + gradient3[gi5][2]*tempz; + + tempy = yc - (y0 + 1); + v[1] = gradient3[gi7][0]*tempx + gradient3[gi7][1]*tempy + gradient3[gi7][2]*tempz; + + tempx = xc - x0; + u[1] = gradient3[gi6][0]*tempx + gradient3[gi6][1]*tempy + gradient3[gi6][2]*tempz; + + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); + + Li5 = Li1 + Cy * (Li2-Li1); + Li6 = Li3 + Cy * (Li4-Li3); + + return Li5 + Cz * (Li6-Li5); + } + + float Perlin::_4D(std::initializer_list coordinates, float scale) const + { + thread_local float xc,yc,zc,wc; + thread_local int x0,y0,z0,w0; + thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; + thread_local int ii,jj,kk,ll; + + thread_local float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; + thread_local float s[4],t[4],u[4],v[4]; + thread_local float Cx,Cy,Cz,Cw; + + thread_local float tmp; + thread_local float tempx,tempy,tempz,tempw; + + std::initializer_list::const_iterator it = coordinates.begin(); + + xc = *(it ) * scale; + yc = *(++it) * scale; + zc = *(++it) * scale; + wc = *(++it) * scale; + + x0 = fastfloor(xc); + y0 = fastfloor(yc); + z0 = fastfloor(zc); + w0 = fastfloor(wc); + + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; + ll = w0 & 255; + + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; + gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; + gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + + gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + + gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + + gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + + tempx = xc - x0; + tempy = yc - y0; + tempz = zc - z0; + tempw = wc - w0; + + Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10); + Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); + Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); + Cw = tempw * tempw * tempw * (tempw * (tempw * 6 - 15) + 10); + + s[0] = gradient4[gi0][0]*tempx + gradient4[gi0][1]*tempy + gradient4[gi0][2]*tempz + gradient4[gi0][3]*tempw; + + tempx = xc - (x0+1); + t[0] = gradient4[gi1][0]*tempx + gradient4[gi1][1]*tempy + gradient4[gi1][2]*tempz + gradient4[gi1][3]*tempw; + + tempy = yc - (y0+1); + v[0] = gradient4[gi3][0]*tempx + gradient4[gi3][1]*tempy + gradient4[gi3][2]*tempz + gradient4[gi3][3]*tempw; + + tempx = xc - x0; + u[0] = gradient4[gi2][0]*tempx + gradient4[gi2][1]*tempy + gradient4[gi2][2]*tempz + gradient4[gi2][3]*tempw; + + tempy = yc - y0; + tempz = zc - (z0+1); + s[1] = gradient4[gi4][0]*tempx + gradient4[gi4][1]*tempy + gradient4[gi4][2]*tempz + gradient4[gi4][3]*tempw; + + tempx = xc - (x0+1); + t[1] = gradient4[gi5][0]*tempx + gradient4[gi5][1]*tempy + gradient4[gi5][2]*tempz + gradient4[gi5][3]*tempw; + + tempy = yc - (y0+1); + v[1] = gradient4[gi7][0]*tempx + gradient4[gi7][1]*tempy + gradient4[gi7][2]*tempz + gradient4[gi7][3]*tempw; + + tempx = xc - x0; + u[1] = gradient4[gi6][0]*tempx + gradient4[gi6][1]*tempy + gradient4[gi6][2]*tempz + gradient4[gi6][3]*tempw; + + + tempy = yc - y0; + tempz = zc - z0; + tempw = wc - (w0+1); + s[2] = gradient4[gi8][0]*tempx + gradient4[gi8][1]*tempy + gradient4[gi8][2]*tempz + gradient4[gi8][3]*tempw; + + tempx = xc - (x0+1); + t[2] = gradient4[gi9][0]*tempx + gradient4[gi9][1]*tempy + gradient4[gi9][2]*tempz + gradient4[gi9][3]*tempw; + + tempy = yc - (y0+1); + v[2] = gradient4[gi11][0]*tempx + gradient4[gi11][1]*tempy + gradient4[gi11][2]*tempz + gradient4[gi11][3]*tempw; + + tempx = xc - x0; + u[2] = gradient4[gi10][0]*tempx + gradient4[gi10][1]*tempy + gradient4[gi10][2]*tempz + gradient4[gi10][3]*tempw; + + + tempy = yc - y0; + tempz = zc - (z0+1); + s[3] = gradient4[gi12][0]*tempx + gradient4[gi12][1]*tempy + gradient4[gi12][2]*tempz + gradient4[gi12][3]*tempw; + + tempx = xc - (x0+1); + t[3] = gradient4[gi13][0]*tempx + gradient4[gi13][1]*tempy + gradient4[gi13][2]*tempz + gradient4[gi13][3]*tempw; + + tempy = yc - (y0+1); + v[3] = gradient4[gi15][0]*tempx + gradient4[gi15][1]*tempy + gradient4[gi15][2]*tempz + gradient4[gi15][3]*tempw; + + tempx = xc - x0; + u[3] = gradient4[gi14][0]*tempx + gradient4[gi14][1]*tempy + gradient4[gi14][2]*tempz + gradient4[gi14][3]*tempw; + + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); + Li5 = s[2] + Cx*(t[2]-s[2]); + Li6 = u[2] + Cx*(v[2]-u[2]); + Li7 = s[3] + Cx*(t[3]-s[3]); + Li8 = u[3] + Cx*(v[3]-u[3]); + + Li9 = Li1 + Cy*(Li2-Li1); + Li10 = Li3 + Cy*(Li4-Li3); + Li11 = Li5 + Cy*(Li6-Li5); + Li12 = Li7 + Cy*(Li8-Li7); + + Li13 = Li9 + Cz*(Li10-Li9); + Li14 = Li11 + Cz*(Li12-Li11); + + return Li13 + Cw*(Li14-Li13); + } +} diff --git a/src/Nazara/Noise/Perlin2D.cpp b/src/Nazara/Noise/Perlin2D.cpp deleted file mode 100644 index 1d26c01e2..000000000 --- a/src/Nazara/Noise/Perlin2D.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Perlin2D::Perlin2D() - { - float grad2Temp[][2] = { - {1.f,1.f}, - {-1.f,1.f}, - {1.f,-1.f}, - {-1.f,-1.f}, - - {1.f,0.f}, - {-1.f,0.f}, - {0.f,1.f}, - {0.f,-1.f} - }; - - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; - } - - Perlin2D::Perlin2D(unsigned int seed) : Perlin2D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Perlin2D::GetValue(float x, float y, float resolution) - { - x *= resolution; - y *= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - - ii = x0 & 255; - jj = y0 & 255; - - gi0 = perm[ii + perm[jj]] & 7; - gi1 = perm[ii + 1 + perm[jj]] & 7; - gi2 = perm[ii + perm[jj + 1]] & 7; - gi3 = perm[ii + 1 + perm[jj + 1]] & 7; - - temp.x = x-x0; - temp.y = y-y0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - - s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; - - temp.x = x-(x0+1); - t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; - - temp.y = y-(y0+1); - v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; - - temp.x = x-x0; - u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; - - Li1 = s + Cx*(t-s); - Li2 = u + Cx*(v-u); - - return Li1 + Cy*(Li2-Li1); - } -} diff --git a/src/Nazara/Noise/Perlin3D.cpp b/src/Nazara/Noise/Perlin3D.cpp deleted file mode 100644 index 2e91154f6..000000000 --- a/src/Nazara/Noise/Perlin3D.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Perlin3D::Perlin3D() - { - float grad3Temp[][3] = { - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} - }; - - for(int i(0) ; i < 16 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; - } - - Perlin3D::Perlin3D(unsigned int seed) : Perlin3D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Perlin3D::GetValue(float x, float y, float z, float resolution) - { - x /= resolution; - y /= resolution; - z /= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); - - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; - - gi0 = perm[ii + perm[jj + perm[kk]]] & 15; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; - - gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; - - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - - s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; - - temp.x = x-(x0+1); - t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; - - temp.y = y-(y0+1); - v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; - - temp.x = x-x0; - u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; - - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; - - temp.x = x-(x0+1); - t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; - - temp.y = y-(y0+1); - v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; - - temp.x = x-x0; - u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; - - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); - - Li5 = Li1 + Cy*(Li2-Li1); - Li6 = Li3 + Cy*(Li4-Li3); - - return Li5 + Cz*(Li6-Li5); - } -} diff --git a/src/Nazara/Noise/Perlin4D.cpp b/src/Nazara/Noise/Perlin4D.cpp deleted file mode 100644 index b321616f6..000000000 --- a/src/Nazara/Noise/Perlin4D.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Perlin4D::Perlin4D() - { - float grad4Temp[][4] = - { - {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, - {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, - {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, - {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, - {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, - {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, - {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, - {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} - }; - - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; - } - - Perlin4D::Perlin4D(unsigned int seed) : Perlin4D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Perlin4D::GetValue(float x, float y, float z, float w, float resolution) - { - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); - w0 = fastfloor(w); - - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; - ll = w0 & 255; - - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; - gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - - gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - - gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - - gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-w0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - Cw = temp.w * temp.w * temp.w * (temp.w * (temp.w * 6 - 15) + 10); - - s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; - - temp.x = x-(x0+1); - t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; - - temp.y = y-(y0+1); - v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; - - temp.x = x-x0; - u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; - - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; - - temp.x = x-(x0+1); - t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; - - temp.y = y-(y0+1); - v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; - - temp.x = x-x0; - u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; - - - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-(w0+1); - s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; - - temp.x = x-(x0+1); - t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; - - temp.y = y-(y0+1); - v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; - - temp.x = x-x0; - u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; - - - temp.y = y-y0; - temp.z = z-(z0+1); - s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; - - temp.x = x-(x0+1); - t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; - - temp.y = y-(y0+1); - v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; - - temp.x = x-x0; - u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; - - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); - Li5 = s[2] + Cx*(t[2]-s[2]); - Li6 = u[2] + Cx*(v[2]-u[2]); - Li7 = s[3] + Cx*(t[3]-s[3]); - Li8 = u[3] + Cx*(v[3]-u[3]); - - Li9 = Li1 + Cy*(Li2-Li1); - Li10 = Li3 + Cy*(Li4-Li3); - Li11 = Li5 + Cy*(Li6-Li5); - Li12 = Li7 + Cy*(Li8-Li7); - - Li13 = Li9 + Cz*(Li10-Li9); - Li14 = Li11 + Cz*(Li12-Li11); - - return Li13 + Cw*(Li14-Li13); - } -} diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp new file mode 100644 index 000000000..c93a226d4 --- /dev/null +++ b/src/Nazara/Noise/Simplex.cpp @@ -0,0 +1,459 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + Simplex::Simplex() : + gradient2{ + {1,1},{-1,1},{1,-1},{-1,-1}, + {1,0},{-1,0},{0,1},{0,-1} + }, + gradient3{ + {1.f,1.f,0.f},{-1.f,1.f,0.f},{1.f,-1.f,0.f},{-1.f,-1.f,0.f}, + {1.f,0.f,1.f},{-1.f,0.f,1.f},{1.f,0.f,-1.f},{-1.f,0.f,-1.f}, + {0.f,1.f,1.f},{0.f,-1.f,1.f},{0.f,1.f,-1.f},{0.f,-1.f,-1.f} + }, + gradient4{ + {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, + {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, + {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, + {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, + {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, + {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, + {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, + {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} + }, + lookupTable4D{ + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} + }, + SkewCoeff2D (0.5f*(std::sqrt(3.f) - 1.f)), + UnskewCoeff2D((3.f-std::sqrt(3.f))/6.f), + SkewCoeff3D (1/3.f), + UnskewCoeff3D (1/6.f), + SkewCoeff4D ((std::sqrt(5.f) - 1.f)/4.f), + UnskewCoeff4D ((5.f - std::sqrt(5.f))/20.f) + { + + } + + Simplex::Simplex(unsigned int seed) : Simplex() + { + SetSeed(seed); + Shuffle(); + } + + float Simplex::Get(std::initializer_list coordinates, float scale) const + { + switch(coordinates.size()) + { + case 2: + return this->_2D(coordinates,scale); + case 3: + return this->_3D(coordinates,scale); + case 4: + return this->_4D(coordinates,scale); + default: + throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); + } + } + + float Simplex::_2D(std::initializer_list coordinates, float scale) const + { + thread_local float xc,yc; + thread_local int ii,jj; + thread_local int gi0,gi1,gi2; + thread_local int skewedCubeOriginx,skewedCubeOriginy; + thread_local int off1x,off1y; + thread_local float n1,n2,n3; + thread_local float c1,c2,c3; + thread_local float sum; + thread_local float unskewedCubeOriginx,unskewedCubeOriginy; + thread_local float unskewedDistToOriginx,unskewedDistToOriginy; + thread_local float d1x,d1y; + thread_local float d2x,d2y; + thread_local float d3x,d3y; + + std::initializer_list::const_iterator it = coordinates.begin(); + + xc = *(it ) * scale; + yc = *(++it) * scale; + + sum = (xc + yc) * SkewCoeff2D; + skewedCubeOriginx = fastfloor(xc + sum); + skewedCubeOriginy = fastfloor(yc + sum); + + sum = (skewedCubeOriginx + skewedCubeOriginy) * UnskewCoeff2D; + unskewedCubeOriginx = skewedCubeOriginx - sum; + unskewedCubeOriginy = skewedCubeOriginy - sum; + + unskewedDistToOriginx = xc - unskewedCubeOriginx;// Difference with 3d and 4d + unskewedDistToOriginy = yc - unskewedCubeOriginy; + + if(unskewedDistToOriginx > unskewedDistToOriginy) + { + off1x = 1; + off1y = 0; + } + else + { + off1x = 0; + off1y = 1; + } + + d1x = - unskewedDistToOriginx; + d1y = - unskewedDistToOriginy; + + d2x = d1x + off1x - UnskewCoeff2D; + d2y = d1y + off1y - UnskewCoeff2D; + + d3x = d1x + 1.f - 2.f * UnskewCoeff2D; + d3y = d1y + 1.f - 2.f * UnskewCoeff2D; + + ii = skewedCubeOriginx & 255; + jj = skewedCubeOriginy & 255; + + gi0 = perm[ii + perm[jj ]] & 7; + gi1 = perm[ii + off1x + perm[jj + off1y ]] & 7; + gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; + + c1 = 0.5f - d1x * d1x - d1y * d1y; + c2 = 0.5f - d2x * d2x - d2y * d2y; + c3 = 0.5f - d3x * d3x - d3y * d3y; + + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1x + gradient2[gi0][1] * d1y); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2x + gradient2[gi1][1] * d2y); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3x + gradient2[gi2][1] * d3y); + + return (n1+n2+n3)*70.f; + } + + float Simplex::_3D(std::initializer_list coordinates, float scale) const + { + thread_local float xc, yc, zc; + thread_local float x,y,z; + thread_local int ii,jj,kk; + thread_local int gi0,gi1,gi2,gi3; + thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz; + + thread_local int off1x,off1y,off1z; + thread_local int off2x,off2y,off2z; + thread_local float n1,n2,n3,n4; + thread_local float c1,c2,c3,c4; + + thread_local float sum; + thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz; + thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz; + thread_local float d1x,d1y,d1z; + thread_local float d2x,d2y,d2z; + thread_local float d3x,d3y,d3z; + thread_local float d4x,d4y,d4z; + + std::initializer_list::const_iterator it = coordinates.begin(); + + x = *(it ); + y = *(++it); + z = *(++it); + + xc = x * scale; + yc = y * scale; + zc = z * scale; + + sum = (xc + yc + zc) * SkewCoeff3D; + skewedCubeOriginx = fastfloor(xc + sum); + skewedCubeOriginy = fastfloor(yc + sum); + skewedCubeOriginz = fastfloor(zc + sum); + + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * UnskewCoeff3D; + unskewedCubeOriginx = skewedCubeOriginx - sum; + unskewedCubeOriginy = skewedCubeOriginy - sum; + unskewedCubeOriginz = skewedCubeOriginz - sum; + + unskewedDistToOriginx = xc - unskewedCubeOriginx; + unskewedDistToOriginy = yc - unskewedCubeOriginy; + unskewedDistToOriginz = zc - unskewedCubeOriginz; + + if(unskewedDistToOriginx >= unskewedDistToOriginy) + { + if(unskewedDistToOriginy >= unskewedDistToOriginz) + { + off1x = 1; + off1y = 0; + off1z = 0; + off2x = 1; + off2y = 1; + off2z = 0; + } + else if(unskewedDistToOriginx >= unskewedDistToOriginz) + { + off1x = 1; + off1y = 0; + off1z = 0; + off2x = 1; + off2y = 0; + off2z = 1; + } + else + { + off1x = 0; + off1y = 0; + off1z = 1; + off2x = 1; + off2y = 0; + off2z = 1; + } + } + else + { + if(unskewedDistToOriginy < unskewedDistToOriginz) + { + off1x = 0; + off1y = 0; + off1z = 1; + off2x = 0; + off2y = 1; + off2z = 1; + } + else if(unskewedDistToOriginx < unskewedDistToOriginz) + { + off1x = 0; + off1y = 1; + off1z = 0; + off2x = 0; + off2y = 1; + off2z = 1; + } + else + { + off1x = 0; + off1y = 1; + off1z = 0; + off2x = 1; + off2y = 1; + off2z = 0; + } + } + + d1x = unskewedDistToOriginx; + d1y = unskewedDistToOriginy; + d1z = unskewedDistToOriginz; + + d2x = d1x - off1x + UnskewCoeff3D; + d2y = d1y - off1y + UnskewCoeff3D; + d2z = d1z - off1z + UnskewCoeff3D; + + d3x = d1x - off2x + 2.f*UnskewCoeff3D; + d3y = d1y - off2y + 2.f*UnskewCoeff3D; + d3z = d1z - off2z + 2.f*UnskewCoeff3D; + + d4x = d1x - 1.f + 3.f*UnskewCoeff3D; + d4y = d1y - 1.f + 3.f*UnskewCoeff3D; + d4z = d1z - 1.f + 3.f*UnskewCoeff3D; + + ii = skewedCubeOriginx & 255; + jj = skewedCubeOriginy & 255; + kk = skewedCubeOriginz & 255; + + gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; + gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z ]]] % 12; + gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z ]]] % 12; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; + + c1 = 0.6f - d1x * d1x - d1y * d1y - d1z * d1z; + c2 = 0.6f - d2x * d2x - d2y * d2y - d2z * d2z; + c3 = 0.6f - d3x * d3x - d3y * d3y - d3z * d3z; + c4 = 0.6f - d4x * d4x - d4y * d4y - d4z * d4z; + + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1x + gradient3[gi0][1] * d1y + gradient3[gi0][2] * d1z); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2x + gradient3[gi1][1] * d2y + gradient3[gi1][2] * d2z); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3x + gradient3[gi2][1] * d3y + gradient3[gi2][2] * d3z); + + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4x + gradient3[gi3][1] * d4y + gradient3[gi3][2] * d4z); + + return (n1+n2+n3+n4)*32; + } + + float Simplex::_4D(std::initializer_list coordinates, float scale) const + { + thread_local float xc,yc,zc,wc; + thread_local float x,y,z,w; + thread_local int ii,jj,kk,ll; + thread_local int gi0,gi1,gi2,gi3,gi4; + thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw; + + thread_local int off1x,off1y,off1z,off1w; + thread_local int off2x,off2y,off2z,off2w; + thread_local int off3x,off3y,off3z,off3w; + + thread_local int c; + thread_local float n1,n2,n3,n4,n5; + thread_local float c1,c2,c3,c4,c5,c6; + + thread_local float sum; + thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; + thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw; + thread_local float d1x,d2x,d3x,d4x,d5x; + thread_local float d1y,d2y,d3y,d4y,d5y; + thread_local float d1z,d2z,d3z,d4z,d5z; + thread_local float d1w,d2w,d3w,d4w,d5w; + + std::initializer_list::const_iterator it = coordinates.begin(); + + x = *(it ); + y = *(++it); + z = *(++it); + w = *(++it); + + xc = x * scale; + yc = y * scale; + zc = z * scale; + wc = w * scale; + + sum = (xc + yc + zc + wc) * SkewCoeff4D; + skewedCubeOriginx = fastfloor(xc + sum); + skewedCubeOriginy = fastfloor(yc + sum); + skewedCubeOriginz = fastfloor(zc + sum); + skewedCubeOriginw = fastfloor(wc + sum); + + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * UnskewCoeff4D; + unskewedCubeOriginx = skewedCubeOriginx - sum; + unskewedCubeOriginy = skewedCubeOriginy - sum; + unskewedCubeOriginz = skewedCubeOriginz - sum; + unskewedCubeOriginw = skewedCubeOriginw - sum; + + unskewedDistToOriginx = xc - unskewedCubeOriginx; + unskewedDistToOriginy = yc - unskewedCubeOriginy; + unskewedDistToOriginz = zc - unskewedCubeOriginz; + unskewedDistToOriginw = wc - unskewedCubeOriginw; + + c1 = (unskewedDistToOriginx > unskewedDistToOriginy) ? 32 : 0; + c2 = (unskewedDistToOriginx > unskewedDistToOriginz) ? 16 : 0; + c3 = (unskewedDistToOriginy > unskewedDistToOriginz) ? 8 : 0; + c4 = (unskewedDistToOriginx > unskewedDistToOriginw) ? 4 : 0; + c5 = (unskewedDistToOriginy > unskewedDistToOriginw) ? 2 : 0; + c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0; + c = c1 + c2 + c3 + c4 + c5 + c6; + + off1x = lookupTable4D[c][0] >= 3 ? 1 : 0; + off1y = lookupTable4D[c][1] >= 3 ? 1 : 0; + off1z = lookupTable4D[c][2] >= 3 ? 1 : 0; + off1w = lookupTable4D[c][3] >= 3 ? 1 : 0; + + off2x = lookupTable4D[c][0] >= 2 ? 1 : 0; + off2y = lookupTable4D[c][1] >= 2 ? 1 : 0; + off2z = lookupTable4D[c][2] >= 2 ? 1 : 0; + off2w = lookupTable4D[c][3] >= 2 ? 1 : 0; + + off3x = lookupTable4D[c][0] >= 1 ? 1 : 0; + off3y = lookupTable4D[c][1] >= 1 ? 1 : 0; + off3z = lookupTable4D[c][2] >= 1 ? 1 : 0; + off3w = lookupTable4D[c][3] >= 1 ? 1 : 0; + + d1x = unskewedDistToOriginx; + d1y = unskewedDistToOriginy; + d1z = unskewedDistToOriginz; + d1w = unskewedDistToOriginw; + + d2x = d1x - off1x + UnskewCoeff4D; + d2y = d1y - off1y + UnskewCoeff4D; + d2z = d1z - off1z + UnskewCoeff4D; + d2w = d1w - off1w + UnskewCoeff4D; + + d3x = d1x - off2x + 2.f*UnskewCoeff4D; + d3y = d1y - off2y + 2.f*UnskewCoeff4D; + d3z = d1z - off2z + 2.f*UnskewCoeff4D; + d3w = d1w - off2w + 2.f*UnskewCoeff4D; + + d4x = d1x - off3x + 3.f*UnskewCoeff4D; + d4y = d1y - off3y + 3.f*UnskewCoeff4D; + d4z = d1z - off3z + 3.f*UnskewCoeff4D; + d4w = d1w - off3w + 3.f*UnskewCoeff4D; + + d5x = d1x - 1.f + 4*UnskewCoeff4D; + d5y = d1y - 1.f + 4*UnskewCoeff4D; + d5z = d1z - 1.f + 4*UnskewCoeff4D; + d5w = d1w - 1.f + 4*UnskewCoeff4D; + + ii = skewedCubeOriginx & 255; + jj = skewedCubeOriginy & 255; + kk = skewedCubeOriginz & 255; + ll = skewedCubeOriginw & 255; + + gi0 = perm[ii + perm[jj + perm[kk + perm[ll ]]]] & 31; + gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z + perm[ll + off1w]]]] & 31; + gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z + perm[ll + off2w]]]] & 31; + gi3 = perm[ii + off3x + perm[jj + off3y + perm[kk + off3z + perm[ll + off3w]]]] & 31; + gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1 ]]]] % 32; + + c1 = 0.6f - d1x*d1x - d1y*d1y - d1z*d1z - d1w*d1w; + c2 = 0.6f - d2x*d2x - d2y*d2y - d2z*d2z - d2w*d2w; + c3 = 0.6f - d3x*d3x - d3y*d3y - d3z*d3z - d3w*d3w; + c4 = 0.6f - d4x*d4x - d4y*d4y - d4z*d4z - d4w*d4w; + c5 = 0.6f - d5x*d5x - d5y*d5y - d5z*d5z - d5w*d5w; + + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1x + gradient4[gi0][1]*d1y + gradient4[gi0][2]*d1z + gradient4[gi0][3]*d1w); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2x + gradient4[gi1][1]*d2y + gradient4[gi1][2]*d2z + gradient4[gi1][3]*d2w); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3x + gradient4[gi2][1]*d3y + gradient4[gi2][2]*d3z + gradient4[gi2][3]*d3w); + + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4x + gradient4[gi3][1]*d4y + gradient4[gi3][2]*d4z + gradient4[gi3][3]*d4w); + + if(c5 < 0) + n5 = 0; + else + n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5x + gradient4[gi4][1]*d5y + gradient4[gi4][2]*d5z + gradient4[gi4][3]*d5w); + + return (n1+n2+n3+n4+n5)*27.f; + } +} diff --git a/src/Nazara/Noise/Simplex2D.cpp b/src/Nazara/Noise/Simplex2D.cpp deleted file mode 100644 index b5e50c996..000000000 --- a/src/Nazara/Noise/Simplex2D.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Simplex2D::Simplex2D() - { - float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, - {1,0},{-1,0},{0,1},{0,-1}}; - - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; - - SkewCoeff2D = 0.5f*(std::sqrt(3.f) - 1.f); - UnskewCoeff2D = (3.f-std::sqrt(3.f))/6.f; - } - - Simplex2D::Simplex2D(unsigned int seed) : Simplex2D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Simplex2D::GetValue(float x, float y, float resolution) - { - x *= resolution; - y *= resolution; - - sum = (x + y) * SkewCoeff2D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - - if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) - { - off1.x = 1; - off1.y = 0; - } - else - { - off1.x = 0; - off1.y = 1; - } - - d1 = - unskewedDistToOrigin; - - d2.x = d1.x + off1.x - UnskewCoeff2D; - d2.y = d1.y + off1.y - UnskewCoeff2D; - - d3.x = d1.x + 1.f - 2.f * UnskewCoeff2D; - d3.y = d1.y + 1.f - 2.f * UnskewCoeff2D; - - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - - gi0 = perm[ii + perm[jj ]] & 7; - gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; - gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; - - c1 = 0.5f - d1.x * d1.x - d1.y * d1.y; - c2 = 0.5f - d2.x * d2.x - d2.y * d2.y; - c3 = 0.5f - d3.x * d3.x - d3.y * d3.y; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); - - return (n1+n2+n3)*70.f; - } -} diff --git a/src/Nazara/Noise/Simplex3D.cpp b/src/Nazara/Noise/Simplex3D.cpp deleted file mode 100644 index 5848f38ce..000000000 --- a/src/Nazara/Noise/Simplex3D.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Simplex3D::Simplex3D() - { - SkewCoeff3D = 1/3.f; - UnskewCoeff3D = 1/6.f; - - float grad3Temp[][3] = { - {1.f,1.f,0.f}, - {-1.f,1.f,0.f}, - {1.f,-1.f,0.f}, - {-1.f,-1.f,0.f}, - - {1.f,0.f,1.f}, - {-1.f,0.f,1.f}, - {1.f,0.f,-1.f}, - {-1.f,0.f,-1.f}, - - {0.f,1.f,1.f}, - {0.f,-1.f,1.f}, - {0.f,1.f,-1.f}, - {0.f,-1.f,-1.f} - }; - - for(int i(0) ; i < 12 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; - } - - Simplex3D::Simplex3D(unsigned int seed) : Simplex3D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Simplex3D::GetValue(float x, float y, float z, float resolution) - { - x *= resolution; - y *= resolution; - z *= resolution; - - sum = (x + y + z) * SkewCoeff3D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z) * UnskewCoeff3D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - - if(unskewedDistToOrigin.x >= unskewedDistToOrigin.y) - { - if(unskewedDistToOrigin.y >= unskewedDistToOrigin.z) - { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } - else if(unskewedDistToOrigin.x >= unskewedDistToOrigin.z) - { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 0; - off2.z = 1; - } - else - { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 1; - off2.y = 0; - off2.z = 1; - } - } - else - { - if(unskewedDistToOrigin.y < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 0; - off2.y = 1; - off2.z = 1; - } - else if(unskewedDistToOrigin.x < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 0; - off2.y = 1; - off2.z = 1; - } - else - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } - } - - d1 = unskewedDistToOrigin; - - d2.x = d1.x - off1.x + UnskewCoeff3D; - d2.y = d1.y - off1.y + UnskewCoeff3D; - d2.z = d1.z - off1.z + UnskewCoeff3D; - - d3.x = d1.x - off2.x + 2.f*UnskewCoeff3D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff3D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff3D; - - d4.x = d1.x - 1.f + 3.f*UnskewCoeff3D; - d4.y = d1.y - 1.f + 3.f*UnskewCoeff3D; - d4.z = d1.z - 1.f + 3.f*UnskewCoeff3D; - - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; - - gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; - - c1 = 0.6f - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; - c2 = 0.6f - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; - c3 = 0.6f - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; - c4 = 0.6f - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z); - - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z); - - return (n1+n2+n3+n4)*32; - } -} diff --git a/src/Nazara/Noise/Simplex4D.cpp b/src/Nazara/Noise/Simplex4D.cpp deleted file mode 100644 index b515d5958..000000000 --- a/src/Nazara/Noise/Simplex4D.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine - Noise module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - Simplex4D::Simplex4D() - { - SkewCoeff4D = (std::sqrt(5.f) - 1.f)/4.f; - UnskewCoeff4D = (5.f - std::sqrt(5.f))/20.f; - - int lookupTemp4D[][4] = - { - {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, - {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, - {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, - {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} - }; - - for(int i(0) ; i < 64 ; ++i) - for(int j(0) ; j < 4 ; ++j) - lookupTable4D[i][j] = lookupTemp4D[i][j]; - - float grad4Temp[][4] = - { - {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, - {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, - {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, - {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, - {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, - {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, - {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, - {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} - }; - - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; - } - - Simplex4D::Simplex4D(unsigned int seed) : Simplex4D() - { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); - } - - float Simplex4D::GetValue(float x, float y, float z, float w, float resolution) - { - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; - - sum = (x + y + z + w) * SkewCoeff4D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); - skewedCubeOrigin.w = fastfloor(w + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z + skewedCubeOrigin.w) * UnskewCoeff4D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - unskewedCubeOrigin.w = skewedCubeOrigin.w - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - unskewedDistToOrigin.w = w - unskewedCubeOrigin.w; - - c1 = (unskewedDistToOrigin.x > unskewedDistToOrigin.y) ? 32 : 0; - c2 = (unskewedDistToOrigin.x > unskewedDistToOrigin.z) ? 16 : 0; - c3 = (unskewedDistToOrigin.y > unskewedDistToOrigin.z) ? 8 : 0; - c4 = (unskewedDistToOrigin.x > unskewedDistToOrigin.w) ? 4 : 0; - c5 = (unskewedDistToOrigin.y > unskewedDistToOrigin.w) ? 2 : 0; - c6 = (unskewedDistToOrigin.z > unskewedDistToOrigin.w) ? 1 : 0; - c = c1 + c2 + c3 + c4 + c5 + c6; - - off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; - off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; - off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; - off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; - - off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; - off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; - off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; - off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; - - off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; - off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; - off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; - off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; - - d1 = unskewedDistToOrigin; - - d2.x = d1.x - off1.x + UnskewCoeff4D; - d2.y = d1.y - off1.y + UnskewCoeff4D; - d2.z = d1.z - off1.z + UnskewCoeff4D; - d2.w = d1.w - off1.w + UnskewCoeff4D; - - d3.x = d1.x - off2.x + 2.f*UnskewCoeff4D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff4D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff4D; - d3.w = d1.w - off2.w + 2.f*UnskewCoeff4D; - - d4.x = d1.x - off3.x + 3.f*UnskewCoeff4D; - d4.y = d1.y - off3.y + 3.f*UnskewCoeff4D; - d4.z = d1.z - off3.z + 3.f*UnskewCoeff4D; - d4.w = d1.w - off3.w + 3.f*UnskewCoeff4D; - - d5.x = d1.x - 1.f + 4*UnskewCoeff4D; - d5.y = d1.y - 1.f + 4*UnskewCoeff4D; - d5.z = d1.z - 1.f + 4*UnskewCoeff4D; - d5.w = d1.w - 1.f + 4*UnskewCoeff4D; - - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; - ll = skewedCubeOrigin.w & 255; - - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] & 31; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] & 31; - gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] & 31; - gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; - - c1 = 0.6f - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; - c2 = 0.6f - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; - c3 = 0.6f - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; - c4 = 0.6f - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; - c5 = 0.6f - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w); - - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w); - - if(c5 < 0) - n5 = 0; - else - n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w); - - return (n1+n2+n3+n4+n5)*27.f; - } -} diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp new file mode 100644 index 000000000..603820706 --- /dev/null +++ b/src/Nazara/Noise/Worley.cpp @@ -0,0 +1,171 @@ +// Copyright (C) 2016 Rémi Bèges +// This file is part of the "Nazara Engine - Noise module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + Worley::Worley() : + scales{ + 1.f / std::sqrt(2), + 0.5f / std::sqrt(2), + 0.5f / std::sqrt(2), + 0.5f / std::sqrt(2) + } + { + function = WorleyFunction_F1; + } + + Worley::Worley(unsigned int seed) : Worley() + { + SetSeed(seed); + Shuffle(); + } + + void Worley::Set(WorleyFunction func) + { + function = func; + } + + float Worley::Get(std::initializer_list coordinates, float scale) const + { + switch(coordinates.size()) + { + case 2: + return this->_2D(coordinates,scale); + case 3: + return this->_3D(coordinates,scale); + case 4: + return this->_4D(coordinates,scale); + default: + throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); + } + } + + float Worley::_2D(std::initializer_list coordinates, float scale) const + { + std::map featurePoints; + std::map::iterator it; + + float xc, yc; + int x0, y0; + float fractx, fracty; + + std::initializer_list::const_iterator c = coordinates.begin(); + + xc = *(c ) * scale; + yc = *(++c) * scale; + + x0 = fastfloor(xc); + y0 = fastfloor(yc); + + fractx = xc - static_cast(x0); + fracty = yc - static_cast(y0); + + featurePoints.clear(); + + _SquareTest(x0,y0,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(fractx < it->first) + _SquareTest(x0 - 1,y0,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(1.f - fractx < it->first) + _SquareTest(x0 + 1,y0,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(fracty < it->first) + _SquareTest(x0,y0 - 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(1.f - fracty < it->first) + _SquareTest(x0,y0 + 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(fractx < it->first && + fracty < it->first) + _SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(1.f - fractx < it->first && + fracty < it->first) + _SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(fractx < it->first && + 1.f - fracty < it->first) + _SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + if(1.f - fractx < it->first && + 1.f - fracty < it->first) + _SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); + + it = featurePoints.begin(); + std::advance(it,function); + + return it->first * scales[function]; + } + + float Worley::_3D(std::initializer_list coordinates, float scale) const + { + throw std::runtime_error("Worley 3D not available yet."); + } + + float Worley::_4D(std::initializer_list coordinates, float scale) const + { + throw std::runtime_error("Worley 4D not available yet."); + } + + + void Worley::_SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const + { + int ii = xi & 255; + int jj = yi & 255; + + int seed = perm[ii + perm[jj]]; + + //On initialise notre rng avec seed + std::minstd_rand0 randomNumberGenerator(seed); + + //On prend un nombre de points à déterminer dans le cube, compris entre 1 et 8 + unsigned int m = (seed & 7) + 1; + + //On calcule les emplacements des différents points + for(unsigned int i(0) ; i < m ; ++i) + { + Nz::Vector2f featurePoint; + featurePoint.x = (randomNumberGenerator() & 1023) / 1023.f + static_cast(xi); + featurePoint.y = (randomNumberGenerator() & 1023) / 1023.f + static_cast(yi); + + // TODO : Check order is correct + float distance = std::sqrt((featurePoint.x - x) * (featurePoint.x - x) + + (featurePoint.y - y) * (featurePoint.y - y)); + + //Insertion dans la liste triée + featurePoints[distance] = featurePoint; + } + } +} From b0fc1c9bf91f67cff82c5adeb6d9f70c05f16c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 18 Jun 2016 12:36:20 +0200 Subject: [PATCH 141/224] Noise: First pass of refactoring Former-commit-id: c71e76f337fd3fc1793f105d189f3ceecb80e537 [formerly 5ac3cfc15257e407cb388bcedb1a96be5381ef67] Former-commit-id: c97fb23feb0e4bd4d6965e83d91a38cec1382e48 --- include/Nazara/Math/Algorithm.hpp | 5 + include/Nazara/Noise/FBM.hpp | 4 +- include/Nazara/Noise/HybridMultiFractal.hpp | 4 +- include/Nazara/Noise/MixerBase.hpp | 4 + include/Nazara/Noise/NoiseBase.hpp | 17 +- include/Nazara/Noise/Perlin.hpp | 20 +- include/Nazara/Noise/Simplex.hpp | 27 +- include/Nazara/Noise/Worley.hpp | 23 +- src/Nazara/Noise/FBM.cpp | 45 ++- src/Nazara/Noise/HybridMultiFractal.cpp | 64 +++- src/Nazara/Noise/NoiseBase.cpp | 62 ++-- src/Nazara/Noise/Perlin.cpp | 239 +++++------- src/Nazara/Noise/Simplex.cpp | 388 ++++++++------------ src/Nazara/Noise/Worley.cpp | 118 +++--- 14 files changed, 485 insertions(+), 535 deletions(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 74cc45593..45281bb50 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -1,3 +1,4 @@ + // Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -28,6 +29,10 @@ #define M_SQRT3 1.7320508075688772935274463 #endif +#ifndef M_SQRT5 +#define M_SQRT5 2.23606797749979 +#endif + namespace Nz { template /*constexpr*/ T Approach(T value, T objective, T increment); diff --git a/include/Nazara/Noise/FBM.hpp b/include/Nazara/Noise/FBM.hpp index ded4aa069..584fb3a10 100644 --- a/include/Nazara/Noise/FBM.hpp +++ b/include/Nazara/Noise/FBM.hpp @@ -18,7 +18,9 @@ namespace Nz FBM(const FBM&) = delete; ~FBM() = default; - float Get(std::initializer_list coordinates, float scale) const; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; FBM& operator=(const FBM&) = delete; diff --git a/include/Nazara/Noise/HybridMultiFractal.hpp b/include/Nazara/Noise/HybridMultiFractal.hpp index a211a4767..c73dafc73 100644 --- a/include/Nazara/Noise/HybridMultiFractal.hpp +++ b/include/Nazara/Noise/HybridMultiFractal.hpp @@ -17,7 +17,9 @@ namespace Nz HybridMultiFractal(const HybridMultiFractal&) = delete; ~HybridMultiFractal() = default; - float Get(std::initializer_list coordinates, float scale) const; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; HybridMultiFractal& operator=(const HybridMultiFractal&) = delete; diff --git a/include/Nazara/Noise/MixerBase.hpp b/include/Nazara/Noise/MixerBase.hpp index 3c7a131b0..8b7a99d56 100644 --- a/include/Nazara/Noise/MixerBase.hpp +++ b/include/Nazara/Noise/MixerBase.hpp @@ -17,6 +17,10 @@ namespace Nz MixerBase(); ~MixerBase() = default; + virtual float Get(float x, float y, float scale) const = 0; + virtual float Get(float x, float y, float z, float scale) const = 0; + virtual float Get(float x, float y, float z, float w, float scale) const = 0; + float GetHurstParameter() const; float GetLacunarity() const; float GetOctaveNumber() const; diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index 6a5c5c37f..f7f9eba09 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -6,7 +6,11 @@ #define NAZARA_NOISEBASE_HPP #include +#include +#include +#include #include +#include #include namespace Nz @@ -17,21 +21,26 @@ namespace Nz NoiseBase(unsigned int seed = 0); ~NoiseBase() = default; - virtual float Get(std::initializer_list coordinates, float scale) const = 0; + virtual float Get(float x, float y, float scale) const = 0; + virtual float Get(float x, float y, float z, float scale) const = 0; + virtual float Get(float x, float y, float z, float w, float scale) const = 0; float GetScale(); void SetScale(float scale); void SetSeed(unsigned int seed); void Shuffle(); - void Shuffle(unsigned int amount); protected: - unsigned int perm[512]; + std::array m_permutations; float m_scale; + static std::array s_gradients2; + static std::array s_gradients3; + static std::array s_gradients4; + private: - std::default_random_engine generator; + std::default_random_engine m_randomEngine; }; } diff --git a/include/Nazara/Noise/Perlin.hpp b/include/Nazara/Noise/Perlin.hpp index 058a3ada5..781d03148 100644 --- a/include/Nazara/Noise/Perlin.hpp +++ b/include/Nazara/Noise/Perlin.hpp @@ -15,21 +15,13 @@ namespace Nz class NAZARA_NOISE_API Perlin : public NoiseBase { public: - Perlin(); - Perlin(unsigned int seed); - ~Perlin() = default; + Perlin() = default; + Perlin(unsigned int seed); + ~Perlin() = default; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - - private: - const float gradient2[8][2]; - const float gradient3[16][3]; - const float gradient4[32][4]; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; }; } diff --git a/include/Nazara/Noise/Simplex.hpp b/include/Nazara/Noise/Simplex.hpp index f131387b6..ae018f7bf 100644 --- a/include/Nazara/Noise/Simplex.hpp +++ b/include/Nazara/Noise/Simplex.hpp @@ -15,28 +15,13 @@ namespace Nz class NAZARA_NOISE_API Simplex : public NoiseBase { public: - Simplex(); - Simplex(unsigned int seed); - ~Simplex() = default; + Simplex() = default; + Simplex(unsigned int seed); + ~Simplex() = default; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - - private: - const float gradient2[8][2]; - const float gradient3[16][3]; - const float gradient4[32][4]; - const float UnskewCoeff2D; - const float SkewCoeff2D; - const float UnskewCoeff3D; - const float SkewCoeff3D; - const float UnskewCoeff4D; - const float SkewCoeff4D; - const int lookupTable4D[64][4]; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; }; } diff --git a/include/Nazara/Noise/Worley.hpp b/include/Nazara/Noise/Worley.hpp index 249da999f..6b9f21f73 100644 --- a/include/Nazara/Noise/Worley.hpp +++ b/include/Nazara/Noise/Worley.hpp @@ -18,23 +18,20 @@ namespace Nz class NAZARA_NOISE_API Worley : public NoiseBase { public: - Worley(); - Worley(unsigned int seed); - ~Worley() = default; + Worley(); + Worley(unsigned int seed); + ~Worley() = default; - void Set(WorleyFunction func); + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - void _SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const; + void Set(WorleyFunction func); private: - const float scales[4]; - WorleyFunction function; + void SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const; + + WorleyFunction m_function; }; } diff --git a/src/Nazara/Noise/FBM.cpp b/src/Nazara/Noise/FBM.cpp index f61bf8f44..96126ec60 100644 --- a/src/Nazara/Noise/FBM.cpp +++ b/src/Nazara/Noise/FBM.cpp @@ -11,20 +11,51 @@ namespace Nz { } - float FBM::Get(std::initializer_list coordinates, float scale) const + ///TODO: Handle with variadic templates + float FBM::Get(float x, float y, float scale) const { - float value = 0.0; - - for(int i(0); i < m_octaves; ++i) + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) { - value += m_source.Get(coordinates,scale) * m_exponent_array.at(i); + value += m_source.Get(x, y, scale) * m_exponent_array.at(i); scale *= m_lacunarity; } float remainder = m_octaves - static_cast(m_octaves); - if(std::fabs(remainder) > 0.01f) - value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum; + } + + float FBM::Get(float x, float y, float z, float scale) const + { + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) + { + value += m_source.Get(x, y, z, scale) * m_exponent_array.at(i); + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + if(std::fabs(remainder) > 0.01f) + value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum; + } + + float FBM::Get(float x, float y, float z, float w, float scale) const + { + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) + { + value += m_source.Get(x, y, z, w, scale) * m_exponent_array.at(i); + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + if(std::fabs(remainder) > 0.01f) + value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast(m_octaves-1)); return value / m_sum; } diff --git a/src/Nazara/Noise/HybridMultiFractal.cpp b/src/Nazara/Noise/HybridMultiFractal.cpp index 3f20809d3..4278d23b2 100644 --- a/src/Nazara/Noise/HybridMultiFractal.cpp +++ b/src/Nazara/Noise/HybridMultiFractal.cpp @@ -12,10 +12,10 @@ namespace Nz { } - float HybridMultiFractal::Get(std::initializer_list coordinates, float scale) const + float HybridMultiFractal::Get(float x, float y, float scale) const { float offset = 1.0f; - float value = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(0); + float value = (m_source.Get(x, y, scale) + offset) * m_exponent_array.at(0); float weight = value; float signal = 0.f; @@ -26,7 +26,7 @@ namespace Nz if (weight > 1.f) weight = 1.f; - signal = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(i); + signal = (m_source.Get(x, y, scale) + offset) * m_exponent_array.at(i); value += weight * signal; weight *= signal; scale *= m_lacunarity; @@ -35,7 +35,63 @@ namespace Nz float remainder = m_octaves - static_cast(m_octaves); if (remainder > 0.f) - value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum - offset; + } + + float HybridMultiFractal::Get(float x, float y, float z, float scale) const + { + float offset = 1.0f; + float value = (m_source.Get(x, y, z, scale) + offset) * m_exponent_array.at(0); + float weight = value; + float signal = 0.f; + + scale *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (weight > 1.f) + weight = 1.f; + + signal = (m_source.Get(x, y, z, scale) + offset) * m_exponent_array.at(i); + value += weight * signal; + weight *= signal; + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if (remainder > 0.f) + value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum - offset; + } + + float HybridMultiFractal::Get(float x, float y, float z, float w, float scale) const + { + float offset = 1.0f; + float value = (m_source.Get(x, y, z, w, scale) + offset) * m_exponent_array.at(0); + float weight = value; + float signal = 0.f; + + scale *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (weight > 1.f) + weight = 1.f; + + signal = (m_source.Get(x, y, z, w, scale) + offset) * m_exponent_array.at(i); + value += weight * signal; + weight *= signal; + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if (remainder > 0.f) + value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast(m_octaves-1)); return value / m_sum - offset; } diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 0cbee9eec..fa5a2c92f 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -7,13 +7,13 @@ namespace Nz { - NoiseBase::NoiseBase(unsigned int seed) + NoiseBase::NoiseBase(unsigned int seed) : + m_scale(0.05f) { SetSeed(seed); - m_scale = 0.05f; - for(unsigned int i(0) ; i < 512; ++i) - perm[i] = i & 255; + // Fill permutations with initial values + std::iota(m_permutations.begin(), m_permutations.begin() + 256, 0); } float NoiseBase::GetScale() @@ -28,32 +28,46 @@ namespace Nz void NoiseBase::SetSeed(unsigned int seed) { - generator.seed(seed); + m_randomEngine.seed(seed); } void NoiseBase::Shuffle() { - int xchanger; - unsigned int ncase; + std::shuffle(m_permutations.begin(), m_permutations.begin() + 256, m_randomEngine); - for(unsigned int i(0) ; i < 256 ; i++) - perm[i] = i; - - for (unsigned int i(0); i < 256 ; ++i) - { - ncase = generator() & 255; - xchanger = perm[i]; - perm[i] = perm[ncase]; - perm[ncase] = xchanger; - } - - for(unsigned int i(256) ; i < 512; ++i) - perm[i] = perm[i & 255]; + for(std::size_t i = 1; i < (m_permutations.size() / 256); ++i) + std::copy(m_permutations.begin(), m_permutations.begin() + 256, m_permutations.begin() + 256 * i); } - void NoiseBase::Shuffle(unsigned int amount) + std::array NoiseBase::s_gradients2 = { - for(unsigned int j(0) ; j < amount ; ++j) - Shuffle(); - } + { + {1.f, 1.f}, {-1.f, 1.f}, {1.f, -1.f}, {-1.f, -1.f}, + {1.f, 0.f}, {-1.f, 0.f}, {0.f, 1.f}, { 0.f, -1.f} + } + }; + + std::array NoiseBase::s_gradients3 = + { + { + {1.f,1.f,0.f}, {-1.f, 1.f, 0.f}, {1.f, -1.f, 0.f}, {-1.f, -1.f, 0.f}, + {1.f,0.f,1.f}, {-1.f, 0.f, 1.f}, {1.f, 0.f, -1.f}, {-1.f, 0.f, -1.f}, + {0.f,1.f,1.f}, { 0.f, -1.f, 1.f}, {0.f, 1.f, -1.f}, {0.f, -1.f, -1.f}, + {1.f,1.f,0.f}, {-1.f, 1.f, 0.f}, {0.f, -1.f, 1.f}, {0.f, -1.f, -1.f} + } + }; + + std::array NoiseBase::s_gradients4 = + { + { + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + } + }; } diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp index f184702de..e6440eb3d 100644 --- a/src/Nazara/Noise/Perlin.cpp +++ b/src/Nazara/Noise/Perlin.cpp @@ -10,68 +10,27 @@ namespace Nz { - Perlin::Perlin() : - gradient2{ - {1.f,1.f},{-1.f,1.f},{1.f,-1.f},{-1.f,-1.f}, - {1.f,0.f},{-1.f,0.f},{0.f,1.f},{0.f,-1.f} - }, - gradient3{ - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} - }, - gradient4{ - {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, - {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, - {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, - {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, - {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, - {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, - {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, - {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} - } - { - - } - - Perlin::Perlin(unsigned int seed) : Perlin() + Perlin::Perlin(unsigned int seed) : + Perlin() { SetSeed(seed); Shuffle(); } - float Perlin::Get(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float scale) const { - switch(coordinates.size()) - { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); - } - } + float xc, yc; + int x0, y0; + int gi0,gi1,gi2,gi3; + int ii, jj; - float Perlin::_2D(std::initializer_list coordinates, float scale) const - { - thread_local float xc, yc; - thread_local int x0, y0; - thread_local int gi0,gi1,gi2,gi3; - thread_local int ii, jj; + float s,t,u,v; + float Cx,Cy; + float Li1, Li2; + float tempx,tempy; - thread_local float s,t,u,v; - thread_local float Cx,Cy; - thread_local float Li1, Li2; - thread_local float tempx,tempy; - - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; + xc = x * scale; + yc = y * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -79,10 +38,10 @@ namespace Nz ii = x0 & 255; jj = y0 & 255; - gi0 = perm[ii + perm[jj]] & 7; - gi1 = perm[ii + 1 + perm[jj]] & 7; - gi2 = perm[ii + perm[jj + 1]] & 7; - gi3 = perm[ii + 1 + perm[jj + 1]] & 7; + gi0 = m_permutations[ii + m_permutations[jj]] & 7; + gi1 = m_permutations[ii + 1 + m_permutations[jj]] & 7; + gi2 = m_permutations[ii + m_permutations[jj + 1]] & 7; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1]] & 7; tempx = xc - x0; tempy = yc - y0; @@ -90,16 +49,16 @@ namespace Nz Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10); Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); - s = gradient2[gi0][0]*tempx + gradient2[gi0][1]*tempy; + s = s_gradients2[gi0][0]*tempx + s_gradients2[gi0][1]*tempy; tempx = xc - (x0 + 1); - t = gradient2[gi1][0]*tempx + gradient2[gi1][1]*tempy; + t = s_gradients2[gi1][0]*tempx + s_gradients2[gi1][1]*tempy; tempy = yc - (y0 + 1); - v = gradient2[gi3][0]*tempx + gradient2[gi3][1]*tempy; + v = s_gradients2[gi3][0]*tempx + s_gradients2[gi3][1]*tempy; tempx = xc - x0; - u = gradient2[gi2][0]*tempx + gradient2[gi2][1]*tempy; + u = s_gradients2[gi2][0]*tempx + s_gradients2[gi2][1]*tempy; Li1 = s + Cx*(t-s); Li2 = u + Cx*(v-u); @@ -107,26 +66,24 @@ namespace Nz return Li1 + Cy*(Li2-Li1); } - float Perlin::_3D(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float z, float scale) const { - thread_local float xc, yc, zc; - thread_local int x0, y0, z0; - thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; - thread_local int ii, jj, kk; + float xc, yc, zc; + int x0, y0, z0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; + int ii, jj, kk; - thread_local float Li1,Li2,Li3,Li4,Li5,Li6; - thread_local float s[2],t[2],u[2],v[2]; - thread_local float Cx,Cy,Cz; - thread_local float nx,ny,nz; + float Li1,Li2,Li3,Li4,Li5,Li6; + float s[2],t[2],u[2],v[2]; + float Cx,Cy,Cz; + float nx,ny,nz; - thread_local float tmp; - thread_local float tempx,tempy,tempz; + float tmp; + float tempx,tempy,tempz; - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; - zc = *(++it) * scale; + xc = x * scale; + yc = y * scale; + zc = z * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -136,15 +93,15 @@ namespace Nz jj = y0 & 255; kk = z0 & 255; - gi0 = perm[ii + perm[jj + perm[kk]]] & 15; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk]]] & 15; + gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk]]] & 15; + gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk]]] & 15; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk]]] & 15; - gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; + gi4 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1]]] & 15; + gi5 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1]]] & 15; + gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15; + gi7 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15; tempx = xc - x0; tempy = yc - y0; @@ -154,29 +111,29 @@ namespace Nz Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); - s[0] = gradient3[gi0][0]*tempx + gradient3[gi0][1]*tempy + gradient3[gi0][2]*tempz; + s[0] = s_gradients3[gi0][0]*tempx + s_gradients3[gi0][1]*tempy + s_gradients3[gi0][2]*tempz; tempx = xc - (x0 + 1); - t[0] = gradient3[gi1][0]*tempx + gradient3[gi1][1]*tempy + gradient3[gi1][2]*tempz; + t[0] = s_gradients3[gi1][0]*tempx + s_gradients3[gi1][1]*tempy + s_gradients3[gi1][2]*tempz; tempy = yc - (y0 + 1); - v[0] = gradient3[gi3][0]*tempx + gradient3[gi3][1]*tempy + gradient3[gi3][2]*tempz; + v[0] = s_gradients3[gi3][0]*tempx + s_gradients3[gi3][1]*tempy + s_gradients3[gi3][2]*tempz; tempx = xc - x0; - u[0] = gradient3[gi2][0]*tempx + gradient3[gi2][1]*tempy + gradient3[gi2][2]*tempz; + u[0] = s_gradients3[gi2][0]*tempx + s_gradients3[gi2][1]*tempy + s_gradients3[gi2][2]*tempz; tempy = yc - y0; tempz = zc - (z0 + 1); - s[1] = gradient3[gi4][0]*tempx + gradient3[gi4][1]*tempy + gradient3[gi4][2]*tempz; + s[1] = s_gradients3[gi4][0]*tempx + s_gradients3[gi4][1]*tempy + s_gradients3[gi4][2]*tempz; tempx = xc - (x0 + 1); - t[1] = gradient3[gi5][0]*tempx + gradient3[gi5][1]*tempy + gradient3[gi5][2]*tempz; + t[1] = s_gradients3[gi5][0]*tempx + s_gradients3[gi5][1]*tempy + s_gradients3[gi5][2]*tempz; tempy = yc - (y0 + 1); - v[1] = gradient3[gi7][0]*tempx + gradient3[gi7][1]*tempy + gradient3[gi7][2]*tempz; + v[1] = s_gradients3[gi7][0]*tempx + s_gradients3[gi7][1]*tempy + s_gradients3[gi7][2]*tempz; tempx = xc - x0; - u[1] = gradient3[gi6][0]*tempx + gradient3[gi6][1]*tempy + gradient3[gi6][2]*tempz; + u[1] = s_gradients3[gi6][0]*tempx + s_gradients3[gi6][1]*tempy + s_gradients3[gi6][2]*tempz; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); @@ -189,26 +146,24 @@ namespace Nz return Li5 + Cz * (Li6-Li5); } - float Perlin::_4D(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float z, float w, float scale) const { - thread_local float xc,yc,zc,wc; - thread_local int x0,y0,z0,w0; - thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; - thread_local int ii,jj,kk,ll; + float xc,yc,zc,wc; + int x0,y0,z0,w0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; + int ii,jj,kk,ll; - thread_local float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; - thread_local float s[4],t[4],u[4],v[4]; - thread_local float Cx,Cy,Cz,Cw; + float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; + float s[4],t[4],u[4],v[4]; + float Cx,Cy,Cz,Cw; - thread_local float tmp; - thread_local float tempx,tempy,tempz,tempw; + float tmp; + float tempx,tempy,tempz,tempw; - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; - zc = *(++it) * scale; - wc = *(++it) * scale; + xc = x * scale; + yc = y * scale; + zc = z * scale; + wc = w * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -220,25 +175,25 @@ namespace Nz kk = z0 & 255; ll = w0 & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; - gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31; + gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31; + gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll]]]] & 31; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll]]]] & 31; - gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi4 = m_permutations[ii + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi5 = m_permutations[ii + 1 + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi7 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; - gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi8 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi9 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi10 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi11 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll + 1]]]] & 31; - gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi12 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi13 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi14 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi15 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; tempx = xc - x0; tempy = yc - y0; @@ -250,58 +205,58 @@ namespace Nz Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); Cw = tempw * tempw * tempw * (tempw * (tempw * 6 - 15) + 10); - s[0] = gradient4[gi0][0]*tempx + gradient4[gi0][1]*tempy + gradient4[gi0][2]*tempz + gradient4[gi0][3]*tempw; + s[0] = s_gradients4[gi0][0]*tempx + s_gradients4[gi0][1]*tempy + s_gradients4[gi0][2]*tempz + s_gradients4[gi0][3]*tempw; tempx = xc - (x0+1); - t[0] = gradient4[gi1][0]*tempx + gradient4[gi1][1]*tempy + gradient4[gi1][2]*tempz + gradient4[gi1][3]*tempw; + t[0] = s_gradients4[gi1][0]*tempx + s_gradients4[gi1][1]*tempy + s_gradients4[gi1][2]*tempz + s_gradients4[gi1][3]*tempw; tempy = yc - (y0+1); - v[0] = gradient4[gi3][0]*tempx + gradient4[gi3][1]*tempy + gradient4[gi3][2]*tempz + gradient4[gi3][3]*tempw; + v[0] = s_gradients4[gi3][0]*tempx + s_gradients4[gi3][1]*tempy + s_gradients4[gi3][2]*tempz + s_gradients4[gi3][3]*tempw; tempx = xc - x0; - u[0] = gradient4[gi2][0]*tempx + gradient4[gi2][1]*tempy + gradient4[gi2][2]*tempz + gradient4[gi2][3]*tempw; + u[0] = s_gradients4[gi2][0]*tempx + s_gradients4[gi2][1]*tempy + s_gradients4[gi2][2]*tempz + s_gradients4[gi2][3]*tempw; tempy = yc - y0; tempz = zc - (z0+1); - s[1] = gradient4[gi4][0]*tempx + gradient4[gi4][1]*tempy + gradient4[gi4][2]*tempz + gradient4[gi4][3]*tempw; + s[1] = s_gradients4[gi4][0]*tempx + s_gradients4[gi4][1]*tempy + s_gradients4[gi4][2]*tempz + s_gradients4[gi4][3]*tempw; tempx = xc - (x0+1); - t[1] = gradient4[gi5][0]*tempx + gradient4[gi5][1]*tempy + gradient4[gi5][2]*tempz + gradient4[gi5][3]*tempw; + t[1] = s_gradients4[gi5][0]*tempx + s_gradients4[gi5][1]*tempy + s_gradients4[gi5][2]*tempz + s_gradients4[gi5][3]*tempw; tempy = yc - (y0+1); - v[1] = gradient4[gi7][0]*tempx + gradient4[gi7][1]*tempy + gradient4[gi7][2]*tempz + gradient4[gi7][3]*tempw; + v[1] = s_gradients4[gi7][0]*tempx + s_gradients4[gi7][1]*tempy + s_gradients4[gi7][2]*tempz + s_gradients4[gi7][3]*tempw; tempx = xc - x0; - u[1] = gradient4[gi6][0]*tempx + gradient4[gi6][1]*tempy + gradient4[gi6][2]*tempz + gradient4[gi6][3]*tempw; + u[1] = s_gradients4[gi6][0]*tempx + s_gradients4[gi6][1]*tempy + s_gradients4[gi6][2]*tempz + s_gradients4[gi6][3]*tempw; tempy = yc - y0; tempz = zc - z0; tempw = wc - (w0+1); - s[2] = gradient4[gi8][0]*tempx + gradient4[gi8][1]*tempy + gradient4[gi8][2]*tempz + gradient4[gi8][3]*tempw; + s[2] = s_gradients4[gi8][0]*tempx + s_gradients4[gi8][1]*tempy + s_gradients4[gi8][2]*tempz + s_gradients4[gi8][3]*tempw; tempx = xc - (x0+1); - t[2] = gradient4[gi9][0]*tempx + gradient4[gi9][1]*tempy + gradient4[gi9][2]*tempz + gradient4[gi9][3]*tempw; + t[2] = s_gradients4[gi9][0]*tempx + s_gradients4[gi9][1]*tempy + s_gradients4[gi9][2]*tempz + s_gradients4[gi9][3]*tempw; tempy = yc - (y0+1); - v[2] = gradient4[gi11][0]*tempx + gradient4[gi11][1]*tempy + gradient4[gi11][2]*tempz + gradient4[gi11][3]*tempw; + v[2] = s_gradients4[gi11][0]*tempx + s_gradients4[gi11][1]*tempy + s_gradients4[gi11][2]*tempz + s_gradients4[gi11][3]*tempw; tempx = xc - x0; - u[2] = gradient4[gi10][0]*tempx + gradient4[gi10][1]*tempy + gradient4[gi10][2]*tempz + gradient4[gi10][3]*tempw; + u[2] = s_gradients4[gi10][0]*tempx + s_gradients4[gi10][1]*tempy + s_gradients4[gi10][2]*tempz + s_gradients4[gi10][3]*tempw; tempy = yc - y0; tempz = zc - (z0+1); - s[3] = gradient4[gi12][0]*tempx + gradient4[gi12][1]*tempy + gradient4[gi12][2]*tempz + gradient4[gi12][3]*tempw; + s[3] = s_gradients4[gi12][0]*tempx + s_gradients4[gi12][1]*tempy + s_gradients4[gi12][2]*tempz + s_gradients4[gi12][3]*tempw; tempx = xc - (x0+1); - t[3] = gradient4[gi13][0]*tempx + gradient4[gi13][1]*tempy + gradient4[gi13][2]*tempz + gradient4[gi13][3]*tempw; + t[3] = s_gradients4[gi13][0]*tempx + s_gradients4[gi13][1]*tempy + s_gradients4[gi13][2]*tempz + s_gradients4[gi13][3]*tempw; tempy = yc - (y0+1); - v[3] = gradient4[gi15][0]*tempx + gradient4[gi15][1]*tempy + gradient4[gi15][2]*tempz + gradient4[gi15][3]*tempw; + v[3] = s_gradients4[gi15][0]*tempx + s_gradients4[gi15][1]*tempy + s_gradients4[gi15][2]*tempz + s_gradients4[gi15][3]*tempw; tempx = xc - x0; - u[3] = gradient4[gi14][0]*tempx + gradient4[gi14][1]*tempy + gradient4[gi14][2]*tempz + gradient4[gi14][3]*tempw; + u[3] = s_gradients4[gi14][0]*tempx + s_gradients4[gi14][1]*tempy + s_gradients4[gi14][2]*tempz + s_gradients4[gi14][3]*tempw; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp index c93a226d4..c2ce28c3f 100644 --- a/src/Nazara/Noise/Simplex.cpp +++ b/src/Nazara/Noise/Simplex.cpp @@ -10,185 +10,95 @@ namespace Nz { - Simplex::Simplex() : - gradient2{ - {1,1},{-1,1},{1,-1},{-1,-1}, - {1,0},{-1,0},{0,1},{0,-1} - }, - gradient3{ - {1.f,1.f,0.f},{-1.f,1.f,0.f},{1.f,-1.f,0.f},{-1.f,-1.f,0.f}, - {1.f,0.f,1.f},{-1.f,0.f,1.f},{1.f,0.f,-1.f},{-1.f,0.f,-1.f}, - {0.f,1.f,1.f},{0.f,-1.f,1.f},{0.f,1.f,-1.f},{0.f,-1.f,-1.f} - }, - gradient4{ - {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, - {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, - {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, - {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, - {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, - {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, - {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, - {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} - }, - lookupTable4D{ - {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, - {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, - {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, - {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} - }, - SkewCoeff2D (0.5f*(std::sqrt(3.f) - 1.f)), - UnskewCoeff2D((3.f-std::sqrt(3.f))/6.f), - SkewCoeff3D (1/3.f), - UnskewCoeff3D (1/6.f), - SkewCoeff4D ((std::sqrt(5.f) - 1.f)/4.f), - UnskewCoeff4D ((5.f - std::sqrt(5.f))/20.f) + namespace { - + constexpr float s_SkewCoeff2D = 0.5f * (M_SQRT3 - 1.f); + constexpr float s_UnskewCoeff2D = (3.f - M_SQRT3)/6.f; + constexpr float s_SkewCoeff3D = 1.f / 3.f; + constexpr float s_UnskewCoeff3D = 1.f / 6.f; + constexpr float s_SkewCoeff4D = (M_SQRT5 - 1.f)/4.f; + constexpr float s_UnskewCoeff4D = (5.f - M_SQRT5)/20.f; } - Simplex::Simplex(unsigned int seed) : Simplex() + Simplex::Simplex(unsigned int seed) { SetSeed(seed); Shuffle(); } - float Simplex::Get(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float scale) const { - switch(coordinates.size()) + float xc = x * scale; + float yc = y * scale; + + float sum = (xc + yc) * s_SkewCoeff2D; + Vector2i skewedCubeOrigin(fastfloor(xc + sum), fastfloor(yc + sum)); + + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * s_UnskewCoeff2D; + Vector2f unskewedCubeOrigin(skewedCubeOrigin.x - sum, skewedCubeOrigin.y - sum); + + Vector2f unskewedDistToOrigin(xc - unskewedCubeOrigin.x, yc - unskewedCubeOrigin.y); + + Vector2f off1; + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) + off1.Set(1, 0); + else + off1.Set(0, 1); + + std::array d; + d[0] = -unskewedDistToOrigin; + d[1] = d[0] + off1 - Vector2f(s_UnskewCoeff2D); + d[2] = d[0] + Vector2f(1.f - 2.f * s_UnskewCoeff2D); + + Vector2i offset(skewedCubeOrigin.x & 255, skewedCubeOrigin.y & 255); + std::array gi = { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); + m_permutations[offset.x + m_permutations[offset.y]] & 7, + m_permutations[offset.x + off1.x + m_permutations[offset.y + off1.y]] & 7, + m_permutations[offset.x + 1 + m_permutations[offset.y + 1]] & 7 + }; + + float n = 0.f; + for (unsigned int i = 0; i < 3; ++i) + { + float c = 0.5f - d[i].x * d[i].x - d[i].y *d[i].y; + if (c > 0.f) + n += c * c * c * c * (s_gradients2[gi[i]].x * d[i].x + s_gradients2[gi[i]].y * d[i].y); } + + return n*70.f; } - float Simplex::_2D(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float z, float scale) const { - thread_local float xc,yc; - thread_local int ii,jj; - thread_local int gi0,gi1,gi2; - thread_local int skewedCubeOriginx,skewedCubeOriginy; - thread_local int off1x,off1y; - thread_local float n1,n2,n3; - thread_local float c1,c2,c3; - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy; - thread_local float d1x,d1y; - thread_local float d2x,d2y; - thread_local float d3x,d3y; + float xc, yc, zc; + int ii,jj,kk; + int gi0,gi1,gi2,gi3; + int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz; - std::initializer_list::const_iterator it = coordinates.begin(); + int off1x,off1y,off1z; + int off2x,off2y,off2z; + float n1,n2,n3,n4; + float c1,c2,c3,c4; - xc = *(it ) * scale; - yc = *(++it) * scale; - - sum = (xc + yc) * SkewCoeff2D; - skewedCubeOriginx = fastfloor(xc + sum); - skewedCubeOriginy = fastfloor(yc + sum); - - sum = (skewedCubeOriginx + skewedCubeOriginy) * UnskewCoeff2D; - unskewedCubeOriginx = skewedCubeOriginx - sum; - unskewedCubeOriginy = skewedCubeOriginy - sum; - - unskewedDistToOriginx = xc - unskewedCubeOriginx;// Difference with 3d and 4d - unskewedDistToOriginy = yc - unskewedCubeOriginy; - - if(unskewedDistToOriginx > unskewedDistToOriginy) - { - off1x = 1; - off1y = 0; - } - else - { - off1x = 0; - off1y = 1; - } - - d1x = - unskewedDistToOriginx; - d1y = - unskewedDistToOriginy; - - d2x = d1x + off1x - UnskewCoeff2D; - d2y = d1y + off1y - UnskewCoeff2D; - - d3x = d1x + 1.f - 2.f * UnskewCoeff2D; - d3y = d1y + 1.f - 2.f * UnskewCoeff2D; - - ii = skewedCubeOriginx & 255; - jj = skewedCubeOriginy & 255; - - gi0 = perm[ii + perm[jj ]] & 7; - gi1 = perm[ii + off1x + perm[jj + off1y ]] & 7; - gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; - - c1 = 0.5f - d1x * d1x - d1y * d1y; - c2 = 0.5f - d2x * d2x - d2y * d2y; - c3 = 0.5f - d3x * d3x - d3y * d3y; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1x + gradient2[gi0][1] * d1y); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2x + gradient2[gi1][1] * d2y); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3x + gradient2[gi2][1] * d3y); - - return (n1+n2+n3)*70.f; - } - - float Simplex::_3D(std::initializer_list coordinates, float scale) const - { - thread_local float xc, yc, zc; - thread_local float x,y,z; - thread_local int ii,jj,kk; - thread_local int gi0,gi1,gi2,gi3; - thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz; - - thread_local int off1x,off1y,off1z; - thread_local int off2x,off2y,off2z; - thread_local float n1,n2,n3,n4; - thread_local float c1,c2,c3,c4; - - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz; - thread_local float d1x,d1y,d1z; - thread_local float d2x,d2y,d2z; - thread_local float d3x,d3y,d3z; - thread_local float d4x,d4y,d4z; - - std::initializer_list::const_iterator it = coordinates.begin(); - - x = *(it ); - y = *(++it); - z = *(++it); + float sum; + float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz; + float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz; + float d1x,d1y,d1z; + float d2x,d2y,d2z; + float d3x,d3y,d3z; + float d4x,d4y,d4z; xc = x * scale; yc = y * scale; zc = z * scale; - sum = (xc + yc + zc) * SkewCoeff3D; + sum = (xc + yc + zc) * s_SkewCoeff3D; skewedCubeOriginx = fastfloor(xc + sum); skewedCubeOriginy = fastfloor(yc + sum); skewedCubeOriginz = fastfloor(zc + sum); - sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * UnskewCoeff3D; + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * s_UnskewCoeff3D; unskewedCubeOriginx = skewedCubeOriginx - sum; unskewedCubeOriginy = skewedCubeOriginy - sum; unskewedCubeOriginz = skewedCubeOriginz - sum; @@ -262,26 +172,26 @@ namespace Nz d1y = unskewedDistToOriginy; d1z = unskewedDistToOriginz; - d2x = d1x - off1x + UnskewCoeff3D; - d2y = d1y - off1y + UnskewCoeff3D; - d2z = d1z - off1z + UnskewCoeff3D; + d2x = d1x - off1x + s_UnskewCoeff3D; + d2y = d1y - off1y + s_UnskewCoeff3D; + d2z = d1z - off1z + s_UnskewCoeff3D; - d3x = d1x - off2x + 2.f*UnskewCoeff3D; - d3y = d1y - off2y + 2.f*UnskewCoeff3D; - d3z = d1z - off2z + 2.f*UnskewCoeff3D; + d3x = d1x - off2x + 2.f*s_UnskewCoeff3D; + d3y = d1y - off2y + 2.f*s_UnskewCoeff3D; + d3z = d1z - off2z + 2.f*s_UnskewCoeff3D; - d4x = d1x - 1.f + 3.f*UnskewCoeff3D; - d4y = d1y - 1.f + 3.f*UnskewCoeff3D; - d4z = d1z - 1.f + 3.f*UnskewCoeff3D; + d4x = d1x - 1.f + 3.f*s_UnskewCoeff3D; + d4y = d1y - 1.f + 3.f*s_UnskewCoeff3D; + d4z = d1z - 1.f + 3.f*s_UnskewCoeff3D; ii = skewedCubeOriginx & 255; jj = skewedCubeOriginy & 255; kk = skewedCubeOriginz & 255; - gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; - gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z ]]] % 12; - gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z ]]] % 12; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk ]]] % 12; + gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z ]]] % 12; + gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z ]]] % 12; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 ]]] % 12; c1 = 0.6f - d1x * d1x - d1y * d1y - d1z * d1z; c2 = 0.6f - d2x * d2x - d2y * d2y - d2z * d2z; @@ -291,69 +201,75 @@ namespace Nz if(c1 < 0) n1 = 0; else - n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1x + gradient3[gi0][1] * d1y + gradient3[gi0][2] * d1z); + n1 = c1*c1*c1*c1*(s_gradients3[gi0][0] * d1x + s_gradients3[gi0][1] * d1y + s_gradients3[gi0][2] * d1z); if(c2 < 0) n2 = 0; else - n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2x + gradient3[gi1][1] * d2y + gradient3[gi1][2] * d2z); + n2 = c2*c2*c2*c2*(s_gradients3[gi1][0] * d2x + s_gradients3[gi1][1] * d2y + s_gradients3[gi1][2] * d2z); if(c3 < 0) n3 = 0; else - n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3x + gradient3[gi2][1] * d3y + gradient3[gi2][2] * d3z); + n3 = c3*c3*c3*c3*(s_gradients3[gi2][0] * d3x + s_gradients3[gi2][1] * d3y + s_gradients3[gi2][2] * d3z); if(c4 < 0) n4 = 0; else - n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4x + gradient3[gi3][1] * d4y + gradient3[gi3][2] * d4z); + n4 = c4*c4*c4*c4*(s_gradients3[gi3][0] * d4x + s_gradients3[gi3][1] * d4y + s_gradients3[gi3][2] * d4z); return (n1+n2+n3+n4)*32; } - float Simplex::_4D(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float z, float w, float scale) const { - thread_local float xc,yc,zc,wc; - thread_local float x,y,z,w; - thread_local int ii,jj,kk,ll; - thread_local int gi0,gi1,gi2,gi3,gi4; - thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw; + static std::array lookupTable = + { + { + {0,1,2,3}, {0,1,3,2}, {0,0,0,0}, {0,2,3,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,2,3,0}, + {0,2,1,3}, {0,0,0,0}, {0,3,1,2}, {0,3,2,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,3,2,0}, + {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, + {1,2,0,3}, {0,0,0,0}, {1,3,0,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,3,0,1}, {2,3,1,0}, + {1,0,2,3}, {1,0,3,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,0,3,1}, {0,0,0,0}, {2,1,3,0}, + {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, + {2,0,1,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,0,1,2}, {3,0,2,1}, {0,0,0,0}, {3,1,2,0}, + {2,1,0,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,1,0,2}, {0,0,0,0}, {3,2,0,1}, {3,2,1,0} + } + }; - thread_local int off1x,off1y,off1z,off1w; - thread_local int off2x,off2y,off2z,off2w; - thread_local int off3x,off3y,off3z,off3w; + float xc,yc,zc,wc; + int ii,jj,kk,ll; + int gi0,gi1,gi2,gi3,gi4; + int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw; - thread_local int c; - thread_local float n1,n2,n3,n4,n5; - thread_local float c1,c2,c3,c4,c5,c6; + int off1x,off1y,off1z,off1w; + int off2x,off2y,off2z,off2w; + int off3x,off3y,off3z,off3w; - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw; - thread_local float d1x,d2x,d3x,d4x,d5x; - thread_local float d1y,d2y,d3y,d4y,d5y; - thread_local float d1z,d2z,d3z,d4z,d5z; - thread_local float d1w,d2w,d3w,d4w,d5w; + int c; + float n1,n2,n3,n4,n5; + float c1,c2,c3,c4,c5,c6; - std::initializer_list::const_iterator it = coordinates.begin(); - - x = *(it ); - y = *(++it); - z = *(++it); - w = *(++it); + float sum; + float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; + float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw; + float d1x,d2x,d3x,d4x,d5x; + float d1y,d2y,d3y,d4y,d5y; + float d1z,d2z,d3z,d4z,d5z; + float d1w,d2w,d3w,d4w,d5w; xc = x * scale; yc = y * scale; zc = z * scale; wc = w * scale; - sum = (xc + yc + zc + wc) * SkewCoeff4D; + sum = (xc + yc + zc + wc) * s_SkewCoeff4D; skewedCubeOriginx = fastfloor(xc + sum); skewedCubeOriginy = fastfloor(yc + sum); skewedCubeOriginz = fastfloor(zc + sum); skewedCubeOriginw = fastfloor(wc + sum); - sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * UnskewCoeff4D; + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * s_UnskewCoeff4D; unskewedCubeOriginx = skewedCubeOriginx - sum; unskewedCubeOriginy = skewedCubeOriginy - sum; unskewedCubeOriginz = skewedCubeOriginz - sum; @@ -372,56 +288,56 @@ namespace Nz c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0; c = c1 + c2 + c3 + c4 + c5 + c6; - off1x = lookupTable4D[c][0] >= 3 ? 1 : 0; - off1y = lookupTable4D[c][1] >= 3 ? 1 : 0; - off1z = lookupTable4D[c][2] >= 3 ? 1 : 0; - off1w = lookupTable4D[c][3] >= 3 ? 1 : 0; + off1x = lookupTable[c][0] >= 3 ? 1 : 0; + off1y = lookupTable[c][1] >= 3 ? 1 : 0; + off1z = lookupTable[c][2] >= 3 ? 1 : 0; + off1w = lookupTable[c][3] >= 3 ? 1 : 0; - off2x = lookupTable4D[c][0] >= 2 ? 1 : 0; - off2y = lookupTable4D[c][1] >= 2 ? 1 : 0; - off2z = lookupTable4D[c][2] >= 2 ? 1 : 0; - off2w = lookupTable4D[c][3] >= 2 ? 1 : 0; + off2x = lookupTable[c][0] >= 2 ? 1 : 0; + off2y = lookupTable[c][1] >= 2 ? 1 : 0; + off2z = lookupTable[c][2] >= 2 ? 1 : 0; + off2w = lookupTable[c][3] >= 2 ? 1 : 0; - off3x = lookupTable4D[c][0] >= 1 ? 1 : 0; - off3y = lookupTable4D[c][1] >= 1 ? 1 : 0; - off3z = lookupTable4D[c][2] >= 1 ? 1 : 0; - off3w = lookupTable4D[c][3] >= 1 ? 1 : 0; + off3x = lookupTable[c][0] >= 1 ? 1 : 0; + off3y = lookupTable[c][1] >= 1 ? 1 : 0; + off3z = lookupTable[c][2] >= 1 ? 1 : 0; + off3w = lookupTable[c][3] >= 1 ? 1 : 0; d1x = unskewedDistToOriginx; d1y = unskewedDistToOriginy; d1z = unskewedDistToOriginz; d1w = unskewedDistToOriginw; - d2x = d1x - off1x + UnskewCoeff4D; - d2y = d1y - off1y + UnskewCoeff4D; - d2z = d1z - off1z + UnskewCoeff4D; - d2w = d1w - off1w + UnskewCoeff4D; + d2x = d1x - off1x + s_UnskewCoeff4D; + d2y = d1y - off1y + s_UnskewCoeff4D; + d2z = d1z - off1z + s_UnskewCoeff4D; + d2w = d1w - off1w + s_UnskewCoeff4D; - d3x = d1x - off2x + 2.f*UnskewCoeff4D; - d3y = d1y - off2y + 2.f*UnskewCoeff4D; - d3z = d1z - off2z + 2.f*UnskewCoeff4D; - d3w = d1w - off2w + 2.f*UnskewCoeff4D; + d3x = d1x - off2x + 2.f*s_UnskewCoeff4D; + d3y = d1y - off2y + 2.f*s_UnskewCoeff4D; + d3z = d1z - off2z + 2.f*s_UnskewCoeff4D; + d3w = d1w - off2w + 2.f*s_UnskewCoeff4D; - d4x = d1x - off3x + 3.f*UnskewCoeff4D; - d4y = d1y - off3y + 3.f*UnskewCoeff4D; - d4z = d1z - off3z + 3.f*UnskewCoeff4D; - d4w = d1w - off3w + 3.f*UnskewCoeff4D; + d4x = d1x - off3x + 3.f*s_UnskewCoeff4D; + d4y = d1y - off3y + 3.f*s_UnskewCoeff4D; + d4z = d1z - off3z + 3.f*s_UnskewCoeff4D; + d4w = d1w - off3w + 3.f*s_UnskewCoeff4D; - d5x = d1x - 1.f + 4*UnskewCoeff4D; - d5y = d1y - 1.f + 4*UnskewCoeff4D; - d5z = d1z - 1.f + 4*UnskewCoeff4D; - d5w = d1w - 1.f + 4*UnskewCoeff4D; + d5x = d1x - 1.f + 4*s_UnskewCoeff4D; + d5y = d1y - 1.f + 4*s_UnskewCoeff4D; + d5z = d1z - 1.f + 4*s_UnskewCoeff4D; + d5w = d1w - 1.f + 4*s_UnskewCoeff4D; ii = skewedCubeOriginx & 255; jj = skewedCubeOriginy & 255; kk = skewedCubeOriginz & 255; ll = skewedCubeOriginw & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll ]]]] & 31; - gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z + perm[ll + off1w]]]] & 31; - gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z + perm[ll + off2w]]]] & 31; - gi3 = perm[ii + off3x + perm[jj + off3y + perm[kk + off3z + perm[ll + off3w]]]] & 31; - gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1 ]]]] % 32; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll ]]]] & 31; + gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z + m_permutations[ll + off1w]]]] & 31; + gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z + m_permutations[ll + off2w]]]] & 31; + gi3 = m_permutations[ii + off3x + m_permutations[jj + off3y + m_permutations[kk + off3z + m_permutations[ll + off3w]]]] & 31; + gi4 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1 ]]]] % 32; c1 = 0.6f - d1x*d1x - d1y*d1y - d1z*d1z - d1w*d1w; c2 = 0.6f - d2x*d2x - d2y*d2y - d2z*d2z - d2w*d2w; @@ -432,27 +348,27 @@ namespace Nz if(c1 < 0) n1 = 0; else - n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1x + gradient4[gi0][1]*d1y + gradient4[gi0][2]*d1z + gradient4[gi0][3]*d1w); + n1 = c1*c1*c1*c1*(s_gradients4[gi0][0]*d1x + s_gradients4[gi0][1]*d1y + s_gradients4[gi0][2]*d1z + s_gradients4[gi0][3]*d1w); if(c2 < 0) n2 = 0; else - n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2x + gradient4[gi1][1]*d2y + gradient4[gi1][2]*d2z + gradient4[gi1][3]*d2w); + n2 = c2*c2*c2*c2*(s_gradients4[gi1][0]*d2x + s_gradients4[gi1][1]*d2y + s_gradients4[gi1][2]*d2z + s_gradients4[gi1][3]*d2w); if(c3 < 0) n3 = 0; else - n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3x + gradient4[gi2][1]*d3y + gradient4[gi2][2]*d3z + gradient4[gi2][3]*d3w); + n3 = c3*c3*c3*c3*(s_gradients4[gi2][0]*d3x + s_gradients4[gi2][1]*d3y + s_gradients4[gi2][2]*d3z + s_gradients4[gi2][3]*d3w); if(c4 < 0) n4 = 0; else - n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4x + gradient4[gi3][1]*d4y + gradient4[gi3][2]*d4z + gradient4[gi3][3]*d4w); + n4 = c4*c4*c4*c4*(s_gradients4[gi3][0]*d4x + s_gradients4[gi3][1]*d4y + s_gradients4[gi3][2]*d4z + s_gradients4[gi3][3]*d4w); if(c5 < 0) n5 = 0; else - n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5x + gradient4[gi4][1]*d5y + gradient4[gi4][2]*d5z + gradient4[gi4][3]*d5w); + n5 = c5*c5*c5*c5*(s_gradients4[gi4][0]*d5x + s_gradients4[gi4][1]*d5y + s_gradients4[gi4][2]*d5z + s_gradients4[gi4][3]*d5w); return (n1+n2+n3+n4+n5)*27.f; } diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp index 603820706..9d262f6b1 100644 --- a/src/Nazara/Noise/Worley.cpp +++ b/src/Nazara/Noise/Worley.cpp @@ -10,56 +10,38 @@ namespace Nz { - Worley::Worley() : - scales{ - 1.f / std::sqrt(2), - 0.5f / std::sqrt(2), - 0.5f / std::sqrt(2), - 0.5f / std::sqrt(2) - } + namespace + { + static constexpr std::array m_functionScales = + { + 1.f / M_SQRT2, + 0.5f / M_SQRT2, + 0.5f / M_SQRT2, + 0.5f / M_SQRT2 + }; + } + Worley::Worley() : + m_function(WorleyFunction_F1) { - function = WorleyFunction_F1; } - Worley::Worley(unsigned int seed) : Worley() + Worley::Worley(unsigned int seed) : + Worley() { SetSeed(seed); Shuffle(); } - void Worley::Set(WorleyFunction func) - { - function = func; - } - - float Worley::Get(std::initializer_list coordinates, float scale) const - { - switch(coordinates.size()) - { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); - } - } - - float Worley::_2D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float scale) const { std::map featurePoints; - std::map::iterator it; float xc, yc; int x0, y0; float fractx, fracty; - std::initializer_list::const_iterator c = coordinates.begin(); - - xc = *(c ) * scale; - yc = *(++c) * scale; + xc = x * scale; + yc = y * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -69,83 +51,83 @@ namespace Nz featurePoints.clear(); - _SquareTest(x0,y0,xc,yc,featurePoints); + SquareTest(x0,y0,xc,yc,featurePoints); - it = featurePoints.begin(); - std::advance(it,function); + auto it = featurePoints.begin(); + std::advance(it, m_function); if(fractx < it->first) - _SquareTest(x0 - 1,y0,xc,yc,featurePoints); + SquareTest(x0 - 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); if(1.f - fractx < it->first) - _SquareTest(x0 + 1,y0,xc,yc,featurePoints); + SquareTest(x0 + 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); if(fracty < it->first) - _SquareTest(x0,y0 - 1,xc,yc,featurePoints); + SquareTest(x0,y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fracty < it->first) - _SquareTest(x0,y0 + 1,xc,yc,featurePoints); + if (1.f - fracty < it->first) + SquareTest(x0,y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(fractx < it->first && - fracty < it->first) - _SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); + if (fractx < it->first && fracty < it->first) + SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fractx < it->first && - fracty < it->first) - _SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); + if (1.f - fractx < it->first && fracty < it->first) + SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(fractx < it->first && - 1.f - fracty < it->first) - _SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); + if (fractx < it->first && 1.f - fracty < it->first) + SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fractx < it->first && - 1.f - fracty < it->first) - _SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); + if(1.f - fractx < it->first && 1.f - fracty < it->first) + SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - return it->first * scales[function]; + return it->first * m_functionScales[m_function]; } - float Worley::_3D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float z, float scale) const { throw std::runtime_error("Worley 3D not available yet."); } - float Worley::_4D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float z, float w, float scale) const { throw std::runtime_error("Worley 4D not available yet."); } + void Worley::Set(WorleyFunction func) + { + m_function = func; + } - void Worley::_SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const + void Worley::SquareTest(int xi, int yi, float x, float y, std::map& featurePoints) const { int ii = xi & 255; int jj = yi & 255; - int seed = perm[ii + perm[jj]]; + int seed = m_permutations[ii + m_permutations[jj]]; //On initialise notre rng avec seed std::minstd_rand0 randomNumberGenerator(seed); From e52656bed8e359ed61ae27d5306b9bc7b65e21c9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 19 Jun 2016 16:09:22 +0200 Subject: [PATCH 142/224] Noise: Fix errors/warnings Former-commit-id: 37e946067a3324f102aabcad1f43bfdd775841a5 [formerly 04d3406dba7c84118888ba2cfdbf364f93860567] Former-commit-id: 53316c61e484c1968ddcfb7c75acc57956a054f4 --- src/Nazara/Noise/NoiseBase.cpp | 1 + src/Nazara/Noise/Perlin.cpp | 4 ---- src/Nazara/Noise/Simplex.cpp | 28 ++++++++++++------------- src/Nazara/Noise/Worley.cpp | 38 ++++++++++++++++++---------------- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index fa5a2c92f..1dc74595a 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp index e6440eb3d..a400972ff 100644 --- a/src/Nazara/Noise/Perlin.cpp +++ b/src/Nazara/Noise/Perlin.cpp @@ -76,9 +76,6 @@ namespace Nz float Li1,Li2,Li3,Li4,Li5,Li6; float s[2],t[2],u[2],v[2]; float Cx,Cy,Cz; - float nx,ny,nz; - - float tmp; float tempx,tempy,tempz; xc = x * scale; @@ -157,7 +154,6 @@ namespace Nz float s[4],t[4],u[4],v[4]; float Cx,Cy,Cz,Cw; - float tmp; float tempx,tempy,tempz,tempw; xc = x * scale; diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp index c2ce28c3f..8d4748bff 100644 --- a/src/Nazara/Noise/Simplex.cpp +++ b/src/Nazara/Noise/Simplex.cpp @@ -12,12 +12,12 @@ namespace Nz { namespace { - constexpr float s_SkewCoeff2D = 0.5f * (M_SQRT3 - 1.f); - constexpr float s_UnskewCoeff2D = (3.f - M_SQRT3)/6.f; + constexpr float s_SkewCoeff2D = 0.5f * (float(M_SQRT3) - 1.f); + constexpr float s_UnskewCoeff2D = (3.f - float(M_SQRT3))/6.f; constexpr float s_SkewCoeff3D = 1.f / 3.f; constexpr float s_UnskewCoeff3D = 1.f / 6.f; - constexpr float s_SkewCoeff4D = (M_SQRT5 - 1.f)/4.f; - constexpr float s_UnskewCoeff4D = (5.f - M_SQRT5)/20.f; + constexpr float s_SkewCoeff4D = (float(M_SQRT5) - 1.f)/4.f; + constexpr float s_UnskewCoeff4D = (5.f - float(M_SQRT5))/20.f; } Simplex::Simplex(unsigned int seed) @@ -39,7 +39,7 @@ namespace Nz Vector2f unskewedDistToOrigin(xc - unskewedCubeOrigin.x, yc - unskewedCubeOrigin.y); - Vector2f off1; + Vector2ui off1; if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) off1.Set(1, 0); else @@ -47,7 +47,7 @@ namespace Nz std::array d; d[0] = -unskewedDistToOrigin; - d[1] = d[0] + off1 - Vector2f(s_UnskewCoeff2D); + d[1] = d[0] + Vector2f(off1) - Vector2f(s_UnskewCoeff2D); d[2] = d[0] + Vector2f(1.f - 2.f * s_UnskewCoeff2D); Vector2i offset(skewedCubeOrigin.x & 255, skewedCubeOrigin.y & 255); @@ -248,7 +248,7 @@ namespace Nz int c; float n1,n2,n3,n4,n5; - float c1,c2,c3,c4,c5,c6; + float c1,c2,c3,c4,c5; float sum; float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; @@ -280,13 +280,13 @@ namespace Nz unskewedDistToOriginz = zc - unskewedCubeOriginz; unskewedDistToOriginw = wc - unskewedCubeOriginw; - c1 = (unskewedDistToOriginx > unskewedDistToOriginy) ? 32 : 0; - c2 = (unskewedDistToOriginx > unskewedDistToOriginz) ? 16 : 0; - c3 = (unskewedDistToOriginy > unskewedDistToOriginz) ? 8 : 0; - c4 = (unskewedDistToOriginx > unskewedDistToOriginw) ? 4 : 0; - c5 = (unskewedDistToOriginy > unskewedDistToOriginw) ? 2 : 0; - c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0; - c = c1 + c2 + c3 + c4 + c5 + c6; + c = 0; + c += (unskewedDistToOriginx > unskewedDistToOriginy) ? 32 : 0; + c += (unskewedDistToOriginx > unskewedDistToOriginz) ? 16 : 0; + c += (unskewedDistToOriginy > unskewedDistToOriginz) ? 8 : 0; + c += (unskewedDistToOriginx > unskewedDistToOriginw) ? 4 : 0; + c += (unskewedDistToOriginy > unskewedDistToOriginw) ? 2 : 0; + c += (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0; off1x = lookupTable[c][0] >= 3 ? 1 : 0; off1y = lookupTable[c][1] >= 3 ? 1 : 0; diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp index 9d262f6b1..cc98fa378 100644 --- a/src/Nazara/Noise/Worley.cpp +++ b/src/Nazara/Noise/Worley.cpp @@ -14,10 +14,10 @@ namespace Nz { static constexpr std::array m_functionScales = { - 1.f / M_SQRT2, - 0.5f / M_SQRT2, - 0.5f / M_SQRT2, - 0.5f / M_SQRT2 + 1.f / float(M_SQRT2), + 0.5f / float(M_SQRT2), + 0.5f / float(M_SQRT2), + 0.5f / float(M_SQRT2) }; } Worley::Worley() : @@ -53,58 +53,60 @@ namespace Nz SquareTest(x0,y0,xc,yc,featurePoints); + std::size_t functionIndex = static_cast(m_function); + auto it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if(fractx < it->first) SquareTest(x0 - 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if(1.f - fractx < it->first) SquareTest(x0 + 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if(fracty < it->first) SquareTest(x0,y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if (1.f - fracty < it->first) SquareTest(x0,y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if (fractx < it->first && fracty < it->first) SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if (1.f - fractx < it->first && fracty < it->first) SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if (fractx < it->first && 1.f - fracty < it->first) SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); if(1.f - fractx < it->first && 1.f - fracty < it->first) SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it, m_function); + std::advance(it, functionIndex); - return it->first * m_functionScales[m_function]; + return it->first * m_functionScales[functionIndex]; } float Worley::Get(float x, float y, float z, float scale) const @@ -127,16 +129,16 @@ namespace Nz int ii = xi & 255; int jj = yi & 255; - int seed = m_permutations[ii + m_permutations[jj]]; + std::size_t seed = m_permutations[ii + m_permutations[jj]]; //On initialise notre rng avec seed - std::minstd_rand0 randomNumberGenerator(seed); + std::minstd_rand0 randomNumberGenerator(static_cast(seed)); //On prend un nombre de points à déterminer dans le cube, compris entre 1 et 8 - unsigned int m = (seed & 7) + 1; + std::size_t m = (seed & 7) + 1; //On calcule les emplacements des différents points - for(unsigned int i(0) ; i < m ; ++i) + for(std::size_t i(0) ; i < m; ++i) { Nz::Vector2f featurePoint; featurePoint.x = (randomNumberGenerator() & 1023) / 1023.f + static_cast(xi); From df4f11681a83919dab2e71d3fdf13ef22955e708 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Jun 2016 09:05:22 +0200 Subject: [PATCH 143/224] Examples/FirstScene: Add console and Ndk::Application Former-commit-id: b30ca2913565a794178eb9776861ec08de96d68a [formerly ebcbf5f3c8196e2023312be7e24ccbeb06c272c8] Former-commit-id: 0ea97849de843faee78c5702f273a911f08c115f --- examples/FirstScene/main.cpp | 212 +++++++++++++++++++++++------------ 1 file changed, 142 insertions(+), 70 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 385b054e0..07e26cd1c 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -1,25 +1,27 @@ /* -** FirstScene - Première scène graphique -** Prérequis: Aucun -** Utilisation du module utilitaire et graphique -** Présente: -** - Création et gestion d'une fenêtre (Traitement des évènements clavier/souris) -** - Gestion du clavier (Récupération de l'état d'une touche) -** - Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage) -** - Éclairage directionnel -** - Gestion d'une caméra free-fly (Avec déplacement fluide) -** - Gestion basique d'une horloge +* FirstScene - Première scène graphique +* Prérequis: Aucun +* Utilisation du module utilitaire et graphique +** Présente : + * -Création et gestion d'une fenêtre (Traitement des évènements clavier/souris) + * -Gestion du clavier(Récupération de l'état d'une touche) + * -Des outils pour afficher une scène basique via le chargement d'un modèle (et son affichage) + * -Éclairage directionnel + * -Gestion d'une caméra free-fly (Avec déplacement fluide) + * -Gestion basique d'une horloge + * -Console */ #include // Horloges +#include // Module de scripting #include // Module graphique #include // Module de rendu #include // Module utilitaire -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include #include @@ -29,26 +31,15 @@ Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& ta int main() { - // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, - // les composants, systèmes, etc. - // NzInitializer est une classe RAII appelant Initialize dans son constructeur et Uninitialize dans son destructeur. - // Autrement dit, une fois ceci fait nous n'avons plus à nous soucier de la libération du moteur. - Nz::Initializer nazara; - if (!nazara) - { - // Une erreur s'est produite dans l'initialisation d'un des modules - std::cout << "Failed to initialize Nazara, see NazaraLog.log for further informations" << std::endl; - std::getchar(); // On laise le temps de voir l'erreur - - return EXIT_FAILURE; - } + // Ndk::Application est une classe s'occupant de l'initialisation du moteur ainsi que de la gestion de beaucoup de choses + Ndk::Application application; // Nazara étant initialisé, nous pouvons créer le monde pour contenir notre scène. // Dans un ECS, le monde représente bien ce que son nom indique, c'est l'ensemble de ce qui existe au niveau de l'application. // Il contient les systèmes et les entités, ces dernières contiennent les composants. // Il est possible d'utiliser plusieurs mondes au sein d'une même application, par exemple pour gérer un mélange de 2D et de 3D, // mais nous verrons cela dans un prochain exemple. - Ndk::World world; + Ndk::WorldHandle world = application.AddWorld().CreateHandle(); // Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base. @@ -73,7 +64,7 @@ int main() Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture)); // Accédons maintenant au système de rendu faisant partie du monde - Ndk::RenderSystem& renderSystem = world.GetSystem(); // Une assertion valide la précondition "le système doit faire partie du monde" + Ndk::RenderSystem& renderSystem = world->GetSystem(); // Une assertion valide la précondition "le système doit faire partie du monde" // Nous assignons ensuite notre skybox comme "fond par défaut" du système // La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu, @@ -146,7 +137,7 @@ int main() // Bien, nous avons un modèle valide, mais celui-ci ne consiste qu'en des informations de rendu, de matériaux et de textures. // Commençons donc par créer une entité vide, cela se fait en demandant au monde de générer une nouvelle entité. - Ndk::EntityHandle spaceship = world.CreateEntity(); + Ndk::EntityHandle spaceship = world->CreateEntity(); // Note: Nous ne récupérons pas l'entité directement mais un "handle" vers elle, ce dernier est un pointeur intelligent non-propriétaire. // Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison. @@ -159,6 +150,7 @@ int main() // Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient, // nous n'avons pas besoin d'agir sur le composant créé. spaceship->AddComponent(); + //spaceship->AddComponent().linearVelocity.Set(-1.f, 0.f, 0.f); // Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible // Nous lui ajoutons donc un GraphicsComponent @@ -178,7 +170,7 @@ int main() // Nous créons donc une seconde entité // Note: La création d'entité est une opération légère au sein du moteur, mais plus vous aurez d'entités et plus le processeur devra travailler. - Ndk::EntityHandle camera = world.CreateEntity(); + Ndk::EntityHandle camera = world->CreateEntity(); // Notre caméra a elle aussi besoin d'être positionnée dans la scène Ndk::NodeComponent& cameraNode = camera->AddComponent(); @@ -188,6 +180,9 @@ int main() // Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent Ndk::CameraComponent& cameraComp = camera->AddComponent(); + // Ajoutons un composant écouteur, si nous venions à avoir du son + camera->AddComponent(); + // Et on n'oublie pas de définir les plans délimitant le champs de vision // (Seul ce qui se trouvera entre les deux plans sera rendu) @@ -208,7 +203,7 @@ int main() // Nous allons créer une lumière directionnelle pour représenter la nébuleuse de notre skybox // Encore une fois, nous créons notre entité - Ndk::EntityHandle nebulaLight = world.CreateEntity(); + Ndk::EntityHandle nebulaLight = world->CreateEntity(); // Lui ajoutons une position dans la scène Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent(); @@ -246,7 +241,7 @@ int main() Nz::RenderTargetParameters parameters; parameters.antialiasingLevel = 4; - Nz::RenderWindow window(mode, windowTitle, style, parameters); + Nz::RenderWindow& window = application.AddWindow(mode, windowTitle, style, parameters); if (!window.IsValid()) { std::cout << "Failed to create render window" << std::endl; @@ -272,8 +267,70 @@ int main() bool smoothMovement = true; Nz::Vector3f targetPos = cameraNode.GetPosition(); - // Début de la boucle de rendu du programme - while (window.IsOpen()) + // Pour ajouter une console à notre application, nous avons besoin d'un monde 2D pour gérer ces rendus + Ndk::WorldHandle world2D = application.AddWorld().CreateHandle(); + world2D->GetSystem().SetDefaultBackground(nullptr); + world2D->GetSystem().SetGlobalUp(Nz::Vector3f::Down()); + + // Nous ajoutons une caméra comme précédement + Ndk::EntityHandle viewEntity = world2D->CreateEntity(); + viewEntity->AddComponent(); + + // À la différence que celui-ci effectuera une projection orthogonale + Ndk::CameraComponent& viewer = viewEntity->AddComponent(); + viewer.SetTarget(&window); + viewer.SetProjectionType(Nz::ProjectionType_Orthogonal); + + // Nous créons un environnement Lua pour gérer nos scripts + Nz::LuaInstance lua; + + // Faisons en sorte d'enregistrer les classes du moteur dans cet environnement + Ndk::LuaAPI::RegisterClasses(lua); + + // Ensuite nous créons la console en elle-même + Ndk::Console console(*world2D, Nz::Vector2f(window.GetWidth(), window.GetHeight() / 4), lua); + + // Nous redirigeons les logs vers cette console + Nz::Log::OnLogWriteType::ConnectionGuard logGuard = Nz::Log::OnLogWrite.Connect([&console] (const Nz::String& str) + { + console.AddLine(str); + }); + + // Nous réécrivons la fonction "print" du Lua pour la rediriger vers la console + lua.PushFunction([&console] (Nz::LuaInstance& instance) + { + Nz::StringStream stream; + + unsigned int argCount = instance.GetStackTop(); + instance.GetGlobal("tostring"); + for (unsigned int i = 1; i <= argCount; ++i) + { + instance.PushValue(-1); // ToString + instance.PushValue(i); // Arg + instance.Call(1, 1); + + std::size_t length; + const char* str = instance.CheckString(-1, &length); + if (i > 1) + stream << '\t'; + + stream << Nz::String(str, length); + instance.Pop(1); + } + + console.AddLine(stream); + return 0; + }); + lua.SetGlobal("print"); + + // Définissons quelques variables de base + lua.PushGlobal("Application", Ndk::Application::Instance()); + lua.PushGlobal("Console", console.CreateHandle()); + lua.PushGlobal("Spaceship", spaceship->CreateHandle()); + lua.PushGlobal("World", world->CreateHandle()); + + // Début de la boucle de rendu du programme (s'occupant par exemple de mettre à jour le monde) + while (application.Run()) { // Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre) Nz::WindowEvent event; @@ -283,6 +340,9 @@ int main() { case Nz::WindowEventType_MouseMoved: // La souris a bougé { + if (console.IsVisible()) + break; + // Gestion de la caméra free-fly (Rotation) float sensitivity = 0.3f; // Sensibilité de la souris @@ -297,15 +357,18 @@ int main() // Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre // Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved - Nz::Mouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); + Nz::Mouse::SetPosition(window.GetWidth() / 2, window.GetHeight() / 2, window); break; } case Nz::WindowEventType_Quit: // L'utilisateur a cliqué sur la croix, ou l'OS veut terminer notre programme - window.Close(); // On demande la fermeture de la fenêtre (Qui aura lieu au prochain tour de boucle) + application.Quit(); break; case Nz::WindowEventType_KeyPressed: // Une touche a été pressée ! + if (console.IsVisible()) + console.SendEvent(event); + if (event.key.code == Nz::Keyboard::Key::Escape) window.Close(); else if (event.key.code == Nz::Keyboard::F1) @@ -318,6 +381,19 @@ int main() else smoothMovement = true; } + else if (event.key.code == Nz::Keyboard::F9) + console.Show(!console.IsVisible()); + break; + + case Nz::WindowEventType_TextEntered: + { + if (console.IsVisible()) + console.SendCharacter(event.text.character); + break; + } + + case Nz::WindowEventType_Resized: + console.SetSize({float(event.size.width), event.size.height / 4.f}); break; default: @@ -337,52 +413,48 @@ int main() { // Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté float elapsedTime = updateAccumulator / 1000000.f; - std::cout << elapsedTime << std::endl; // Vitesse de déplacement de la caméra float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde - // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) - cameraSpeed *= 2.f; + if (!console.IsVisible()) + { + // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) + cameraSpeed *= 2.f; - // Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser - // les directions locales de la caméra + // Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser + // les directions locales de la caméra - // Si la flèche du haut ou la touche Z (vive ZQSD) est pressée, on avance - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) - targetPos += cameraNode.GetForward() * cameraSpeed; + // Si la flèche du haut ou la touche Z (vive ZQSD) est pressée, on avance + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) + targetPos += cameraNode.GetForward() * cameraSpeed; - // Si la flèche du bas ou la touche S est pressée, on recule - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) - targetPos += cameraNode.GetBackward() * cameraSpeed; + // Si la flèche du bas ou la touche S est pressée, on recule + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) + targetPos += cameraNode.GetBackward() * cameraSpeed; - // Etc... - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q)) - targetPos += cameraNode.GetLeft() * cameraSpeed; + // Etc... + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q)) + targetPos += cameraNode.GetLeft() * cameraSpeed; - // Etc... - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) - targetPos += cameraNode.GetRight() * cameraSpeed; + // Etc... + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) + targetPos += cameraNode.GetRight() * cameraSpeed; - // Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation) - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) - targetPos += Nz::Vector3f::Up() * cameraSpeed; + // Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation) + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) + targetPos += Nz::Vector3f::Up() * cameraSpeed; - // Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc... - if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl)) - targetPos += Nz::Vector3f::Down() * cameraSpeed; + // Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc... + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl)) + targetPos += Nz::Vector3f::Down() * cameraSpeed; + } cameraNode.SetPosition((smoothMovement) ? DampedString(cameraNode.GetPosition(), targetPos, elapsedTime) : targetPos, Nz::CoordSys_Global); - updateAccumulator = 0; } - // Et maintenant pour rendre la scène, il nous suffit de mettre à jour le monde en lui envoyant le temps depuis la dernière mise à jour - // Note: La plupart des systèmes, à l'exception de celui de rendu, ont une fréquence de mise à jour fixe (modifiable) - // Il n'est donc pas nécessaire de limiter vous-même les mises à jour du monde - world.Update(elapsedUS / 1000000.f); - // Après avoir dessiné sur la fenêtre, il faut s'assurer qu'elle affiche cela // Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering) window.Display(); @@ -410,7 +482,7 @@ int main() } } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength) @@ -430,7 +502,7 @@ Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& ta if (Nz::NumberEquals(displacementLength, 0.f)) return currentPos; - float invDisplacementLength = 1.f/displacementLength; + float invDisplacementLength = 1.f / displacementLength; const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length From 84039cd78ad8be4423a49d32b8c8e4830841b315 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Jun 2016 13:10:09 +0200 Subject: [PATCH 144/224] Core/ObjectRef: Add comparison operators Former-commit-id: 64e1994a16df92191d22dd3d6cd9b249707c74f7 [formerly b77b0afef5c0b720b5660893adb3246c97e55797] Former-commit-id: b9dbc04e30c52f8414637b89b52028103022bead --- include/Nazara/Core/ObjectRef.hpp | 29 +++- include/Nazara/Core/ObjectRef.inl | 235 ++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 6f3ccab9a..d1cd13ec0 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -44,8 +44,33 @@ namespace Nz T* m_object; }; - template struct PointedType> {typedef T type;}; - template struct PointedType const> {typedef T type;}; + template bool operator==(const ObjectRef& lhs, const ObjectRef& rhs); + template bool operator==(const T& lhs, const ObjectRef& rhs); + template bool operator==(const ObjectRef& lhs, const T& rhs); + + template bool operator!=(const ObjectRef& lhs, const ObjectRef& rhs); + template bool operator!=(const T& lhs, const ObjectRef& rhs); + template bool operator!=(const ObjectRef& lhs, const T& rhs); + + template bool operator<(const ObjectRef& lhs, const ObjectRef& rhs); + template bool operator<(const T& lhs, const ObjectRef& rhs); + template bool operator<(const ObjectRef& lhs, const T& rhs); + + template bool operator<=(const ObjectRef, const ObjectRef& rhs); + template bool operator<=(const T& lhs, const ObjectRef& rhs); + template bool operator<=(const ObjectRef& lhs, const T& rhs); + + template bool operator>(const ObjectRef& lhs, const ObjectRef& rhs); + template bool operator>(const T& lhs, const ObjectRef& rhs); + template bool operator>(const ObjectRef& lhs, const T& rhs); + + template bool operator>=(const ObjectRef& lhs, const ObjectRef& rhs); + template bool operator>=(const T& lhs, const ObjectRef& rhs); + template bool operator>=(const ObjectRef& lhs, const T& rhs); + + + template struct PointedType> { typedef T type; }; + template struct PointedType const> { typedef T type; }; } #include diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index ad74b4f2e..8dab06948 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -245,6 +245,241 @@ namespace Nz return *this; } + + + /*! + * \brief Checks whether the first object handle is equal to the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator==(const ObjectRef& lhs, const ObjectRef& rhs) + { + return lhs.Get() == rhs.Get(); + } + + /*! + * \brief Checks whether the object is equal to the second object handle + * \return true if it is the case + * + * \param first Object to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator==(const T& lhs, const ObjectRef& rhs) + { + return &lhs == rhs.Get(); + } + + /*! + * \brief Checks whether the object handle is equal to the second object + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second Object to compare in right hand side + */ + template + bool operator==(const ObjectRef& lhs, const T& rhs) + { + return lhs.Get() == &rhs; + } + + /*! + * \brief Checks whether the first object handle is equal to the second object handle + * \return false if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator!=(const ObjectRef& lhs, const ObjectRef& rhs) + { + return !(lhs == rhs); + } + + /*! + * \brief Checks whether the object is equal to the second object handle + * \return false if it is the case + * + * \param first Object to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator!=(const T& lhs, const ObjectRef& rhs) + { + return !(lhs == rhs); + } + + /*! + * \brief Checks whether the object handle is equal to the second object + * \return false if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second Object to compare in right hand side + */ + template + bool operator!=(const ObjectRef& lhs, const T& rhs) + { + return !(lhs == rhs); + } + + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<(const ObjectRef& lhs, const ObjectRef& rhs) + { + return lhs.m_object < rhs.m_object; + } + + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<(const T& lhs, const ObjectRef& rhs) + { + return &lhs < rhs.m_object; + } + + /*! + * \brief Checks whether the first object handle is less than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<(const ObjectRef& lhs, const T& rhs) + { + return lhs.m_object < &rhs; + } + + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<=(const ObjectRef& lhs, const ObjectRef& rhs) + { + return !(lhs > rhs); + } + + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<=(const T& lhs, const ObjectRef& rhs) + { + return !(lhs > rhs); + } + + /*! + * \brief Checks whether the first object handle is less or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator<=(const ObjectRef& lhs, const T& rhs) + { + return !(lhs > rhs); + } + + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>(const ObjectRef& lhs, const ObjectRef& rhs) + { + return rhs < lhs; + } + + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>(const T& lhs, const ObjectRef& rhs) + { + return rhs < lhs; + } + + /*! + * \brief Checks whether the first object handle is greather than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>(const ObjectRef& lhs, const T& rhs) + { + return rhs < lhs; + } + + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>=(const ObjectRef& lhs, const ObjectRef& rhs) + { + return !(lhs < rhs); + } + + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>=(const T& lhs, const ObjectRef& rhs) + { + return !(lhs < rhs); + } + + /*! + * \brief Checks whether the first object handle is greather or equal than the second object handle + * \return true if it is the case + * + * \param first ObjectRef to compare in left hand side + * \param second ObjectRef to compare in right hand side + */ + template + bool operator>=(const ObjectRef& lhs, const T& rhs) + { + return !(lhs < rhs); + } } namespace std From 04e52caa88301d2504db4bef33b5d82ceeb81092 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Jun 2016 13:11:31 +0200 Subject: [PATCH 145/224] Sdk/GraphicsComponent: Add Detach method Former-commit-id: 16bcd7d8a3b50235cdd50443d8a1ed55e4b939f2 [formerly 93e838eebb955d5bbe17113ced86a247122bf522] Former-commit-id: be3d0d2e8fb9a887eb903c6b17f16a56e5eee1c7 --- .../NDK/Components/GraphicsComponent.hpp | 18 ++++++++++++++++++ .../NDK/Components/GraphicsComponent.inl | 13 +++++++++++++ .../Nazara/Graphics/InstancedRenderable.hpp | 17 +++++++++++++++-- src/Nazara/Core/String.cpp | 2 +- src/Nazara/Graphics/Billboard.cpp | 2 +- src/Nazara/Graphics/InstancedRenderable.cpp | 2 +- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Graphics/SkeletalModel.cpp | 2 +- src/Nazara/Graphics/Sprite.cpp | 8 ++++---- src/Nazara/Graphics/TextSprite.cpp | 2 +- 10 files changed, 56 insertions(+), 12 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index c94cec4ab..f079303b8 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -31,6 +31,8 @@ namespace Ndk inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); + inline void Detach(Nz::InstancedRenderableRef renderable); + inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; @@ -63,6 +65,22 @@ namespace Ndk { } + Renderable(Renderable&& renderable) noexcept : + data(std::move(renderable.data)), + renderable(std::move(renderable.renderable)), + dataUpdated(renderable.dataUpdated) + { + } + + Renderable& operator=(Renderable&& r) noexcept + { + data = std::move(r.data); + dataUpdated = r.dataUpdated; + renderable = std::move(r.renderable); + + return *this; + } + NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot); mutable Nz::InstancedRenderable::InstanceData data; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index c330da5eb..c736ecc48 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Prerequesites.hpp #include +#include "GraphicsComponent.hpp" namespace Ndk { @@ -46,6 +47,18 @@ namespace Ndk InvalidateBoundingVolume(); } + inline void GraphicsComponent::Detach(Nz::InstancedRenderableRef renderable) + { + for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it) + { + if (it->renderable == renderable) + { + m_renderables.erase(it); + break; + } + } + } + inline void GraphicsComponent::EnsureBoundingVolumeUpdate() const { if (!m_boundingVolumeUpdated) diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 561cc4c97..d1c07bf9b 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -55,14 +55,27 @@ namespace Nz struct InstanceData { InstanceData(Matrix4f& referenceMatrix) : - transformMatrix(referenceMatrix), + transformMatrix(&referenceMatrix), flags(0) { } + InstanceData(InstanceData&& instanceData) noexcept = default; + + InstanceData& operator=(InstanceData&& instanceData) noexcept + { + data = std::move(instanceData.data); + flags = instanceData.flags; + renderOrder = instanceData.renderOrder; + transformMatrix = instanceData.transformMatrix; + volume = instanceData.volume; + + return *this; + } + std::vector data; BoundingVolumef volume; - Matrix4f& transformMatrix; + Matrix4f* transformMatrix; UInt32 flags; int renderOrder; }; diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index a57d89861..21831bcdf 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -211,7 +211,7 @@ namespace Nz */ String::String(const std::string& string) : - String(string.c_str(), string.size()) + String(string.data(), string.size()) { } diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 6f47e9847..e06d3c921 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -30,7 +30,7 @@ namespace Nz if (!m_material) return; - renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); + renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix->GetTranslation(), m_size, m_sinCos, m_color); } /* diff --git a/src/Nazara/Graphics/InstancedRenderable.cpp b/src/Nazara/Graphics/InstancedRenderable.cpp index ef5f62b96..03da17984 100644 --- a/src/Nazara/Graphics/InstancedRenderable.cpp +++ b/src/Nazara/Graphics/InstancedRenderable.cpp @@ -80,7 +80,7 @@ namespace Nz NazaraAssert(instanceData, "Invalid instance data"); NazaraUnused(instanceData); - instanceData->volume.Update(instanceData->transformMatrix); + instanceData->volume.Update(*instanceData->transformMatrix); } /*! diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index d382c77d9..2b9e03cc1 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -82,7 +82,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = mesh->GetVertexBuffer(); - renderQueue->AddMesh(instanceData.renderOrder, material, meshData, mesh->GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, mesh->GetAABB(), *instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b91ac0076..8621d1fce 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -69,7 +69,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = SkinningManager::GetBuffer(mesh, &m_skeleton); - renderQueue->AddMesh(instanceData.renderOrder, material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, m_skeleton.GetAABB(), *instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 76bf5fff2..4bf076183 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -58,19 +58,19 @@ namespace Nz SparsePtr texCoordPtr(&vertices[0].uv, sizeof(VertexStruct_XYZ_Color_UV)); *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(Vector3f(0.f)); + *posPtr++ = instanceData->transformMatrix->Transform(Vector3f(0.f)); *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_LeftTop); *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*Vector3f::Right()); + *posPtr++ = instanceData->transformMatrix->Transform(m_size.x*Vector3f::Right()); *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightTop); *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.y*Vector3f::Down()); + *posPtr++ = instanceData->transformMatrix->Transform(m_size.y*Vector3f::Down()); *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_LeftBottom); *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*Vector3f::Right() + m_size.y*Vector3f::Down()); + *posPtr++ = instanceData->transformMatrix->Transform(m_size.x*Vector3f::Right() + m_size.y*Vector3f::Down()); *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightBottom); } diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 42dba4aaf..2f1d733b4 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -310,7 +310,7 @@ namespace Nz Vector3f localPos = localVertex->position.x*Vector3f::Right() + localVertex->position.y*Vector3f::Down(); localPos *= m_scale; - *pos++ = instanceData->transformMatrix.Transform(localPos); + *pos++ = instanceData->transformMatrix->Transform(localPos); *color++ = m_color * localVertex->color; *uv++ = localVertex->uv; From bd2b73bba7419a101922d83262990c18f2bcaf96 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 20 Jun 2016 13:12:09 +0200 Subject: [PATCH 146/224] Renderer/RenderWindow: Fix visibility of OnWindow*() events Former-commit-id: 221602aecc845cf0b8c385d7ffd7bbf94fcc716f [formerly 43f42f18548e618a5af37d8b4a2e195694d925b8] Former-commit-id: 30084dc77a88fc721f06b28755a44b7ffa32e2a3 --- include/Nazara/Renderer/RenderWindow.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index d9889d803..1cda9d63d 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -65,12 +65,11 @@ namespace Nz protected: bool Activate() const override; void EnsureTargetUpdated() const override; - - private: bool OnWindowCreated() override; void OnWindowDestroy() override; void OnWindowResized() override; + private: mutable std::vector m_buffer; Clock m_clock; ContextParameters m_parameters; From 63ed1aaa51d9a1eaa632ad280a590ece398ff4a7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 21 Jun 2016 19:14:29 +0200 Subject: [PATCH 147/224] Sdk/GraphicsComponent: Add Clear method Former-commit-id: dfa7a9813fe3e15212c16103763cb185e1d8df30 [formerly ead9d5788df957502aa22c526fa272f797348599] Former-commit-id: 74ce601066d7ab1d28609d6a859495e4626c7a18 --- SDK/include/NDK/Components/GraphicsComponent.hpp | 4 +++- SDK/include/NDK/Components/GraphicsComponent.inl | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index f079303b8..aed427105 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -31,7 +31,9 @@ namespace Ndk inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); - inline void Detach(Nz::InstancedRenderableRef renderable); + inline void Clear(); + + inline void Detach(const Nz::InstancedRenderableRef& renderable); inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index c736ecc48..9ca100d0e 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -47,12 +47,20 @@ namespace Ndk InvalidateBoundingVolume(); } - inline void GraphicsComponent::Detach(Nz::InstancedRenderableRef renderable) + inline void GraphicsComponent::Clear() + { + m_renderables.clear(); + + InvalidateBoundingVolume(); + } + + inline void GraphicsComponent::Detach(const Nz::InstancedRenderableRef& renderable) { for (auto it = m_renderables.begin(); it != m_renderables.end(); ++it) { if (it->renderable == renderable) { + InvalidateBoundingVolume(); m_renderables.erase(it); break; } From 9215e80db6b4fd014dc93145b198894abb43ee42 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 23 Jun 2016 00:37:32 +0200 Subject: [PATCH 148/224] Core/PluginManager: Fix usage of Mount(Plugin) Former-commit-id: b1e02a118828724f83be8830e4f0c8966558d0fa [formerly a1c537e8962a75da319c127e8b9bc27109a595bb] Former-commit-id: 6e706993915981df3b77ae7ae1c9139eb5d97ac4 --- src/Nazara/Core/PluginManager.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 24fbafcfb..b71af6677 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -19,8 +19,7 @@ namespace Nz String s_pluginFiles[] = { - "NazaraAssimp", // Plugin_Assimp - "NazaraFreetype" // Plugin_FreeType + "PluginAssimp", // Plugin_Assimp }; } @@ -80,7 +79,13 @@ namespace Nz bool PluginManager::Mount(Plugin plugin) { - return Mount(s_pluginFiles[plugin]); + Nz::String pluginName = s_pluginFiles[plugin]; + #ifdef NAZARA_DEBUG + if (Mount(pluginName + "-d", true)) + return true; + #endif + + return Mount(pluginName, true); } /*! From c83b9d049193486c66002e735b286f5155161838 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 08:56:18 +0200 Subject: [PATCH 149/224] Graphics/Material: Add SaveToParameters Former-commit-id: 87b9ca6e0f5f391f45edf6106efbd550dd52ac53 [formerly 91ba614d69d3a2e9762da0e059ee96985c891749] Former-commit-id: e049a9db776f407e2cd7635bfb1825d809223c77 --- include/Nazara/Graphics/Material.hpp | 2 + src/Nazara/Graphics/Material.cpp | 100 ++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 85c4d315c..b30c215c1 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -120,6 +120,8 @@ namespace Nz void Reset(); + void SaveToParameters(ParameterList* matData); + inline bool SetAlphaMap(const String& textureName); inline void SetAlphaMap(TextureRef alphaMap); inline void SetAlphaThreshold(float alphaThreshold); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index bfc6ee88a..14da83eb0 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -310,10 +310,108 @@ namespace Nz SetShader(matParams.shaderName); } + void Material::SaveToParameters(ParameterList* matData) + { + NazaraAssert(matData, "Invalid ParameterList"); + + matData->SetParameter(MaterialData::AlphaTest, IsAlphaTestEnabled()); + matData->SetParameter(MaterialData::AlphaThreshold, GetAlphaThreshold()); + matData->SetParameter(MaterialData::AmbientColor, GetAmbientColor()); + matData->SetParameter(MaterialData::CullingSide, int(GetFaceCulling())); + matData->SetParameter(MaterialData::DepthFunc, int(GetDepthFunc())); + matData->SetParameter(MaterialData::DepthSorting, IsDepthSortingEnabled()); + matData->SetParameter(MaterialData::DiffuseColor, GetDiffuseColor()); + matData->SetParameter(MaterialData::DstBlend, int(GetDstBlend())); + matData->SetParameter(MaterialData::FaceFilling, int(GetFaceFilling())); + matData->SetParameter(MaterialData::Lighting, IsLightingEnabled()); + matData->SetParameter(MaterialData::LineWidth, GetRenderStates().lineWidth); + matData->SetParameter(MaterialData::PointSize, GetRenderStates().pointSize); + matData->SetParameter(MaterialData::Shininess, GetShininess()); + matData->SetParameter(MaterialData::SpecularColor, GetSpecularColor()); + matData->SetParameter(MaterialData::SrcBlend, int(GetSrcBlend())); + matData->SetParameter(MaterialData::Transform, IsTransformEnabled()); + + // RendererParameter + matData->SetParameter(MaterialData::Blending, GetRenderStates().parameters[RendererParameter_Blend]); + matData->SetParameter(MaterialData::ColorWrite, GetRenderStates().parameters[RendererParameter_ColorWrite]); + matData->SetParameter(MaterialData::DepthBuffer, GetRenderStates().parameters[RendererParameter_DepthBuffer]); + matData->SetParameter(MaterialData::DepthWrite, GetRenderStates().parameters[RendererParameter_DepthWrite]); + matData->SetParameter(MaterialData::FaceCulling, GetRenderStates().parameters[RendererParameter_FaceCulling]); + matData->SetParameter(MaterialData::ScissorTest, GetRenderStates().parameters[RendererParameter_ScissorTest]); + matData->SetParameter(MaterialData::StencilTest, GetRenderStates().parameters[RendererParameter_StencilTest]); + + // Samplers + matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, int(GetDiffuseSampler().GetAnisotropicLevel())); + matData->SetParameter(MaterialData::DiffuseFilter, int(GetDiffuseSampler().GetFilterMode())); + matData->SetParameter(MaterialData::DiffuseWrap, int(GetDiffuseSampler().GetWrapMode())); + + matData->SetParameter(MaterialData::SpecularAnisotropyLevel, int(GetSpecularSampler().GetAnisotropicLevel())); + matData->SetParameter(MaterialData::SpecularFilter, int(GetSpecularSampler().GetFilterMode())); + matData->SetParameter(MaterialData::SpecularWrap, int(GetSpecularSampler().GetWrapMode())); + + // Stencil + matData->SetParameter(MaterialData::StencilCompare, int(GetRenderStates().frontFace.stencilCompare)); + matData->SetParameter(MaterialData::StencilFail, int(GetRenderStates().frontFace.stencilFail)); + matData->SetParameter(MaterialData::StencilPass, int(GetRenderStates().frontFace.stencilPass)); + matData->SetParameter(MaterialData::StencilZFail, int(GetRenderStates().frontFace.stencilZFail)); + matData->SetParameter(MaterialData::StencilMask, int(GetRenderStates().frontFace.stencilMask)); + matData->SetParameter(MaterialData::StencilReference, int(GetRenderStates().frontFace.stencilReference)); + + // Stencil (back) + matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetRenderStates().backFace.stencilCompare)); + matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetRenderStates().backFace.stencilFail)); + matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetRenderStates().backFace.stencilPass)); + matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetRenderStates().backFace.stencilZFail)); + matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetRenderStates().backFace.stencilMask)); + matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetRenderStates().backFace.stencilReference)); + + // Textures + if (HasAlphaMap()) + { + const String& path = GetAlphaMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::AlphaTexturePath, path); + } + + if (HasDiffuseMap()) + { + const String& path = GetDiffuseMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::DiffuseTexturePath, path); + } + + if (HasEmissiveMap()) + { + const String& path = GetEmissiveMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::EmissiveTexturePath, path); + } + + if (HasHeightMap()) + { + const String& path = GetHeightMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::HeightTexturePath, path); + } + + if (HasNormalMap()) + { + const String& path = GetNormalMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::NormalTexturePath, path); + } + + if (HasSpecularMap()) + { + const String& path = GetSpecularMap()->GetFilePath(); + if (!path.IsEmpty()) + matData->SetParameter(MaterialData::SpecularTexturePath, path); + } + } + /*! * \brief Resets the material, cleans everything */ - void Material::Reset() { OnMaterialReset(this); From 832cde4bea6ce00174fe2d22034cb9b8732c1640 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 08:56:45 +0200 Subject: [PATCH 150/224] Core/StringStream: Add Clear and GetBufferSize methods Former-commit-id: 4d8b940c300ff415fb8060b0e20b3087dc6bb076 [formerly af2dfd84721ba70df0735c04021f9ff39e90d05d] Former-commit-id: 3eecd417e811c29345f502f82219754ffa54c141 --- include/Nazara/Core/StringStream.hpp | 4 +++ src/Nazara/Core/StringStream.cpp | 41 +++++++++++++--------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index da68e8b27..f727ed35c 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -22,6 +22,10 @@ namespace Nz StringStream(const StringStream&) = default; StringStream(StringStream&&) noexcept = default; + void Clear(); + + std::size_t GetBufferSize() const; + String ToString() const; StringStream& operator=(const StringStream&) = default; diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index ebd509c65..14d35799d 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -1,3 +1,4 @@ +#include "..\..\..\include\Nazara\Core\StringStream.hpp" // 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 @@ -16,7 +17,6 @@ namespace Nz /*! * \brief Constructs a StringStream object by default */ - StringStream::StringStream() : m_bufferSize(0) { @@ -27,18 +27,34 @@ namespace Nz * * \param str First value of the stream */ - StringStream::StringStream(const String& str) : m_bufferSize(str.GetSize()) { m_strings.push_back(str); } + /*! + * \brief Resets the state of the stream, erasing every contained text + */ + void StringStream::Clear() + { + m_bufferSize = 0; + m_strings.clear(); + } + + /*! + * \brief Get the current buffer size + * \return The internal accumulation buffer size, this is equivalent to the size of the final string + */ + std::size_t StringStream::GetBufferSize() const + { + return m_bufferSize; + } + /*! * \brief Gives a string representation * \return A string representation of the object where every objects of the stream has been converted with Nz::String */ - String StringStream::ToString() const { String string; @@ -56,7 +72,6 @@ namespace Nz * * \param boolean Boolean value */ - StringStream& StringStream::operator<<(bool boolean) { m_strings.push_back(String::Boolean(boolean)); @@ -71,7 +86,6 @@ namespace Nz * * \param number Short value */ - StringStream& StringStream::operator<<(short number) { m_strings.push_back(String::Number(number)); @@ -86,7 +100,6 @@ namespace Nz * * \param number Short value */ - StringStream& StringStream::operator<<(unsigned short number) { m_strings.push_back(String::Number(number)); @@ -101,7 +114,6 @@ namespace Nz * * \param number Int value */ - StringStream& StringStream::operator<<(int number) { m_strings.push_back(String::Number(number)); @@ -116,7 +128,6 @@ namespace Nz * * \param number Int value */ - StringStream& StringStream::operator<<(unsigned int number) { m_strings.push_back(String::Number(number)); @@ -131,7 +142,6 @@ namespace Nz * * \param number Long value */ - StringStream& StringStream::operator<<(long number) { m_strings.push_back(String::Number(number)); @@ -146,7 +156,6 @@ namespace Nz * * \param number Long value */ - StringStream& StringStream::operator<<(unsigned long number) { m_strings.push_back(String::Number(number)); @@ -161,7 +170,6 @@ namespace Nz * * \param number Long long value */ - StringStream& StringStream::operator<<(long long number) { m_strings.push_back(String::Number(number)); @@ -176,7 +184,6 @@ namespace Nz * * \param number Long long value */ - StringStream& StringStream::operator<<(unsigned long long number) { m_strings.push_back(String::Number(number)); @@ -191,7 +198,6 @@ namespace Nz * * \param number Float value */ - StringStream& StringStream::operator<<(float number) { m_strings.push_back(String::Number(number)); @@ -206,7 +212,6 @@ namespace Nz * * \param number Double value */ - StringStream& StringStream::operator<<(double number) { m_strings.push_back(String::Number(number)); @@ -221,7 +226,6 @@ namespace Nz * * \param number Long double value */ - StringStream& StringStream::operator<<(long double number) { m_strings.push_back(String::Number(number)); @@ -236,7 +240,6 @@ namespace Nz * * \param character Char value */ - StringStream& StringStream::operator<<(char character) { m_strings.push_back(String(character)); @@ -251,7 +254,6 @@ namespace Nz * * \param character Char value */ - StringStream& StringStream::operator<<(unsigned char character) { m_strings.push_back(String(static_cast(character))); @@ -266,7 +268,6 @@ namespace Nz * * \param string String value */ - StringStream& StringStream::operator<<(const char* string) { m_strings.push_back(string); @@ -281,7 +282,6 @@ namespace Nz * * \param string String value */ - StringStream& StringStream::operator<<(const std::string& string) { m_strings.push_back(string); @@ -296,7 +296,6 @@ namespace Nz * * \param string String value */ - StringStream& StringStream::operator<<(const String& string) { m_strings.push_back(string); @@ -311,7 +310,6 @@ namespace Nz * * \param ptr Pointer value */ - StringStream& StringStream::operator<<(const void* ptr) { m_strings.push_back(String::Pointer(ptr)); @@ -324,7 +322,6 @@ namespace Nz * \brief Converts this to Nz::String * \return The string representation of the stream */ - StringStream::operator String() const { return ToString(); From 0b0dfda89d7f720c4c71275d960f57fd59031062 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 08:57:11 +0200 Subject: [PATCH 151/224] Utility/MaterialData: Fix FaceCulling being used for FaceSide Former-commit-id: b82f598a9c94700bea58d651b5f29dcf47251af1 [formerly 5790a8397870a66dfaeb9e56862e5fb2ae850cfc] Former-commit-id: 93372a3b733d3c84de11abacc6eaa3804b98079a --- include/Nazara/Utility/MaterialData.hpp | 1 + src/Nazara/Graphics/Material.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp index ea8ffd0f5..66df97689 100644 --- a/include/Nazara/Utility/MaterialData.hpp +++ b/include/Nazara/Utility/MaterialData.hpp @@ -22,6 +22,7 @@ namespace Nz static constexpr const char* BackFaceStencilReference = "MatBackFaceStencilReference"; static constexpr const char* BackFaceStencilZFail = "MatBackFaceStencilZFail"; static constexpr const char* Blending = "MatBlending"; + static constexpr const char* CullingSide = "MatCullingSide"; static constexpr const char* CustomDefined = "MatCustomDefined"; static constexpr const char* ColorWrite = "MatColorWrite"; static constexpr const char* DepthBuffer = "MatDepthBuffer"; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 14da83eb0..651f2581c 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -170,6 +170,9 @@ namespace Nz if (matData.GetColorParameter(MaterialData::AmbientColor, &color)) SetAmbientColor(color); + if (matData.GetIntegerParameter(MaterialData::CullingSide, &iValue)) + SetFaceCulling(static_cast(iValue)); + if (matData.GetIntegerParameter(MaterialData::DepthFunc, &iValue)) SetDepthFunc(static_cast(iValue)); @@ -182,9 +185,6 @@ namespace Nz if (matData.GetIntegerParameter(MaterialData::DstBlend, &iValue)) SetDstBlend(static_cast(iValue)); - if (matData.GetIntegerParameter(MaterialData::FaceCulling, &iValue)) - SetFaceCulling(static_cast(iValue)); - if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue)) SetFaceFilling(static_cast(iValue)); From 964b4cf730ab530ac5a2be99f8100595bb214754 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 08:57:29 +0200 Subject: [PATCH 152/224] Renderer/Texture: Remember FilePath when loading from an image Former-commit-id: 45ccc8b81490ab30e0f31b09a77ab77bcee6c975 [formerly ba58653223f2c61a0b8ba3a5f3abae8037efc266] Former-commit-id: 81e567f17199a829cc03004bca17699a34fb516d --- src/Nazara/Renderer/Texture.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index b8bed61a0..458fb9992 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -582,6 +582,9 @@ namespace Nz } } + // Keep resource path info + SetFilePath(image.GetFilePath()); + destroyOnExit.Reset(); return true; From a92a3a290113d9b01ee3334baa31c7b60ca1a9e1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 09:00:35 +0200 Subject: [PATCH 153/224] Utility/OBJParser: Optimized loading Former-commit-id: b21724d63e15bda0a9c5b8a4c9941b4b606b3525 [formerly 375bc4032044631fd2a1f51f3407b71c2c582944] Former-commit-id: aa71b4fcfacd25991da8c3b69fbc7ac9c0039ad6 --- include/Nazara/Utility/Formats/OBJParser.hpp | 50 ++-- include/Nazara/Utility/Formats/OBJParser.inl | 88 +++++++ src/Nazara/Utility/Formats/OBJLoader.cpp | 22 +- src/Nazara/Utility/Formats/OBJParser.cpp | 253 +++++++------------ 4 files changed, 222 insertions(+), 191 deletions(-) create mode 100644 include/Nazara/Utility/Formats/OBJParser.inl diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 90e653f93..64fd0ce4c 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -29,51 +29,59 @@ namespace Nz struct Face { - std::vector vertices; + std::size_t firstVertex; + std::size_t vertexCount; }; struct Mesh { std::vector faces; + std::vector vertices; String name; - unsigned int material; + std::size_t material; }; - OBJParser(Stream& stream$); - ~OBJParser(); + OBJParser() = default; + ~OBJParser() = default; - const String* GetMaterials() const; - unsigned int GetMaterialCount() const; - const Mesh* GetMeshes() const; - unsigned int GetMeshCount() const; - const String& GetMtlLib() const; - const Vector3f* GetNormals() const; - unsigned int GetNormalCount() const; - const Vector4f* GetPositions() const; - unsigned int GetPositionCount() const; - const Vector3f* GetTexCoords() const; - unsigned int GetTexCoordCount() const; + inline const String* GetMaterials() const; + inline unsigned int GetMaterialCount() const; + inline const Mesh* GetMeshes() const; + inline unsigned int GetMeshCount() const; + inline const String& GetMtlLib() const; + inline const Vector3f* GetNormals() const; + inline unsigned int GetNormalCount() const; + inline const Vector4f* GetPositions() const; + inline unsigned int GetPositionCount() const; + inline const Vector3f* GetTexCoords() const; + inline unsigned int GetTexCoordCount() const; - bool Parse(std::size_t reservedVertexCount = 100); + bool Parse(Stream& stream, std::size_t reservedVertexCount = 100); private: bool Advance(bool required = true); - void Error(const String& message); - void Warning(const String& message); - void UnrecognizedLine(bool error = false); + template void Emit(const T& text) const; + inline void EmitLine() const; + template void EmitLine(const T& line) const; + inline void Error(const String& message); + inline void Flush() const; + inline void Warning(const String& message); + inline void UnrecognizedLine(bool error = false); std::vector m_meshes; std::vector m_materials; std::vector m_normals; std::vector m_positions; std::vector m_texCoords; - Stream& m_stream; + mutable Stream* m_currentStream; String m_currentLine; String m_mtlLib; + mutable StringStream m_outputStream; bool m_keepLastLine; unsigned int m_lineCount; - unsigned int m_streamFlags; }; } +#include + #endif // NAZARA_FORMATS_OBJPARSER_HPP diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl new file mode 100644 index 000000000..c8ea75e8c --- /dev/null +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -0,0 +1,88 @@ +// 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 + +namespace Nz +{ + inline const String* OBJParser::GetMaterials() const + { + return m_materials.data(); + } + + inline unsigned int OBJParser::GetMaterialCount() const + { + return m_materials.size(); + } + + inline const OBJParser::Mesh* OBJParser::GetMeshes() const + { + return m_meshes.data(); + } + + inline unsigned int OBJParser::GetMeshCount() const + { + return m_meshes.size(); + } + + inline const String& OBJParser::GetMtlLib() const + { + return m_mtlLib; + } + + inline const Vector3f* OBJParser::GetNormals() const + { + return m_normals.data(); + } + + inline unsigned int OBJParser::GetNormalCount() const + { + return m_normals.size(); + } + + inline const Vector4f* OBJParser::GetPositions() const + { + return m_positions.data(); + } + + inline unsigned int OBJParser::GetPositionCount() const + { + return m_positions.size(); + } + + inline const Vector3f* OBJParser::GetTexCoords() const + { + return m_texCoords.data(); + } + + inline unsigned int OBJParser::GetTexCoordCount() const + { + return m_texCoords.size(); + } + + + inline void OBJParser::Error(const String& message) + { + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + + inline void OBJParser::Warning(const String& message) + { + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); + } + + inline void OBJParser::UnrecognizedLine(bool error) + { + String message = "Unrecognized \"" + m_currentLine + '"'; + + if (error) + Error(message); + else + Warning(message); + } +} + +#include diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 05b39f81f..720b5ec5d 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -123,8 +123,8 @@ namespace Nz if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount)) reservedVertexCount = 100; - OBJParser parser(stream); - if (!parser.Parse(reservedVertexCount)) + OBJParser parser; + if (!parser.Parse(stream, reservedVertexCount)) { NazaraError("OBJ parser failed"); return false; @@ -177,23 +177,24 @@ namespace Nz { bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const { - return lhs.normal == rhs.normal && + return lhs.normal == rhs.normal && lhs.position == rhs.position && lhs.texCoord == rhs.texCoord; } }; std::unordered_map vertices; + vertices.reserve(meshes[i].vertices.size()); unsigned int vertexCount = 0; for (unsigned int j = 0; j < faceCount; ++j) { - unsigned int faceVertexCount = meshes[i].faces[j].vertices.size(); + unsigned int faceVertexCount = meshes[i].faces[j].vertexCount; faceIndices.resize(faceVertexCount); for (unsigned int k = 0; k < faceVertexCount; ++k) { - const OBJParser::FaceVertex& vertex = meshes[i].faces[j].vertices[k]; + const OBJParser::FaceVertex& vertex = meshes[i].vertices[meshes[i].faces[j].firstVertex + k]; auto it = vertices.find(vertex); if (it == vertices.end()) @@ -202,6 +203,7 @@ namespace Nz faceIndices[k] = it->second; } + // Triangulation for (unsigned int k = 1; k < faceVertexCount-1; ++k) { indices.push_back(faceIndices[0]); @@ -233,17 +235,17 @@ namespace Nz MeshVertex& vertex = meshVertices[index]; - const Vector4f& vec = positions[vertexIndices.position]; + const Vector4f& vec = positions[vertexIndices.position-1]; vertex.position = Vector3f(parameters.matrix * vec); - if (vertexIndices.normal >= 0) - vertex.normal = normals[vertexIndices.normal]; + if (vertexIndices.normal > 0) + vertex.normal = normals[vertexIndices.normal-1]; else hasNormals = false; - if (vertexIndices.texCoord >= 0) + if (vertexIndices.texCoord > 0) { - const Vector3f& uvw = texCoords[vertexIndices.texCoord]; + const Vector3f& uvw = texCoords[vertexIndices.texCoord-1]; vertex.uv.Set(uvw.x, (parameters.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé } else diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index c0daf1f84..03a251d5a 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include @@ -13,77 +13,22 @@ namespace Nz { - OBJParser::OBJParser(Stream& stream) : - m_stream(stream), - m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags + bool OBJParser::Parse(Nz::Stream& stream, std::size_t reservedVertexCount) { - m_stream.EnableTextMode(true); - } + m_currentStream = &stream; - OBJParser::~OBJParser() - { - // Reset stream flags - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.EnableTextMode(false); - } + // Force stream in text mode, reset it at the end + Nz::CallOnExit resetTextMode; + if ((stream.GetStreamOptions() & StreamOption_Text) == 0) + { + stream.EnableTextMode(true); - const String* OBJParser::GetMaterials() const - { - return m_materials.data(); - } + resetTextMode.Reset([&stream] () + { + stream.EnableTextMode(false); + }); + } - unsigned int OBJParser::GetMaterialCount() const - { - return m_materials.size(); - } - - const OBJParser::Mesh* OBJParser::GetMeshes() const - { - return m_meshes.data(); - } - - unsigned int OBJParser::GetMeshCount() const - { - return m_meshes.size(); - } - - const String& OBJParser::GetMtlLib() const - { - return m_mtlLib; - } - - const Vector3f* OBJParser::GetNormals() const - { - return m_normals.data(); - } - - unsigned int OBJParser::GetNormalCount() const - { - return m_normals.size(); - } - - const Vector4f* OBJParser::GetPositions() const - { - return m_positions.data(); - } - - unsigned int OBJParser::GetPositionCount() const - { - return m_positions.size(); - } - - const Vector3f* OBJParser::GetTexCoords() const - { - return m_texCoords.data(); - } - - unsigned int OBJParser::GetTexCoordCount() const - { - return m_texCoords.size(); - } - - bool OBJParser::Parse(std::size_t reservedVertexCount) - { String matName, meshName; matName = meshName = "default"; m_keepLastLine = false; @@ -100,32 +45,56 @@ namespace Nz m_positions.reserve(reservedVertexCount); m_texCoords.reserve(reservedVertexCount); - // On va regrouper les meshs par nom et par matériau - using FaceVec = std::vector; - using MatPair = std::pair; - std::unordered_map> meshes; + // Sort meshes by material and group + using MatPair = std::pair; + std::unordered_map> meshesByName; - unsigned int matIndex = 0; - auto GetMaterial = [&meshes, &matIndex] (const String& mesh, const String& material) -> FaceVec* + std::size_t faceReserve = 0; + std::size_t vertexReserve = 0; + unsigned int matCount = 0; + auto GetMaterial = [&] (const String& meshName, const String& matName) -> Mesh* { - auto& map = meshes[mesh]; - auto it = map.find(material); + auto& map = meshesByName[meshName]; + auto it = map.find(matName); if (it == map.end()) - it = map.insert(std::make_pair(material, MatPair(FaceVec(), matIndex++))).first; + it = map.insert(std::make_pair(matName, MatPair(Mesh(), matCount++))).first; + + Mesh& mesh = it->second.first; + + mesh.faces.reserve(faceReserve); + mesh.vertices.reserve(vertexReserve); + faceReserve = 0; + vertexReserve = 0; return &(it->second.first); }; // On prépare le mesh par défaut - FaceVec* currentMesh = nullptr; + Mesh* currentMesh = nullptr; while (Advance(false)) { switch (std::tolower(m_currentLine[0])) { - case 'f': // Une face + case '#': //< Comment + // Some softwares write comments to gives the number of vertex/faces an importer can expect + std::size_t data; + if (std::sscanf(m_currentLine.GetConstBuffer(), "# position count: %zu", &data) == 1) + m_positions.reserve(data); + else if (std::sscanf(m_currentLine.GetConstBuffer(), "# normal count: %zu", &data) == 1) + m_normals.reserve(data); + else if (std::sscanf(m_currentLine.GetConstBuffer(), "# texcoords count: %zu", &data) == 1) + m_texCoords.reserve(data); + else if (std::sscanf(m_currentLine.GetConstBuffer(), "# face count: %zu", &data) == 1) + faceReserve = data; + else if (std::sscanf(m_currentLine.GetConstBuffer(), "# vertex count: %zu", &data) == 1) + vertexReserve = data; + + break; + + case 'f': //< Face { - if (m_currentLine.GetSize() < 7) // Le minimum syndical pour définir une face de trois sommets (f 1 2 3) + if (m_currentLine.GetSize() < 7) // Since we only treat triangles, this is the minimum length of a face line (f 1 2 3) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING UnrecognizedLine(); @@ -142,17 +111,23 @@ namespace Nz break; } + if (!currentMesh) + currentMesh = GetMaterial(meshName, matName); + Face face; - face.vertices.resize(vertexCount); + face.firstVertex = currentMesh->vertices.size(); + face.vertexCount = vertexCount; + + currentMesh->vertices.resize(face.firstVertex + vertexCount, FaceVertex{0, 0, 0}); bool error = false; unsigned int pos = 2; for (unsigned int i = 0; i < vertexCount; ++i) { int offset; - int& n = face.vertices[i].normal; - int& p = face.vertices[i].position; - int& t = face.vertices[i].texCoord; + int& n = currentMesh->vertices[face.firstVertex + i].normal; + int& p = currentMesh->vertices[face.firstVertex + i].position; + int& t = currentMesh->vertices[face.firstVertex + i].texCoord; if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { @@ -168,22 +143,13 @@ namespace Nz error = true; break; } - else - { - n = 0; - t = 0; - } } - else - n = 0; } - else - t = 0; } if (p < 0) { - p += m_positions.size(); + p += m_positions.size() - 1; if (p < 0) { Error("Vertex index out of range (" + String::Number(p) + " < 0"); @@ -191,48 +157,42 @@ namespace Nz break; } } - else - p--; if (n < 0) { - n += m_normals.size(); + n += m_normals.size() - 1; if (n < 0) { - Error("Vertex index out of range (" + String::Number(n) + " < 0"); + Error("Normal index out of range (" + String::Number(n) + " < 0"); error = true; break; } } - else - n--; if (t < 0) { - t += m_texCoords.size(); + t += m_texCoords.size() - 1; if (t < 0) { - Error("Vertex index out of range (" + String::Number(t) + " < 0"); + Error("Texture coordinates index out of range (" + String::Number(t) + " < 0"); error = true; break; } } - else - t--; - if (static_cast(p) >= m_positions.size()) + if (static_cast(p) > m_positions.size()) { Error("Vertex index out of range (" + String::Number(p) + " >= " + String::Number(m_positions.size()) + ')'); error = true; break; } - else if (n >= 0 && static_cast(n) >= m_normals.size()) + else if (n != 0 && static_cast(n) > m_normals.size()) { Error("Normal index out of range (" + String::Number(n) + " >= " + String::Number(m_normals.size()) + ')'); error = true; break; } - else if (t >= 0 && static_cast(t) >= m_texCoords.size()) + else if (t != 0 && static_cast(t) > m_texCoords.size()) { Error("TexCoord index out of range (" + String::Number(t) + " >= " + String::Number(m_texCoords.size()) + ')'); error = true; @@ -243,17 +203,14 @@ namespace Nz } if (!error) - { - if (!currentMesh) - currentMesh = GetMaterial(meshName, matName); - - currentMesh->push_back(std::move(face)); - } + currentMesh->faces.push_back(std::move(face)); + else + currentMesh->vertices.resize(face.firstVertex); //< Remove vertices break; } - case 'm': + case 'm': //< MTLLib #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING if (m_currentLine.GetWord(0).ToLower() != "mtllib") UnrecognizedLine(); @@ -262,8 +219,8 @@ namespace Nz m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); break; - case 'g': - case 'o': + case 'g': //< Group (inside a mesh) + case 'o': //< Object (defines a mesh) { if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ') { @@ -283,12 +240,12 @@ namespace Nz } meshName = objectName; - currentMesh = GetMaterial(meshName, matName); + currentMesh = nullptr; break; } #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - case 's': + case 's': //< Smooth if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ') { String param = m_currentLine.SubString(2); @@ -298,15 +255,16 @@ namespace Nz else UnrecognizedLine(); break; - #endif + #endif - case 'u': + case 'u': //< Usemtl #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING if (m_currentLine.GetWord(0) != "usemtl") UnrecognizedLine(); #endif matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); + currentMesh = nullptr; if (matName.IsEmpty()) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING @@ -314,18 +272,16 @@ namespace Nz #endif break; } - - currentMesh = GetMaterial(meshName, matName); break; - case 'v': + case 'v': //< Position/Normal/Texcoords { String word = m_currentLine.GetWord(0).ToLower(); if (word == 'v') { Vector4f vertex(Vector3f::Zero(), 1.f); unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w); - if (paramCount >= 3) + if (paramCount >= 1) m_positions.push_back(vertex); #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING else @@ -371,26 +327,24 @@ namespace Nz } std::unordered_map materials; - m_materials.resize(matIndex); + m_materials.resize(matCount); - for (auto& meshIt : meshes) + for (auto& meshPair : meshesByName) { - for (auto& matIt : meshIt.second) + for (auto& matPair : meshPair.second) { - auto& faceVec = matIt.second.first; - unsigned int index = matIt.second.second; - if (!faceVec.empty()) + Mesh& mesh = matPair.second.first; + unsigned int index = matPair.second.second; + if (!mesh.faces.empty()) { - Mesh mesh; - mesh.faces = std::move(faceVec); - mesh.name = meshIt.first; + mesh.name = meshPair.first; - auto it = materials.find(matIt.first); + auto it = materials.find(matPair.first); if (it == materials.end()) { mesh.material = index; - materials[matIt.first] = index; - m_materials[index] = matIt.first; + materials[matPair.first] = index; + m_materials[index] = matPair.first; } else mesh.material = it->second; @@ -415,7 +369,7 @@ namespace Nz { do { - if (m_stream.EndOfStream()) + if (m_currentStream->EndOfStream()) { if (required) Error("Incomplete OBJ file"); @@ -425,9 +379,8 @@ namespace Nz m_lineCount++; - m_currentLine = m_stream.ReadLine(); - m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires - m_currentLine.Simplify(); // Pour un traitement plus simple + m_currentLine = m_currentStream->ReadLine(); + m_currentLine.Simplify(); // Simplify lines (convert multiple blanks into a single space and trims) } while (m_currentLine.IsEmpty()); } @@ -436,24 +389,4 @@ namespace Nz return true; } - - void OBJParser::Error(const String& message) - { - NazaraError(message + " at line #" + String::Number(m_lineCount)); - } - - void OBJParser::Warning(const String& message) - { - NazaraWarning(message + " at line #" + String::Number(m_lineCount)); - } - - void OBJParser::UnrecognizedLine(bool error) - { - String message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); - } } From bbb218f9a0a9f6ddb2276140ecc7e37e6af3748c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 09:00:50 +0200 Subject: [PATCH 154/224] Utility/OBJParser: Add saving Former-commit-id: f991f0a66a82a68659f14a7ba887b49a2690f5a7 [formerly e4c96019484ad436048d001bd307ac549dfc615a] Former-commit-id: 946f9e5f99ff46c26741f1877391506b23602517 --- include/Nazara/Utility/Formats/OBJParser.hpp | 2 + include/Nazara/Utility/Formats/OBJParser.inl | 25 ++++ src/Nazara/Utility/Formats/OBJParser.cpp | 142 +++++++++++++++++++ 3 files changed, 169 insertions(+) diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 64fd0ce4c..79aa1824a 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -58,6 +58,8 @@ namespace Nz bool Parse(Stream& stream, std::size_t reservedVertexCount = 100); + bool Save(Stream& stream) const; + private: bool Advance(bool required = true); template void Emit(const T& text) const; diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index c8ea75e8c..7cd0060b4 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -63,12 +63,37 @@ namespace Nz return m_texCoords.size(); } + template + void OBJParser::Emit(const T& text) const + { + m_outputStream << text; + if (m_outputStream.GetBufferSize() > 1024 * 1024) + Flush(); + } + + inline void OBJParser::EmitLine() const + { + Emit('\n'); + } + + template + void OBJParser::EmitLine(const T& line) const + { + Emit(line); + Emit('\n'); + } inline void OBJParser::Error(const String& message) { NazaraError(message + " at line #" + String::Number(m_lineCount)); } + inline void OBJParser::Flush() const + { + m_currentStream->Write(m_outputStream); + m_outputStream.Clear(); + } + inline void OBJParser::Warning(const String& message) { NazaraWarning(message + " at line #" + String::Number(m_lineCount)); diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 03a251d5a..a05ef6960 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -363,6 +363,148 @@ namespace Nz return true; } + bool OBJParser::Save(Stream& stream) const + { + m_currentStream = &stream; + + // Force stream in text mode, reset it at the end + Nz::CallOnExit resetTextMode; + if ((stream.GetStreamOptions() & StreamOption_Text) == 0) + { + stream.EnableTextMode(true); + + resetTextMode.Reset([&stream] () + { + stream.EnableTextMode(false); + }); + } + + m_outputStream.Clear(); + + EmitLine("# Exported by Nazara Engine"); + + if (!m_mtlLib.IsEmpty()) + { + Emit("mtlib "); + EmitLine(m_mtlLib); + EmitLine(); + } + + Emit("# position count: "); + EmitLine(m_positions.size()); + + for (const Nz::Vector4f& position : m_positions) + { + Emit("v "); + Emit(position.x); + Emit(' '); + Emit(position.y); + if (!NumberEquals(position.z, 0.f) || !NumberEquals(position.w, 1.f)) + { + Emit(' '); + Emit(position.z); + + if (!NumberEquals(position.w, 1.f)) + { + Emit(' '); + Emit(position.w); + } + } + EmitLine(); + } + EmitLine(); + + Emit("# normal count: "); + EmitLine(m_normals.size()); + + for (const Nz::Vector3f& normal : m_normals) + { + Emit("vn "); + Emit(normal.x); + Emit(' '); + Emit(normal.y); + Emit(' '); + Emit(normal.y); + EmitLine(); + } + EmitLine(); + + Emit("# texcoords count: "); + EmitLine(m_texCoords.size()); + + for (const Nz::Vector3f& uvw : m_texCoords) + { + Emit("vt "); + Emit(uvw.x); + Emit(' '); + Emit(uvw.y); + if (NumberEquals(uvw.z, 0.f)) + { + Emit(' '); + Emit(uvw.z); + } + EmitLine(); + } + EmitLine(); + + std::unordered_map /* meshes*/> meshesByMaterials; + std::size_t meshIndex = 0; + for (const Mesh& mesh : m_meshes) + meshesByMaterials[mesh.material].push_back(meshIndex++); + + for (auto& pair : meshesByMaterials) + { + Emit("usemtl "); + EmitLine(m_materials[pair.first]); + Emit("# groups count: "); + EmitLine(pair.second.size()); + EmitLine(); + + for (std::size_t meshIndex : pair.second) + { + const Mesh& mesh = m_meshes[meshIndex]; + + Emit("g "); + EmitLine(mesh.name); + EmitLine(); + + Emit("# face count: "); + EmitLine(mesh.faces.size()); + Emit("# vertex count: "); + EmitLine(mesh.vertices.size()); + + for (const Face& face : mesh.faces) + { + Emit('f'); + for (std::size_t i = 0; i < face.vertexCount; ++i) + { + Emit(' '); + const FaceVertex& faceVertex = mesh.vertices[face.firstVertex + i]; + Emit(faceVertex.position); + if (faceVertex.texCoord != 0 || faceVertex.normal != 0) + { + Emit('/'); + if (faceVertex.texCoord != 0) + Emit(faceVertex.texCoord); + + if (faceVertex.normal != 0) + { + Emit('/'); + Emit(faceVertex.normal); + } + } + } + EmitLine(); + } + } + EmitLine(); + } + + Flush(); + + return true; + } + bool OBJParser::Advance(bool required) { if (!m_keepLastLine) From 068465b6b987ce9ee55d3feaffba585fb8e27284 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 09:01:08 +0200 Subject: [PATCH 155/224] Math/Vector4: Fix w value when converting from Vector3 Former-commit-id: 54b45268d18c3839bceffa065e52e47a7a44e811 [formerly 3a349b4380d23163a5f56a2aedb1860f140856cb] Former-commit-id: 453d4705694d89bba0122c5a37c76ddf5478213b --- include/Nazara/Math/Vector4.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index d1e51433a..b84a4cb17 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -28,7 +28,7 @@ namespace Nz explicit Vector4(T scale); Vector4(const T vec[4]); Vector4(const Vector2& vec, T Z = 0.0, T W = 1.0); - Vector4(const Vector3& vec, T W = 0.0); + Vector4(const Vector3& vec, T W = 1.0); template explicit Vector4(const Vector4& vec); Vector4(const Vector4& vec) = default; ~Vector4() = default; From 3b1dddf26df6155c610df4d687f570e60081452c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 18:07:43 +0200 Subject: [PATCH 156/224] Ndk/GraphicsComponent: Add GetAttachedRenderables Former-commit-id: 6a5a017caf0af3fd5c40ead7d67d30b640eba243 [formerly 2796343e15655263669366fc7dd5ff8b3ca65d76] Former-commit-id: 7738d1c5a929d3cd1261aaa1c9899bddf0ad1541 --- SDK/include/NDK/Components/GraphicsComponent.hpp | 5 +++++ SDK/include/NDK/Components/GraphicsComponent.inl | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index aed427105..4ea76d0d8 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -23,6 +23,8 @@ namespace Ndk friend class RenderSystem; public: + using RenderableList = std::vector; + GraphicsComponent() = default; inline GraphicsComponent(const GraphicsComponent& graphicsComponent); ~GraphicsComponent() = default; @@ -38,6 +40,9 @@ namespace Ndk inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; + inline void GetAttachedRenderables(Nz::InstancedRenderableRef* renderables) const; + inline std::size_t GetAttachedRenderableCount() const; + inline const Nz::BoundingVolumef& GetBoundingVolume() const; static ComponentIndex componentIndex; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 9ca100d0e..b38ce6dd6 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -79,6 +79,20 @@ namespace Ndk UpdateTransformMatrix(); } + inline void GraphicsComponent::GetAttachedRenderables(RenderableList* renderables) const + { + NazaraAssert(renderables, "Invalid renderable list"); + + renderables->reserve(renderables->size() + m_renderables.size()); + for (const Renderable& r : m_renderables) + renderables->push_back(r.renderable); + } + + inline std::size_t GraphicsComponent::GetAttachedRenderableCount() const + { + return m_renderables.size(); + } + inline const Nz::BoundingVolumef& GraphicsComponent::GetBoundingVolume() const { EnsureBoundingVolumeUpdate(); From a4120e0a37cc1629e9eb04c831c7c85f95eb4898 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 7 Jul 2016 18:17:18 +0200 Subject: [PATCH 157/224] Fix typo Former-commit-id: 07bb1e9aa33b06c79b6d30af8598c5678eb4b37c [formerly db529eb77de00026196de3000f67fd13916011ef] Former-commit-id: 25db8b31bbd53791033517a4788471a8a3eafe9b --- SDK/include/NDK/Components/GraphicsComponent.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 4ea76d0d8..a7ac3ebc2 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -40,7 +40,7 @@ namespace Ndk inline void EnsureBoundingVolumeUpdate() const; inline void EnsureTransformMatrixUpdate() const; - inline void GetAttachedRenderables(Nz::InstancedRenderableRef* renderables) const; + inline void GetAttachedRenderables(RenderableList* renderables) const; inline std::size_t GetAttachedRenderableCount() const; inline const Nz::BoundingVolumef& GetBoundingVolume() const; From b3e888563b11f9a578c2db470d241cf4f7e8cfb2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:34:45 +0200 Subject: [PATCH 158/224] Utility/OBJParser: Prepare for saving Former-commit-id: 90a78b4ca33ff8ce36fd5d37191799b196803c09 [formerly b39fe56eafb502516007de75ca77fdc6ab8a3391] Former-commit-id: 5481142d659e43f687a5b8b4e1634405702bfc7b --- include/Nazara/Utility/Formats/OBJParser.hpp | 67 ++++++++++++-------- include/Nazara/Utility/Formats/OBJParser.inl | 64 +++++++++++++++++++ src/Nazara/Utility/Formats/OBJLoader.cpp | 4 +- src/Nazara/Utility/Formats/OBJLoader.hpp | 4 +- src/Nazara/Utility/Formats/OBJParser.cpp | 10 ++- 5 files changed, 117 insertions(+), 32 deletions(-) diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 79aa1824a..b9c5e41c3 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -20,12 +20,41 @@ namespace Nz class NAZARA_UTILITY_API OBJParser { public: - struct FaceVertex - { - int normal; - int position; - int texCoord; - }; + struct Face; + struct FaceVertex; + struct Mesh; + + OBJParser() = default; + ~OBJParser() = default; + + inline void Clear(); + + inline String* GetMaterials(); + inline const String* GetMaterials() const; + inline unsigned int GetMaterialCount() const; + inline Mesh* GetMeshes(); + inline const Mesh* GetMeshes() const; + inline unsigned int GetMeshCount() const; + inline const String& GetMtlLib() const; + inline Vector3f* GetNormals(); + inline const Vector3f* GetNormals() const; + inline unsigned int GetNormalCount() const; + inline Vector4f* GetPositions(); + inline const Vector4f* GetPositions() const; + inline unsigned int GetPositionCount() const; + inline Vector3f* GetTexCoords(); + inline const Vector3f* GetTexCoords() const; + inline unsigned int GetTexCoordCount() const; + + bool Parse(Stream& stream, std::size_t reservedVertexCount = 100); + + bool Save(Stream& stream) const; + + inline String* SetMaterialCount(std::size_t materialCount); + inline Mesh* SetMeshCount(std::size_t meshCount); + inline Vector3f* SetNormalCount(std::size_t normalCount); + inline Vector4f* SetPositionCount(std::size_t positionCount); + inline Vector3f* SetTexCoordCount(std::size_t texCoordCount); struct Face { @@ -33,6 +62,13 @@ namespace Nz std::size_t vertexCount; }; + struct FaceVertex + { + std::size_t normal; + std::size_t position; + std::size_t texCoord; + }; + struct Mesh { std::vector faces; @@ -41,25 +77,6 @@ namespace Nz std::size_t material; }; - OBJParser() = default; - ~OBJParser() = default; - - inline const String* GetMaterials() const; - inline unsigned int GetMaterialCount() const; - inline const Mesh* GetMeshes() const; - inline unsigned int GetMeshCount() const; - inline const String& GetMtlLib() const; - inline const Vector3f* GetNormals() const; - inline unsigned int GetNormalCount() const; - inline const Vector4f* GetPositions() const; - inline unsigned int GetPositionCount() const; - inline const Vector3f* GetTexCoords() const; - inline unsigned int GetTexCoordCount() const; - - bool Parse(Stream& stream, std::size_t reservedVertexCount = 100); - - bool Save(Stream& stream) const; - private: bool Advance(bool required = true); template void Emit(const T& text) const; diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index 7cd0060b4..a4fcffaec 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -8,6 +8,20 @@ namespace Nz { + inline void OBJParser::Clear() + { + m_materials.clear(); + m_meshes.clear(); + m_positions.clear(); + m_normals.clear(); + m_texCoords.clear(); + } + + inline String* OBJParser::GetMaterials() + { + return m_materials.data(); + } + inline const String* OBJParser::GetMaterials() const { return m_materials.data(); @@ -18,6 +32,11 @@ namespace Nz return m_materials.size(); } + inline OBJParser::Mesh* OBJParser::GetMeshes() + { + return m_meshes.data(); + } + inline const OBJParser::Mesh* OBJParser::GetMeshes() const { return m_meshes.data(); @@ -33,6 +52,11 @@ namespace Nz return m_mtlLib; } + inline Vector3f* OBJParser::GetNormals() + { + return m_normals.data(); + } + inline const Vector3f* OBJParser::GetNormals() const { return m_normals.data(); @@ -43,6 +67,11 @@ namespace Nz return m_normals.size(); } + inline Vector4f* OBJParser::GetPositions() + { + return m_positions.data(); + } + inline const Vector4f* OBJParser::GetPositions() const { return m_positions.data(); @@ -53,6 +82,11 @@ namespace Nz return m_positions.size(); } + inline Vector3f* OBJParser::GetTexCoords() + { + return m_texCoords.data(); + } + inline const Vector3f* OBJParser::GetTexCoords() const { return m_texCoords.data(); @@ -63,6 +97,36 @@ namespace Nz return m_texCoords.size(); } + inline String* OBJParser::SetMaterialCount(std::size_t materialCount) + { + m_materials.resize(materialCount); + return m_materials.data(); + } + + inline OBJParser::Mesh* OBJParser::SetMeshCount(std::size_t meshCount) + { + m_meshes.resize(meshCount); + return m_meshes.data(); + } + + inline Vector3f* OBJParser::SetNormalCount(std::size_t normalCount) + { + m_normals.resize(normalCount); + return m_normals.data(); + } + + inline Vector4f* OBJParser::SetPositionCount(std::size_t positionCount) + { + m_positions.resize(positionCount); + return m_positions.data(); + } + + inline Vector3f* OBJParser::SetTexCoordCount(std::size_t texCoordCount) + { + m_texCoords.resize(texCoordCount); + return m_texCoords.data(); + } + template void OBJParser::Emit(const T& text) const { diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 720b5ec5d..a8d5d68ec 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -298,12 +298,12 @@ namespace Nz namespace Loaders { - void RegisterOBJ() + void RegisterOBJLoader() { MeshLoader::RegisterLoader(IsSupported, Check, Load); } - void UnregisterOBJ() + void UnregisterOBJLoader() { MeshLoader::UnregisterLoader(IsSupported, Check, Load); } diff --git a/src/Nazara/Utility/Formats/OBJLoader.hpp b/src/Nazara/Utility/Formats/OBJLoader.hpp index 05a3efdff..46dd8d976 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.hpp +++ b/src/Nazara/Utility/Formats/OBJLoader.hpp @@ -13,8 +13,8 @@ namespace Nz { namespace Loaders { - void RegisterOBJ(); - void UnregisterOBJ(); + void RegisterOBJLoader(); + void UnregisterOBJLoader(); } } diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index a05ef6960..5c941e938 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -125,9 +125,9 @@ namespace Nz for (unsigned int i = 0; i < vertexCount; ++i) { int offset; - int& n = currentMesh->vertices[face.firstVertex + i].normal; - int& p = currentMesh->vertices[face.firstVertex + i].position; - int& t = currentMesh->vertices[face.firstVertex + i].texCoord; + std::size_t n = 0; + std::size_t p = 0; + std::size_t t = 0; if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { @@ -199,6 +199,10 @@ namespace Nz break; } + currentMesh->vertices[face.firstVertex + i].normal = static_cast(n); + currentMesh->vertices[face.firstVertex + i].position = static_cast(p); + currentMesh->vertices[face.firstVertex + i].texCoord = static_cast(t); + pos += offset; } From a1108ed9551634838546eb58d745025e97ec712b Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:35:36 +0200 Subject: [PATCH 159/224] Utility/IndexMapper: Makes it work without index buffers (sequential mode) Former-commit-id: 594f3f2c31f30122889e8b3f2dd214b09455b640 [formerly 085c770b3effaa2faf9b61fa32280a7957f71258] Former-commit-id: a54711d1cfb80f2792a80174a5808bb44d2095f3 --- include/Nazara/Utility/IndexMapper.hpp | 7 +- src/Nazara/Utility/IndexMapper.cpp | 89 +++++++++++++++----------- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index 9dd6a5c46..7f632f196 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -23,9 +23,10 @@ namespace Nz class NAZARA_UTILITY_API IndexMapper { public: - IndexMapper(IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadWrite); - IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadOnly); - IndexMapper(const SubMesh* subMesh); + IndexMapper(IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadWrite, std::size_t indexCount = 0); + IndexMapper(SubMesh* subMesh, BufferAccess access = BufferAccess_ReadWrite); + IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadOnly, std::size_t indexCount = 0); + IndexMapper(const SubMesh* subMesh, BufferAccess access = BufferAccess_ReadOnly); ~IndexMapper() = default; UInt32 Get(unsigned int i) const; diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index adf80a764..5a664128c 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -12,6 +12,13 @@ namespace Nz { namespace { + UInt32 GetterSequential(const void* buffer, unsigned int i) + { + NazaraUnused(buffer); + + return i; + } + UInt32 Getter16(const void* buffer, unsigned int i) { const UInt16* ptr = static_cast(buffer); @@ -42,61 +49,67 @@ namespace Nz } } - IndexMapper::IndexMapper(IndexBuffer* indexBuffer, BufferAccess access) : - m_indexCount(indexBuffer->GetIndexCount()) + IndexMapper::IndexMapper(IndexBuffer* indexBuffer, BufferAccess access, std::size_t indexCount) : + m_indexCount((indexCount != 0) ? indexCount : indexBuffer->GetIndexCount()) { - #if NAZARA_UTILITY_SAFE - if (!indexBuffer) - { - NazaraError("Index buffer must be valid"); - return; - } - #endif + NazaraAssert(indexCount != 0 || indexBuffer, "Invalid index count with invalid index buffer"); - if (!m_mapper.Map(indexBuffer, access)) - NazaraError("Failed to map buffer"); ///TODO: Unexcepted - - if (indexBuffer->HasLargeIndices()) + if (indexBuffer) { - m_getter = Getter32; - if (access != BufferAccess_ReadOnly) - m_setter = Setter32; + if (!m_mapper.Map(indexBuffer, access)) + NazaraError("Failed to map buffer"); ///TODO: Unexcepted + + if (indexBuffer->HasLargeIndices()) + { + m_getter = Getter32; + if (access != BufferAccess_ReadOnly) + m_setter = Setter32; + else + m_setter = SetterError; + } else - m_setter = SetterError; + { + m_getter = Getter16; + if (access != BufferAccess_ReadOnly) + m_setter = Setter16; + else + m_setter = SetterError; + } } else { - m_getter = Getter16; - if (access != BufferAccess_ReadOnly) - m_setter = Setter16; - else - m_setter = SetterError; + m_getter = GetterSequential; + m_setter = SetterError; } } - IndexMapper::IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access) : + IndexMapper::IndexMapper(SubMesh* subMesh, BufferAccess access) : + IndexMapper(subMesh->GetIndexBuffer(), access, (subMesh->GetIndexBuffer()) ? 0 : subMesh->GetVertexCount()) + { + } + + IndexMapper::IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access, std::size_t indexCount) : m_setter(SetterError), - m_indexCount(indexBuffer->GetIndexCount()) + m_indexCount((indexCount != 0) ? indexCount : indexBuffer->GetIndexCount()) { - #if NAZARA_UTILITY_SAFE - if (!indexBuffer) + NazaraAssert(indexCount != 0 || indexBuffer, "Invalid index count with invalid index buffer"); + + if (indexBuffer) { - NazaraError("Index buffer must be valid"); - return; + if (!m_mapper.Map(indexBuffer, access)) + NazaraError("Failed to map buffer"); ///TODO: Unexcepted + + if (indexBuffer->HasLargeIndices()) + m_getter = Getter32; + else + m_getter = Getter16; } - #endif - - if (!m_mapper.Map(indexBuffer, access)) - NazaraError("Failed to map buffer"); ///TODO: Unexcepted - - if (indexBuffer->HasLargeIndices()) - m_getter = Getter32; else - m_getter = Getter16; + m_getter = GetterSequential; } - IndexMapper::IndexMapper(const SubMesh* subMesh) : - IndexMapper(subMesh->GetIndexBuffer()) + IndexMapper::IndexMapper(const SubMesh* subMesh, BufferAccess access) : + IndexMapper(subMesh->GetIndexBuffer(), access, (subMesh->GetIndexBuffer()) ? 0 : subMesh->GetVertexCount()) { } From 52436a93955405b0fe3a3c1fc9e7bd3a9c6de990 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:35:48 +0200 Subject: [PATCH 160/224] Utility: Fix an oopsie Former-commit-id: 90d740ad9f3dac2dc742a5febc431b269c90ddbb [formerly 46c254826cbbca0231713289771add7a46df3a3c] Former-commit-id: c34ceb2f44c83914d2207454612682590b4fcfb4 --- src/Nazara/Utility/Utility.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 78553ce54..ae5b5066d 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -124,7 +124,7 @@ namespace Nz Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10) // Mesh (text) - Loaders::RegisterOBJ(); + Loaders::RegisterOBJLoader(); // Mesh Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8) @@ -162,7 +162,7 @@ namespace Nz Loaders::UnregisterMD2(); Loaders::UnregisterMD5Anim(); Loaders::UnregisterMD5Mesh(); - Loaders::UnregisterOBJ(); + Loaders::UnregisterOBJLoader(); Loaders::UnregisterPCX(); Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); From 5711ff555fb67a126423967b7bd9c84c489c1c57 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:36:42 +0200 Subject: [PATCH 161/224] Utility: Allow TriangleIterator and VertexMapper to take constant submesh Former-commit-id: 708fe75333a54b739794e7c9729ee1557ab26164 [formerly c68c2ff4e2deb1a512237ec4e502f00c801f7c7e] Former-commit-id: 5fd3fd8b0a518526ee3c91d418cf321611d2bc67 --- include/Nazara/Utility/TriangleIterator.hpp | 2 +- include/Nazara/Utility/VertexMapper.hpp | 2 ++ src/Nazara/Utility/TriangleIterator.cpp | 13 ++++++-- src/Nazara/Utility/VertexMapper.cpp | 36 +++++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Utility/TriangleIterator.hpp b/include/Nazara/Utility/TriangleIterator.hpp index 0addb1836..32c9ceb07 100644 --- a/include/Nazara/Utility/TriangleIterator.hpp +++ b/include/Nazara/Utility/TriangleIterator.hpp @@ -19,7 +19,7 @@ namespace Nz { public: TriangleIterator(PrimitiveMode primitiveMode, const IndexBuffer* indexBuffer); - TriangleIterator(SubMesh* subMesh); + TriangleIterator(const SubMesh* subMesh); ~TriangleIterator() = default; bool Advance(); diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index 3dc9accdb..e18250d7c 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -22,6 +22,8 @@ namespace Nz public: VertexMapper(SubMesh* subMesh, BufferAccess access = BufferAccess_ReadWrite); VertexMapper(VertexBuffer* vertexBuffer, BufferAccess access = BufferAccess_ReadWrite); + VertexMapper(const SubMesh* subMesh, BufferAccess access = BufferAccess_ReadOnly); + VertexMapper(const VertexBuffer* vertexBuffer, BufferAccess access = BufferAccess_ReadOnly); ~VertexMapper(); template SparsePtr GetComponentPtr(VertexComponent component); diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index 0c6830c87..53086ddb8 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -17,12 +17,19 @@ namespace Nz m_triangleIndices[1] = m_indexMapper.Get(1); m_triangleIndices[2] = m_indexMapper.Get(2); - m_indexCount = indexBuffer->GetIndexCount(); + m_indexCount = m_indexMapper.GetIndexCount(); } - TriangleIterator::TriangleIterator(SubMesh* subMesh) : - TriangleIterator(subMesh->GetPrimitiveMode(), subMesh->GetIndexBuffer()) + TriangleIterator::TriangleIterator(const SubMesh* subMesh) : + m_primitiveMode(subMesh->GetPrimitiveMode()), + m_indexMapper(subMesh, BufferAccess_ReadOnly) { + m_currentIndex = 3; + m_triangleIndices[0] = m_indexMapper.Get(0); + m_triangleIndices[1] = m_indexMapper.Get(1); + m_triangleIndices[2] = m_indexMapper.Get(2); + + m_indexCount = m_indexMapper.GetIndexCount(); } bool TriangleIterator::Advance() diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 1edbdc7f8..158dae801 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -47,6 +47,42 @@ namespace Nz ErrorFlags flags(ErrorFlag_ThrowException, true); m_mapper.Map(vertexBuffer, access); } + + VertexMapper::VertexMapper(const SubMesh* subMesh, BufferAccess access) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + const VertexBuffer* buffer = nullptr; + switch (subMesh->GetAnimationType()) + { + case AnimationType_Skeletal: + { + const SkeletalMesh* skeletalMesh = static_cast(subMesh); + buffer = skeletalMesh->GetVertexBuffer(); + break; + } + + case AnimationType_Static: + { + const StaticMesh* staticMesh = static_cast(subMesh); + buffer = staticMesh->GetVertexBuffer(); + break; + } + } + + if (!buffer) + { + NazaraInternalError("Animation type not handled (0x" + String::Number(subMesh->GetAnimationType(), 16) + ')'); + } + + m_mapper.Map(buffer, access); + } + + VertexMapper::VertexMapper(const VertexBuffer* vertexBuffer, BufferAccess access) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + m_mapper.Map(vertexBuffer, access); + } VertexMapper::~VertexMapper() = default; From c2270f23ce16a3122780b7c5b337faf36f5a2a7c Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:36:54 +0200 Subject: [PATCH 162/224] Utility/STBSaver: Fix error message Former-commit-id: 40d0d01efcce56f8cd1ba516a5f1336ac4dc2a26 [formerly 46a7331866a7a1033d8238d2f49a6100bc9e8dd6] Former-commit-id: 52de2bb4622a3499f69fb59dc5b9f1602cbac8cb --- src/Nazara/Utility/Formats/STBSaver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Formats/STBSaver.cpp b/src/Nazara/Utility/Formats/STBSaver.cpp index 4166de86f..1b65312fe 100644 --- a/src/Nazara/Utility/Formats/STBSaver.cpp +++ b/src/Nazara/Utility/Formats/STBSaver.cpp @@ -121,7 +121,7 @@ namespace Nz ImageType type = image.GetType(); if (type != ImageType_1D && type != ImageType_2D) { - NazaraError("Image type 0x" + String::Number(type, 16) + " is not "); + NazaraError("Image type 0x" + String::Number(type, 16) + " is not in a supported format"); return false; } From f17228d568a21063d26c5888fea6074b1ef949d0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:37:22 +0200 Subject: [PATCH 163/224] Utility/Mesh: Add MeshSaver Former-commit-id: 5d80ab9f7da18c157ba5f2b903007b8702f12700 [formerly 2e7f2fe5ea6ba7d744f7af8a89c073fb2519b4db] Former-commit-id: 05124de36a78a3780dd167efea9865c1728cc475 --- include/Nazara/Utility/Mesh.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 865a228a9..11e7c14bd 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ namespace Nz using MeshLoader = ResourceLoader; using MeshManager = ResourceManager; using MeshRef = ObjectRef; + using MeshSaver = ResourceSaver; struct MeshImpl; From a1a445d90dcba7df1109d5ddab8545e6a80fd53a Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:38:34 +0200 Subject: [PATCH 164/224] Utility/OBJParser: Fix mistake Former-commit-id: 09440c600405f710e5f1c03cac353f6986830814 [formerly 3ce06ef4b0d7c941835580b080e8a73c853e13cf] Former-commit-id: 21b606ff995a7192e5fa322b6eb11759ce274e39 --- src/Nazara/Utility/Formats/OBJParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 5c941e938..cec716442 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -125,9 +125,9 @@ namespace Nz for (unsigned int i = 0; i < vertexCount; ++i) { int offset; - std::size_t n = 0; - std::size_t p = 0; - std::size_t t = 0; + int n = 0; + int p = 0; + int t = 0; if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { From 6c34b55bdd77b4e5b615688e13cdfe1432b3cade Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:40:51 +0200 Subject: [PATCH 165/224] Utility/Mesh: Fix linking Former-commit-id: 03c42c75e847592a08693b607270673838a47230 [formerly 077959728baeaf36fe3ad80cf0fb2e8b6cc7e7e9] Former-commit-id: caae509fb871f0b05147f034c75403cafadd2959 --- src/Nazara/Utility/Mesh.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index f41f67440..0401a9a10 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -697,4 +697,5 @@ namespace Nz MeshLoader::LoaderList Mesh::s_loaders; MeshManager::ManagerMap Mesh::s_managerMap; MeshManager::ManagerParams Mesh::s_managerParameters; + MeshSaver::SaverList Mesh::s_savers; } From 925156b04445af44853da3b7ae836db1f80c1b06 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 12:40:25 +0200 Subject: [PATCH 167/224] Utility/Mesh: Fix error Former-commit-id: 0f5d9e858d70fe81c4d5d5c55fc6ceb6fe1c44ef [formerly e36fa3c3b8f9ba71e4147f582231e22a6e5340a7] Former-commit-id: 11d8c79aaf3edef5e5c6734d48994d464e18a680 --- include/Nazara/Utility/Mesh.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 11e7c14bd..36798e689 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -148,6 +148,7 @@ namespace Nz static MeshLoader::LoaderList s_loaders; static MeshManager::ManagerMap s_managerMap; static MeshManager::ManagerParams s_managerParameters; + static MeshSaver::SaverList s_savers; }; } From fa1dae35f3078acef2bfb4ac180237ce18545f53 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 18:02:19 +0200 Subject: [PATCH 168/224] Core/ParameterList: Fix GetIntegerParameter Former-commit-id: a7d0c83297d656a22f5688fed716b62ea15402c0 [formerly f45c562d8f8fdfe095c3f4b0dc7488da26332ff6] Former-commit-id: 53c706e8e5f13898f6e1287336d12106fc28a6e3 --- src/Nazara/Core/ParameterList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index abe93c640..bda37b4d4 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -249,7 +249,7 @@ namespace Nz case ParameterType_Integer: *value = it->second.value.intVal; - return false; + return true; case ParameterType_String: { From 1d193ec74adf43427d0234fcbbcdb49800498baa Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:34:45 +0200 Subject: [PATCH 169/224] Utility/OBJParser: Prepare for saving Former-commit-id: 245d757401397e329b906a4f48c913b434830475 [formerly da4af71db1570c669e82ab92c0a8a7a6301a5809] Former-commit-id: 5b14b24fe157a1411a9f76d6374c18be82e254de --- src/Nazara/Utility/Formats/OBJParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index cec716442..5c941e938 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -125,9 +125,9 @@ namespace Nz for (unsigned int i = 0; i < vertexCount; ++i) { int offset; - int n = 0; - int p = 0; - int t = 0; + std::size_t n = 0; + std::size_t p = 0; + std::size_t t = 0; if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { From 9bd73098b1fbf6cb57f89f66ca893c3621ea30b0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Jul 2016 08:38:34 +0200 Subject: [PATCH 170/224] Utility/OBJParser: Fix mistake Former-commit-id: 33818e53f56d87be8138a0380d20aa3a79ddf5ae [formerly f7f5cafdeb378db42fe74bd983d3049b45a9f636] Former-commit-id: 7e02c6e60c944941d2583ad8c96ac7c43ed66e94 --- src/Nazara/Utility/Formats/OBJParser.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 5c941e938..cec716442 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -125,9 +125,9 @@ namespace Nz for (unsigned int i = 0; i < vertexCount; ++i) { int offset; - std::size_t n = 0; - std::size_t p = 0; - std::size_t t = 0; + int n = 0; + int p = 0; + int t = 0; if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { From 45c51d2a13398e64ef8d2fd59f020cb6aa4872e3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:09:31 +0200 Subject: [PATCH 171/224] Core/ResourceSaver: Truncate output file Former-commit-id: dc3d2191feeb53daac920670d8054d74bea899c5 [formerly 58e3f50290a8f3dde6f0745438bf5852b12dab29] Former-commit-id: a5b9c5fe16ce738968d2e7b12b922344dc35e52d --- include/Nazara/Core/ResourceSaver.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Core/ResourceSaver.inl b/include/Nazara/Core/ResourceSaver.inl index 11d3f2a44..85f95fd3a 100644 --- a/include/Nazara/Core/ResourceSaver.inl +++ b/include/Nazara/Core/ResourceSaver.inl @@ -84,7 +84,7 @@ namespace Nz } else { - if (!file.Open(OpenMode_WriteOnly)) + if (!file.Open(OpenMode_WriteOnly | OpenMode_Truncate)) { NazaraError("Failed to save to file: unable to open \"" + filePath + "\" in write mode"); return false; From 58b014eb95b20bcd46976428c340c71197f16390 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:09:42 +0200 Subject: [PATCH 172/224] Build/Examples: Fix HardwareInfo console Former-commit-id: 0e23e60d138e896aa162ddfadda25ef16b2330fe [formerly 87731440d2a891659f6ebcbeaef220ee8a542739] Former-commit-id: 8b7aa329f80c332e5f3c5174942607ebc2b6de27 --- examples/HardwareInfo/build.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/HardwareInfo/build.lua b/examples/HardwareInfo/build.lua index e1b487bd6..afcc7b544 100644 --- a/examples/HardwareInfo/build.lua +++ b/examples/HardwareInfo/build.lua @@ -1,6 +1,6 @@ EXAMPLE.Name = "HardwareInfo" -EXAMPLE.Console = true +EXAMPLE.EnableConsole = true EXAMPLE.Defines = { "NAZARA_RENDERER_OPENGL" From 2d2c34cb4159c02247e1dcd847c9d68c1a43cf87 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:10:12 +0200 Subject: [PATCH 173/224] Utility/Formats: Make MD2Loader specify diffuse texture path instead of material filepath Former-commit-id: a2aa5553318958c7bf809bb83ee775062d80dca3 [formerly d290eac77b0ab16b2ccfb394ca5da3d508b66bc7] Former-commit-id: fb2b3a72ddfcd32562a6af726541367516f2adbf --- src/Nazara/Utility/Formats/MD2Loader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 126eeaa35..d1d03cf52 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -102,7 +102,8 @@ namespace Nz stream.Read(skin, 68*sizeof(char)); ParameterList matData; - matData.SetParameter(MaterialData::FilePath, baseDir + skin); + matData.SetParameter(MaterialData::CustomDefined, true); + matData.SetParameter(MaterialData::DiffuseTexturePath, baseDir + skin); mesh->SetMaterialData(i, std::move(matData)); } From ce8461ca35a9e69faf843c034b3346383a3dd8cc Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:11:03 +0200 Subject: [PATCH 174/224] Utility: Add MTL exporting Former-commit-id: b524c2d445f4c5cdadedabc3a9c38307dbfecb9b [formerly d65160f4e3f2fa2c7c9ddd151c73990c6712b4c1] Former-commit-id: 7ccdf043ccf793d3d9a5c9d93c65919ac015b52c --- include/Nazara/Utility/Formats/MTLParser.hpp | 39 +++- include/Nazara/Utility/Formats/MTLParser.inl | 83 +++++++ include/Nazara/Utility/Formats/OBJParser.hpp | 1 + include/Nazara/Utility/Formats/OBJParser.inl | 5 + src/Nazara/Utility/Formats/MTLParser.cpp | 234 +++++++++++++------ src/Nazara/Utility/Formats/OBJLoader.cpp | 28 ++- src/Nazara/Utility/Formats/OBJParser.cpp | 17 +- 7 files changed, 316 insertions(+), 91 deletions(-) create mode 100644 include/Nazara/Utility/Formats/MTLParser.inl diff --git a/include/Nazara/Utility/Formats/MTLParser.hpp b/include/Nazara/Utility/Formats/MTLParser.hpp index d58148ec7..9c5b49828 100644 --- a/include/Nazara/Utility/Formats/MTLParser.hpp +++ b/include/Nazara/Utility/Formats/MTLParser.hpp @@ -19,6 +19,22 @@ namespace Nz class NAZARA_UTILITY_API MTLParser { public: + struct Material; + + MTLParser() = default; + ~MTLParser() = default; + + inline Material* AddMaterial(const String& matName); + + inline void Clear(); + + inline const Material* GetMaterial(const String& materialName) const; + inline const std::unordered_map& GetMaterials() const; + + bool Parse(Stream& stream); + + bool Save(Stream& stream) const; + struct Material { Color ambient = Color::White; @@ -39,27 +55,26 @@ namespace Nz unsigned int illumModel = 0; }; - MTLParser(Stream& stream$); - ~MTLParser(); - - const Material* GetMaterial(const String& materialName) const; - const std::unordered_map& GetMaterials() const; - - bool Parse(); - private: bool Advance(bool required = true); - void Error(const String& message); - void Warning(const String& message); - void UnrecognizedLine(bool error = false); + template void Emit(const T& text) const; + inline void EmitLine() const; + template void EmitLine(const T& line) const; + inline void Error(const String& message); + inline void Flush() const; + inline void Warning(const String& message); + inline void UnrecognizedLine(bool error = false); std::unordered_map m_materials; - Stream& m_stream; + mutable Stream* m_currentStream; String m_currentLine; + mutable StringStream m_outputStream; bool m_keepLastLine; unsigned int m_lineCount; unsigned int m_streamFlags; }; } +#include + #endif // NAZARA_FORMATS_MTLPARSER_HPP diff --git a/include/Nazara/Utility/Formats/MTLParser.inl b/include/Nazara/Utility/Formats/MTLParser.inl new file mode 100644 index 000000000..0f8cd4f66 --- /dev/null +++ b/include/Nazara/Utility/Formats/MTLParser.inl @@ -0,0 +1,83 @@ +// 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 + +namespace Nz +{ + inline MTLParser::Material* MTLParser::AddMaterial(const String& matName) + { + return &m_materials[matName]; + } + + inline void MTLParser::Clear() + { + m_materials.clear(); + } + + inline const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const + { + auto it = m_materials.find(materialName); + if (it != m_materials.end()) + return &it->second; + else + return nullptr; + } + + inline const std::unordered_map& MTLParser::GetMaterials() const + { + return m_materials; + } + + template + void MTLParser::Emit(const T& text) const + { + m_outputStream << text; + if (m_outputStream.GetBufferSize() > 1024 * 1024) + Flush(); + } + + inline void MTLParser::EmitLine() const + { + Emit('\n'); + } + + template + void MTLParser::EmitLine(const T& line) const + { + Emit(line); + Emit('\n'); + } + + inline void MTLParser::Error(const String& message) + { + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + + inline void MTLParser::Flush() const + { + m_currentStream->Write(m_outputStream); + m_outputStream.Clear(); + } + + inline void MTLParser::Warning(const String& message) + { + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); + } + + inline void MTLParser::UnrecognizedLine(bool error) + { + String message = "Unrecognized \"" + m_currentLine + '"'; + + if (error) + Error(message); + else + Warning(message); + } +} + +#include +#include "MTLParser.hpp" diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index b9c5e41c3..50fa58900 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -52,6 +52,7 @@ namespace Nz inline String* SetMaterialCount(std::size_t materialCount); inline Mesh* SetMeshCount(std::size_t meshCount); + inline void SetMtlLib(const String& mtlLib); inline Vector3f* SetNormalCount(std::size_t normalCount); inline Vector4f* SetPositionCount(std::size_t positionCount); inline Vector3f* SetTexCoordCount(std::size_t texCoordCount); diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index a4fcffaec..9d961d54f 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -109,6 +109,11 @@ namespace Nz return m_meshes.data(); } + inline void OBJParser::SetMtlLib(const String& mtlLib) + { + m_mtlLib = mtlLib; + } + inline Vector3f* OBJParser::SetNormalCount(std::size_t normalCount) { m_normals.resize(normalCount); diff --git a/src/Nazara/Utility/Formats/MTLParser.cpp b/src/Nazara/Utility/Formats/MTLParser.cpp index 2398ccb3f..6685bcd04 100644 --- a/src/Nazara/Utility/Formats/MTLParser.cpp +++ b/src/Nazara/Utility/Formats/MTLParser.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -12,36 +13,22 @@ namespace Nz { - MTLParser::MTLParser(Stream& stream) : - m_stream(stream), - m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags + bool MTLParser::Parse(Stream& stream) { - m_stream.EnableTextMode(true); - } + m_currentStream = &stream; - MTLParser::~MTLParser() - { - // Reset stream flags - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.EnableTextMode(false); - } + // Force stream in text mode, reset it at the end + Nz::CallOnExit resetTextMode; + if ((stream.GetStreamOptions() & StreamOption_Text) == 0) + { + stream.EnableTextMode(true); - const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const - { - auto it = m_materials.find(materialName); - if (it != m_materials.end()) - return &it->second; - else - return nullptr; - } + resetTextMode.Reset([&stream] () + { + stream.EnableTextMode(false); + }); + } - const std::unordered_map& MTLParser::GetMaterials() const - { - return m_materials; - } - - bool MTLParser::Parse() - { m_keepLastLine = false; m_lineCount = 0; m_materials.clear(); @@ -57,7 +44,7 @@ namespace Nz if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->ambient = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); } @@ -72,7 +59,7 @@ namespace Nz if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->diffuse = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); } @@ -87,7 +74,7 @@ namespace Nz if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->specular = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); } @@ -102,7 +89,7 @@ namespace Nz if (std::sscanf(&m_currentLine[3], "%f", &density) == 1) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->refractionIndex = density; } @@ -117,7 +104,7 @@ namespace Nz if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->shininess = coef; } @@ -132,7 +119,7 @@ namespace Nz if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->alpha = alpha; } @@ -147,7 +134,7 @@ namespace Nz if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque } @@ -162,7 +149,7 @@ namespace Nz if (std::sscanf(&m_currentLine[6], "%u", &model) == 1) { if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->illumModel = model; } @@ -178,7 +165,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->ambientMap = map; } @@ -190,7 +177,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->diffuseMap = map; } @@ -202,7 +189,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->specularMap = map; } @@ -214,7 +201,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->bumpMap = map; } @@ -226,7 +213,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->alphaMap = map; } @@ -238,7 +225,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->decalMap = map; } @@ -250,7 +237,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->displacementMap = map; } @@ -262,7 +249,7 @@ namespace Nz { String map = m_currentLine.SubString(mapPos); if (!currentMaterial) - currentMaterial = &m_materials["default"]; + currentMaterial = AddMaterial("default"); currentMaterial->reflectionMap = map; } @@ -271,7 +258,7 @@ namespace Nz { String materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); if (!materialName.IsEmpty()) - currentMaterial = &m_materials[materialName]; + currentMaterial = AddMaterial(materialName); #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING else UnrecognizedLine(); @@ -286,13 +273,150 @@ namespace Nz return true; } + bool MTLParser::Save(Stream& stream) const + { + m_currentStream = &stream; + + // Force stream in text mode, reset it at the end + Nz::CallOnExit resetTextMode; + if ((stream.GetStreamOptions() & StreamOption_Text) == 0) + { + stream.EnableTextMode(true); + + resetTextMode.Reset([&stream] () + { + stream.EnableTextMode(false); + }); + } + + m_outputStream.Clear(); + + EmitLine("# Exported by Nazara Engine"); + EmitLine(); + + Emit("# material count: "); + Emit(m_materials.size()); + EmitLine(); + + for (auto& pair : m_materials) + { + const String& matName = pair.first; + const Material& mat = pair.second; + + Emit("newmtl "); + EmitLine(pair.first); + EmitLine(); + + Emit("Ka "); + Emit(mat.ambient.r / 255.f); + Emit(' '); + Emit(mat.ambient.g / 255.f); + Emit(' '); + Emit(mat.ambient.b / 255.f); + EmitLine(); + + Emit("Kd "); + Emit(mat.diffuse.r / 255.f); + Emit(' '); + Emit(mat.diffuse.g / 255.f); + Emit(' '); + Emit(mat.diffuse.b / 255.f); + EmitLine(); + + Emit("Ks "); + Emit(mat.specular.r / 255.f); + Emit(' '); + Emit(mat.specular.g / 255.f); + Emit(' '); + Emit(mat.specular.b / 255.f); + EmitLine(); + + if (mat.alpha != 1.f) + { + Emit("d "); + EmitLine(mat.alpha); + } + + if (mat.refractionIndex != 1.f) + { + Emit("ni "); + EmitLine(mat.refractionIndex); + } + + if (mat.shininess != 1.f) + { + Emit("ns "); + EmitLine(mat.shininess); + } + + if (mat.illumModel != 0) + { + Emit("illum "); + EmitLine(mat.illumModel); + } + + if (!mat.ambientMap.IsEmpty()) + { + Emit("map_Ka "); + EmitLine(mat.ambientMap); + } + + if (!mat.diffuseMap.IsEmpty()) + { + Emit("map_Kd "); + EmitLine(mat.diffuseMap); + } + + if (!mat.specularMap.IsEmpty()) + { + Emit("map_Ks "); + EmitLine(mat.specularMap); + } + + if (!mat.bumpMap.IsEmpty()) + { + Emit("map_bump "); + EmitLine(mat.bumpMap); + } + + if (!mat.alphaMap.IsEmpty()) + { + Emit("map_d "); + EmitLine(mat.alphaMap); + } + + if (!mat.decalMap.IsEmpty()) + { + Emit("map_decal "); + EmitLine(mat.decalMap); + } + + if (!mat.displacementMap.IsEmpty()) + { + Emit("map_disp "); + EmitLine(mat.displacementMap); + } + + if (!mat.reflectionMap.IsEmpty()) + { + Emit("map_refl "); + EmitLine(mat.reflectionMap); + } + EmitLine(); + } + + Flush(); + + return true; + } + bool MTLParser::Advance(bool required) { if (!m_keepLastLine) { do { - if (m_stream.EndOfStream()) + if (m_currentStream->EndOfStream()) { if (required) Error("Incomplete MTL file"); @@ -302,7 +426,7 @@ namespace Nz m_lineCount++; - m_currentLine = m_stream.ReadLine(); + m_currentLine = m_currentStream->ReadLine(); m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires m_currentLine.Simplify(); // Pour un traitement plus simple } @@ -313,24 +437,4 @@ namespace Nz return true; } - - void MTLParser::Error(const String& message) - { - NazaraError(message + " at line #" + String::Number(m_lineCount)); - } - - void MTLParser::Warning(const String& message) - { - NazaraWarning(message + " at line #" + String::Number(m_lineCount)); - } - - void MTLParser::UnrecognizedLine(bool error) - { - String message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); - } } diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index a8d5d68ec..1b1835b2b 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -49,8 +49,8 @@ namespace Nz return false; } - MTLParser materialParser(file); - if (!materialParser.Parse()) + MTLParser materialParser; + if (!materialParser.Parse(file)) { NazaraError("MTL parser failed"); return false; @@ -90,13 +90,31 @@ namespace Nz data.SetParameter(MaterialData::SpecularColor, specularColor); if (!mtlMat->alphaMap.IsEmpty()) - data.SetParameter(MaterialData::AlphaTexturePath, baseDir + mtlMat->alphaMap); + { + String fullPath = mtlMat->alphaMap; + if (!Nz::File::IsAbsolute(fullPath)) + fullPath.Prepend(baseDir); + + data.SetParameter(MaterialData::AlphaTexturePath, fullPath); + } if (!mtlMat->diffuseMap.IsEmpty()) - data.SetParameter(MaterialData::DiffuseTexturePath, baseDir + mtlMat->diffuseMap); + { + String fullPath = mtlMat->diffuseMap; + if (!Nz::File::IsAbsolute(fullPath)) + fullPath.Prepend(baseDir); + + data.SetParameter(MaterialData::DiffuseTexturePath, fullPath); + } if (!mtlMat->specularMap.IsEmpty()) - data.SetParameter(MaterialData::SpecularTexturePath, baseDir + mtlMat->specularMap); + { + String fullPath = mtlMat->specularMap; + if (!Nz::File::IsAbsolute(fullPath)) + fullPath.Prepend(baseDir); + + data.SetParameter(MaterialData::SpecularTexturePath, fullPath); + } // If we either have an alpha value or an alpha map, let's configure the material for transparency if (alphaValue != 255 || !mtlMat->alphaMap.IsEmpty()) diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index cec716442..bd189305f 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -386,10 +386,11 @@ namespace Nz m_outputStream.Clear(); EmitLine("# Exported by Nazara Engine"); + EmitLine(); if (!m_mtlLib.IsEmpty()) { - Emit("mtlib "); + Emit("mtllib "); EmitLine(m_mtlLib); EmitLine(); } @@ -403,17 +404,15 @@ namespace Nz Emit(position.x); Emit(' '); Emit(position.y); - if (!NumberEquals(position.z, 0.f) || !NumberEquals(position.w, 1.f)) + Emit(' '); + Emit(position.z); + + if (!NumberEquals(position.w, 1.f)) { Emit(' '); - Emit(position.z); - - if (!NumberEquals(position.w, 1.f)) - { - Emit(' '); - Emit(position.w); - } + Emit(position.w); } + EmitLine(); } EmitLine(); From 6084ff1707b66f09a3428a727985200c8bcbe626 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:11:25 +0200 Subject: [PATCH 175/224] Utility/Mesh: Add MeshSaver properly Former-commit-id: 08a7fb99853e68e692e1346577c8d616c1f4a6f9 [formerly 626e980416ee0ceea15036bd6355321400a19475] Former-commit-id: d39fd4d74d2d58c14057b0f769ceb7ce120c103a --- include/Nazara/Utility/Mesh.hpp | 4 ++++ src/Nazara/Utility/Mesh.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 36798e689..62a372384 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -71,6 +71,7 @@ namespace Nz friend MeshLibrary; friend MeshLoader; friend MeshManager; + friend MeshSaver; friend class Utility; public: @@ -126,6 +127,9 @@ namespace Nz void RemoveSubMesh(const String& identifier); void RemoveSubMesh(unsigned int index); + bool SaveToFile(const String& filePath, const MeshParams& params = MeshParams()); + bool SaveToStream(Stream& stream, const String& format, const MeshParams& params = MeshParams()); + void SetAnimation(const String& animationPath); void SetMaterialCount(unsigned int matCount); void SetMaterialData(unsigned int matIndex, ParameterList data); diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 0401a9a10..84559abda 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -606,6 +606,16 @@ namespace Nz InvalidateAABB(); } + bool Mesh::SaveToFile(const String& filePath, const MeshParams& params) + { + return MeshSaver::SaveToFile(*this, filePath, params); + } + + bool Mesh::SaveToStream(Stream& stream, const String& format, const MeshParams& params) + { + return MeshSaver::SaveToStream(*this, stream, format, params); + } + void Mesh::SetAnimation(const String& animationPath) { NazaraAssert(m_impl, "Mesh should be created first"); From f814f5054e11520cc8ab5c04a07fced2e78fe140 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 08:11:50 +0200 Subject: [PATCH 176/224] Utility/Formats: Add OBJSaver (WIP) Former-commit-id: 8f5fab2823f86ff5b12348eacfe238c74281c235 [formerly 9c9ad4880ee31052ae1850c53e4781690ce69f49] Former-commit-id: bde101aca68d5c6d205bb3d2252d656a6f7e078f --- src/Nazara/Utility/Formats/OBJSaver.cpp | 228 ++++++++++++++++++++++++ src/Nazara/Utility/Formats/OBJSaver.hpp | 21 +++ src/Nazara/Utility/Utility.cpp | 4 + 3 files changed, 253 insertions(+) create mode 100644 src/Nazara/Utility/Formats/OBJSaver.cpp create mode 100644 src/Nazara/Utility/Formats/OBJSaver.hpp diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp new file mode 100644 index 000000000..4fe468135 --- /dev/null +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -0,0 +1,228 @@ +// 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 +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace + { + template + class VertexCache + { + public: + VertexCache(T* ptr) : + m_count(0), + m_buffer(ptr) + { + } + + std::size_t GetCount() const + { + return m_count; + } + + std::size_t Insert(const T& data) + { + auto it = m_cache.find(data); + if (it == m_cache.end()) + { + it = m_cache.insert(std::make_pair(data, m_count)).first; + m_buffer[m_count] = data; + m_count++; + } + + return it->second + 1; + } + + private: + std::size_t m_count; + std::map m_cache; + T* m_buffer; + }; + + bool IsSupported(const String& extension) + { + return (extension == "obj"); + } + + bool SaveToStream(const Mesh& mesh, const String& format, Stream& stream, const MeshParams& parameters) + { + if (!mesh.IsValid()) + { + NazaraError("Invalid mesh"); + return false; + } + + if (mesh.IsAnimable()) + { + NazaraError("An animated mesh cannot be saved to " + format + " format"); + return false; + } + + std::size_t worstCacheVertexCount = mesh.GetVertexCount(); + OBJParser objFormat; + objFormat.SetNormalCount(worstCacheVertexCount); + objFormat.SetPositionCount(worstCacheVertexCount); + objFormat.SetTexCoordCount(worstCacheVertexCount); + + String mtlPath = stream.GetPath(); + if (!mtlPath.IsEmpty()) + { + mtlPath.Replace(".obj", ".mtl"); + String fileName = mtlPath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); + if (!fileName.IsEmpty()) + objFormat.SetMtlLib(fileName); + } + + VertexCache normalCache(objFormat.GetNormals()); + VertexCache positionCache(objFormat.GetPositions()); + VertexCache texCoordsCache(objFormat.GetTexCoords()); + + // Materials + MTLParser mtlFormat; + std::unordered_set registredMaterials; + + std::size_t matCount = mesh.GetMaterialCount(); + String* materialNames = objFormat.SetMaterialCount(matCount); + for (std::size_t i = 0; i < matCount; ++i) + { + const ParameterList& matData = mesh.GetMaterialData(i); + + String name; + if (!matData.GetStringParameter(MaterialData::Name, &name)) + name = "material_" + String::Number(i); + + // Makes sure we only have one material of that name + while (registredMaterials.find(name) != registredMaterials.end()) + name += '_'; + + registredMaterials.insert(name); + materialNames[i] = name; + + MTLParser::Material* material = mtlFormat.AddMaterial(name); + + bool bValue; + String strVal; + if (matData.GetBooleanParameter(MaterialData::CustomDefined, &bValue) && bValue) + { + Color colorVal; + float fValue; + + if (matData.GetColorParameter(MaterialData::AmbientColor, &colorVal)) + material->ambient = colorVal; + + if (matData.GetColorParameter(MaterialData::DiffuseColor, &colorVal)) + material->diffuse = colorVal; + + if (matData.GetColorParameter(MaterialData::SpecularColor, &colorVal)) + material->specular = colorVal; + + if (matData.GetFloatParameter(MaterialData::Shininess, &fValue)) + material->shininess = fValue; + + if (matData.GetStringParameter(MaterialData::AlphaTexturePath, &strVal)) + material->alphaMap = strVal; + + if (matData.GetStringParameter(MaterialData::DiffuseTexturePath, &strVal)) + material->diffuseMap = strVal; + + if (matData.GetStringParameter(MaterialData::SpecularTexturePath, &strVal)) + material->specularMap = strVal; + } + else if (matData.GetStringParameter(MaterialData::FilePath, &strVal)) + material->diffuseMap = strVal; + } + + // Meshes + std::size_t meshCount = mesh.GetSubMeshCount(); + OBJParser::Mesh* meshes = objFormat.SetMeshCount(meshCount); + for (std::size_t i = 0; i < meshCount; ++i) + { + const StaticMesh* staticMesh = static_cast(mesh.GetSubMesh(i)); + + std::size_t triangleCount = staticMesh->GetTriangleCount(); + std::size_t vertexCount = staticMesh->GetVertexCount(); + + meshes[i].faces.resize(triangleCount); + meshes[i].vertices.resize(triangleCount * 3); + + { + VertexMapper vertexMapper(staticMesh); + + SparsePtr normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + SparsePtr positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + SparsePtr texCoordsPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + std::size_t faceIndex = 0; + TriangleIterator triangle(staticMesh); + do + { + OBJParser::Face& face = meshes[i].faces[faceIndex]; + face.firstVertex = faceIndex * 3; + face.vertexCount = 3; + + for (std::size_t j = 0; j < 3; ++j) + { + OBJParser::FaceVertex& vertexIndices = meshes[i].vertices[face.firstVertex + j]; + + std::size_t index = triangle[j]; + vertexIndices.normal = normalCache.Insert(normalPtr[index]); + vertexIndices.position = positionCache.Insert(positionPtr[index]); + vertexIndices.texCoord = texCoordsCache.Insert(texCoordsPtr[index]); + } + + faceIndex++; + } + while (triangle.Advance()); + } + } + + objFormat.SetNormalCount(normalCache.GetCount()); + objFormat.SetPositionCount(positionCache.GetCount()); + objFormat.SetTexCoordCount(texCoordsCache.GetCount()); + + objFormat.Save(stream); + + if (!mtlPath.IsEmpty()) + { + File mtlFile(mtlPath, OpenMode_WriteOnly | OpenMode_Truncate); + if (mtlFile.IsOpen()) + mtlFormat.Save(mtlFile); + } + + return true; + } + } + + namespace Loaders + { + void RegisterOBJSaver() + { + MeshSaver::RegisterSaver(IsSupported, SaveToStream); + } + + void UnregisterOBJSaver() + { + MeshSaver::UnregisterSaver(IsSupported, SaveToStream); + } + } +} diff --git a/src/Nazara/Utility/Formats/OBJSaver.hpp b/src/Nazara/Utility/Formats/OBJSaver.hpp new file mode 100644 index 000000000..ed909f165 --- /dev/null +++ b/src/Nazara/Utility/Formats/OBJSaver.hpp @@ -0,0 +1,21 @@ +// 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_FORMATS_OBJSAVER_HPP +#define NAZARA_FORMATS_OBJSAVER_HPP + +#include + +namespace Nz +{ + namespace Loaders + { + void RegisterOBJSaver(); + void UnregisterOBJSaver(); + } +} + +#endif // NAZARA_FORMATS_OBJSAVER_HPP diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index ae5b5066d..6b2f66353 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -125,10 +126,12 @@ namespace Nz // Mesh (text) Loaders::RegisterOBJLoader(); + Loaders::RegisterOBJSaver(); // Mesh Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8) Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10) + Loaders::RegisterOBJLoader(); // Loader de fichiers .md5mesh (v10) // Image Loaders::RegisterPCX(); // Loader de fichiers .pcx (1, 4, 8, 24 bits) @@ -163,6 +166,7 @@ namespace Nz Loaders::UnregisterMD5Anim(); Loaders::UnregisterMD5Mesh(); Loaders::UnregisterOBJLoader(); + Loaders::UnregisterOBJSaver(); Loaders::UnregisterPCX(); Loaders::UnregisterSTBLoader(); Loaders::UnregisterSTBSaver(); From f8c4dda97f470a90ef8b6193b210fcd6db530988 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 12 Jul 2016 17:16:20 +0200 Subject: [PATCH 177/224] Delete Image.inl.save-failed Former-commit-id: 160b8d589c85d05886f46f77f191781e966ded37 [formerly 2bd02c1131275b7f48e71966f935c33a8517fa8e] Former-commit-id: b721cff7e246a88538296e29f9f7234f3773b431 --- include/Nazara/Utility/Image.inl.save-failed | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 include/Nazara/Utility/Image.inl.save-failed diff --git a/include/Nazara/Utility/Image.inl.save-failed b/include/Nazara/Utility/Image.inl.save-failed deleted file mode 100644 index 5cb8ef42f..000000000 --- a/include/Nazara/Utility/Image.inl.save-failed +++ /dev/null @@ -1,20 +0,0 @@ -// 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 From e3bb204ddf3843409af8f17ce0b742ecc6b12352 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 13 Jul 2016 12:26:38 +0200 Subject: [PATCH 178/224] Prevent GitHub to count external libraries into the project files Former-commit-id: 6ca53002d7211efbcac22d8062d02b19ce9cf85c [formerly 6b0ae084ee52a9d2f12dc251f73db8a9bc5a0d55] Former-commit-id: 7b9361c5c702b7e53556b7d81a011c599ffeeab0 --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitattributes b/.gitattributes index dfe077042..a788acb7e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,4 @@ # Auto detect text files and perform LF normalization * text=auto +extlibs/* linguist-vendored +NazaraModuleTemplate/* linguist-vendored From c7355ad166ffbf27fce73d9c7bca739bc55995ca Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 13 Jul 2016 12:27:30 +0200 Subject: [PATCH 179/224] Update global headers Former-commit-id: 57e803ee99f077bc0436b5284dc14bab7ab33555 [formerly 1551090a7423e44e74b68452c0f209a121ad8cd8] Former-commit-id: b275b8b680a3ddee30589d0e5f67a49d0448f066 --- include/Nazara/Graphics.hpp | 4 +++- include/Nazara/Noise.hpp | 29 ++++++++++------------------- include/Nazara/Utility.hpp | 3 ++- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 465aeb999..17b10e9a1 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 17 Nov 2015 at 13:20:45 +// This file was automatically generated on 12 Jul 2016 at 17:44:43 /* Nazara Engine - Graphics module @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/include/Nazara/Noise.hpp b/include/Nazara/Noise.hpp index 45b240378..e1d14460e 100644 --- a/include/Nazara/Noise.hpp +++ b/include/Nazara/Noise.hpp @@ -1,9 +1,9 @@ -// This file was automatically generated on 17 Nov 2015 at 13:20:45 +// This file was automatically generated on 12 Jul 2016 at 17:44:43 /* Nazara Engine - Noise module - Copyright (C) 2015 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) + Copyright (C) 2016 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -29,25 +29,16 @@ #ifndef NAZARA_GLOBAL_NOISE_HPP #define NAZARA_GLOBAL_NOISE_HPP -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include #endif // NAZARA_GLOBAL_NOISE_HPP diff --git a/include/Nazara/Utility.hpp b/include/Nazara/Utility.hpp index 156ca6389..d7676277e 100644 --- a/include/Nazara/Utility.hpp +++ b/include/Nazara/Utility.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 24 Jun 2015 at 13:55:50 +// This file was automatically generated on 12 Jul 2016 at 17:44:43 /* Nazara Engine - Utility module @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include From ef7759468a5d7ca11ae05d85737a758724b8141d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 17 Jul 2016 21:10:20 +0200 Subject: [PATCH 180/224] Utility/OBJSaver: Fix multiple materials saving Former-commit-id: 18d8c235a58fc627bcc4ecbbe5cfcd8fcdf00014 [formerly 358b88c21f73a36051baed60a943643c3ae9b03c] Former-commit-id: c1f89cb0f375db6c68048f0bc8e857306b6ca034 --- src/Nazara/Utility/Formats/MD2Loader.cpp | 2 +- src/Nazara/Utility/Formats/OBJSaver.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index d1d03cf52..c61dffd09 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -102,7 +102,7 @@ namespace Nz stream.Read(skin, 68*sizeof(char)); ParameterList matData; - matData.SetParameter(MaterialData::CustomDefined, true); + matData.SetParameter(MaterialData::CustomDefined); matData.SetParameter(MaterialData::DiffuseTexturePath, baseDir + skin); mesh->SetMaterialData(i, std::move(matData)); diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp index 4fe468135..9a79638bc 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.cpp +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -122,7 +122,7 @@ namespace Nz bool bValue; String strVal; - if (matData.GetBooleanParameter(MaterialData::CustomDefined, &bValue) && bValue) + if (matData.HasParameter(MaterialData::CustomDefined)) { Color colorVal; float fValue; @@ -160,9 +160,10 @@ namespace Nz const StaticMesh* staticMesh = static_cast(mesh.GetSubMesh(i)); std::size_t triangleCount = staticMesh->GetTriangleCount(); - std::size_t vertexCount = staticMesh->GetVertexCount(); meshes[i].faces.resize(triangleCount); + meshes[i].material = staticMesh->GetMaterialIndex(); + meshes[i].name = "mesh_" + String::Number(i); meshes[i].vertices.resize(triangleCount * 3); { From 31bc8604a412db9941c94affabeab680e0d3e4b1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Jul 2016 19:07:12 +0200 Subject: [PATCH 181/224] Build/Assimp: Fix compilation error because of missing includes Former-commit-id: b13f32ba6a53da69c8243425ca19766c96b97d26 [formerly 66000790be4f8ebe750ebe0d241f764b668278a1] Former-commit-id: 1da2a2b75eb42f118a1b843463fe715bd5fbabb0 --- build/scripts/tools/assimp.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/build/scripts/tools/assimp.lua b/build/scripts/tools/assimp.lua index 08688ef72..c810d6c0a 100644 --- a/build/scripts/tools/assimp.lua +++ b/build/scripts/tools/assimp.lua @@ -5,6 +5,7 @@ TOOL.Kind = "Plugin" TOOL.TargetDirectory = "../SDK/lib" TOOL.Includes = { + "../extlibs/include", "../include", "../plugins/Assimp" } From 56443c91e467bd0ffb92c918280042b838f0c938 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 21 Jul 2016 23:00:09 +0200 Subject: [PATCH 182/224] Renderer/RenderStates: Update RenderStates structure (preparing for renderer update) Former-commit-id: 392c7c33ff64d19e0fe3c7bdc8b22fe17c150887 [formerly d12a3c5f664fccebe0ee40a73bb0310e2d02287e] Former-commit-id: 22743f015567a8471f97cb90a06175f600ef0f8f --- include/Nazara/Graphics/Material.inl | 62 +++++++++- include/Nazara/Renderer/RenderStates.hpp | 84 +++++++++---- include/Nazara/Renderer/RenderStates.inl | 42 +------ src/Nazara/Graphics/ColorBackground.cpp | 8 +- src/Nazara/Graphics/DeferredBloomPass.cpp | 2 +- src/Nazara/Graphics/DeferredDOFPass.cpp | 2 +- src/Nazara/Graphics/DeferredFXAAPass.cpp | 2 +- src/Nazara/Graphics/DeferredFinalPass.cpp | 2 +- src/Nazara/Graphics/DeferredFogPass.cpp | 2 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 10 +- .../Graphics/DeferredPhongLightingPass.cpp | 30 ++--- src/Nazara/Graphics/Material.cpp | 66 +++++----- src/Nazara/Graphics/SkyboxBackground.cpp | 8 +- src/Nazara/Graphics/TextureBackground.cpp | 8 +- src/Nazara/Renderer/DebugDrawer.cpp | 6 +- src/Nazara/Renderer/OpenGL.cpp | 113 ++++++++++-------- src/Nazara/Renderer/Renderer.cpp | 110 ++++++++++++----- 17 files changed, 339 insertions(+), 218 deletions(-) diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 1e59e6157..6d5315640 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -53,7 +53,36 @@ namespace Nz { NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum"); - m_states.parameters[renderParameter] = enable; + switch (renderParameter) + { + case RendererParameter_Blend: + m_states.blending = enable; + return; + + case RendererParameter_ColorWrite: + m_states.colorWrite = enable; + return; + + case RendererParameter_DepthBuffer: + m_states.depthBuffer = enable; + return; + + case RendererParameter_DepthWrite: + m_states.depthWrite = enable; + return; + + case RendererParameter_FaceCulling: + m_states.faceCulling = enable; + return; + + case RendererParameter_ScissorTest: + m_states.scissorTest = enable; + return; + + case RendererParameter_StencilTest: + m_states.stencilTest = enable; + return; + } } /*! @@ -257,7 +286,7 @@ namespace Nz inline FaceSide Material::GetFaceCulling() const { - return m_states.faceCulling; + return m_states.cullingSide; } /*! @@ -489,7 +518,32 @@ namespace Nz { NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum"); - return m_states.parameters[parameter]; + switch (parameter) + { + case RendererParameter_Blend: + return m_states.blending; + + case RendererParameter_ColorWrite: + return m_states.colorWrite; + + case RendererParameter_DepthBuffer: + return m_states.depthBuffer; + + case RendererParameter_DepthWrite: + return m_states.depthWrite; + + case RendererParameter_FaceCulling: + return m_states.faceCulling; + + case RendererParameter_ScissorTest: + return m_states.scissorTest; + + case RendererParameter_StencilTest: + return m_states.stencilTest; + } + + NazaraInternalError("Unhandled renderer parameter: 0x" + String::Number(parameter, 16)); + return false; } /*! @@ -778,7 +832,7 @@ namespace Nz inline void Material::SetFaceCulling(FaceSide faceSide) { - m_states.faceCulling = faceSide; + m_states.cullingSide = faceSide; } /*! diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index 4040bec55..a885b2a7d 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -8,37 +8,75 @@ #define NAZARA_RENDERSTATES_HPP #include +#include namespace Nz { struct RenderStates { - RenderStates(); - RenderStates(const RenderStates& states); - ~RenderStates() = default; + BlendFunc dstBlend = BlendFunc_Zero; + BlendFunc srcBlend = BlendFunc_One; + FaceFilling faceFilling = FaceFilling_Fill; + FaceSide cullingSide = FaceSide_Back; + RendererComparison depthFunc = RendererComparison_Less; - RenderStates& operator=(const RenderStates& states); - - struct Face + struct { - RendererComparison stencilCompare; - StencilOperation stencilFail; - StencilOperation stencilPass; - StencilOperation stencilZFail; - UInt32 stencilMask; - unsigned int stencilReference; - }; + RendererComparison back = RendererComparison_Always; + RendererComparison front = RendererComparison_Always; + } stencilCompare; - Face backFace; - Face frontFace; - BlendFunc dstBlend; - BlendFunc srcBlend; - FaceFilling faceFilling; - FaceSide faceCulling; - RendererComparison depthFunc; - bool parameters[RendererParameter_Max+1]; - float lineWidth; - float pointSize; + struct + { + UInt32 back = 0xFFFFFFFF; + UInt32 front = 0xFFFFFFFF; + } stencilCompareMask; + + struct + { + StencilOperation back = StencilOperation_Keep; + StencilOperation front = StencilOperation_Keep; + } stencilDepthFail; + + struct + { + StencilOperation back = StencilOperation_Keep; + StencilOperation front = StencilOperation_Keep; + } stencilFail; + + struct + { + StencilOperation back = StencilOperation_Keep; + StencilOperation front = StencilOperation_Keep; + } stencilPass; + + struct + { + UInt32 back = 0U; + UInt32 front = 0U; + } stencilReference; + + struct + { + UInt32 back = 0xFFFFFFFF; + UInt32 front = 0xFFFFFFFF; + } stencilWriteMask; + + bool blending = false; + bool colorWrite = true; + bool depthBuffer = false; + bool depthWrite = true; + bool faceCulling = false; + bool scissorTest = false; + bool stencilTest = false; + + float lineWidth = 1.f; + float pointSize = 1.f; + }; + + struct RenderPipeline : RenderStates + { + ShaderConstRef shader; }; } diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 6840d3b5f..1f7564166 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -2,52 +2,12 @@ // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include namespace Nz { - inline RenderStates::RenderStates() : - dstBlend(BlendFunc_Zero), - srcBlend(BlendFunc_One), - faceFilling(FaceFilling_Fill), - faceCulling(FaceSide_Back), - depthFunc(RendererComparison_Less), - lineWidth(1.f), - pointSize(1.f) - { - parameters[RendererParameter_Blend] = false; - parameters[RendererParameter_ColorWrite] = true; - parameters[RendererParameter_DepthBuffer] = false; - parameters[RendererParameter_DepthWrite] = true; - parameters[RendererParameter_FaceCulling] = false; - parameters[RendererParameter_ScissorTest] = false; - parameters[RendererParameter_StencilTest] = false; - - for (unsigned int i = 0; i < 2; ++i) - { - Face& face = (i == 0) ? backFace : frontFace; - - face.stencilCompare = RendererComparison_Always; - face.stencilFail = StencilOperation_Keep; - face.stencilMask = 0xFFFFFFFF; - face.stencilPass = StencilOperation_Keep; - face.stencilReference = 0; - face.stencilZFail = StencilOperation_Keep; - } - } - - inline RenderStates::RenderStates(const RenderStates& states) - { - std::memcpy(this, &states, sizeof(RenderStates)); - } - - inline RenderStates& RenderStates::operator=(const RenderStates& states) - { - std::memcpy(this, &states, sizeof(RenderStates)); - - return *this; - } } #include diff --git a/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index 33c282390..dcacb1a46 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -19,11 +19,11 @@ namespace Nz RenderStates BuildRenderStates() { RenderStates states; + states.cullingSide = FaceSide_Back; states.depthFunc = RendererComparison_Equal; - states.faceCulling = FaceSide_Back; - states.parameters[RendererParameter_DepthBuffer] = true; - states.parameters[RendererParameter_DepthWrite] = false; - states.parameters[RendererParameter_FaceCulling] = true; + states.depthBuffer = true; + states.depthWrite = false; + states.faceCulling = true; return states; } diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index c902c7615..9cf39831a 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -32,7 +32,7 @@ namespace Nz m_bloomBrightShader = ShaderLibrary::Get("DeferredBloomBright"); m_bloomFinalShader = ShaderLibrary::Get("DeferredBloomFinal"); - m_bloomStates.parameters[RendererParameter_DepthBuffer] = false; + m_bloomStates.depthBuffer = false; m_gaussianBlurShader = ShaderLibrary::Get("DeferredGaussianBlur"); m_gaussianBlurShaderFilterLocation = m_gaussianBlurShader->GetUniformLocation("Filter"); diff --git a/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index 63df2c400..b39085400 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -127,7 +127,7 @@ namespace Nz m_pointSampler.SetFilterMode(SamplerFilter_Nearest); m_pointSampler.SetWrapMode(SamplerWrap_Clamp); - m_states.parameters[RendererParameter_DepthBuffer] = false; + m_states.depthBuffer = false; } DeferredDOFPass::~DeferredDOFPass() = default; diff --git a/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index 3f1e9395a..d4ba72ddf 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -28,7 +28,7 @@ namespace Nz m_pointSampler.SetFilterMode(SamplerFilter_Nearest); m_pointSampler.SetWrapMode(SamplerWrap_Clamp); - m_states.parameters[RendererParameter_DepthBuffer] = false; + m_states.depthBuffer = false; } DeferredFXAAPass::~DeferredFXAAPass() = default; diff --git a/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index 091c95af6..c4ab348eb 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -26,7 +26,7 @@ namespace Nz m_pointSampler.SetFilterMode(SamplerFilter_Nearest); m_pointSampler.SetWrapMode(SamplerWrap_Clamp); - m_states.parameters[RendererParameter_DepthBuffer] = false; + m_states.depthBuffer = false; m_uberShader = UberShaderLibrary::Get("Basic"); diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index f64521daf..f47a4ea56 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -141,7 +141,7 @@ namespace Nz m_shader = BuildFogShader(); m_shaderEyePositionLocation = m_shader->GetUniformLocation("EyePosition"); - m_states.parameters[RendererParameter_DepthBuffer] = false; + m_states.depthBuffer = false; } DeferredFogPass::~DeferredFogPass() = default; diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 08b111a70..86815558c 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -31,12 +31,12 @@ namespace Nz DeferredGeometryPass::DeferredGeometryPass() { m_clearShader = ShaderLibrary::Get("DeferredGBufferClear"); - m_clearStates.parameters[RendererParameter_DepthBuffer] = true; - m_clearStates.parameters[RendererParameter_FaceCulling] = true; - m_clearStates.parameters[RendererParameter_StencilTest] = true; + m_clearStates.depthBuffer = true; + m_clearStates.faceCulling = true; + m_clearStates.stencilTest = true; m_clearStates.depthFunc = RendererComparison_Always; - m_clearStates.frontFace.stencilCompare = RendererComparison_Always; - m_clearStates.frontFace.stencilPass = StencilOperation_Zero; + m_clearStates.stencilCompare.front = RendererComparison_Always; + m_clearStates.stencilPass.front = StencilOperation_Zero; } DeferredGeometryPass::~DeferredGeometryPass() = default; diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index efcc88e75..afe17ed13 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -120,9 +120,9 @@ namespace Nz RenderStates lightStates; lightStates.dstBlend = BlendFunc_One; lightStates.srcBlend = BlendFunc_One; - lightStates.parameters[RendererParameter_Blend] = true; - lightStates.parameters[RendererParameter_DepthBuffer] = false; - lightStates.parameters[RendererParameter_DepthWrite] = false; + lightStates.blending = true; + lightStates.depthBuffer = false; + lightStates.depthWrite = false; // Directional lights if (!m_renderQueue->directionalLights.empty()) @@ -146,18 +146,18 @@ namespace Nz if (!m_renderQueue->pointLights.empty() || !m_renderQueue->spotLights.empty()) { // http://www.altdevblogaday.com/2011/08/08/stencil-buffer-optimisation-for-deferred-lights/ - lightStates.parameters[RendererParameter_StencilTest] = true; - lightStates.faceCulling = FaceSide_Front; - lightStates.backFace.stencilMask = 0xFF; - lightStates.backFace.stencilReference = 0; - lightStates.backFace.stencilFail = StencilOperation_Keep; - lightStates.backFace.stencilPass = StencilOperation_Keep; - lightStates.backFace.stencilZFail = StencilOperation_Invert; - lightStates.frontFace.stencilMask = 0xFF; - lightStates.frontFace.stencilReference = 0; - lightStates.frontFace.stencilFail = StencilOperation_Keep; - lightStates.frontFace.stencilPass = StencilOperation_Keep; - lightStates.frontFace.stencilZFail = StencilOperation_Invert; + lightStates.cullingSide = FaceSide_Front; + lightStates.stencilTest = true; + lightStates.stencilDepthFail.back = StencilOperation_Invert; + lightStates.stencilDepthFail.front = StencilOperation_Invert; + lightStates.stencilFail.back = StencilOperation_Keep; + lightStates.stencilFail.front = StencilOperation_Keep; + lightStates.stencilPass.back = StencilOperation_Keep; + lightStates.stencilPass.front = StencilOperation_Keep; + lightStates.stencilReference.back = 0; + lightStates.stencilReference.front = 0; + lightStates.stencilWriteMask.back = 0xFF; + lightStates.stencilWriteMask.front = 0xFF; Renderer::SetRenderStates(lightStates); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 651f2581c..53e0e3e3e 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -252,41 +252,41 @@ namespace Nz // Stencil if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue)) - m_states.frontFace.stencilCompare = static_cast(iValue); + m_states.stencilCompare.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue)) - m_states.frontFace.stencilFail = static_cast(iValue); + m_states.stencilFail.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue)) - m_states.frontFace.stencilPass = static_cast(iValue); + m_states.stencilPass.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue)) - m_states.frontFace.stencilZFail = static_cast(iValue); + m_states.stencilDepthFail.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue)) - m_states.frontFace.stencilMask = static_cast(iValue); + m_states.stencilWriteMask.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue)) - m_states.frontFace.stencilReference = static_cast(iValue); + m_states.stencilReference.front = static_cast(iValue); // Stencil (back) if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue)) - m_states.backFace.stencilCompare = static_cast(iValue); + m_states.stencilCompare.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue)) - m_states.backFace.stencilFail = static_cast(iValue); + m_states.stencilFail.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue)) - m_states.backFace.stencilPass = static_cast(iValue); + m_states.stencilPass.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue)) - m_states.backFace.stencilZFail = static_cast(iValue); + m_states.stencilDepthFail.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue)) - m_states.backFace.stencilMask = static_cast(iValue); + m_states.stencilWriteMask.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue)) - m_states.backFace.stencilReference = static_cast(iValue); + m_states.stencilReference.back = static_cast(iValue); // Textures if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path)) @@ -332,13 +332,13 @@ namespace Nz matData->SetParameter(MaterialData::Transform, IsTransformEnabled()); // RendererParameter - matData->SetParameter(MaterialData::Blending, GetRenderStates().parameters[RendererParameter_Blend]); - matData->SetParameter(MaterialData::ColorWrite, GetRenderStates().parameters[RendererParameter_ColorWrite]); - matData->SetParameter(MaterialData::DepthBuffer, GetRenderStates().parameters[RendererParameter_DepthBuffer]); - matData->SetParameter(MaterialData::DepthWrite, GetRenderStates().parameters[RendererParameter_DepthWrite]); - matData->SetParameter(MaterialData::FaceCulling, GetRenderStates().parameters[RendererParameter_FaceCulling]); - matData->SetParameter(MaterialData::ScissorTest, GetRenderStates().parameters[RendererParameter_ScissorTest]); - matData->SetParameter(MaterialData::StencilTest, GetRenderStates().parameters[RendererParameter_StencilTest]); + matData->SetParameter(MaterialData::Blending, GetRenderStates().blending); + matData->SetParameter(MaterialData::ColorWrite, GetRenderStates().colorWrite); + matData->SetParameter(MaterialData::DepthBuffer, GetRenderStates().depthBuffer); + matData->SetParameter(MaterialData::DepthWrite, GetRenderStates().depthWrite); + matData->SetParameter(MaterialData::FaceCulling, GetRenderStates().faceCulling); + matData->SetParameter(MaterialData::ScissorTest, GetRenderStates().scissorTest); + matData->SetParameter(MaterialData::StencilTest, GetRenderStates().stencilTest); // Samplers matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, int(GetDiffuseSampler().GetAnisotropicLevel())); @@ -350,20 +350,20 @@ namespace Nz matData->SetParameter(MaterialData::SpecularWrap, int(GetSpecularSampler().GetWrapMode())); // Stencil - matData->SetParameter(MaterialData::StencilCompare, int(GetRenderStates().frontFace.stencilCompare)); - matData->SetParameter(MaterialData::StencilFail, int(GetRenderStates().frontFace.stencilFail)); - matData->SetParameter(MaterialData::StencilPass, int(GetRenderStates().frontFace.stencilPass)); - matData->SetParameter(MaterialData::StencilZFail, int(GetRenderStates().frontFace.stencilZFail)); - matData->SetParameter(MaterialData::StencilMask, int(GetRenderStates().frontFace.stencilMask)); - matData->SetParameter(MaterialData::StencilReference, int(GetRenderStates().frontFace.stencilReference)); + matData->SetParameter(MaterialData::StencilCompare, int(GetRenderStates().stencilCompare.front)); + matData->SetParameter(MaterialData::StencilFail, int(GetRenderStates().stencilFail.front)); + matData->SetParameter(MaterialData::StencilPass, int(GetRenderStates().stencilPass.front)); + matData->SetParameter(MaterialData::StencilZFail, int(GetRenderStates().stencilDepthFail.front)); + matData->SetParameter(MaterialData::StencilMask, int(GetRenderStates().stencilWriteMask.front)); + matData->SetParameter(MaterialData::StencilReference, int(GetRenderStates().stencilReference.front)); // Stencil (back) - matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetRenderStates().backFace.stencilCompare)); - matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetRenderStates().backFace.stencilFail)); - matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetRenderStates().backFace.stencilPass)); - matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetRenderStates().backFace.stencilZFail)); - matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetRenderStates().backFace.stencilMask)); - matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetRenderStates().backFace.stencilReference)); + matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetRenderStates().stencilCompare.back)); + matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetRenderStates().stencilFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetRenderStates().stencilPass.back)); + matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetRenderStates().stencilDepthFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetRenderStates().stencilWriteMask.back)); + matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetRenderStates().stencilReference.back)); // Textures if (HasAlphaMap()) @@ -441,8 +441,8 @@ namespace Nz m_specularColor = Color::White; m_specularSampler = TextureSampler(); m_states = RenderStates(); - m_states.parameters[RendererParameter_DepthBuffer] = true; - m_states.parameters[RendererParameter_FaceCulling] = true; + m_states.depthBuffer = true; + m_states.faceCulling = true; m_transformEnabled = true; SetShader("Basic"); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 75bc0cc12..fa7faefac 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -181,10 +181,10 @@ namespace Nz // Renderstates s_renderStates.depthFunc = RendererComparison_Equal; - s_renderStates.faceCulling = FaceSide_Front; - s_renderStates.parameters[RendererParameter_DepthBuffer] = true; - s_renderStates.parameters[RendererParameter_DepthWrite] = false; - s_renderStates.parameters[RendererParameter_FaceCulling] = true; + s_renderStates.cullingSide = FaceSide_Front; + s_renderStates.depthBuffer = true; + s_renderStates.depthWrite = false; + s_renderStates.faceCulling = true; // Exception-free zone s_indexBuffer = std::move(indexBuffer); diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index 1b2e53e72..a990f4af6 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -20,10 +20,10 @@ namespace Nz { RenderStates states; states.depthFunc = RendererComparison_Equal; - states.faceCulling = FaceSide_Back; - states.parameters[RendererParameter_DepthBuffer] = true; - states.parameters[RendererParameter_DepthWrite] = false; - states.parameters[RendererParameter_FaceCulling] = true; + states.cullingSide = FaceSide_Back; + states.depthBuffer = true; + states.depthWrite = false; + states.faceCulling = true; return states; } diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 5623e6e8d..9f06c880f 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -652,7 +652,7 @@ namespace Nz void DebugDrawer::EnableDepthBuffer(bool depthBuffer) { - s_renderStates.parameters[RendererParameter_DepthBuffer] = depthBuffer; + s_renderStates.depthBuffer = depthBuffer; } float DebugDrawer::GetLineWidth() @@ -698,7 +698,7 @@ namespace Nz } s_primaryColor = Color::Red; - s_renderStates.parameters[RendererParameter_DepthBuffer] = true; + s_renderStates.depthBuffer = true; s_secondaryColor = Color::Green; s_initialized = true; @@ -709,7 +709,7 @@ namespace Nz bool DebugDrawer::IsDepthBufferEnabled() { - return s_renderStates.parameters[RendererParameter_DepthBuffer]; + return s_renderStates.depthBuffer; } void DebugDrawer::SetLineWidth(float width) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index b77319997..ba17fe015 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -158,7 +158,7 @@ namespace Nz RenderStates& currentRenderStates = s_contextStates->renderStates; // Les fonctions de blend n'a aucun intérêt sans blending - if (states.parameters[RendererParameter_Blend]) + if (states.blending) { if (currentRenderStates.dstBlend != states.dstBlend || currentRenderStates.srcBlend != states.srcBlend) @@ -169,7 +169,7 @@ namespace Nz } } - if (states.parameters[RendererParameter_DepthBuffer]) + if (states.depthBuffer) { // La comparaison de profondeur n'a aucun intérêt sans depth buffer if (currentRenderStates.depthFunc != states.depthFunc) @@ -179,20 +179,20 @@ namespace Nz } // Le DepthWrite n'a aucune importance si le DepthBuffer est désactivé - if (currentRenderStates.parameters[RendererParameter_DepthWrite] != states.parameters[RendererParameter_DepthWrite]) + if (currentRenderStates.depthWrite != states.depthWrite) { - glDepthMask((states.parameters[RendererParameter_DepthWrite]) ? GL_TRUE : GL_FALSE); - currentRenderStates.parameters[RendererParameter_DepthWrite] = states.parameters[RendererParameter_DepthWrite]; + glDepthMask((states.depthWrite) ? GL_TRUE : GL_FALSE); + currentRenderStates.depthWrite = states.depthWrite; } } // Inutile de changer le mode de face culling s'il n'est pas actif - if (states.parameters[RendererParameter_FaceCulling]) + if (states.faceCulling) { - if (currentRenderStates.faceCulling != states.faceCulling) + if (currentRenderStates.cullingSide != states.cullingSide) { - glCullFace(FaceSide[states.faceCulling]); - currentRenderStates.faceCulling = states.faceCulling; + glCullFace(FaceSide[states.cullingSide]); + currentRenderStates.cullingSide = states.cullingSide; } } @@ -203,33 +203,46 @@ namespace Nz } // Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé - if (states.parameters[RendererParameter_StencilTest]) + if (states.stencilTest) { - for (unsigned int i = 0; i < 2; ++i) + if (currentRenderStates.stencilCompare.back != states.stencilCompare.back || + currentRenderStates.stencilReference.back != states.stencilReference.back || + currentRenderStates.stencilWriteMask.back != states.stencilWriteMask.back) { - GLenum face = (i == 0) ? GL_BACK : GL_FRONT; - const RenderStates::Face& srcStates = (i == 0) ? states.backFace : states.frontFace; - RenderStates::Face& dstStates = (i == 0) ? currentRenderStates.backFace : currentRenderStates.frontFace; + glStencilFuncSeparate(GL_BACK, RendererComparison[states.stencilCompare.back], states.stencilReference.back, states.stencilWriteMask.back); + currentRenderStates.stencilCompare.back = states.stencilCompare.back; + currentRenderStates.stencilReference.back = states.stencilReference.back; + currentRenderStates.stencilWriteMask.back = states.stencilWriteMask.back; + } - if (dstStates.stencilCompare != srcStates.stencilCompare || - dstStates.stencilMask != srcStates.stencilMask || - dstStates.stencilReference != srcStates.stencilReference) - { - glStencilFuncSeparate(face, RendererComparison[srcStates.stencilCompare], srcStates.stencilReference, srcStates.stencilMask); - dstStates.stencilCompare = srcStates.stencilCompare; - dstStates.stencilMask = srcStates.stencilMask; - dstStates.stencilReference = srcStates.stencilReference; - } + if (currentRenderStates.stencilDepthFail.back != states.stencilDepthFail.back || + currentRenderStates.stencilFail.back != states.stencilFail.back || + currentRenderStates.stencilPass.back != states.stencilPass.back) + { + glStencilOpSeparate(GL_BACK, StencilOperation[states.stencilFail.back], StencilOperation[states.stencilDepthFail.back], StencilOperation[states.stencilPass.back]); + currentRenderStates.stencilDepthFail.back = states.stencilDepthFail.back; + currentRenderStates.stencilFail.back = states.stencilFail.back; + currentRenderStates.stencilPass.back = states.stencilPass.back; + } - if (dstStates.stencilFail != srcStates.stencilFail || - dstStates.stencilPass != srcStates.stencilPass || - dstStates.stencilZFail != srcStates.stencilZFail) - { - glStencilOpSeparate(face, StencilOperation[srcStates.stencilFail], StencilOperation[srcStates.stencilZFail], StencilOperation[srcStates.stencilPass]); - dstStates.stencilFail = srcStates.stencilFail; - dstStates.stencilPass = srcStates.stencilPass; - dstStates.stencilZFail = srcStates.stencilZFail; - } + if (currentRenderStates.stencilCompare.front != states.stencilCompare.front || + currentRenderStates.stencilReference.front != states.stencilReference.front || + currentRenderStates.stencilWriteMask.front != states.stencilWriteMask.front) + { + glStencilFuncSeparate(GL_FRONT, RendererComparison[states.stencilCompare.front], states.stencilReference.front, states.stencilWriteMask.front); + currentRenderStates.stencilCompare.front = states.stencilCompare.front; + currentRenderStates.stencilReference.front = states.stencilReference.front; + currentRenderStates.stencilWriteMask.front = states.stencilWriteMask.front; + } + + if (currentRenderStates.stencilDepthFail.front != states.stencilDepthFail.front || + currentRenderStates.stencilFail.front != states.stencilFail.front || + currentRenderStates.stencilPass.front != states.stencilPass.front) + { + glStencilOpSeparate(GL_FRONT, StencilOperation[states.stencilFail.front], StencilOperation[states.stencilDepthFail.front], StencilOperation[states.stencilPass.front]); + currentRenderStates.stencilDepthFail.front = states.stencilDepthFail.front; + currentRenderStates.stencilFail.front = states.stencilFail.front; + currentRenderStates.stencilPass.front = states.stencilPass.front; } } @@ -246,62 +259,62 @@ namespace Nz } // Paramètres de rendu - if (currentRenderStates.parameters[RendererParameter_Blend] != states.parameters[RendererParameter_Blend]) + if (currentRenderStates.blending != states.blending) { - if (states.parameters[RendererParameter_Blend]) + if (states.blending) glEnable(GL_BLEND); else glDisable(GL_BLEND); - currentRenderStates.parameters[RendererParameter_Blend] = states.parameters[RendererParameter_Blend]; + currentRenderStates.blending = states.blending; } - if (currentRenderStates.parameters[RendererParameter_ColorWrite] != states.parameters[RendererParameter_ColorWrite]) + if (currentRenderStates.colorWrite != states.colorWrite) { - GLboolean param = (states.parameters[RendererParameter_ColorWrite]) ? GL_TRUE : GL_FALSE; + GLboolean param = (states.colorWrite) ? GL_TRUE : GL_FALSE; glColorMask(param, param, param, param); - currentRenderStates.parameters[RendererParameter_ColorWrite] = states.parameters[RendererParameter_ColorWrite]; + currentRenderStates.colorWrite = states.colorWrite; } - if (currentRenderStates.parameters[RendererParameter_DepthBuffer] != states.parameters[RendererParameter_DepthBuffer]) + if (currentRenderStates.depthBuffer != states.depthBuffer) { - if (states.parameters[RendererParameter_DepthBuffer]) + if (states.depthBuffer) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - currentRenderStates.parameters[RendererParameter_DepthBuffer] = states.parameters[RendererParameter_DepthBuffer]; + currentRenderStates.depthBuffer = states.depthBuffer; } - if (currentRenderStates.parameters[RendererParameter_FaceCulling] != states.parameters[RendererParameter_FaceCulling]) + if (currentRenderStates.faceCulling != states.faceCulling) { - if (states.parameters[RendererParameter_FaceCulling]) + if (states.faceCulling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - currentRenderStates.parameters[RendererParameter_FaceCulling] = states.parameters[RendererParameter_FaceCulling]; + currentRenderStates.faceCulling = states.faceCulling; } - if (currentRenderStates.parameters[RendererParameter_ScissorTest] != states.parameters[RendererParameter_ScissorTest]) + if (currentRenderStates.scissorTest != states.scissorTest) { - if (states.parameters[RendererParameter_ScissorTest]) + if (states.scissorTest) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); - currentRenderStates.parameters[RendererParameter_ScissorTest] = states.parameters[RendererParameter_ScissorTest]; + currentRenderStates.scissorTest = states.scissorTest; } - if (currentRenderStates.parameters[RendererParameter_StencilTest] != states.parameters[RendererParameter_StencilTest]) + if (currentRenderStates.stencilTest != states.stencilTest) { - if (states.parameters[RendererParameter_StencilTest]) + if (states.stencilTest) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST); - currentRenderStates.parameters[RendererParameter_StencilTest] = states.parameters[RendererParameter_StencilTest]; + currentRenderStates.stencilTest = states.stencilTest; } } diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index e49db2cec..028f7513f 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -396,7 +396,38 @@ namespace Nz } #endif - s_states.parameters[parameter] = enable; + switch (parameter) + { + case RendererParameter_Blend: + s_states.blending = enable; + return; + + case RendererParameter_ColorWrite: + s_states.colorWrite = enable; + return; + + case RendererParameter_DepthBuffer: + s_states.depthBuffer = enable; + return; + + case RendererParameter_DepthWrite: + s_states.depthWrite = enable; + return; + + case RendererParameter_FaceCulling: + s_states.faceCulling = enable; + return; + + case RendererParameter_ScissorTest: + s_states.scissorTest = enable; + return; + + case RendererParameter_StencilTest: + s_states.stencilTest = enable; + return; + } + + NazaraInternalError("Unhandled renderer parameter: 0x" + String::Number(parameter, 16)); } void Renderer::EndCondition() @@ -762,7 +793,32 @@ namespace Nz } #endif - return s_states.parameters[parameter]; + switch (parameter) + { + case RendererParameter_Blend: + return s_states.blending; + + case RendererParameter_ColorWrite: + return s_states.colorWrite; + + case RendererParameter_DepthBuffer: + return s_states.depthBuffer; + + case RendererParameter_DepthWrite: + return s_states.depthWrite; + + case RendererParameter_FaceCulling: + return s_states.faceCulling; + + case RendererParameter_ScissorTest: + return s_states.scissorTest; + + case RendererParameter_StencilTest: + return s_states.stencilTest; + } + + NazaraInternalError("Unhandled renderer parameter: 0x" + String::Number(parameter, 16)); + return false; } bool Renderer::IsInitialized() @@ -865,7 +921,7 @@ namespace Nz } #endif - s_states.faceCulling = faceSide; + s_states.cullingSide = faceSide; } void Renderer::SetFaceFilling(FaceFilling fillingMode) @@ -1042,16 +1098,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilCompare = compareFunc; + s_states.stencilCompare.back = compareFunc; break; case FaceSide_Front: - s_states.frontFace.stencilCompare = compareFunc; + s_states.stencilCompare.front = compareFunc; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilCompare = compareFunc; - s_states.frontFace.stencilCompare = compareFunc; + s_states.stencilCompare.back = compareFunc; + s_states.stencilCompare.front = compareFunc; break; } } @@ -1075,16 +1131,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilFail = failOperation; + s_states.stencilFail.back = failOperation; break; case FaceSide_Front: - s_states.frontFace.stencilFail = failOperation; + s_states.stencilFail.front = failOperation; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilFail = failOperation; - s_states.frontFace.stencilFail = failOperation; + s_states.stencilFail.back = failOperation; + s_states.stencilFail.front = failOperation; break; } } @@ -1102,16 +1158,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilMask = mask; + s_states.stencilWriteMask.back = mask; break; case FaceSide_Front: - s_states.frontFace.stencilMask = mask; + s_states.stencilWriteMask.front = mask; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilMask = mask; - s_states.frontFace.stencilMask = mask; + s_states.stencilWriteMask.back = mask; + s_states.stencilWriteMask.front = mask; break; } } @@ -1135,16 +1191,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilPass = passOperation; + s_states.stencilPass.back = passOperation; break; case FaceSide_Front: - s_states.frontFace.stencilPass = passOperation; + s_states.stencilPass.front = passOperation; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilPass = passOperation; - s_states.frontFace.stencilPass = passOperation; + s_states.stencilPass.back = passOperation; + s_states.stencilPass.front = passOperation; break; } } @@ -1162,16 +1218,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilReference = refValue; + s_states.stencilReference.back = refValue; break; case FaceSide_Front: - s_states.frontFace.stencilReference = refValue; + s_states.stencilReference.front = refValue; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilReference = refValue; - s_states.frontFace.stencilReference = refValue; + s_states.stencilReference.back = refValue; + s_states.stencilReference.front = refValue; break; } } @@ -1195,16 +1251,16 @@ namespace Nz switch (faceSide) { case FaceSide_Back: - s_states.backFace.stencilZFail = zfailOperation; + s_states.stencilDepthFail.back = zfailOperation; break; case FaceSide_Front: - s_states.frontFace.stencilZFail = zfailOperation; + s_states.stencilDepthFail.front = zfailOperation; break; case FaceSide_FrontAndBack: - s_states.backFace.stencilZFail = zfailOperation; - s_states.frontFace.stencilZFail = zfailOperation; + s_states.stencilDepthFail.back = zfailOperation; + s_states.stencilDepthFail.front = zfailOperation; break; } } From 25d7112054e45d2fd7717355817130422ae9ba80 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 23 Jul 2016 18:06:17 +0200 Subject: [PATCH 183/224] Graphics: Add TileMap class Former-commit-id: 0a45b956501998a40a6406f7fff6e6cc85b4b4db [formerly ab84ea10c52b128b17241844e6a4b3887c6618ab] Former-commit-id: d62bbb11f5205daa6af3f7b9152be3fb213ca564 --- include/Nazara/Graphics/TileMap.hpp | 97 ++++++ include/Nazara/Graphics/TileMap.inl | 441 ++++++++++++++++++++++++++++ src/Nazara/Graphics/Graphics.cpp | 8 + src/Nazara/Graphics/TileMap.cpp | 110 +++++++ 4 files changed, 656 insertions(+) create mode 100644 include/Nazara/Graphics/TileMap.hpp create mode 100644 include/Nazara/Graphics/TileMap.inl create mode 100644 src/Nazara/Graphics/TileMap.cpp diff --git a/include/Nazara/Graphics/TileMap.hpp b/include/Nazara/Graphics/TileMap.hpp new file mode 100644 index 000000000..89a901b9a --- /dev/null +++ b/include/Nazara/Graphics/TileMap.hpp @@ -0,0 +1,97 @@ +// Copyright (C) 2016 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_TILEMAP_HPP +#define NAZARA_TILEMAP_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + class TileMap; + + using TileMapConstRef = ObjectRef; + using TileMapLibrary = ObjectLibrary; + using TileMapRef = ObjectRef; + + class NAZARA_GRAPHICS_API TileMap : public InstancedRenderable + { + friend TileMapLibrary; + friend class Graphics; + + public: + struct Tile; + + inline TileMap(const Nz::Vector2ui& mapSize, const Nz::Vector2f& tileSize, std::size_t materialCount = 1); + TileMap(const TileMap& TileMap) = default; + TileMap(TileMap&&) = delete; + ~TileMap() = default; + + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + + inline void DisableTile(const Vector2ui& tilePos); + inline void DisableTiles(); + inline void DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount); + + inline void EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); + inline void EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); + inline void EnableTiles(const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); + inline void EnableTiles(const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); + inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color = Color::White, std::size_t materialIndex = 0U); + inline void EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color = Color::White, std::size_t materialIndex = 0U); + + inline const MaterialRef& GetMaterial(std::size_t index) const; + inline std::size_t GetMaterialCount() const; + inline const Vector2ui& GetMapSize() const; + inline Vector2f GetSize() const; + inline const Tile& GetTile(const Vector2ui& tilePos) const; + inline const Vector2f& GetTileSize() const; + + inline void SetMaterial(std::size_t index, MaterialRef material); + + inline TileMap& operator=(const TileMap& TileMap); + TileMap& operator=(TileMap&& TileMap) = delete; + + template static TileMapRef New(Args&&... args); + + struct Tile + { + std::size_t layerIndex = 0U; + Color color = Color::White; + Rectf textureCoords = Rectf::Zero(); + bool enabled = false; + }; + + private: + void MakeBoundingVolume() const override; + void UpdateData(InstanceData* instanceData) const override; + + static bool Initialize(); + static void Uninitialize(); + + struct Layer + { + MaterialRef material; + std::set tiles; + }; + + std::vector m_tiles; + std::vector m_layers; + Vector2ui m_mapSize; + Vector2f m_tileSize; + + static TileMapLibrary::LibraryMap s_library; + }; +} + +#include + +#endif // NAZARA_TILEMAP_HPP diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl new file mode 100644 index 000000000..684b21387 --- /dev/null +++ b/include/Nazara/Graphics/TileMap.inl @@ -0,0 +1,441 @@ +// 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 +{ + /*! + * \brief Constructs a TileMap object, containing mapSize tileSize-sized tiles + * + * \param mapSize Number of tiles in each dimension, must be + * \param tileSize Size of each tile of the TileMap + * \param materialCount The maximum number of differents Material this TileMap will use + * + * \remark When constructed, a TileMap has no tile active and will not be rendered + * To use it, you have to enable some tiles. + * + * \remark The default material is used for every material requested + */ + inline TileMap::TileMap(const Nz::Vector2ui& mapSize, const Nz::Vector2f& tileSize, std::size_t materialCount) : + m_tiles(mapSize.x * mapSize.y), + m_layers(materialCount), + m_mapSize(mapSize), + m_tileSize(tileSize) + { + NazaraAssert(m_tiles.size() != 0U, "Invalid map size"); + NazaraAssert(m_tileSize.x != 0U && m_tileSize.y != 0U, "Invalid tile size"); + NazaraAssert(m_layers.size() != 0U, "Invalid material count"); + + for (Layer& layer : m_layers) + layer.material = Material::GetDefault(); + + InvalidateBoundingVolume(); + } + + /*! + * \brief Disable the tile at position tilePos, disabling rendering at this location + * + * \param tilePos Position of the tile to disable + * + * \seealso DisableTiles + */ + inline void TileMap::DisableTile(const Vector2ui& tilePos) + { + NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds"); + + std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x; + Tile& tile = m_tiles[tileIndex]; + tile.enabled = false; + + m_layers[tile.layerIndex].tiles.erase(tileIndex); + + InvalidateInstanceData(1U << tile.layerIndex); + } + + /*! + * \brief Disable all tiles + */ + inline void TileMap::DisableTiles() + { + for (Tile& tile : m_tiles) + tile.enabled = false; + + for (Layer& layer : m_layers) + layer.tiles.clear(); + + InvalidateInstanceData(0xFFFFFFFF); + } + + /*! + * \brief Disable tileCount tiles at positions contained at tilesPos location, disabling rendering at those locations + * + * This is equivalent to calling tileCount times DisableTile with the positions contained at tilesPos + * + * \param tilesPos Pointer to a valid array of at least tileCount positions + * \param tileCount Number of tiles to disable + * + * \remark if tileCount is zero, this is a no-op and the value of tilesPos is not used + * + * \seealso DisableTile + */ + inline void TileMap::DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount) + { + NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount"); + + UInt32 invalidatedLayers = 0; + + for (std::size_t i = 0; i < tileCount; ++i) + { + NazaraAssert(tilesPos->x < m_mapSize.x && tilesPos->y < m_mapSize.y, "Tile position is out of bounds"); + + std::size_t tileIndex = tilesPos->y * m_mapSize.x + tilesPos->x; + Tile& tile = m_tiles[tileIndex]; + tile.enabled = false; + + m_layers[tile.layerIndex].tiles.erase(tileIndex); + + invalidatedLayers |= 1U << tile.layerIndex; + + tilesPos++; + } + + if (tileCount > 0) + InvalidateInstanceData(invalidatedLayers); + } + + /*! + * \brief Enable and sets the tile at position tilePos + * + * Setup the tile at position tilePos using color, normalized coordinates coords and materialIndex + * + * \param tilePos Position of the tile to enable + * \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \seealso EnableTiles + */ + inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color, std::size_t materialIndex) + { + NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds"); + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + + UInt32 invalidatedLayers = 1U << materialIndex; + + std::size_t tileIndex = tilePos.y * m_mapSize.x + tilePos.x; + Tile& tile = m_tiles[tilePos.y * m_mapSize.x + tilePos.x]; + + if (!tile.enabled) + m_layers[materialIndex].tiles.insert(tileIndex); + else if (materialIndex != tile.layerIndex) + { + m_layers[materialIndex].tiles.erase(tileIndex); + m_layers[tile.layerIndex].tiles.insert(tileIndex); + + invalidatedLayers |= 1U << tile.layerIndex; + } + + tile.enabled = true; + tile.color = color; + tile.textureCoords = coords; + tile.layerIndex = materialIndex; + + InvalidateInstanceData(invalidatedLayers); + } + + /*! + * \brief Enable and sets the tile at position tilePos + * + * Setup the tile at position tilePos using color, unnormalized coordinates rect and materialIndex + * + * \param tilePos Position of the tile to enable + * \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \remark The material at [materialIndex] must have a valid diffuse map before using this function, + * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. + * + * \seealso EnableTiles + */ + inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color, std::size_t materialIndex) + { + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + float invWidth = 1.f / diffuseMap->GetWidth(); + float invHeight = 1.f / diffuseMap->GetHeight(); + + Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height); + EnableTile(tilePos, unnormalizedCoords, color, materialIndex); + } + + /*! + * \brief Enable and sets all the tiles + * + * Setup all tiles using color, normalized coordinates coords and materialIndex + * + * \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \remark The material at [materialIndex] must have a valid diffuse map before using this function, + * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. + * + * \seealso EnableTile + */ + inline void TileMap::EnableTiles(const Rectf& coords, const Color& color, std::size_t materialIndex) + { + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + + for (Layer& layer : m_layers) + layer.tiles.clear(); + + std::size_t tileIndex = 0; + for (Tile& tile : m_tiles) + { + tile.enabled = true; + tile.color = color; + tile.textureCoords = coords; + tile.layerIndex = materialIndex; + + m_layers[materialIndex].tiles.insert(tileIndex++); + } + + InvalidateInstanceData(0xFFFFFFFF); + } + + /*! + * \brief Enable and sets all the tiles + * + * Setup all tiles using color, unnormalized coordinates coords and materialIndex + * + * \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \remark The material at [materialIndex] must have a valid diffuse map before using this function, + * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. + * + * \seealso EnableTile + */ + inline void TileMap::EnableTiles(const Rectui& rect, const Color& color, std::size_t materialIndex) + { + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + + Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + float invWidth = 1.f / diffuseMap->GetWidth(); + float invHeight = 1.f / diffuseMap->GetHeight(); + + Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height); + EnableTiles(unnormalizedCoords, color, materialIndex); + } + + /*! + * \brief Enable and sets tileCount tiles at positions contained at tilesPos location, enabling rendering at those locations + * + * Setup all tiles using color, normalized coordinates coords and materialIndex + * + * \param tilesPos Pointer to a valid array of at least tileCount positions + * \param tileCount Number of tiles to enable + * \param coords Normalized coordinates ([0..1]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \seealso EnableTile + */ + inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color, std::size_t materialIndex) + { + NazaraAssert(tilesPos || tileCount == 0, "Invalid tile position array with a non-zero tileCount"); + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + + UInt32 invalidatedLayers = 1U << materialIndex; + + for (std::size_t i = 0; i < tileCount; ++i) + { + NazaraAssert(tilesPos->x < m_mapSize.x && tilesPos->y < m_mapSize.y, "Tile position is out of bounds"); + + std::size_t tileIndex = tilesPos->y * m_mapSize.x + tilesPos->x; + Tile& tile = m_tiles[tileIndex]; + + if (!tile.enabled) + m_layers[materialIndex].tiles.insert(tileIndex); + else if (materialIndex != tile.layerIndex) + { + m_layers[materialIndex].tiles.erase(tileIndex); + m_layers[tile.layerIndex].tiles.insert(tileIndex); + + invalidatedLayers |= 1U << tile.layerIndex; + } + + tile.enabled = true; + tile.color = color; + tile.textureCoords = coords; + tile.layerIndex = materialIndex; + tilesPos++; + } + + if (tileCount > 0) + InvalidateInstanceData(invalidatedLayers); + } + + /*! + * \brief Enable and sets tileCount tiles at positions contained at tilesPos location, enabling rendering at those locations + * + * Setup all tiles using color, unnormalized coordinates coords and materialIndex + * + * \param tilesPos Pointer to a valid array of at least tileCount positions + * \param tileCount Number of tiles to enable + * \param coords Unnormalized coordinates ([0..size]) used to specify which region of the material textures will be used + * \param color The multiplicative color applied to the tile + * \param materialIndex The material which will be used for rendering this tile + * + * \remark The material at [materialIndex] must have a valid diffuse map before using this function, + * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. + * + * \seealso EnableTile + */ + inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color, std::size_t materialIndex) + { + NazaraAssert(materialIndex < m_layers.size(), "Material out of bounds"); + NazaraAssert(m_layers[materialIndex].material->HasDiffuseMap(), "Material has no diffuse map"); + + Texture* diffuseMap = m_layers[materialIndex].material->GetDiffuseMap(); + float invWidth = 1.f / diffuseMap->GetWidth(); + float invHeight = 1.f / diffuseMap->GetHeight(); + + Rectf unnormalizedCoords(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height); + EnableTiles(tilesPos, tileCount, unnormalizedCoords, color, materialIndex); + } + + /*! + * \brief Gets the material at position index used by the TileMap + * + * \param index Index of the material to query + * + * \return Material at index + */ + inline const MaterialRef& TileMap::GetMaterial(std::size_t index) const + { + NazaraAssert(index < m_layers.size(), "Material out of bounds"); + + return m_layers[index].material; + } + + /*! + * \brief Gets the maximum material count this TileMap can use + * \return Material count + */ + inline std::size_t TileMap::GetMaterialCount() const + { + return m_layers.size(); + } + + /*! + * \brief Gets the tilemap size (i.e. number of tiles in each dimension) + * \return Number of tiles in each dimension + * + * \seealso GetSize + * \seealso GetTileSize + */ + inline const Vector2ui& TileMap::GetMapSize() const + { + return m_mapSize; + } + + /*! + * \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize()) + * \return Maximum size in units occupied by this tilemap + * + * \seealso GetMapSize + * \seealso GetTileSize + */ + inline Vector2f TileMap::GetSize() const + { + return Vector2f(m_mapSize) * m_tileSize; + } + + /*! + * \brief Returns informations about a particular tile + * + * \param tilePos Position of the tile to get (enabled or not) + * + * \return Maximum size in units occupied by this tilemap + */ + inline const TileMap::Tile& TileMap::GetTile(const Vector2ui& tilePos) const + { + NazaraAssert(tilePos.x < m_mapSize.x && tilePos.y < m_mapSize.y, "Tile position is out of bounds"); + + return m_tiles[tilePos.y * m_mapSize.x + tilePos.x]; + } + + /*! + * \brief Gets the tile size (i.e. number of units occupied by a tile in each dimension) + * \return Tile size in each dimension + * + * \seealso GetMapSize + * \seealso GetSize + */ + inline const Vector2f& TileMap::GetTileSize() const + { + return m_tileSize; + } + + /*! + * \brief Sets a material of the TileMap + * + * \param index Index of the material to change + * \param material Material for the TileMap + */ + inline void TileMap::SetMaterial(std::size_t index, MaterialRef material) + { + NazaraAssert(index < m_layers.size(), "Material out of bounds"); + + m_layers[index].material = std::move(material); + } + + /*! + * \brief Sets the current TileMap with the content of the other one + * \return A reference to this + * + * \param TileMap The other TileMap + */ + inline TileMap& TileMap::operator=(const TileMap& TileMap) + { + InstancedRenderable::operator=(TileMap); + + m_layers = TileMap.m_layers; + m_mapSize = TileMap.m_mapSize; + m_tiles = TileMap.m_tiles; + m_tileSize = TileMap.m_tileSize; + + // We do not copy final vertices because it's highly probable that our parameters are modified and they must be regenerated + InvalidateBoundingVolume(); + InvalidateInstanceData(0xFFFFFFFF); + + return *this; + } + + /*! + * \brief Creates a new TileMap from the arguments + * \return A reference to the newly created TileMap + * + * \param args Arguments for the TileMap + */ + template + TileMapRef TileMap::New(Args&&... args) + { + std::unique_ptr object(new TileMap(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index c9cc652a8..5e6cd72b7 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,12 @@ namespace Nz return false; } + if (!TileMap::Initialize()) + { + NazaraError("Failed to initialize tilemaps"); + return false; + } + // Generic loaders Loaders::RegisterMesh(); Loaders::RegisterTexture(); @@ -217,6 +224,7 @@ namespace Nz Material::Uninitialize(); SkyboxBackground::Uninitialize(); Sprite::Uninitialize(); + TileMap::Uninitialize(); NazaraNotice("Uninitialized: Graphics module"); diff --git a/src/Nazara/Graphics/TileMap.cpp b/src/Nazara/Graphics/TileMap.cpp new file mode 100644 index 000000000..9d835cb24 --- /dev/null +++ b/src/Nazara/Graphics/TileMap.cpp @@ -0,0 +1,110 @@ +// 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 + +namespace Nz +{ + /*! + * \ingroup graphics + * \class Nz::TileMap + * \brief Graphics class that represent several tiles of the same size assembled into a grid + * This class is far more efficient than using a sprite for every tile + */ + + /*! + * \brief Adds the TileMap to the rendering queue + * + * \param renderQueue Queue to be added + * \param instanceData Data for the instance + */ + void TileMap::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const + { + const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + + std::size_t spriteCount = 0; + for (const Layer& layer : m_layers) + { + if (layer.material) + renderQueue->AddSprites(instanceData.renderOrder, layer.material, &vertices[spriteCount], layer.tiles.size()); + + spriteCount += layer.tiles.size(); + } + } + + void TileMap::MakeBoundingVolume() const + { + Nz::Vector2f size = GetSize(); + m_boundingVolume.Set(Vector3f(0.f), size.x*Vector3f::Right() + size.y*Vector3f::Down()); + } + + void TileMap::UpdateData(InstanceData* instanceData) const + { + std::size_t spriteCount = 0; + for (const Layer& layer : m_layers) + spriteCount += layer.tiles.size(); + + instanceData->data.resize(4 * spriteCount * sizeof(VertexStruct_XYZ_Color_UV)); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); + + spriteCount = 0; + for (const Layer& layer : m_layers) + { + SparsePtr colorPtr(&vertices[spriteCount].color, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr posPtr(&vertices[spriteCount].position, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr texCoordPtr(&vertices[spriteCount].uv, sizeof(VertexStruct_XYZ_Color_UV)); + + for (std::size_t tileIndex : layer.tiles) + { + const Tile& tile = m_tiles[tileIndex]; + NazaraAssert(tile.enabled, "Tile specified for rendering is not enabled"); + + std::size_t x = tileIndex % m_mapSize.x; + std::size_t y = tileIndex / m_mapSize.x; + Vector3f tileLeftCorner(x * m_tileSize.x, y * -m_tileSize.y, 0.f); + + *colorPtr++ = tile.color; + *posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner); + *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftTop); + + *colorPtr++ = tile.color; + *posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right()); + *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightTop); + + *colorPtr++ = tile.color; + *posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.y * Vector3f::Down()); + *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_LeftBottom); + + *colorPtr++ = tile.color; + *posPtr++ = instanceData->transformMatrix->Transform(tileLeftCorner + m_tileSize.x * Vector3f::Right() + m_tileSize.y * Vector3f::Down()); + *texCoordPtr++ = tile.textureCoords.GetCorner(RectCorner_RightBottom); + } + spriteCount += layer.tiles.size(); + } + } + + bool TileMap::Initialize() + { + if (!TileMapLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + return true; + } + + void TileMap::Uninitialize() + { + TileMapLibrary::Uninitialize(); + } + + TileMapLibrary::LibraryMap TileMap::s_library; +} From b988c34622482d4d4fd8ecbc4026e4352f19b217 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 23 Jul 2016 18:24:27 +0200 Subject: [PATCH 184/224] Doc: Fix \see Former-commit-id: 2d9bd386e63fc602f2a92ac083f3e252b9a9b797 [formerly 6fd2cb0e7bb10a68d83b3d44520413f679f8872a] Former-commit-id: 70d70144834b1dea6055348f70960a5df5197309 --- include/Nazara/Core/ResourceSaver.inl | 4 ++-- include/Nazara/Graphics/TileMap.inl | 28 +++++++++++++-------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/Nazara/Core/ResourceSaver.inl b/include/Nazara/Core/ResourceSaver.inl index 85f95fd3a..a22c29d60 100644 --- a/include/Nazara/Core/ResourceSaver.inl +++ b/include/Nazara/Core/ResourceSaver.inl @@ -48,7 +48,7 @@ namespace Nz * \remark The previous file content will be discarded, to prevent this behavior you should use SaveToStream * \remark The file extension will be used as format for the saver ("image.png" => "png", to write a specified format to a user-specified extension you should use SaveToStream * - * \seealso SaveToStream + * \see SaveToStream */ template bool ResourceSaver::SaveToFile(const Type& resource, const String& filePath, const Parameters& parameters) @@ -114,7 +114,7 @@ namespace Nz * \param format Data format to save the resource to * \param parameters Parameters for the saving * - * \seealso SaveToFile + * \see SaveToFile */ template bool ResourceSaver::SaveToStream(const Type& resource, Stream& stream, const String& format, const Parameters& parameters) diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index 684b21387..405683f40 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -42,7 +42,7 @@ namespace Nz * * \param tilePos Position of the tile to disable * - * \seealso DisableTiles + * \see DisableTiles */ inline void TileMap::DisableTile(const Vector2ui& tilePos) { @@ -81,7 +81,7 @@ namespace Nz * * \remark if tileCount is zero, this is a no-op and the value of tilesPos is not used * - * \seealso DisableTile + * \see DisableTile */ inline void TileMap::DisableTiles(const Vector2ui* tilesPos, std::size_t tileCount) { @@ -118,7 +118,7 @@ namespace Nz * \param color The multiplicative color applied to the tile * \param materialIndex The material which will be used for rendering this tile * - * \seealso EnableTiles + * \see EnableTiles */ inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectf& coords, const Color& color, std::size_t materialIndex) { @@ -161,7 +161,7 @@ namespace Nz * \remark The material at [materialIndex] must have a valid diffuse map before using this function, * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. * - * \seealso EnableTiles + * \see EnableTiles */ inline void TileMap::EnableTile(const Vector2ui& tilePos, const Rectui& rect, const Color& color, std::size_t materialIndex) { @@ -188,7 +188,7 @@ namespace Nz * \remark The material at [materialIndex] must have a valid diffuse map before using this function, * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. * - * \seealso EnableTile + * \see EnableTile */ inline void TileMap::EnableTiles(const Rectf& coords, const Color& color, std::size_t materialIndex) { @@ -223,7 +223,7 @@ namespace Nz * \remark The material at [materialIndex] must have a valid diffuse map before using this function, * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. * - * \seealso EnableTile + * \see EnableTile */ inline void TileMap::EnableTiles(const Rectui& rect, const Color& color, std::size_t materialIndex) { @@ -248,7 +248,7 @@ namespace Nz * \param color The multiplicative color applied to the tile * \param materialIndex The material which will be used for rendering this tile * - * \seealso EnableTile + * \see EnableTile */ inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectf& coords, const Color& color, std::size_t materialIndex) { @@ -299,7 +299,7 @@ namespace Nz * \remark The material at [materialIndex] must have a valid diffuse map before using this function, * as the size of the material diffuse map is used to compute normalized texture coordinates before returning. * - * \seealso EnableTile + * \see EnableTile */ inline void TileMap::EnableTiles(const Vector2ui* tilesPos, std::size_t tileCount, const Rectui& rect, const Color& color, std::size_t materialIndex) { @@ -341,8 +341,8 @@ namespace Nz * \brief Gets the tilemap size (i.e. number of tiles in each dimension) * \return Number of tiles in each dimension * - * \seealso GetSize - * \seealso GetTileSize + * \see GetSize + * \see GetTileSize */ inline const Vector2ui& TileMap::GetMapSize() const { @@ -353,8 +353,8 @@ namespace Nz * \brief Returns the size of the tilemap in units (which is equivalent to GetMapSize() * GetTileSize()) * \return Maximum size in units occupied by this tilemap * - * \seealso GetMapSize - * \seealso GetTileSize + * \see GetMapSize + * \see GetTileSize */ inline Vector2f TileMap::GetSize() const { @@ -379,8 +379,8 @@ namespace Nz * \brief Gets the tile size (i.e. number of units occupied by a tile in each dimension) * \return Tile size in each dimension * - * \seealso GetMapSize - * \seealso GetSize + * \see GetMapSize + * \see GetSize */ inline const Vector2f& TileMap::GetTileSize() const { From 08b85b477b5ce1d0efc1947a44f4ad9f6d9f9dd4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 26 Jul 2016 12:11:36 +0200 Subject: [PATCH 185/224] Add LICENSE file Former-commit-id: c3b781cb39efac0785c2da23f7f877e0e3db4c09 [formerly f39522f479e4a628f4b3c52806269dc14a62033a] Former-commit-id: 52a7895664b35053e60da1f6ddb11382ba6b6098 --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..aa1920df5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jérôme Leclercq + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 99fde96fee1e4ef797e993d22bb7d9a0544c9fc7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 26 Jul 2016 21:00:39 +0200 Subject: [PATCH 186/224] Build/UnitTest: Fix linking against Network module Former-commit-id: 01a994a6bf23fa8296ef087157d3d88598c1bb31 [formerly 929a9a29884daa2676c9e54f55361ecbd742fe37] Former-commit-id: d5437f0a27908e9e8a87e04aff14ddbb3c849b07 --- build/scripts/tools/unittests.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build/scripts/tools/unittests.lua b/build/scripts/tools/unittests.lua index fc0f4bad6..0d3dcc7d2 100644 --- a/build/scripts/tools/unittests.lua +++ b/build/scripts/tools/unittests.lua @@ -21,9 +21,10 @@ TOOL.Libraries = { "NazaraCore", "NazaraAudio", "NazaraLua", + "NazaraGraphics", + "NazaraRenderer", + "NazaraNetwork", "NazaraNoise", "NazaraPhysics", - "NazaraUtility", - "NazaraRenderer", - "NazaraGraphics" + "NazaraUtility" } From 4b02ab698f9ab709ac1ceec8fc758763b2a05b81 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 26 Jul 2016 21:07:20 +0200 Subject: [PATCH 187/224] Sdk/State: Make destructor virtual Former-commit-id: 51b552a0f0282173e73c8613d1924cc1e4105ac1 [formerly 1250f95f374a7b67e47667f4a5dd00f9ae5b1a1f] Former-commit-id: 85a77a07290da117bfcfbe6ccec7bc85b2c170dc --- SDK/include/NDK/State.hpp | 2 +- SDK/src/NDK/State.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 SDK/src/NDK/State.cpp diff --git a/SDK/include/NDK/State.hpp b/SDK/include/NDK/State.hpp index 613a504ab..f60cd6c4d 100644 --- a/SDK/include/NDK/State.hpp +++ b/SDK/include/NDK/State.hpp @@ -17,7 +17,7 @@ namespace Ndk { public: State() = default; - ~State() = default; + virtual ~State(); virtual void Enter(StateMachine& fsm) = 0; virtual void Leave(StateMachine& fsm) = 0; diff --git a/SDK/src/NDK/State.cpp b/SDK/src/NDK/State.cpp new file mode 100644 index 000000000..e256a7f1c --- /dev/null +++ b/SDK/src/NDK/State.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include + +namespace Ndk +{ + State::~State() = default; +} From 2f91c106798141711e1568186e2941d3843bedb3 Mon Sep 17 00:00:00 2001 From: Ardakaniz Date: Wed, 27 Jul 2016 20:33:42 +0200 Subject: [PATCH 188/224] Sdk/State: Fix State link error Former-commit-id: dfd30810abde2e2901fefb530977894f451abc0d [formerly 970b554c5d21b2f654b079e4da4a2f12dc9e95a8] Former-commit-id: 0e695a5cf47817c71c19aefcd409d2dce982137a --- SDK/include/NDK/State.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/State.hpp b/SDK/include/NDK/State.hpp index f60cd6c4d..621227fbe 100644 --- a/SDK/include/NDK/State.hpp +++ b/SDK/include/NDK/State.hpp @@ -13,7 +13,7 @@ namespace Ndk { class StateMachine; - class State + class NDK_API State { public: State() = default; From 4c1c8dd2a9cd8d8b444f82b3ef8bbad52bcbb047 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Thu, 28 Jul 2016 19:22:41 +0200 Subject: [PATCH 189/224] Various fixes Former-commit-id: bc799bb6b028f94a57c30dad8563367ab8a89973 [formerly 6c3e07c34170a8df0a4465d80cdfe9e5b8e04087] Former-commit-id: e685bae1b31f698856efaf66d7bab8d96cb047f8 --- include/Nazara/Core/Algorithm.inl | 3 +- include/Nazara/Core/ByteArray.inl | 38 ++++++------- include/Nazara/Core/ObjectHandle.inl | 75 +++++++++++++------------- include/Nazara/Core/ObjectRef.inl | 74 ++++++++++++------------- include/Nazara/Core/String.inl | 15 +++--- include/Nazara/Graphics/Renderable.inl | 4 +- include/Nazara/Math/Algorithm.inl | 6 +-- include/Nazara/Math/BoundingVolume.hpp | 1 + include/Nazara/Math/Box.hpp | 1 + include/Nazara/Math/Box.inl | 2 +- include/Nazara/Math/EulerAngles.hpp | 1 + include/Nazara/Math/Frustum.hpp | 2 + include/Nazara/Math/Matrix4.inl | 8 +-- include/Nazara/Math/OrientedBox.hpp | 1 + include/Nazara/Math/OrientedBox.inl | 2 +- include/Nazara/Math/Plane.hpp | 2 + include/Nazara/Math/Ray.hpp | 1 + include/Nazara/Math/Rect.hpp | 1 + include/Nazara/Math/Rect.inl | 10 ++-- include/Nazara/Math/Sphere.hpp | 1 + include/Nazara/Math/Vector2.hpp | 1 + include/Nazara/Math/Vector3.hpp | 1 + include/Nazara/Math/Vector4.hpp | 1 + src/Nazara/Core/File.cpp | 6 +-- src/Nazara/Core/StringStream.cpp | 1 - src/Nazara/Utility/Image.cpp | 9 ++++ 26 files changed, 141 insertions(+), 126 deletions(-) diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 6997f8d1e..c77a5c3bb 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -78,7 +78,7 @@ namespace Nz * \param v Object to hash * * \remark a HashAppend specialization for type T is required - * + * * \see ComputeHash */ template @@ -124,6 +124,7 @@ namespace Nz template constexpr std::size_t CountOf(T(&name)[N]) noexcept { + NazaraUnused(name); return N; } diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 1ff9bf185..068bee4b6 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -23,10 +23,10 @@ namespace Nz /*! * \brief Constructs a ByteArray object with a raw memory and a size * - * \param ptr Pointer to raw memory + * \param buffer Pointer to raw memory * \param n Size that can be accessed * - * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * \remark If preallocated space of buffer is less than the size, the behaviour is undefined */ inline ByteArray::ByteArray(const void* buffer, size_type n) : @@ -62,10 +62,10 @@ namespace Nz /*! * \brief Appends the content of raw memory * - * \param ptr Constant pointer to raw memory + * \param buffer Constant pointer to raw memory * \param n Size that can be read * - * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * \remark If preallocated space of buffer is less than the size, the behaviour is undefined * * \see Insert */ @@ -298,11 +298,11 @@ namespace Nz } /*! - * \brief Inserts n times the same value at the iterator position + * \brief Inserts n times the same byte at the iterator position * * \param pos Iterator to the position * \param n Number of repetitions - * \param value Value to repeat + * \param byte Value to repeat */ inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte) @@ -359,10 +359,10 @@ namespace Nz /*! * \brief Prepends the content of raw memory * - * \param ptr Constant pointer to raw memory + * \param buffer Constant pointer to raw memory * \param n Size that can be read * - * \remark If preallocated space of ptr is less than the size, the behaviour is undefined + * \remark If preallocated space of buffer is less than the size, the behaviour is undefined * * \see Insert */ @@ -682,8 +682,7 @@ namespace Nz * \brief Checks whether the first byte array is equal to the second byte array * \return true if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator==(const ByteArray& rhs) const @@ -695,8 +694,7 @@ namespace Nz * \brief Checks whether the first byte array is equal to the second byte array * \return false if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator!=(const ByteArray& rhs) const @@ -708,8 +706,7 @@ namespace Nz * \brief Checks whether the first byte array is less than the second byte array * \return true if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator<(const ByteArray& rhs) const @@ -721,8 +718,7 @@ namespace Nz * \brief Checks whether the first byte array is less or equal than the second byte array * \return true if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator<=(const ByteArray& rhs) const @@ -731,11 +727,10 @@ namespace Nz } /*! - * \brief Checks whether the first byte array is greather than the second byte array + * \brief Checks whether the first byte array is greater than the second byte array * \return true if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator>(const ByteArray& rhs) const @@ -744,11 +739,10 @@ namespace Nz } /*! - * \brief Checks whether the first byte array is greather or equal than the second byte array + * \brief Checks whether the first byte array is greater or equal than the second byte array * \return true if it is the case * - * \param first ByteArray to compare in left hand side - * \param second ByteArray to compare in right hand side + * \param rhs ByteArray to compare with */ inline bool ByteArray::operator>=(const ByteArray& rhs) const diff --git a/include/Nazara/Core/ObjectHandle.inl b/include/Nazara/Core/ObjectHandle.inl index ee6e26268..d5badc964 100644 --- a/include/Nazara/Core/ObjectHandle.inl +++ b/include/Nazara/Core/ObjectHandle.inl @@ -291,15 +291,16 @@ namespace Nz template std::ostream& operator<<(std::ostream& out, const ObjectHandle& handle) { - return handle.ToString(); + out << handle.ToString(); + return out; } /*! * \brief Checks whether the first object handle is equal to the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator==(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -311,8 +312,8 @@ namespace Nz * \brief Checks whether the object is equal to the second object handle * \return true if it is the case * - * \param first Object to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs Object to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator==(const T& lhs, const ObjectHandle& rhs) @@ -324,8 +325,8 @@ namespace Nz * \brief Checks whether the object handle is equal to the second object * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second Object to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs Object to compare in right hand side */ template bool operator==(const ObjectHandle& lhs, const T& rhs) @@ -337,8 +338,8 @@ namespace Nz * \brief Checks whether the first object handle is equal to the second object handle * \return false if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator!=(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -350,8 +351,8 @@ namespace Nz * \brief Checks whether the object is equal to the second object handle * \return false if it is the case * - * \param first Object to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs Object to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator!=(const T& lhs, const ObjectHandle& rhs) @@ -363,8 +364,8 @@ namespace Nz * \brief Checks whether the object handle is equal to the second object * \return false if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second Object to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs Object to compare in right hand side */ template bool operator!=(const ObjectHandle& lhs, const T& rhs) @@ -376,8 +377,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -389,8 +390,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<(const T& lhs, const ObjectHandle& rhs) @@ -402,8 +403,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<(const ObjectHandle& lhs, const T& rhs) @@ -415,8 +416,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<=(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -428,8 +429,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<=(const T& lhs, const ObjectHandle& rhs) @@ -441,8 +442,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator<=(const ObjectHandle& lhs, const T& rhs) @@ -454,8 +455,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -467,8 +468,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>(const T& lhs, const ObjectHandle& rhs) @@ -480,8 +481,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>(const ObjectHandle& lhs, const T& rhs) @@ -493,8 +494,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>=(const ObjectHandle& lhs, const ObjectHandle& rhs) @@ -506,8 +507,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>=(const T& lhs, const ObjectHandle& rhs) @@ -519,8 +520,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectHandle to compare in left hand side - * \param second ObjectHandle to compare in right hand side + * \param lhs ObjectHandle to compare in left hand side + * \param rhs ObjectHandle to compare in right hand side */ template bool operator>=(const ObjectHandle& lhs, const T& rhs) diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index 8dab06948..85baff8bf 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -184,7 +184,7 @@ namespace Nz { return m_object; } - + /*! * \brief Assigns the object into this * \return A reference to this @@ -251,8 +251,8 @@ namespace Nz * \brief Checks whether the first object handle is equal to the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator==(const ObjectRef& lhs, const ObjectRef& rhs) @@ -264,8 +264,8 @@ namespace Nz * \brief Checks whether the object is equal to the second object handle * \return true if it is the case * - * \param first Object to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs Object to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator==(const T& lhs, const ObjectRef& rhs) @@ -277,8 +277,8 @@ namespace Nz * \brief Checks whether the object handle is equal to the second object * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second Object to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs Object to compare in right hand side */ template bool operator==(const ObjectRef& lhs, const T& rhs) @@ -290,8 +290,8 @@ namespace Nz * \brief Checks whether the first object handle is equal to the second object handle * \return false if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator!=(const ObjectRef& lhs, const ObjectRef& rhs) @@ -303,8 +303,8 @@ namespace Nz * \brief Checks whether the object is equal to the second object handle * \return false if it is the case * - * \param first Object to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs Object to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator!=(const T& lhs, const ObjectRef& rhs) @@ -316,8 +316,8 @@ namespace Nz * \brief Checks whether the object handle is equal to the second object * \return false if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second Object to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs Object to compare in right hand side */ template bool operator!=(const ObjectRef& lhs, const T& rhs) @@ -329,8 +329,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<(const ObjectRef& lhs, const ObjectRef& rhs) @@ -342,8 +342,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<(const T& lhs, const ObjectRef& rhs) @@ -355,8 +355,8 @@ namespace Nz * \brief Checks whether the first object handle is less than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<(const ObjectRef& lhs, const T& rhs) @@ -368,8 +368,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<=(const ObjectRef& lhs, const ObjectRef& rhs) @@ -381,8 +381,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<=(const T& lhs, const ObjectRef& rhs) @@ -394,8 +394,8 @@ namespace Nz * \brief Checks whether the first object handle is less or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator<=(const ObjectRef& lhs, const T& rhs) @@ -407,8 +407,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>(const ObjectRef& lhs, const ObjectRef& rhs) @@ -420,8 +420,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>(const T& lhs, const ObjectRef& rhs) @@ -433,8 +433,8 @@ namespace Nz * \brief Checks whether the first object handle is greather than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>(const ObjectRef& lhs, const T& rhs) @@ -446,8 +446,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>=(const ObjectRef& lhs, const ObjectRef& rhs) @@ -459,8 +459,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>=(const T& lhs, const ObjectRef& rhs) @@ -472,8 +472,8 @@ namespace Nz * \brief Checks whether the first object handle is greather or equal than the second object handle * \return true if it is the case * - * \param first ObjectRef to compare in left hand side - * \param second ObjectRef to compare in right hand side + * \param lhs ObjectRef to compare in left hand side + * \param rhs ObjectRef to compare in right hand side */ template bool operator>=(const ObjectRef& lhs, const T& rhs) diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index aa4343371..a5e099a3c 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -45,7 +45,7 @@ namespace Nz */ inline String::SharedString::SharedString(std::size_t strSize) : - capacity(strSize), + capacity(strSize), size(strSize), string(new char[strSize + 1]) { @@ -84,16 +84,15 @@ namespace Nz namespace std { - /*! - * \brief Specialisation of std to hash - * \return Result of the hash - * - * \param str String to hash - */ - template<> struct hash { + /*! + * \brief Specialisation of std to hash + * \return Result of the hash + * + * \param str String to hash + */ size_t operator()(const Nz::String& str) const { // Algorithme DJB2 diff --git a/include/Nazara/Graphics/Renderable.inl b/include/Nazara/Graphics/Renderable.inl index 9a69329a5..804567814 100644 --- a/include/Nazara/Graphics/Renderable.inl +++ b/include/Nazara/Graphics/Renderable.inl @@ -24,9 +24,7 @@ namespace Nz } /*! - * \brief Updates the bounding volume by a matrix - * - * \param transformMatrix Matrix transformation for our bounding volume + * \brief Updates the bounding volume */ inline void Renderable::UpdateBoundingVolume() const diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 524f0bd4c..2c865ad1b 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -105,7 +105,7 @@ namespace Nz * * \param value Initial value * \param objective Target value - * \parma increment One step value + * \param increment One step value */ template @@ -412,7 +412,7 @@ namespace Nz * \brief Gets the log in base 2 of integral number, only works for power of two ! * \return Log of the number * - * \param number To get log in base 2 + * \param pot To get log in base 2 * * \remark Only works for power of two * \remark If number is 0, 0 is returned @@ -431,7 +431,7 @@ namespace Nz * \return base^exponent for integral * * \param base Base of the exponentation - * \parma exponent Power for the base + * \param exponent Power for the base */ //TODO: Mark as constexpr when supported by all major compilers diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 6f1f4b804..6c863b729 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -53,6 +53,7 @@ namespace Nz void Update(const Vector3& translation); BoundingVolume operator*(T scalar) const; + BoundingVolume& operator=(const BoundingVolume& other) = default; BoundingVolume& operator*=(T scalar); diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index a2a6f25d1..25e9a8069 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -79,6 +79,7 @@ namespace Nz Box operator*(T scalar) const; Box operator*(const Vector3& vec) const; + Box& operator=(const Box& other) = default; Box& operator*=(T scalar); Box& operator*=(const Vector3& vec); diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index a6200cbe4..71c98a70b 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -787,7 +787,7 @@ namespace Nz * \brief Multiplies the lengths with the scalar * \return A box where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar * - * \param scale The scalar to multiply width, height and depth with + * \param scalar The scalar to multiply width, height and depth with */ template diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 6ada39982..ab267e81f 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -47,6 +47,7 @@ namespace Nz EulerAngles operator-(const EulerAngles& angles) const; /*EulerAngles operator*(const EulerAngles& angles) const; EulerAngles operator/(const EulerAngles& angles) const;*/ + EulerAngles& operator=(const EulerAngles& other) = default; EulerAngles& operator+=(const EulerAngles& angles); EulerAngles& operator-=(const EulerAngles& angles); diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index 2e51c0bd6..96c78004c 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -50,6 +50,8 @@ namespace Nz IntersectionSide Intersect(const Sphere& sphere) const; IntersectionSide Intersect(const Vector3* points, unsigned int pointCount) const; + Frustum& operator=(const Frustum& other) = default; + Frustum& Set(const Frustum& frustum); template Frustum& Set(const Frustum& frustum); diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index b0decee2a..4cf2eaa6e 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -750,7 +750,7 @@ namespace Nz * \brief Inverts this matrix * \return A reference to this matrix inverted * - * \param bool Optional argument to know if matrix has been successfully inverted + * \param succeeded Optional argument to know if matrix has been successfully inverted * * \see InverseAffine */ @@ -769,7 +769,7 @@ namespace Nz * \brief Inverts this matrix * \return A reference to this matrix inverted * - * \param bool Optional argument to know if matrix has been successfully inverted + * \param succeeded Optional argument to know if matrix has been successfully inverted * * \see Inverse */ @@ -1487,7 +1487,7 @@ namespace Nz * \brief Compares the matrix to other one * \return true if the matrices are the same * - * \param matrix Other matrix to compare with + * \param mat Other matrix to compare with */ template @@ -1504,7 +1504,7 @@ namespace Nz * \brief Compares the matrix to other one * \return false if the matrices are the same * - * \param matrix Other matrix to compare with + * \param mat Other matrix to compare with */ template diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 43d4b1aaf..2b806e56b 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -52,6 +52,7 @@ namespace Nz Vector3 operator()(unsigned int i) const; OrientedBox operator*(T scalar) const; + OrientedBox& operator=(const OrientedBox& other) = default; OrientedBox& operator*=(T scalar); diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 9bcd94e1d..3320dce1a 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -340,7 +340,7 @@ namespace Nz * \brief Multiplies the lengths with the scalar * \return A OrientedBox where the position is the same and width, height and depth are the product of the old width, height and depth and the scalar * - * \param scale The scalar to multiply width, height and depth with + * \param scalar The scalar to multiply width, height and depth with */ template diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index f37fc90c7..0eb201123 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -45,6 +45,8 @@ namespace Nz String ToString() const; + Plane& operator=(const Plane& other) = default; + bool operator==(const Plane& plane) const; bool operator!=(const Plane& plane) const; diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index b391ad866..7e8c0790a 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -61,6 +61,7 @@ namespace Nz String ToString() const; Vector3 operator*(T lambda) const; + Ray& operator=(const Ray& other) = default; bool operator==(const Ray& ray) const; bool operator!=(const Ray& ray) const; diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index 393d8d116..843ff6126 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -71,6 +71,7 @@ namespace Nz Rect operator*(const Vector2& vec) const; Rect operator/(T scalar) const; Rect operator/(const Vector2& vec) const; + Rect& operator=(const Rect& other) = default; Rect& operator*=(T scalar); Rect& operator*=(const Vector2& vec); diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index f53dd0c0f..21d0e7e93 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -629,7 +629,7 @@ namespace Nz * \brief Multiplies the lengths with the scalar * \return A rectangle where the position is the same and width and height are the product of the old width and height and the scalar * - * \param scale The scalar to multiply width and height with + * \param scalar The scalar to multiply width and height with */ template @@ -655,13 +655,13 @@ namespace Nz * \brief Divides the lengths with the scalar * \return A rectangle where the position is the same and width and height are the quotient of the old width and height and the scalar * - * \param scale The scalar to divide width and height with + * \param scalar The scalar to divide width and height with */ template Rect Rect::operator/(T scalar) const { - return Rect(x, y, width/scalar, height/scalar); + return Rect(x, y, width / scalar, height / scalar); } /*! @@ -745,7 +745,7 @@ namespace Nz * \brief Compares the rectangle to other one * \return true if the rectangles are the same * - * \param rec Other rectangle to compare with + * \param rect Other rectangle to compare with */ template @@ -759,7 +759,7 @@ namespace Nz * \brief Compares the rectangle to other one * \return false if the rectangles are the same * - * \param rec Other rectangle to compare with + * \param rect Other rectangle to compare with */ template diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 929c1ec71..8f7ac9e14 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -67,6 +67,7 @@ namespace Nz T operator[](unsigned int i) const; Sphere operator*(T scalar) const; + Sphere& operator=(const Sphere& other) = default; Sphere& operator*=(T scalar); diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index b275d0544..e0ac1d68d 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -76,6 +76,7 @@ namespace Nz Vector2 operator*(T scale) const; Vector2 operator/(const Vector2& vec) const; Vector2 operator/(T scale) const; + Vector2& operator=(const Vector2& other) = default; Vector2& operator+=(const Vector2& vec); Vector2& operator-=(const Vector2& vec); diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 7743e7a35..4e6da14ec 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -87,6 +87,7 @@ namespace Nz Vector3 operator*(T scale) const; Vector3 operator/(const Vector3& vec) const; Vector3 operator/(T scale) const; + Vector3& operator=(const Vector3& vec) = default; Vector3& operator+=(const Vector3& vec); Vector3& operator-=(const Vector3& vec); diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index b84a4cb17..0f8e907fc 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -74,6 +74,7 @@ namespace Nz Vector4 operator*(T scale) const; Vector4 operator/(const Vector4& vec) const; Vector4 operator/(T scale) const; + Vector4& operator=(const Vector4& other) = default; Vector4& operator+=(const Vector4& vec); Vector4& operator-=(const Vector4& vec); diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 97504b0ee..131ceb7f3 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -385,7 +385,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param pos Position of the cursor @@ -404,7 +404,7 @@ namespace Nz } /*! - * \brief Sets the position of the cursor + * \brief Sets the position of the cursor * \return true if cursor is successfully positioned * * \param offset Offset according to the cursor begin position @@ -725,7 +725,7 @@ namespace Nz return true; else if (path.Match("\\\\*")) // Ex: \\Laptop return true; - else if (path.StartsWith('\\')) // Special : '\' refering to the root + else if (path.StartsWith('\\')) // Special : '\' referring to the root return true; else return false; diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index 14d35799d..0b27077e5 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -1,4 +1,3 @@ -#include "..\..\..\include\Nazara\Core\StringStream.hpp" // 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 diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 9e0213cf6..4b780eef1 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1352,6 +1352,15 @@ namespace Nz void Image::Copy(UInt8* destination, const UInt8* source, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, unsigned int dstWidth, unsigned int dstHeight, unsigned int srcWidth, unsigned int srcHeight) { + #if NAZARA_UTILITY_SAFE + if (width == 0) + NazaraError("Width must be greater than zero"); + if (height == 0) + NazaraError("Height must be greater than zero"); + if (depth == 0) + NazaraError("Depth must be greater than zero"); + #endif + if (dstWidth == 0) dstWidth = width; From 9fa726752386e8b3ac86e974f6cfb3355947a653 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 13:24:19 +0200 Subject: [PATCH 190/224] Graphics: Rename ParticleSystem to ParticleGroup Preparing for integration into the ECS Former-commit-id: 201e28c9f00ee31f809d9de3d9a37f57a7fe740c [formerly 9b88616308f9801482fc8811a9a19a7231dce2a7] Former-commit-id: 579f4e9597f94620f922fb145931202d8fc9cc96 --- include/Nazara/Graphics.hpp | 2 +- .../Nazara/Graphics/ParticleController.hpp | 4 +- include/Nazara/Graphics/ParticleEmitter.hpp | 4 +- include/Nazara/Graphics/ParticleGenerator.hpp | 4 +- .../{ParticleSystem.hpp => ParticleGroup.hpp} | 18 ++--- include/Nazara/Graphics/ParticleRenderer.hpp | 4 +- src/Nazara/Graphics/ParticleEmitter.cpp | 4 +- .../{ParticleSystem.cpp => ParticleGroup.cpp} | 66 +++++++++---------- .../{ParticleSystem.cpp => ParticleGroup.cpp} | 26 ++++---- 9 files changed, 66 insertions(+), 66 deletions(-) rename include/Nazara/Graphics/{ParticleSystem.hpp => ParticleGroup.hpp} (84%) rename src/Nazara/Graphics/{ParticleSystem.cpp => ParticleGroup.cpp} (83%) rename tests/Engine/Graphics/{ParticleSystem.cpp => ParticleGroup.cpp} (75%) diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 17b10e9a1..4809d9481 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -63,10 +63,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index 17e4ac9e1..05537ba55 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -18,7 +18,7 @@ namespace Nz { class ParticleController; class ParticleMapper; - class ParticleSystem; + class ParticleGroup; using ParticleControllerConstRef = ObjectRef; using ParticleControllerLibrary = ObjectLibrary; @@ -34,7 +34,7 @@ namespace Nz ParticleController(const ParticleController& controller); virtual ~ParticleController(); - virtual void Apply(ParticleSystem& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; + virtual void Apply(ParticleGroup& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; // Signals: NazaraSignal(OnParticleControllerRelease, const ParticleController* /*particleController*/); diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index d5e3c8ea8..b6acee156 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -14,7 +14,7 @@ namespace Nz { class ParticleMapper; - class ParticleSystem; + class ParticleGroup; class NAZARA_GRAPHICS_API ParticleEmitter : public Node { @@ -24,7 +24,7 @@ namespace Nz ParticleEmitter(ParticleEmitter&& emitter) = default; virtual ~ParticleEmitter(); - virtual void Emit(ParticleSystem& system, float elapsedTime) const; + virtual void Emit(ParticleGroup& system, float elapsedTime) const; void EnableLagCompensation(bool enable); diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index d9d2a789a..d072ae346 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -18,7 +18,7 @@ namespace Nz { class ParticleGenerator; class ParticleMapper; - class ParticleSystem; + class ParticleGroup; using ParticleGeneratorConstRef = ObjectRef; using ParticleGeneratorLibrary = ObjectLibrary; @@ -34,7 +34,7 @@ namespace Nz ParticleGenerator(const ParticleGenerator& generator); virtual ~ParticleGenerator(); - virtual void Generate(ParticleSystem& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; + virtual void Generate(ParticleGroup& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; // Signals: NazaraSignal(OnParticleGeneratorRelease, const ParticleGenerator* /*particleGenerator*/); diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleGroup.hpp similarity index 84% rename from include/Nazara/Graphics/ParticleSystem.hpp rename to include/Nazara/Graphics/ParticleGroup.hpp index 76b834f6e..aaa65bb7f 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -4,8 +4,8 @@ #pragma once -#ifndef NAZARA_PARTICLESYSTEM_HPP -#define NAZARA_PARTICLESYSTEM_HPP +#ifndef NAZARA_PARTICLEGROUP_HPP +#define NAZARA_PARTICLEGROUP_HPP #include #include @@ -22,13 +22,13 @@ namespace Nz { - class NAZARA_GRAPHICS_API ParticleSystem : public Renderable + class NAZARA_GRAPHICS_API ParticleGroup : public Renderable { public: - ParticleSystem(unsigned int maxParticleCount, ParticleLayout layout); - ParticleSystem(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration); - ParticleSystem(const ParticleSystem& emitter); - ~ParticleSystem(); + ParticleGroup(unsigned int maxParticleCount, ParticleLayout layout); + ParticleGroup(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration); + ParticleGroup(const ParticleGroup& emitter); + ~ParticleGroup(); void AddController(ParticleControllerRef controller); void AddEmitter(ParticleEmitter* emitter); @@ -66,7 +66,7 @@ namespace Nz void Update(float elapsedTime); void UpdateBoundingVolume(const Matrix4f& transformMatrix) override; - ParticleSystem& operator=(const ParticleSystem& emitter); + ParticleGroup& operator=(const ParticleGroup& emitter); private: void MakeBoundingVolume() const override; @@ -89,4 +89,4 @@ namespace Nz }; } -#endif // NAZARA_PARTICLESYSTEM_HPP +#endif // NAZARA_PARTICLEGROUP_HPP diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index d79d448f2..2ddca18b3 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -19,7 +19,7 @@ namespace Nz class AbstractRenderQueue; class ParticleMapper; class ParticleRenderer; - class ParticleSystem; + class ParticleGroup; using ParticleRendererConstRef = ObjectRef; using ParticleRendererLibrary = ObjectLibrary; @@ -35,7 +35,7 @@ namespace Nz ParticleRenderer(const ParticleRenderer& renderer); virtual ~ParticleRenderer(); - virtual void Render(const ParticleSystem& system, const ParticleMapper& mapper, unsigned int startId, unsigned int endId, AbstractRenderQueue* renderQueue) = 0; + virtual void Render(const ParticleGroup& system, const ParticleMapper& mapper, unsigned int startId, unsigned int endId, AbstractRenderQueue* renderQueue) = 0; // Signals: NazaraSignal(OnParticleRendererRelease, const ParticleRenderer* /*particleRenderer*/); diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index ded77d80e..b11cfdfe9 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,7 +41,7 @@ namespace Nz * \param elapsedTime Delta time between the previous frame */ - void ParticleEmitter::Emit(ParticleSystem& system, float elapsedTime) const + void ParticleEmitter::Emit(ParticleGroup& system, float elapsedTime) const { if (m_emissionRate > 0.f) { diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleGroup.cpp similarity index 83% rename from src/Nazara/Graphics/ParticleSystem.cpp rename to src/Nazara/Graphics/ParticleGroup.cpp index 0783dd7fd..08fb03f39 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -2,7 +2,7 @@ // 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 @@ -26,8 +26,8 @@ namespace Nz * \param layout Enumeration for the layout of data information for the particles */ - ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleLayout layout) : - ParticleSystem(maxParticleCount, ParticleDeclaration::Get(layout)) + ParticleGroup::ParticleGroup(unsigned int maxParticleCount, ParticleLayout layout) : + ParticleGroup(maxParticleCount, ParticleDeclaration::Get(layout)) { } @@ -38,7 +38,7 @@ namespace Nz * \param declaration Data information for the particles */ - ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration) : + ParticleGroup::ParticleGroup(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration) : m_declaration(std::move(declaration)), m_processing(false), m_maxParticleCount(maxParticleCount), @@ -58,7 +58,7 @@ namespace Nz * \param system ParticleSystem to copy into this */ - ParticleSystem::ParticleSystem(const ParticleSystem& system) : + ParticleGroup::ParticleGroup(const ParticleGroup& system) : Renderable(system), m_controllers(system.m_controllers), m_generators(system.m_generators), @@ -77,7 +77,7 @@ namespace Nz std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); } - ParticleSystem::~ParticleSystem() = default; + ParticleGroup::~ParticleGroup() = default; /*! * \brief Adds a controller to the particles @@ -87,7 +87,7 @@ namespace Nz * \remark Produces a NazaraAssert if controller is invalid */ - void ParticleSystem::AddController(ParticleControllerRef controller) + void ParticleGroup::AddController(ParticleControllerRef controller) { NazaraAssert(controller, "Invalid particle controller"); @@ -102,7 +102,7 @@ namespace Nz * \remark Produces a NazaraAssert if emitter is invalid */ - void ParticleSystem::AddEmitter(ParticleEmitter* emitter) + void ParticleGroup::AddEmitter(ParticleEmitter* emitter) { NazaraAssert(emitter, "Invalid particle emitter"); @@ -117,7 +117,7 @@ namespace Nz * \remark Produces a NazaraAssert if generator is invalid */ - void ParticleSystem::AddGenerator(ParticleGeneratorRef generator) + void ParticleGroup::AddGenerator(ParticleGeneratorRef generator) { NazaraAssert(generator, "Invalid particle generator"); @@ -134,7 +134,7 @@ namespace Nz * \remark Produces a NazaraAssert if renderQueue is invalid */ - void ParticleSystem::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const + void ParticleGroup::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const { NazaraAssert(m_renderer, "Invalid particle renderer"); NazaraAssert(renderQueue, "Invalid renderqueue"); @@ -155,7 +155,7 @@ namespace Nz * \param elapsedTime Delta time between the previous frame */ - void ParticleSystem::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) + void ParticleGroup::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) { m_processing = true; @@ -190,7 +190,7 @@ namespace Nz * \return Pointer to the particle memory buffer */ - void* ParticleSystem::CreateParticle() + void* ParticleGroup::CreateParticle() { return CreateParticles(1); } @@ -200,7 +200,7 @@ namespace Nz * \return Pointer to the first particle memory buffer */ - void* ParticleSystem::CreateParticles(unsigned int count) + void* ParticleGroup::CreateParticles(unsigned int count) { if (count == 0) return nullptr; @@ -219,7 +219,7 @@ namespace Nz * \return Pointer to the particle memory buffer */ - void* ParticleSystem::GenerateParticle() + void* ParticleGroup::GenerateParticle() { return GenerateParticles(1); } @@ -229,7 +229,7 @@ namespace Nz * \return Pointer to the first particle memory buffer */ - void* ParticleSystem::GenerateParticles(unsigned int count) + void* ParticleGroup::GenerateParticles(unsigned int count) { void* ptr = CreateParticles(count); if (!ptr) @@ -247,7 +247,7 @@ namespace Nz * \return Particle declaration */ - const ParticleDeclarationConstRef& ParticleSystem::GetDeclaration() const + const ParticleDeclarationConstRef& ParticleGroup::GetDeclaration() const { return m_declaration; } @@ -257,7 +257,7 @@ namespace Nz * \return Current fixed step size */ - float ParticleSystem::GetFixedStepSize() const + float ParticleGroup::GetFixedStepSize() const { return m_stepSize; } @@ -267,7 +267,7 @@ namespace Nz * \return Current maximum number */ - unsigned int ParticleSystem::GetMaxParticleCount() const + unsigned int ParticleGroup::GetMaxParticleCount() const { return m_maxParticleCount; } @@ -277,7 +277,7 @@ namespace Nz * \return Current number */ - unsigned int ParticleSystem::GetParticleCount() const + unsigned int ParticleGroup::GetParticleCount() const { return m_particleCount; } @@ -287,7 +287,7 @@ namespace Nz * \return Current size */ - unsigned int ParticleSystem::GetParticleSize() const + unsigned int ParticleGroup::GetParticleSize() const { return m_particleSize; } @@ -297,7 +297,7 @@ namespace Nz * \return true If it is the case */ - bool ParticleSystem::IsFixedStepEnabled() const + bool ParticleGroup::IsFixedStepEnabled() const { return m_fixedStepEnabled; } @@ -308,7 +308,7 @@ namespace Nz * \param index Index of the particle */ - void ParticleSystem::KillParticle(unsigned int index) + void ParticleGroup::KillParticle(unsigned int index) { ///FIXME: Verify the index @@ -328,7 +328,7 @@ namespace Nz * \brief Kills every particles */ - void ParticleSystem::KillParticles() + void ParticleGroup::KillParticles() { m_particleCount = 0; } @@ -339,7 +339,7 @@ namespace Nz * \param controller Controller for the particles to remove */ - void ParticleSystem::RemoveController(ParticleController* controller) + void ParticleGroup::RemoveController(ParticleController* controller) { auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); if (it != m_controllers.end()) @@ -352,7 +352,7 @@ namespace Nz * \param emitter Emitter for the particles to remove */ - void ParticleSystem::RemoveEmitter(ParticleEmitter* emitter) + void ParticleGroup::RemoveEmitter(ParticleEmitter* emitter) { auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); if (it != m_emitters.end()) @@ -365,7 +365,7 @@ namespace Nz * \param generator Generator for the particles to remove */ - void ParticleSystem::RemoveGenerator(ParticleGenerator* generator) + void ParticleGroup::RemoveGenerator(ParticleGenerator* generator) { auto it = std::find(m_generators.begin(), m_generators.end(), generator); if (it != m_generators.end()) @@ -378,7 +378,7 @@ namespace Nz * \param stepSize Fixed step size */ - void ParticleSystem::SetFixedStepSize(float stepSize) + void ParticleGroup::SetFixedStepSize(float stepSize) { m_stepSize = stepSize; } @@ -389,7 +389,7 @@ namespace Nz * \param renderer Renderer for the particles */ - void ParticleSystem::SetRenderer(ParticleRenderer* renderer) + void ParticleGroup::SetRenderer(ParticleRenderer* renderer) { m_renderer = renderer; } @@ -400,7 +400,7 @@ namespace Nz * \param elapsedTime Delta time between the previous frame */ - void ParticleSystem::Update(float elapsedTime) + void ParticleGroup::Update(float elapsedTime) { // Emission for (ParticleEmitter* emitter : m_emitters) @@ -421,7 +421,7 @@ namespace Nz * \param transformMatrix Matrix transformation for our bounding volume */ - void ParticleSystem::UpdateBoundingVolume(const Matrix4f& transformMatrix) + void ParticleGroup::UpdateBoundingVolume(const Matrix4f& transformMatrix) { NazaraUnused(transformMatrix); @@ -435,7 +435,7 @@ namespace Nz * \param system The other ParticleSystem */ - ParticleSystem& ParticleSystem::operator=(const ParticleSystem& system) + ParticleGroup& ParticleGroup::operator=(const ParticleGroup& system) { ErrorFlags flags(ErrorFlag_ThrowException, true); @@ -468,7 +468,7 @@ namespace Nz * \brief Makes the bounding volume of this text */ - void ParticleSystem::MakeBoundingVolume() const + void ParticleGroup::MakeBoundingVolume() const { ///TODO: Compute the AABB (taking into account the size of particles) m_boundingVolume.MakeInfinite(); @@ -480,7 +480,7 @@ namespace Nz * \remark Produces a NazaraError if resize did not work */ - void ParticleSystem::ResizeBuffer() + void ParticleGroup::ResizeBuffer() { // Just to have a better description of our problem in case of error try diff --git a/tests/Engine/Graphics/ParticleSystem.cpp b/tests/Engine/Graphics/ParticleGroup.cpp similarity index 75% rename from tests/Engine/Graphics/ParticleSystem.cpp rename to tests/Engine/Graphics/ParticleGroup.cpp index 32f5f01f9..36ad2cb0b 100644 --- a/tests/Engine/Graphics/ParticleSystem.cpp +++ b/tests/Engine/Graphics/ParticleGroup.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -8,7 +8,7 @@ class TestParticleController : public Nz::ParticleController { public: // Be aware that the interval is [startId, endId] and NOT [startId, endId) - void Apply(Nz::ParticleSystem& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) override + void Apply(Nz::ParticleGroup& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) override { Nz::SparsePtr positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); Nz::SparsePtr velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); @@ -32,7 +32,7 @@ class TestParticleEmitter : public Nz::ParticleEmitter public: ~TestParticleEmitter() override = default; - void Emit(Nz::ParticleSystem& system, float elapsedTime) const override + void Emit(Nz::ParticleGroup& system, float elapsedTime) const override { system.GenerateParticles(GetEmissionCount()); } @@ -49,7 +49,7 @@ class TestParticleGenerator : public Nz::ParticleGenerator ~TestParticleGenerator() override = default; // Be aware that the interval is [startId, endId] and NOT [startId, endId) - void Generate(Nz::ParticleSystem& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId) override + void Generate(Nz::ParticleGroup& system, Nz::ParticleMapper& mapper, unsigned int startId, unsigned int endId) override { Nz::SparsePtr positionPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Position); Nz::SparsePtr velocityPtr = mapper.GetComponentPtr(Nz::ParticleComponent_Velocity); @@ -68,35 +68,35 @@ class TestParticleGenerator : public Nz::ParticleGenerator } }; -SCENARIO("ParticleSystem", "[GRAPHICS][PARTICLESYSTEM]") +SCENARIO("ParticleGroup", "[GRAPHICS][PARTICLEGROUP]") { GIVEN("A particle system of maximum 10 billboards with its generators") { // These need to be alive longer than the particle system TestParticleController particleController; TestParticleGenerator particleGenerator; - Nz::ParticleSystem particleSystem(10, Nz::ParticleLayout_Billboard); + Nz::ParticleGroup particleGroup(10, Nz::ParticleLayout_Billboard); - particleSystem.AddController(&particleController); + particleGroup.AddController(&particleController); TestParticleEmitter particleEmitter; particleEmitter.SetEmissionCount(10); - particleSystem.AddEmitter(&particleEmitter); + particleGroup.AddEmitter(&particleEmitter); - particleSystem.AddGenerator(&particleGenerator); + particleGroup.AddGenerator(&particleGenerator); WHEN("We update to generate 10 particles") { - particleSystem.Update(1.f); + particleGroup.Update(1.f); THEN("There must be 10 particles") { - REQUIRE(particleSystem.GetParticleCount() == 10); + REQUIRE(particleGroup.GetParticleCount() == 10); } AND_THEN("We update to make them die") { - particleSystem.Update(2.f); - REQUIRE(particleSystem.GetParticleCount() == 0); + particleGroup.Update(2.f); + REQUIRE(particleGroup.GetParticleCount() == 0); } } } From 5d6cee82919537e938548a34e8366d9a156d5632 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 13:37:44 +0200 Subject: [PATCH 191/224] Utility/OBJParser: Abort parsing when there's more than one error per two line Former-commit-id: b8126ca529f91492a1d116da7cb446b8eaa25a90 [formerly c33f7b8d27ba18303b839693aa3ef056d1f48ae1] Former-commit-id: 701965304b9e51ddf1ee2233559f2f97d4a51894 --- include/Nazara/Utility/Formats/OBJParser.hpp | 3 +- include/Nazara/Utility/Formats/OBJParser.inl | 12 ++++- src/Nazara/Utility/Formats/OBJParser.cpp | 53 ++++++++++++-------- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 50fa58900..114f72635 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -86,7 +86,7 @@ namespace Nz inline void Error(const String& message); inline void Flush() const; inline void Warning(const String& message); - inline void UnrecognizedLine(bool error = false); + inline bool UnrecognizedLine(bool error = false); std::vector m_meshes; std::vector m_materials; @@ -99,6 +99,7 @@ namespace Nz mutable StringStream m_outputStream; bool m_keepLastLine; unsigned int m_lineCount; + unsigned int m_errorCount; }; } diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index 9d961d54f..054d57754 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -168,7 +168,7 @@ namespace Nz NazaraWarning(message + " at line #" + String::Number(m_lineCount)); } - inline void OBJParser::UnrecognizedLine(bool error) + inline bool OBJParser::UnrecognizedLine(bool error) { String message = "Unrecognized \"" + m_currentLine + '"'; @@ -176,6 +176,16 @@ namespace Nz Error(message); else Warning(message); + + m_errorCount++; + + if (m_lineCount > 20 && (m_errorCount * 100 / m_lineCount) > 50) + { + NazaraError("Aborting parsing because of error percentage"); + return false; //< Abort parsing if error percentage is too high + } + + return true; } } diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index bd189305f..7d3019c39 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -97,7 +97,8 @@ namespace Nz if (m_currentLine.GetSize() < 7) // Since we only treat triangles, this is the minimum length of a face line (f 1 2 3) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } @@ -106,7 +107,8 @@ namespace Nz if (vertexCount < 3) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } @@ -138,7 +140,8 @@ namespace Nz if (std::sscanf(&m_currentLine[pos], "%d%n", &p, &offset) != 1) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif error = true; break; @@ -217,7 +220,8 @@ namespace Nz case 'm': //< MTLLib #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING if (m_currentLine.GetWord(0).ToLower() != "mtllib") - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); @@ -229,7 +233,8 @@ namespace Nz if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ') { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } @@ -238,7 +243,8 @@ namespace Nz if (objectName.IsEmpty()) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } @@ -254,17 +260,20 @@ namespace Nz { String param = m_currentLine.SubString(2); if (param != "all" && param != "on" && param != "off" && !param.IsNumber()) - UnrecognizedLine(); + { + if (!UnrecognizedLine()) + return false; + } } - else - UnrecognizedLine(); + else if (!UnrecognizedLine()) + return false; break; #endif case 'u': //< Usemtl #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (m_currentLine.GetWord(0) != "usemtl") - UnrecognizedLine(); + if (m_currentLine.GetWord(0) != "usemtl" && !UnrecognizedLine()) + return false; #endif matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); @@ -272,7 +281,8 @@ namespace Nz if (matName.IsEmpty()) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } @@ -288,8 +298,8 @@ namespace Nz if (paramCount >= 1) m_positions.push_back(vertex); #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); + else if (!UnrecognizedLine()) + false; #endif } else if (word == "vn") @@ -299,8 +309,8 @@ namespace Nz if (paramCount == 3) m_normals.push_back(normal); #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); + else if (!UnrecognizedLine()) + false; #endif } else if (word == "vt") @@ -310,13 +320,13 @@ namespace Nz if (paramCount >= 2) m_texCoords.push_back(uvw); #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); + else if (!UnrecognizedLine()) + false; #endif } #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); + else if (!UnrecognizedLine()) + false; #endif break; @@ -324,7 +334,8 @@ namespace Nz default: #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); + if (!UnrecognizedLine()) + return false; #endif break; } From 3a50c1e553e3c8a97e281030c48fd8f73efae548 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 13:38:00 +0200 Subject: [PATCH 192/224] UnitTests: Fix blocking case Former-commit-id: b504a619172a7c4c57d07d168fe4ae33bbd98210 [formerly 054c9b2c1261c438b74722be9f345417e64f3611] Former-commit-id: 498b99790dc187ace705a57cd9fdcec43ac1345d --- tests/Engine/Graphics/Model.cpp | 5 ++++- tests/Engine/Network/TCP.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/Engine/Graphics/Model.cpp b/tests/Engine/Graphics/Model.cpp index d67a261bb..b363a0be2 100644 --- a/tests/Engine/Graphics/Model.cpp +++ b/tests/Engine/Graphics/Model.cpp @@ -9,8 +9,11 @@ SCENARIO("Model", "[GRAPHICS][MODEL]") { THEN("These results are expected") { + Nz::ModelParameters params; + params.mesh.optimizeIndexBuffers = false; + Nz::ModelRef model = Nz::Model::New(); - REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj")); + REQUIRE(model->LoadFromFile("resources/Engine/Graphics/dragon_recon/dragon_vrip_res4.obj", params)); REQUIRE(model->GetMaterialCount() == 2); REQUIRE(model->GetSkin() == 0); diff --git a/tests/Engine/Network/TCP.cpp b/tests/Engine/Network/TCP.cpp index 63b4fe2df..a613cf0c6 100644 --- a/tests/Engine/Network/TCP.cpp +++ b/tests/Engine/Network/TCP.cpp @@ -18,6 +18,8 @@ SCENARIO("TCP", "[NETWORK][TCP]") Nz::UInt16 port = dis(gen); Nz::TcpServer server; + server.EnableBlocking(false); + REQUIRE(server.Listen(Nz::NetProtocol_IPv4, port) == Nz::SocketState_Bound); Nz::IpAddress serverIP = server.GetBoundAddress(); REQUIRE(serverIP.IsValid()); From e68b962f4d49258c377234d3275c3eae4c2e1dad Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 13:55:59 +0200 Subject: [PATCH 193/224] Graphics/ParticleGroup: Remove fixed step parameter (wasn't used) Former-commit-id: 28e6d1d11ac699d184e9f0ca90994c1ae6368962 [formerly 696269b6f34dd4f9f61fd1c1f4b93bd2a50fdcdf] Former-commit-id: d3fbf42609596a03cde0cdaf1256dd014e87087e --- include/Nazara/Graphics/ParticleGroup.hpp | 9 ------ src/Nazara/Graphics/ParticleGroup.cpp | 38 ++--------------------- 2 files changed, 2 insertions(+), 45 deletions(-) diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index aaa65bb7f..412b94511 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -40,19 +40,14 @@ namespace Nz void* CreateParticle(); void* CreateParticles(unsigned int count); - void EnableFixedStep(bool fixedStep); - void* GenerateParticle(); void* GenerateParticles(unsigned int count); const ParticleDeclarationConstRef& GetDeclaration() const; - float GetFixedStepSize() const; unsigned int GetMaxParticleCount() const; unsigned int GetParticleCount() const; unsigned int GetParticleSize() const; - bool IsFixedStepEnabled() const; - void KillParticle(unsigned int index); void KillParticles(); @@ -60,7 +55,6 @@ namespace Nz void RemoveEmitter(ParticleEmitter* emitter); void RemoveGenerator(ParticleGenerator* generator); - void SetFixedStepSize(float stepSize); void SetRenderer(ParticleRenderer* renderer); void Update(float elapsedTime); @@ -79,10 +73,7 @@ namespace Nz std::vector m_generators; ParticleDeclarationConstRef m_declaration; ParticleRendererRef m_renderer; - bool m_fixedStepEnabled; bool m_processing; - float m_stepAccumulator; - float m_stepSize; unsigned int m_maxParticleCount; unsigned int m_particleCount; unsigned int m_particleSize; diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index 08fb03f39..d93c085db 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -154,7 +154,6 @@ namespace Nz * \param particleCount Number of particles * \param elapsedTime Delta time between the previous frame */ - void ParticleGroup::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) { m_processing = true; @@ -174,8 +173,8 @@ namespace Nz if (m_dyingParticles.size() < m_particleCount) { // We kill them in reverse order, std::set sorting them via std::greater - // The reason is simple, as the death of a particle means the move of the last particle in the buffer, - // without this solution, certain particles could avoid the death + // The reason is simple, as the death of a particle means moving the last particle in the buffer, + // without this solution, certain particles could avoid death for (unsigned int index : m_dyingParticles) KillParticle(index); } @@ -252,16 +251,6 @@ namespace Nz return m_declaration; } - /*! - * \brief Gets the fixed step size - * \return Current fixed step size - */ - - float ParticleGroup::GetFixedStepSize() const - { - return m_stepSize; - } - /*! * \brief Gets the maximum number of particles * \return Current maximum number @@ -292,16 +281,6 @@ namespace Nz return m_particleSize; } - /*! - * \brief Checks whether the fixed step is enabled - * \return true If it is the case - */ - - bool ParticleGroup::IsFixedStepEnabled() const - { - return m_fixedStepEnabled; - } - /*! * \brief Kills one particle * @@ -372,17 +351,6 @@ namespace Nz m_generators.erase(it); } - /*! - * \brief Sets the fixed step size - * - * \param stepSize Fixed step size - */ - - void ParticleGroup::SetFixedStepSize(float stepSize) - { - m_stepSize = stepSize; - } - /*! * \brief Sets the renderer of the particles * @@ -448,12 +416,10 @@ namespace Nz m_particleCount = system.m_particleCount; m_particleSize = system.m_particleSize; m_renderer = system.m_renderer; - m_stepSize = system.m_stepSize; // The copy can not (or should not) happen during the update, there is no use to copy m_dyingParticles.clear(); m_processing = false; - m_stepAccumulator = 0.f; m_buffer.clear(); // To avoid a copy due to resize() which will be pointless ResizeBuffer(); From 095a19e450fd29b57f9b9f6254f2630215e69738 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 18:49:16 +0200 Subject: [PATCH 194/224] SDK/ListenerComponent: Fix warnings Former-commit-id: 7d1294593a24bce6d68a34326d9cb48f76127401 [formerly 6728deb3276df51fe4d850c1bd7a58b30d6fd53a] Former-commit-id: c7ab5f3d821d86948a39468a67b31a597350eb93 --- SDK/include/NDK/Components/ListenerComponent.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SDK/include/NDK/Components/ListenerComponent.hpp b/SDK/include/NDK/Components/ListenerComponent.hpp index 3d472bed3..a2b9d59d2 100644 --- a/SDK/include/NDK/Components/ListenerComponent.hpp +++ b/SDK/include/NDK/Components/ListenerComponent.hpp @@ -15,11 +15,11 @@ namespace Ndk class NDK_API ListenerComponent : public Component { public: - ListenerComponent(); + inline ListenerComponent(); ~ListenerComponent() = default; - bool IsActive() const; - void SetActive(bool active = true); + inline bool IsActive() const; + inline void SetActive(bool active = true); static ComponentIndex componentIndex; From 9576759abb2dd7c5667f9b0433e2024141c45599 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 23:47:09 +0200 Subject: [PATCH 195/224] Build: Add a separate config file and library/binary search paths support Former-commit-id: f875de03150e6c505816bf526bc0432c9fffccac [formerly 52eef94d32a8b41b1381cfc63fcb5eb1e058f2b9] Former-commit-id: 22da03a49982c4f48a1feb6cf7319b07949ad295 --- build/config.lua | 17 ++ build/scripts/common.lua | 500 ++++++++++++++++++++++----------------- 2 files changed, 304 insertions(+), 213 deletions(-) create mode 100644 build/config.lua diff --git a/build/config.lua b/build/config.lua new file mode 100644 index 000000000..8370331c7 --- /dev/null +++ b/build/config.lua @@ -0,0 +1,17 @@ +-- This file contains special configurations values, such as directories to extern libraries (Qt) +-- Editing this file is not required to use/compile the engine, as default values should be enough + +-- Builds Nazara extern libraries (such as lua/STB) +BuildDependencies = true + +-- Builds Nazara examples +BuildExamples = true + +-- Setup additionnals install directories, separated by a semi-colon ; (library binaries will be copied there) +--InstallDir = "/usr/local/lib64" + +-- Excludes client-only modules/tools/examples +ServerMode = false + +-- Builds modules as one united library (useless on POSIX systems) +UniteModules = false diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 2b4906569..66345ef7e 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -24,7 +24,7 @@ function NazaraBuild:Execute() if (self.Actions[_ACTION] == nil) then local makeLibDir = os.is("windows") and "mingw" or "gmake" - if (_OPTIONS["with-extlibs"]) then + if (self.Config["BuildDependencies"]) then workspace("NazaraExtlibs") platforms(platformData) @@ -39,12 +39,6 @@ function NazaraBuild:Execute() location(_ACTION) kind("StaticLib") - configuration("x32") - libdirs("../extlibs/lib/common/x86") - - configuration("x64") - libdirs("../extlibs/lib/common/x64") - configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") @@ -111,6 +105,12 @@ function NazaraBuild:Execute() includedirs(libTable.Includes) links(libTable.Libraries) + configuration("x32") + libdirs(libTable.LibraryPaths.x86) + + configuration("x64") + libdirs(libTable.LibraryPaths.x64) + for k,v in pairs(libTable.ConfigurationLibraries) do configuration(k) links(v) @@ -188,11 +188,11 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common") configuration("x32") - libdirs("../extlibs/lib/common/x86") + libdirs(moduleTable.LibraryPaths.x86) configuration("x64") defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") + libdirs(moduleTable.LibraryPaths.x64) configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") @@ -297,11 +297,11 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common") configuration("x32") - libdirs("../extlibs/lib/common/x86") + libdirs(toolTable.LibraryPaths.x86) configuration("x64") defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") + libdirs(toolTable.LibraryPaths.x64) configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") @@ -431,11 +431,11 @@ function NazaraBuild:Execute() links(exampleTable.Libraries) configuration("x32") - libdirs("../extlibs/lib/common/x86") + libdirs(exampleTable.LibraryPaths.x86) configuration("x64") defines("NAZARA_PLATFORM_x64") - libdirs("../extlibs/lib/common/x64") + libdirs(exampleTable.LibraryPaths.x64) configuration({"codeblocks or codelite or gmake", "x32"}) libdirs("../lib/" .. makeLibDir .. "/x86") @@ -465,33 +465,29 @@ function NazaraBuild:Execute() end end +function NazaraBuild:GetConfig() + return self.Config +end + +function NazaraBuild:GetDependency(infoTable, name) + local projectName = name:match("Nazara(%w+)") + if (projectName) then + -- tool or module + local moduleTable = self.Modules[projectName:lower()] + if (moduleTable) then + return moduleTable + else + local toolTable = self.Tools[projectName:lower()] + if (toolTable) then + return toolTable + end + end + else + return self.ExtLibs[name:lower()] + end +end + function NazaraBuild:Initialize() - -- Commençons par les options - newoption({ - trigger = "install-path", - description = "Setup additionnals install directories (library binaries will be copied there)" - }) - - newoption({ - trigger = "server", - description = "Excludes client-only modules/tools/examples" - }) - - newoption({ - trigger = "united", - description = "Builds all the modules as one united library" - }) - - newoption({ - trigger = "with-extlibs", - description = "Builds the extern libraries" - }) - - newoption({ - trigger = "with-examples", - description = "Builds the examples" - }) - self.Actions = {} self.Examples = {} self.ExecutableDir = {} @@ -500,12 +496,8 @@ function NazaraBuild:Initialize() self.Modules = {} self.Tools = {} - if (_OPTIONS["install-path"]) then - local paths = string.explode(_OPTIONS["install-path"], ";") - for k,v in pairs(paths) do - self:AddInstallPath(v) - end - end + self.Config = {} + self:LoadConfig() -- Actions modules = os.matchfiles("scripts/actions/*.lua") @@ -593,7 +585,7 @@ function NazaraBuild:Initialize() TOOL = nil -- Examples - if (_OPTIONS["with-examples"]) then + if (self.Config["BuildExamples"]) then local examples = os.matchdirs("../examples/*") for k,v in pairs(examples) do local dirName = v:match(".*/(.*)") @@ -643,6 +635,236 @@ function NazaraBuild:Initialize() end end +function NazaraBuild:LoadConfig() + local f = io.open("config.lua", "r") + if (not f) then + print("Failed to open config.lua") + return + end + + local content = f:read("*a") + f:close() + + local func, err = loadstring(content) + if (not func) then + print("Failed to parse config.lua: " .. err) + return + end + + setfenv(func, self.Config) + + local status, err = pcall(func) + if (not status) then + print("Failed to load config.lua: " .. err) + return + end + + local configTable = self.Config + local AddBoolOption = function (option, name, description) + newoption({ + trigger = name, + description = description + }) + + local str = _OPTIONS[name] + if (str) then + if (#str == 0 or str == "1" or str == "yes" or str == "true") then + configTable[option] = true + elseif (str == "0" or str == "no" or str == "false") then + configTable[option] = false + else + error("Invalid entry for " .. name .. " option: \"" .. str .. "\"") + end + end + end + + AddBoolOption("BuildDependencies", "with-extlibs", "Builds the extern libraries") + AddBoolOption("BuildExamples", "with-examples", "Builds the examples") + AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples") + AddBoolOption("UniteModules", "united", "Builds all the modules as one united library") + + -- InstallDir + newoption({ + trigger = "install-path", + description = "Setup additionnals install directories (library binaries will be copied there)" + }) + + self.Config["InstallDir"] = self.Config["InstallDir"] or "" + if (_OPTIONS["install-path"] ~= nil) then + self.Config["InstallDir"] = self.Config["InstallDir"] .. ";" .. _OPTIONS["install-path"] + end + + local paths = string.explode(self.Config["InstallDir"], ";") + for k,v in pairs(paths) do + self:AddInstallPath(v) + end +end + +function NazaraBuild:MakeInstallCommands(infoTable) + if (PremakeVersion < 50) then + return + end + + if (os.is("windows")) then + configuration({}) + + for k,v in pairs(self.InstallDir) do + local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) + postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "]] .. destPath .. [[\" /E /Y]]}) + end + + for k,fileName in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do + local paths = {} + for k,v in pairs(infoTable.BinaryPaths.x86) do + table.insert(paths, {"x32", v .. "/" .. fileName .. ".dll"}) + table.insert(paths, {"x32", v .. "/lib" .. fileName .. ".dll"}) + end + + for k,v in pairs(infoTable.BinaryPaths.x64) do + table.insert(paths, {"x64", v .. "/" .. fileName .. ".dll"}) + table.insert(paths, {"x64", v .. "/lib" .. fileName .. ".dll"}) + end + + for k,v in pairs(paths) do + local config = v[1] + local srcPath = v[2] + if (os.isfile(srcPath)) then + if (infoTable.Kind == "plugin") then + srcPath = "../../" .. srcPath + end + + configuration(config) + + for k,v in pairs(self.ExecutableDir) do + local srcPath = path.isabsolute(srcPath) and path.translate(srcPath) or [[%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. srcPath .. [[")}]] + local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) + postbuildcommands({[[xcopy "]] .. srcPath .. [[" "]] .. destPath .. [[\" /E /Y]]}) + end + end + end + end + end +end + +local PosixOSes = { + ["bsd"] = true, + ["linux"] = true, + ["macosx"] = true, + ["solaris"] = true +} + +function NazaraBuild:Process(infoTable) + local libraries = {} + for k, library in pairs(infoTable.Libraries) do + local libraryTable = self:GetDependency(infoTable, library) + if (libraryTable) then + if (libraryTable.Excluded) then + infoTable.Excluded = true + infoTable.ExcludeReason = "depends on excluded " .. library .. " " .. libraryTable.Type:lower() + return false + end + + if (libraryTable.Type == "Module") then + if (_OPTIONS["united"]) then + library = "NazaraEngine" + else + library = "Nazara" .. libraryTable.Name + end + + if (not self.Config["UniteModules"] or infoTable.Type ~= "Module") then + table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) + end + elseif (libraryTable.Type == "ExternLib") then + library = libraryTable.Name + + table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") + elseif (libraryTable.Type == "Tool") then + library = "Nazara" .. libraryTable.Name + + -- Import tools includes + for k,v in ipairs(libraryTable.Includes) do + table.insert(infoTable.Includes, v) + end + + -- And libraries + for k, v in pairs(libraryTable.Libraries) do + table.insert(infoTable.Libraries, v) + end + + for config, libs in pairs(libraryTable.ConfigurationLibraries) do + for k,v in pairs(libs) do + table.insert(infoTable.ConfigurationLibraries[config], v) + end + end + + table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") + table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) + else + infoTable.Excluded = true + infoTable.ExcludeReason = "dependency " .. library .. " has invalid type \"" .. libraryTable.Type .. "\"" + return false + end + else + table.insert(libraries, library) + end + end + infoTable.Libraries = libraries + + for k,v in pairs(infoTable) do + local target = k:match("Os(%w+)") + if (target) then + local targetTable = infoTable[target] + if (targetTable) then + local excludeTargetTable = infoTable[target .. "Excluded"] + for platform, defineTable in pairs(v) do + platform = string.lower(platform) + if (platform == "posix") then + local osname = os.get() + if (PosixOSes[osname]) then + platform = osname + end + end + + if (os.is(platform)) then + for k,v in ipairs(defineTable) do + table.insert(targetTable, v) + end + elseif (excludeTargetTable) then + for k,v in ipairs(defineTable) do + table.insert(excludeTargetTable, v) + end + end + end + + infoTable[k] = nil + end + end + end + + if (infoTable.Kind == "application") then + self:AddExecutablePath(infoTable.TargetDirectory) + end + + if (infoTable.Validate) then + local ret, err = infoTable:Validate() + if (not ret) then + infoTable.Excluded = true + infoTable.ExcludeReason = "validation failed: " .. err + return false + end + end + + return true +end + function NazaraBuild:RegisterAction(actionTable) if (actionTable.Name == nil or type(actionTable.Name) ~= "string" or string.len(actionTable.Name) == 0) then return false, "Invalid action name" @@ -750,7 +972,7 @@ function NazaraBuild:RegisterModule(moduleTable) table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.inl") table.insert(moduleTable.Files, "../src/Nazara/" .. moduleTable.Name .. "/**.cpp") - if (_OPTIONS["united"] and lowerCaseName ~= "core") then + if (self.Config["UniteModules"] and lowerCaseName ~= "core") then table.insert(moduleTable.FilesExcluded, "../src/Nazara/" .. moduleTable.Name .. "/Debug/NewOverload.cpp") end @@ -789,132 +1011,8 @@ function NazaraBuild:RegisterTool(toolTable) return true end -local PosixOSes = { - ["bsd"] = true, - ["linux"] = true, - ["macosx"] = true, - ["solaris"] = true -} - -function NazaraBuild:Process(infoTable) - local libraries = {} - for k, library in pairs(infoTable.Libraries) do - local projectName = library:match("Nazara(%w+)") - local moduleTable = projectName and self.Modules[projectName:lower()] - local toolTable = projectName and self.Tools[projectName:lower()] - - if (moduleTable) then - if (moduleTable.Excluded) then - infoTable.Excluded = true - infoTable.ExcludeReason = "depends on excluded " .. projectName .. " module" - return false - end - - if (_OPTIONS["united"]) then - library = "NazaraEngine" - else - library = "Nazara" .. moduleTable.Name - end - - if (not _OPTIONS["united"] or infoTable.Type ~= "Module") then - table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") - table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) - end - else - local extLibTable = self.ExtLibs[library:lower()] - if (extLibTable) then - if (extLibTable.Excluded) then - infoTable.Excluded = true - infoTable.ExcludeReason = "depends on excluded " .. extLibTable.Name .. " external library" - return false - end - - library = extLibTable.Name - - table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") - table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") - else - if (toolTable and toolTable.Kind == "library") then - if (toolTable.Excluded) then - infoTable.Excluded = true - infoTable.ExcludeReason = "depends on excluded " .. toolTable.Name .. " tool" - return false - end - - library = "Nazara" .. toolTable.Name - - -- Import tools includes - for k,v in ipairs(toolTable.Includes) do - table.insert(infoTable.Includes, v) - end - - -- And libraries - for k, v in pairs(toolTable.Libraries) do - table.insert(infoTable.Libraries, v) - end - - for config, libs in pairs(toolTable.ConfigurationLibraries) do - for k,v in pairs(libs) do - table.insert(infoTable.ConfigurationLibraries[config], v) - end - end - - table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") - table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") - table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) - else - table.insert(libraries, library) - end - end - end - end - infoTable.Libraries = libraries - - for k,v in pairs(infoTable) do - local target = k:match("Os(%w+)") - if (target) then - local targetTable = infoTable[target] - if (targetTable) then - local excludeTargetTable = infoTable[target .. "Excluded"] - for platform, defineTable in pairs(v) do - platform = string.lower(platform) - if (platform == "posix") then - local osname = os.get() - if (PosixOSes[osname]) then - platform = osname - end - end - - if (os.is(platform)) then - for k,v in ipairs(defineTable) do - table.insert(targetTable, v) - end - elseif (excludeTargetTable) then - for k,v in ipairs(defineTable) do - table.insert(excludeTargetTable, v) - end - end - end - - infoTable[k] = nil - end - end - end - - if (infoTable.Kind == "application") then - self:AddExecutablePath(infoTable.TargetDirectory) - end - - return true -end - function NazaraBuild:Resolve(infoTable) - if (infoTable.ClientOnly and _OPTIONS["server"]) then + if (infoTable.ClientOnly and self.Config["ServerMode"]) then infoTable.Excluded = true infoTable.ExcludeReason = "excluded by command-line options (client-only)" end @@ -937,53 +1035,19 @@ function NazaraBuild:Resolve(infoTable) end end -function NazaraBuild:MakeInstallCommands(infoTable) - if (PremakeVersion < 50) then - return - end - - if (os.is("windows")) then - configuration({}) - - for k,v in pairs(self.InstallDir) do - local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "]] .. destPath .. [[\" /E /Y]]}) - end - - for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do - local paths = {} - table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"}) - table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) - table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) - table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) - - for k,v in pairs(paths) do - local config = v[1] - local srcPath = v[2] - if (os.isfile(srcPath)) then - if (infoTable.Kind == "plugin") then - srcPath = "../../" .. srcPath - end - - configuration(config) - - for k,v in pairs(self.ExecutableDir) do - local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k) - postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. srcPath .. [[")}" "]] .. destPath .. [[\" /E /Y]]}) - end - end - end - end - end -end - function NazaraBuild:SetupInfoTable(infoTable) - infoTable.Excludable = true + infoTable.BinaryPaths = {} + infoTable.BinaryPaths.x86 = {} + infoTable.BinaryPaths.x64 = {} infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries.DebugStatic = {} infoTable.ConfigurationLibraries.ReleaseStatic = {} infoTable.ConfigurationLibraries.DebugDynamic = {} infoTable.ConfigurationLibraries.ReleaseDynamic = {} + infoTable.Excludable = true + infoTable.LibraryPaths = {} + infoTable.LibraryPaths.x86 = {} + infoTable.LibraryPaths.x64 = {} local infos = {"Defines", "DynLib", "Files", "FilesExcluded", "Flags", "Includes", "Libraries"} for k,v in ipairs(infos) do @@ -1003,12 +1067,22 @@ function NazaraBuild:SetupExtlibTable(infoTable) self:SetupInfoTable(infoTable) infoTable.Kind = "library" + + table.insert(infoTable.BinaryPaths.x86, "../extlibs/lib/common/x86") + table.insert(infoTable.BinaryPaths.x64, "../extlibs/lib/common/x64") + table.insert(infoTable.LibraryPaths.x86, "../extlibs/lib/common/x86") + table.insert(infoTable.LibraryPaths.x64, "../extlibs/lib/common/x64") end function NazaraBuild:SetupModuleTable(infoTable) self:SetupInfoTable(infoTable) infoTable.Kind = "library" + + table.insert(infoTable.BinaryPaths.x86, "../extlibs/lib/common/x86") + table.insert(infoTable.BinaryPaths.x64, "../extlibs/lib/common/x64") + table.insert(infoTable.LibraryPaths.x86, "../extlibs/lib/common/x86") + table.insert(infoTable.LibraryPaths.x64, "../extlibs/lib/common/x64") end NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable \ No newline at end of file From 528842b11cd92873ac39b23aecc77d0094075aca Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 29 Jul 2016 23:56:38 +0200 Subject: [PATCH 196/224] Add build/config.lua to .gitignore Former-commit-id: c6e30e048553752e79e14b2284f30a8d11606904 [formerly 7b9f1d013e1a871438733d854455b15d64fe0ccd] Former-commit-id: 4b65dc81e89fc13ded4e948c7bdbb56379dc89e6 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c930343f4..463291bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # Nazara build +build/config.lua examples/bin/*.exe examples/bin/*.pdb examples/bin/*.dll From 2b8032debbdf99ead73b58edee592402ecd8f28c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Jul 2016 14:06:29 +0200 Subject: [PATCH 197/224] Build: Remove "united" shortcuts (since we have config.lua now) Former-commit-id: d071f7274e5a6420101282a6b094a19e9a35e4b1 [formerly aba8dffc998bf3e574c6f26375081240eb106a8f] Former-commit-id: 70068527e5b4b974370b6dfd9023a2448eb6471c --- build/Build_CodeBlocks.bat | 2 +- build/Build_CodeBlocks_OneLibrary.bat | 1 - build/Build_CodeLite.bat | 2 +- build/Build_CodeLite_OneLibrary.bat | 1 - build/Build_VS2015.bat | 2 +- build/Build_VS2015_OneLibrary.bat | 1 - 6 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 build/Build_CodeBlocks_OneLibrary.bat delete mode 100644 build/Build_CodeLite_OneLibrary.bat delete mode 100644 build/Build_VS2015_OneLibrary.bat diff --git a/build/Build_CodeBlocks.bat b/build/Build_CodeBlocks.bat index 983c7ae80..439c5efac 100644 --- a/build/Build_CodeBlocks.bat +++ b/build/Build_CodeBlocks.bat @@ -1 +1 @@ -premake4 --with-extlibs --with-examples codeblocks \ No newline at end of file +premake4 codeblocks \ No newline at end of file diff --git a/build/Build_CodeBlocks_OneLibrary.bat b/build/Build_CodeBlocks_OneLibrary.bat deleted file mode 100644 index b7c5ab4c9..000000000 --- a/build/Build_CodeBlocks_OneLibrary.bat +++ /dev/null @@ -1 +0,0 @@ -premake4 --united --with-extlibs --with-examples codeblocks \ No newline at end of file diff --git a/build/Build_CodeLite.bat b/build/Build_CodeLite.bat index 8584e6d9b..170e7a451 100644 --- a/build/Build_CodeLite.bat +++ b/build/Build_CodeLite.bat @@ -1 +1 @@ -premake5 --with-extlibs --with-examples codelite \ No newline at end of file +premake5 codelite \ No newline at end of file diff --git a/build/Build_CodeLite_OneLibrary.bat b/build/Build_CodeLite_OneLibrary.bat deleted file mode 100644 index 52a80f504..000000000 --- a/build/Build_CodeLite_OneLibrary.bat +++ /dev/null @@ -1 +0,0 @@ -premake5 --united --with-extlibs --with-examples codelite \ No newline at end of file diff --git a/build/Build_VS2015.bat b/build/Build_VS2015.bat index 2dd6e578a..6d0726faf 100644 --- a/build/Build_VS2015.bat +++ b/build/Build_VS2015.bat @@ -1 +1 @@ -premake5 --with-extlibs --with-examples vs2015 \ No newline at end of file +premake5 vs2015 \ No newline at end of file diff --git a/build/Build_VS2015_OneLibrary.bat b/build/Build_VS2015_OneLibrary.bat deleted file mode 100644 index aaab1938c..000000000 --- a/build/Build_VS2015_OneLibrary.bat +++ /dev/null @@ -1 +0,0 @@ -premake5 --united --with-extlibs --with-examples vs2015 \ No newline at end of file From f60ce60cd5d1aa165aad7d11c9fdf1482e6122a6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Jul 2016 15:50:02 +0200 Subject: [PATCH 198/224] Sdk: Components no longer need to be default-constructibles Former-commit-id: 7fffb2029784fc5361e560e3568d4c739f433a91 [formerly 14435fa68c516f1d16b2c474bef81f9a465cd7be] Former-commit-id: 8a14c5defaabc15e92ef8e2854de5598683e27ac --- SDK/include/NDK/Component.inl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/SDK/include/NDK/Component.inl b/SDK/include/NDK/Component.inl index e39091224..833395957 100644 --- a/SDK/include/NDK/Component.inl +++ b/SDK/include/NDK/Component.inl @@ -28,13 +28,11 @@ namespace Ndk template ComponentIndex Component::RegisterComponent(ComponentId id) { - // Il faut que notre composant possède un constructeur par défaut (pour la factory) - static_assert(std::is_default_constructible::value, "ComponentType must be default-constructible"); - // On utilise les lambda pour créer une fonction factory auto factory = []() -> BaseComponent* { - return new ComponentType; + return nullptr; //< Temporary workaround to allow non-default-constructed components, will be updated for serialization + //return new ComponentType; }; return BaseComponent::RegisterComponent(id, factory); From 4efb8f0354ce0a5ddaae48d5e4b573b3c706bd58 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Jul 2016 15:50:41 +0200 Subject: [PATCH 199/224] Graphics/ParticleEmitter: No longer inherit from Node Former-commit-id: d2d67fdfc9940cf09b6bf15560c4f8b2b8c3819d [formerly 6deadba03ab57675310b279ce401c1db8b02869b] Former-commit-id: 115f0a7f6293703be1bd497a107419ec95683dc1 --- include/Nazara/Graphics/ParticleEmitter.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index b6acee156..7e2c6a7f8 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -9,14 +9,13 @@ #include #include -#include namespace Nz { class ParticleMapper; class ParticleGroup; - class NAZARA_GRAPHICS_API ParticleEmitter : public Node + class NAZARA_GRAPHICS_API ParticleEmitter { public: ParticleEmitter(); From 654b52bb0c1b12a03cae2f9af7892b461a84825d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 30 Jul 2016 15:51:46 +0200 Subject: [PATCH 200/224] Sdk: Integrate particles Former-commit-id: 48dac6b378c45130c43f5b8214a7b13a35cf06d1 [formerly c874b77869e750df33a1e77fdb40747b543b2efa] Former-commit-id: a2c06e5f2b0fe3dd1c74ce2835436a7219260bf8 --- SDK/include/NDK/Components.hpp | 4 +- .../Components/ParticleEmitterComponent.hpp | 45 ++++++++++++++ .../Components/ParticleEmitterComponent.inl | 18 ++++++ .../NDK/Components/ParticleGroupComponent.hpp | 35 +++++++++++ .../NDK/Components/ParticleGroupComponent.inl | 17 ++++++ SDK/include/NDK/Systems.hpp | 3 +- SDK/include/NDK/Systems/ParticleSystem.hpp | 29 +++++++++ SDK/include/NDK/Systems/ParticleSystem.inl | 3 + SDK/include/NDK/Systems/RenderSystem.hpp | 1 + .../Components/ParticleEmitterComponent.cpp | 59 +++++++++++++++++++ .../NDK/Components/ParticleGroupComponent.cpp | 10 ++++ SDK/src/NDK/Sdk.cpp | 6 ++ SDK/src/NDK/Systems/ParticleSystem.cpp | 26 ++++++++ SDK/src/NDK/Systems/RenderSystem.cpp | 16 +++++ SDK/src/NDK/World.cpp | 2 + 15 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 SDK/include/NDK/Components/ParticleEmitterComponent.hpp create mode 100644 SDK/include/NDK/Components/ParticleEmitterComponent.inl create mode 100644 SDK/include/NDK/Components/ParticleGroupComponent.hpp create mode 100644 SDK/include/NDK/Components/ParticleGroupComponent.inl create mode 100644 SDK/include/NDK/Systems/ParticleSystem.hpp create mode 100644 SDK/include/NDK/Systems/ParticleSystem.inl create mode 100644 SDK/src/NDK/Components/ParticleEmitterComponent.cpp create mode 100644 SDK/src/NDK/Components/ParticleGroupComponent.cpp create mode 100644 SDK/src/NDK/Systems/ParticleSystem.cpp diff --git a/SDK/include/NDK/Components.hpp b/SDK/include/NDK/Components.hpp index ca993b5b6..79bc196f7 100644 --- a/SDK/include/NDK/Components.hpp +++ b/SDK/include/NDK/Components.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 01 Jun 2016 at 13:11:09 +// This file was automatically generated on 30 Jul 2016 at 15:29:16 #pragma once @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp new file mode 100644 index 000000000..add138ee9 --- /dev/null +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_SERVER +#ifndef NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP +#define NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP + +#include +#include + +namespace Ndk +{ + class NDK_API ParticleEmitterComponent : public Component, public Nz::ParticleEmitter + { + public: + using SetupFunc = std::function; + + ParticleEmitterComponent(Nz::ParticleGroup* group); + ParticleEmitterComponent(const ParticleEmitterComponent& emitter); + ~ParticleEmitterComponent(); + + inline bool IsActive() const; + + void SetActive(bool active = true); + void SetGroup(Nz::ParticleGroup* group); + inline void SetSetupFunc(SetupFunc func); + + static ComponentIndex componentIndex; + + private: + void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override; + + SetupFunc m_setupFunc; + Nz::ParticleGroup* m_particleGroup; + bool m_isActive; + }; +} + +#include + +#endif // NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP +#endif // NDK_SERVER \ No newline at end of file diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.inl b/SDK/include/NDK/Components/ParticleEmitterComponent.inl new file mode 100644 index 000000000..6cc9e8c29 --- /dev/null +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.inl @@ -0,0 +1,18 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include + +namespace Ndk +{ + inline bool ParticleEmitterComponent::IsActive() const + { + return m_isActive; + } + + inline void Ndk::ParticleEmitterComponent::SetSetupFunc(SetupFunc func) + { + m_setupFunc = std::move(func); + } +} diff --git a/SDK/include/NDK/Components/ParticleGroupComponent.hpp b/SDK/include/NDK/Components/ParticleGroupComponent.hpp new file mode 100644 index 000000000..638f877d3 --- /dev/null +++ b/SDK/include/NDK/Components/ParticleGroupComponent.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_SERVER +#ifndef NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP +#define NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP + +#include +#include + +namespace Ndk +{ + class ParticleGroupComponent; + + using ParticleGroupComponentHandle = Nz::ObjectHandle; + + class NDK_API ParticleGroupComponent : public Component, public Nz::ParticleGroup + { + public: + inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout); + inline ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration); + ParticleGroupComponent(const ParticleGroupComponent&) = default; + ~ParticleGroupComponent() = default; + + static ComponentIndex componentIndex; + }; +} + +#include + +#endif // NDK_COMPONENTS_PARTICLEGROUPCOMPONENT_HPP +#endif // NDK_SERVER \ No newline at end of file diff --git a/SDK/include/NDK/Components/ParticleGroupComponent.inl b/SDK/include/NDK/Components/ParticleGroupComponent.inl new file mode 100644 index 000000000..7aefdad56 --- /dev/null +++ b/SDK/include/NDK/Components/ParticleGroupComponent.inl @@ -0,0 +1,17 @@ +#include "ParticleGroupComponent.hpp" +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +namespace Ndk +{ + inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleLayout layout) : + ParticleGroup(maxParticleCount, layout) + { + } + + inline ParticleGroupComponent::ParticleGroupComponent(unsigned int maxParticleCount, Nz::ParticleDeclarationConstRef declaration) : + ParticleGroup(maxParticleCount, std::move(declaration)) + { + } +} diff --git a/SDK/include/NDK/Systems.hpp b/SDK/include/NDK/Systems.hpp index 176a956ee..269bead6f 100644 --- a/SDK/include/NDK/Systems.hpp +++ b/SDK/include/NDK/Systems.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 01 Jun 2016 at 13:11:09 +// This file was automatically generated on 30 Jul 2016 at 15:29:16 #pragma once @@ -6,6 +6,7 @@ #define NDK_SYSTEMS_GLOBAL_HPP #include +#include #include #include #include diff --git a/SDK/include/NDK/Systems/ParticleSystem.hpp b/SDK/include/NDK/Systems/ParticleSystem.hpp new file mode 100644 index 000000000..3ae00a995 --- /dev/null +++ b/SDK/include/NDK/Systems/ParticleSystem.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#pragma once + +#ifndef NDK_SYSTEMS_PARTICLESYSTEM_HPP +#define NDK_SYSTEMS_PARTICLESYSTEM_HPP + +#include + +namespace Ndk +{ + class NDK_API ParticleSystem : public System + { + public: + ParticleSystem(); + ~ParticleSystem() = default; + + static SystemIndex systemIndex; + + private: + void OnUpdate(float elapsedTime) override; + }; +} + +#include + +#endif // NDK_SYSTEMS_PARTICLESYSTEM_HPP diff --git a/SDK/include/NDK/Systems/ParticleSystem.inl b/SDK/include/NDK/Systems/ParticleSystem.inl new file mode 100644 index 000000000..e5f296d27 --- /dev/null +++ b/SDK/include/NDK/Systems/ParticleSystem.inl @@ -0,0 +1,3 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index f2fbc7a65..82e558773 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -60,6 +60,7 @@ namespace Ndk EntityList m_directionalLights; EntityList m_lights; EntityList m_pointSpotLights; + EntityList m_particleGroups; Nz::BackgroundRef m_background; Nz::DepthRenderTechnique m_shadowTechnique; Nz::Matrix4f m_coordinateSystemMatrix; diff --git a/SDK/src/NDK/Components/ParticleEmitterComponent.cpp b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp new file mode 100644 index 000000000..6a3cfeb7e --- /dev/null +++ b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + ParticleEmitterComponent::ParticleEmitterComponent(Nz::ParticleGroup* group) : + m_particleGroup(group), + m_isActive(true) + { + if (m_particleGroup) + m_particleGroup->AddEmitter(this); + } + + ParticleEmitterComponent::ParticleEmitterComponent(const ParticleEmitterComponent& emitter) : + m_particleGroup(emitter.m_particleGroup), + m_isActive(emitter.m_isActive) + { + if (m_isActive) + m_particleGroup->AddEmitter(this); + } + + ParticleEmitterComponent::~ParticleEmitterComponent() + { + m_particleGroup->RemoveEmitter(this); + } + + inline void Ndk::ParticleEmitterComponent::SetActive(bool active) + { + if (m_isActive != active) + { + if (active) + m_particleGroup->AddEmitter(this); + else + m_particleGroup->RemoveEmitter(this); + } + } + + void ParticleEmitterComponent::SetGroup(Nz::ParticleGroup* group) + { + if (m_particleGroup) + m_particleGroup->RemoveEmitter(this); + + m_particleGroup = group; + if (m_particleGroup && m_isActive) + m_particleGroup = group; + } + + inline void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const + { + if (m_setupFunc) + m_setupFunc(m_entity, mapper, count); + } + + ComponentIndex ParticleEmitterComponent::componentIndex; +} diff --git a/SDK/src/NDK/Components/ParticleGroupComponent.cpp b/SDK/src/NDK/Components/ParticleGroupComponent.cpp new file mode 100644 index 000000000..4e0845871 --- /dev/null +++ b/SDK/src/NDK/Components/ParticleGroupComponent.cpp @@ -0,0 +1,10 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include + +namespace Ndk +{ + ComponentIndex ParticleGroupComponent::componentIndex; +} diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index 7f29bb18e..964913bf8 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include #include #endif @@ -71,6 +74,8 @@ namespace Ndk InitializeComponent("NdkLight"); InitializeComponent("NdkList"); InitializeComponent("NdkGfx"); + InitializeComponent("NdkPaEmi"); + InitializeComponent("NdkPaGrp"); #endif // Systems @@ -84,6 +89,7 @@ namespace Ndk #ifndef NDK_SERVER // Client systems InitializeSystem(); + InitializeSystem(); InitializeSystem(); #endif diff --git a/SDK/src/NDK/Systems/ParticleSystem.cpp b/SDK/src/NDK/Systems/ParticleSystem.cpp new file mode 100644 index 000000000..a9f63cb6c --- /dev/null +++ b/SDK/src/NDK/Systems/ParticleSystem.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Development Kit" +// For conditions of distribution and use, see copyright notice in Prerequesites.hpp + +#include +#include + +namespace Ndk +{ + ParticleSystem::ParticleSystem() + { + Requires(); + } + + void ParticleSystem::OnUpdate(float elapsedTime) + { + for (const Ndk::EntityHandle& entity : GetEntities()) + { + ParticleGroupComponent& group = entity->GetComponent(); + + group.Update(elapsedTime); + } + } + + SystemIndex ParticleSystem::systemIndex; +} diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 7b90761b6..fcfd5c6a5 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace Ndk { @@ -25,8 +26,11 @@ namespace Ndk void RenderSystem::OnEntityRemoved(Entity* entity) { m_cameras.Remove(entity); + m_directionalLights.Remove(entity); m_drawables.Remove(entity); m_lights.Remove(entity); + m_particleGroups.Remove(entity); + m_pointSpotLights.Remove(entity); } void RenderSystem::OnEntityValidation(Entity* entity, bool justAdded) @@ -71,6 +75,11 @@ namespace Ndk m_lights.Remove(entity); m_pointSpotLights.Remove(entity); } + + if (entity->HasComponent()) + m_particleGroups.Insert(entity); + else + m_particleGroups.Remove(entity); } void RenderSystem::OnUpdate(float elapsedTime) @@ -118,6 +127,13 @@ namespace Ndk lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, lightNode.GetTransformMatrix())); } + for (const Ndk::EntityHandle& particleGroup : m_particleGroups) + { + ParticleGroupComponent& groupComponent = particleGroup->GetComponent(); + + groupComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::Identity()); //< ParticleGroup doesn't use Matrix4f + } + camComponent.ApplyView(); Nz::SceneData sceneData; diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index e95785896..5d0e4900b 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -9,6 +9,7 @@ #ifndef NDK_SERVER #include +#include #include #endif @@ -27,6 +28,7 @@ namespace Ndk #ifndef NDK_SERVER AddSystem(); + AddSystem(); AddSystem(); #endif } From 8f50162924e1886d68902f48b64b1a04b1af56d0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 31 Jul 2016 11:01:07 +0200 Subject: [PATCH 201/224] Build: Fix command line arguments being ignored if config.lua loading failed Former-commit-id: a21dc17f960e089dc3f8a2330def494660c682a9 [formerly b776370d7fc80107c412fe91526de7d11d53d501] Former-commit-id: b5df17fcceeba1996b06c7fa92abf8616a2a8006 --- build/scripts/common.lua | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 66345ef7e..fa610e85c 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -637,28 +637,25 @@ end function NazaraBuild:LoadConfig() local f = io.open("config.lua", "r") - if (not f) then + if (f) then + local content = f:read("*a") + f:close() + + local func, err = loadstring(content) + if (func) then + setfenv(func, self.Config) + + local status, err = pcall(func) + if (not status) then + print("Failed to load config.lua: " .. err) + end + else + print("Failed to parse config.lua: " .. err) + end + else print("Failed to open config.lua") - return end - local content = f:read("*a") - f:close() - - local func, err = loadstring(content) - if (not func) then - print("Failed to parse config.lua: " .. err) - return - end - - setfenv(func, self.Config) - - local status, err = pcall(func) - if (not status) then - print("Failed to load config.lua: " .. err) - return - end - local configTable = self.Config local AddBoolOption = function (option, name, description) newoption({ From 9d018485cbc9ed3e33377b59dce9ec423c05abbb Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 31 Jul 2016 11:01:47 +0200 Subject: [PATCH 202/224] Build/NDKServer: Fix dependencies, allowing it to exists in server mode Former-commit-id: 8130fc4bd6898f21d08bfad37e3b54676ee34b96 [formerly 9f64adc84777930b63419690bf0e454582989158] Former-commit-id: 3838886ff2303fe94b69403e1cab51cc4c99a05c --- build/scripts/tools/ndk_server.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/build/scripts/tools/ndk_server.lua b/build/scripts/tools/ndk_server.lua index 2881c56fc..e536f1036 100644 --- a/build/scripts/tools/ndk_server.lua +++ b/build/scripts/tools/ndk_server.lua @@ -37,13 +37,11 @@ TOOL.FilesExcluded = { } -TOOL.Libraries = function() - local libraries = {} - for k,v in pairs(NazaraBuild.Modules) do - if (not v.ClientOnly) then - table.insert(libraries, "Nazara" .. v.Name) - end - end - - return libraries -end +TOOL.Libraries = { + "NazaraCore", + "NazaraLua", + "NazaraNetwork", + "NazaraNoise", + "NazaraPhysics", + "NazaraUtility" +} From 554c17702bbb22e2f2fbfb5df2256891dc3833ef Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 31 Jul 2016 12:59:04 +0200 Subject: [PATCH 203/224] Build: Fix empty install commands Former-commit-id: 7083dfd9716873707791d46bc1fe333a6e229712 [formerly a8122cb99bcf5023ffad732fbf8d2b922faf1252] Former-commit-id: b9913ad6e47551044afd0259f9a1b64b82b1a743 --- .../Components/ParticleEmitterComponent.hpp | 5 ++++ build/scripts/common.lua | 4 +++- include/Nazara/Graphics/ParticleEmitter.hpp | 9 +++++-- include/Nazara/Graphics/ParticleGroup.hpp | 4 ++++ src/Nazara/Graphics/ParticleEmitter.cpp | 24 ++++++++++++++++++- src/Nazara/Graphics/ParticleGroup.cpp | 5 +++- 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp index add138ee9..b874e0818 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -20,6 +20,7 @@ namespace Ndk ParticleEmitterComponent(Nz::ParticleGroup* group); ParticleEmitterComponent(const ParticleEmitterComponent& emitter); + ParticleEmitterComponent(ParticleEmitterComponent&& emitter); ~ParticleEmitterComponent(); inline bool IsActive() const; @@ -31,8 +32,12 @@ namespace Ndk static ComponentIndex componentIndex; private: + void OnParticleGroupRelease(const Nz::ParticleGroup* particleGroup); + void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override; + NazaraSlot(Nz::ParticleGroup, OnParticleGroupRelease, m_particleGroupRelease); + SetupFunc m_setupFunc; Nz::ParticleGroup* m_particleGroup; bool m_isActive; diff --git a/build/scripts/common.lua b/build/scripts/common.lua index fa610e85c..b467eb9c5 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -693,7 +693,9 @@ function NazaraBuild:LoadConfig() local paths = string.explode(self.Config["InstallDir"], ";") for k,v in pairs(paths) do - self:AddInstallPath(v) + if (#v > 0) then + self:AddInstallPath(v) + end end end diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 7e2c6a7f8..b7a168262 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -8,6 +8,7 @@ #define NAZARA_PARTICLEEMITTER_HPP #include +#include #include namespace Nz @@ -20,7 +21,7 @@ namespace Nz public: ParticleEmitter(); ParticleEmitter(const ParticleEmitter& emitter) = default; - ParticleEmitter(ParticleEmitter&& emitter) = default; + ParticleEmitter(ParticleEmitter&& emitter); virtual ~ParticleEmitter(); virtual void Emit(ParticleGroup& system, float elapsedTime) const; @@ -36,7 +37,11 @@ namespace Nz void SetEmissionRate(float rate); ParticleEmitter& operator=(const ParticleEmitter& emitter) = default; - ParticleEmitter& operator=(ParticleEmitter&& emitter) = default; + ParticleEmitter& operator=(ParticleEmitter&& emitter); + + // Signals: + NazaraSignal(OnParticleEmitterMove, const ParticleEmitter* /*oldParticleEmitter*/, const ParticleEmitter* /*newParticleEmitter*/); + NazaraSignal(OnParticleEmitterRelease, const ParticleEmitter* /*particleEmitter*/); private: virtual void SetupParticles(ParticleMapper& mapper, unsigned int count) const = 0; diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index 412b94511..4d4704171 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -8,6 +8,7 @@ #define NAZARA_PARTICLEGROUP_HPP #include +#include #include #include #include @@ -62,6 +63,9 @@ namespace Nz ParticleGroup& operator=(const ParticleGroup& emitter); + // Signals: + NazaraSignal(OnParticleGroupRelease, const ParticleGroup* /*particleGroup*/); + private: void MakeBoundingVolume() const override; void ResizeBuffer(); diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index b11cfdfe9..10f057dce 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -32,7 +32,19 @@ namespace Nz { } - ParticleEmitter::~ParticleEmitter() = default; + ParticleEmitter::ParticleEmitter(ParticleEmitter&& emitter) : + m_lagCompensationEnabled(emitter.m_lagCompensationEnabled), + m_emissionAccumulator(0.f), + m_emissionRate(emitter.m_emissionRate), + m_emissionCount(emitter.m_emissionCount) + { + OnParticleEmitterMove(&emitter, this); + } + + ParticleEmitter::~ParticleEmitter() + { + OnParticleEmitterRelease(this); + } /*! * \brief Emits particles according to the delta time between the previous frame @@ -141,4 +153,14 @@ namespace Nz { m_emissionRate = rate; } + + ParticleEmitter& ParticleEmitter::operator=(ParticleEmitter && emitter) + { + m_emissionCount = emitter.m_emissionCount; + m_emissionRate = emitter.m_emissionRate; + m_lagCompensationEnabled = emitter.m_lagCompensationEnabled; + + OnParticleEmitterMove(&emitter, this); + return *this; + } } diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index d93c085db..87dbb390c 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -77,7 +77,10 @@ namespace Nz std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); } - ParticleGroup::~ParticleGroup() = default; + ParticleGroup::~ParticleGroup() + { + OnParticleGroupRelease(this); + } /*! * \brief Adds a controller to the particles From 44174feac6f7f14b0a7316592753c4c69c0f61e9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 1 Aug 2016 12:04:15 +0200 Subject: [PATCH 204/224] SDK/ParticleEmitterComponent: Fix missing include Former-commit-id: c644ce38c5df7ba217ba07db68f9bf7e6f00ff71 [formerly 3224ccdeff42968cda92f414bc42c8f803f33740] Former-commit-id: fa34edce4e8e3d514e43e7101fa5b2678d7a5eae --- SDK/include/NDK/Components/ParticleEmitterComponent.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp index b874e0818..8d93e0495 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -9,6 +9,7 @@ #define NDK_COMPONENTS_PARTICLEEMITTERCOMPONENT_HPP #include +#include #include namespace Ndk From 07725ceb038c45c557f63ddf0e5f7bb7cc305344 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 2 Aug 2016 12:52:49 +0200 Subject: [PATCH 205/224] Core/RefCounted: Remove persistent boolean Former-commit-id: 99602e0fa1e54b6fc8e0087ef89d0e2c74bcfc15 [formerly 83374368c28b83e4916958e7a58d54ec663a9842] Former-commit-id: 603d0c81eada7d1f25058163bbf97672cd96d08c --- include/Nazara/Audio/SoundBuffer.inl | 2 - include/Nazara/Core/RefCounted.hpp | 7 +--- include/Nazara/Graphics/Billboard.inl | 2 - include/Nazara/Graphics/ColorBackground.inl | 2 - include/Nazara/Graphics/Material.inl | 2 - include/Nazara/Graphics/Model.inl | 2 - include/Nazara/Graphics/SkyboxBackground.inl | 2 - include/Nazara/Graphics/Sprite.inl | 2 - include/Nazara/Graphics/TextSprite.inl | 2 - include/Nazara/Graphics/TextureBackground.inl | 2 - include/Nazara/Graphics/TileMap.inl | 2 - include/Nazara/Physics/Geom.inl | 16 -------- include/Nazara/Renderer/RenderBuffer.inl | 2 - include/Nazara/Renderer/Shader.inl | 2 - include/Nazara/Renderer/Texture.inl | 2 - .../Renderer/UberShaderPreprocessor.inl | 2 - include/Nazara/Utility/Animation.inl | 2 - include/Nazara/Utility/Buffer.inl | 2 - include/Nazara/Utility/Font.inl | 2 - include/Nazara/Utility/Image.inl | 2 - include/Nazara/Utility/IndexBuffer.inl | 2 - include/Nazara/Utility/Mesh.inl | 2 - include/Nazara/Utility/SkeletalMesh.inl | 2 - include/Nazara/Utility/Skeleton.inl | 2 - include/Nazara/Utility/StaticMesh.inl | 2 - include/Nazara/Utility/VertexBuffer.inl | 2 - include/Nazara/Utility/VertexDeclaration.inl | 2 - src/Nazara/Core/RefCounted.cpp | 41 ++----------------- 28 files changed, 4 insertions(+), 110 deletions(-) diff --git a/include/Nazara/Audio/SoundBuffer.inl b/include/Nazara/Audio/SoundBuffer.inl index a4c42be69..22ed4b19a 100644 --- a/include/Nazara/Audio/SoundBuffer.inl +++ b/include/Nazara/Audio/SoundBuffer.inl @@ -18,8 +18,6 @@ namespace Nz SoundBufferRef SoundBuffer::New(Args&&... args) { std::unique_ptr object(new SoundBuffer(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp index 542784787..42936ff7e 100644 --- a/include/Nazara/Core/RefCounted.hpp +++ b/include/Nazara/Core/RefCounted.hpp @@ -22,7 +22,7 @@ namespace Nz class NAZARA_CORE_API RefCounted { public: - RefCounted(bool persistent = true); + RefCounted(); RefCounted(const RefCounted&) = delete; RefCounted(RefCounted&&) = default; virtual ~RefCounted(); @@ -31,17 +31,12 @@ namespace Nz unsigned int GetReferenceCount() const; - bool IsPersistent() const; - bool RemoveReference() const; - bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); - RefCounted& operator=(const RefCounted&) = delete; RefCounted& operator=(RefCounted&&) = default; private: - std::atomic_bool m_persistent; mutable std::atomic_uint m_referenceCount; }; } diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 6c4a1e0a9..95a0e5b87 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -234,8 +234,6 @@ namespace Nz BillboardRef Billboard::New(Args&&... args) { std::unique_ptr object(new Billboard(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl index 67b1f2558..49efd4874 100644 --- a/include/Nazara/Graphics/ColorBackground.inl +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -18,8 +18,6 @@ namespace Nz ColorBackgroundRef ColorBackground::New(Args&&... args) { std::unique_ptr object(new ColorBackground(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 6d5315640..801e341ae 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -1099,8 +1099,6 @@ namespace Nz MaterialRef Material::New(Args&&... args) { std::unique_ptr object(new Material(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index a2b4c3967..fba9655ec 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -18,8 +18,6 @@ namespace Nz ModelRef Model::New(Args&&... args) { std::unique_ptr object(new Model(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index 6171f1e28..15d3eb137 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -119,8 +119,6 @@ namespace Nz SkyboxBackgroundRef SkyboxBackground::New(Args&&... args) { std::unique_ptr object(new SkyboxBackground(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 840a930e6..166807f2b 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -271,8 +271,6 @@ namespace Nz SpriteRef Sprite::New(Args&&... args) { std::unique_ptr object(new Sprite(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index baeeb50db..48b0c061b 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -210,8 +210,6 @@ namespace Nz TextSpriteRef TextSprite::New(Args&&... args) { std::unique_ptr object(new TextSprite(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl index 31067f36c..423ab5a81 100644 --- a/include/Nazara/Graphics/TextureBackground.inl +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -41,8 +41,6 @@ namespace Nz TextureBackgroundRef TextureBackground::New(Args&&... args) { std::unique_ptr object(new TextureBackground(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index 405683f40..0f7c8faca 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -432,8 +432,6 @@ namespace Nz TileMapRef TileMap::New(Args&&... args) { std::unique_ptr object(new TileMap(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Physics/Geom.inl b/include/Nazara/Physics/Geom.inl index 9699cac96..0a21fbd23 100644 --- a/include/Nazara/Physics/Geom.inl +++ b/include/Nazara/Physics/Geom.inl @@ -11,8 +11,6 @@ namespace Nz BoxGeomRef BoxGeom::New(Args&&... args) { std::unique_ptr object(new BoxGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -20,8 +18,6 @@ namespace Nz CapsuleGeomRef CapsuleGeom::New(Args&&... args) { std::unique_ptr object(new CapsuleGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -29,8 +25,6 @@ namespace Nz CompoundGeomRef CompoundGeom::New(Args&&... args) { std::unique_ptr object(new CompoundGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -38,8 +32,6 @@ namespace Nz ConeGeomRef ConeGeom::New(Args&&... args) { std::unique_ptr object(new ConeGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -47,8 +39,6 @@ namespace Nz ConvexHullGeomRef ConvexHullGeom::New(Args&&... args) { std::unique_ptr object(new ConvexHullGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -56,8 +46,6 @@ namespace Nz CylinderGeomRef CylinderGeom::New(Args&&... args) { std::unique_ptr object(new CylinderGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -65,8 +53,6 @@ namespace Nz NullGeomRef NullGeom::New(Args&&... args) { std::unique_ptr object(new NullGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } @@ -74,8 +60,6 @@ namespace Nz SphereGeomRef SphereGeom::New(Args&&... args) { std::unique_ptr object(new SphereGeom(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Renderer/RenderBuffer.inl b/include/Nazara/Renderer/RenderBuffer.inl index bd81e7a17..59a9a5dd8 100644 --- a/include/Nazara/Renderer/RenderBuffer.inl +++ b/include/Nazara/Renderer/RenderBuffer.inl @@ -11,8 +11,6 @@ namespace Nz RenderBufferRef RenderBuffer::New(Args&&... args) { std::unique_ptr object(new RenderBuffer(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Renderer/Shader.inl b/include/Nazara/Renderer/Shader.inl index b868c540e..0e8309008 100644 --- a/include/Nazara/Renderer/Shader.inl +++ b/include/Nazara/Renderer/Shader.inl @@ -11,8 +11,6 @@ namespace Nz ShaderRef Shader::New(Args&&... args) { std::unique_ptr object(new Shader(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Renderer/Texture.inl b/include/Nazara/Renderer/Texture.inl index 4dc53464b..c9813ac73 100644 --- a/include/Nazara/Renderer/Texture.inl +++ b/include/Nazara/Renderer/Texture.inl @@ -11,8 +11,6 @@ namespace Nz TextureRef Texture::New(Args&&... args) { std::unique_ptr object(new Texture(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.inl b/include/Nazara/Renderer/UberShaderPreprocessor.inl index 1e6528775..fb9477030 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.inl +++ b/include/Nazara/Renderer/UberShaderPreprocessor.inl @@ -11,8 +11,6 @@ namespace Nz UberShaderPreprocessorRef UberShaderPreprocessor::New(Args&&... args) { std::unique_ptr object(new UberShaderPreprocessor(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Animation.inl b/include/Nazara/Utility/Animation.inl index 0ae58c0f4..f742e4c0e 100644 --- a/include/Nazara/Utility/Animation.inl +++ b/include/Nazara/Utility/Animation.inl @@ -11,8 +11,6 @@ namespace Nz AnimationRef Animation::New(Args&&... args) { std::unique_ptr object(new Animation(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Buffer.inl b/include/Nazara/Utility/Buffer.inl index 8703fd82c..39c1960f7 100644 --- a/include/Nazara/Utility/Buffer.inl +++ b/include/Nazara/Utility/Buffer.inl @@ -11,8 +11,6 @@ namespace Nz BufferRef Buffer::New(Args&&... args) { std::unique_ptr object(new Buffer(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Font.inl b/include/Nazara/Utility/Font.inl index 241915a3e..5f8e94c2c 100644 --- a/include/Nazara/Utility/Font.inl +++ b/include/Nazara/Utility/Font.inl @@ -11,8 +11,6 @@ namespace Nz FontRef Font::New(Args&&... args) { std::unique_ptr object(new Font(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Image.inl b/include/Nazara/Utility/Image.inl index 5cb8ef42f..ca111f9e9 100644 --- a/include/Nazara/Utility/Image.inl +++ b/include/Nazara/Utility/Image.inl @@ -11,8 +11,6 @@ namespace Nz ImageRef Image::New(Args&&... args) { std::unique_ptr object(new Image(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index 1c1d16a18..789019f91 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -11,8 +11,6 @@ namespace Nz IndexBufferRef IndexBuffer::New(Args&&... args) { std::unique_ptr object(new IndexBuffer(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Mesh.inl b/include/Nazara/Utility/Mesh.inl index 4877e03fe..21d52bf7d 100644 --- a/include/Nazara/Utility/Mesh.inl +++ b/include/Nazara/Utility/Mesh.inl @@ -11,8 +11,6 @@ namespace Nz MeshRef Mesh::New(Args&&... args) { std::unique_ptr object(new Mesh(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/SkeletalMesh.inl b/include/Nazara/Utility/SkeletalMesh.inl index 69119dc87..f6a590902 100644 --- a/include/Nazara/Utility/SkeletalMesh.inl +++ b/include/Nazara/Utility/SkeletalMesh.inl @@ -11,8 +11,6 @@ namespace Nz SkeletalMeshRef SkeletalMesh::New(Args&&... args) { std::unique_ptr object(new SkeletalMesh(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/Skeleton.inl b/include/Nazara/Utility/Skeleton.inl index 4c0ef4546..839227462 100644 --- a/include/Nazara/Utility/Skeleton.inl +++ b/include/Nazara/Utility/Skeleton.inl @@ -11,8 +11,6 @@ namespace Nz SkeletonRef Skeleton::New(Args&&... args) { std::unique_ptr object(new Skeleton(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/StaticMesh.inl b/include/Nazara/Utility/StaticMesh.inl index 06afcec95..a18ae32f5 100644 --- a/include/Nazara/Utility/StaticMesh.inl +++ b/include/Nazara/Utility/StaticMesh.inl @@ -11,8 +11,6 @@ namespace Nz StaticMeshRef StaticMesh::New(Args&&... args) { std::unique_ptr object(new StaticMesh(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/VertexBuffer.inl b/include/Nazara/Utility/VertexBuffer.inl index 24268e9cb..a4ebef1be 100644 --- a/include/Nazara/Utility/VertexBuffer.inl +++ b/include/Nazara/Utility/VertexBuffer.inl @@ -11,8 +11,6 @@ namespace Nz VertexBufferRef VertexBuffer::New(Args&&... args) { std::unique_ptr object(new VertexBuffer(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index beed900d5..f74e29a7c 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -11,8 +11,6 @@ namespace Nz VertexDeclarationRef VertexDeclaration::New(Args&&... args) { std::unique_ptr object(new VertexDeclaration(std::forward(args)...)); - object->SetPersistent(false); - return object.release(); } } diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index 31e749515..f37300c32 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -23,13 +23,10 @@ namespace Nz */ /*! - * \brief Constructs a RefCounted object with a persistance aspect - * - * \param persistent if false, object is destroyed when no more referenced + * \brief Constructs a RefCounted object */ - RefCounted::RefCounted(bool persistent) : - m_persistent(persistent), + RefCounted::RefCounted() : m_referenceCount(0) { } @@ -67,16 +64,6 @@ namespace Nz return m_referenceCount; } - /*! - * \brief Checks whether the object is persistent - * \return true if object is not destroyed when no more referenced - */ - - bool RefCounted::IsPersistent() const - { - return m_persistent; - } - /*! * \brief Removes a reference to the object * \return true if object is deleted because no more referenced @@ -94,7 +81,7 @@ namespace Nz } #endif - if (--m_referenceCount == 0 && !m_persistent) + if (--m_referenceCount == 0) { delete this; // Suicide @@ -103,26 +90,4 @@ namespace Nz else return false; } - - /*! - * \brief Sets the persistence of the object - * \return true if object is deleted because no more referenced - * - * \param persistent Sets the persistence of the object - * \param checkReferenceCount Checks if the object should be destroyed if true - */ - - bool RefCounted::SetPersistent(bool persistent, bool checkReferenceCount) - { - m_persistent = persistent; - - if (checkReferenceCount && !persistent && m_referenceCount == 0) - { - delete this; - - return true; - } - else - return false; - } } From e8c89f158d69e8f782ce5b0f480c222ba52c1d8f Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 2 Aug 2016 12:56:03 +0200 Subject: [PATCH 206/224] Fix compile Former-commit-id: b703781f87d0bd13e7e0436bb9ed5d20ef3cb09f [formerly 4a2bc52bfc39448000a6f3569fd8cfa657bc58ee] Former-commit-id: 1e42734fafb9eb1a161cfcc3c781927f32c5ad07 --- src/Nazara/Utility/SubMesh.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index 8b0589808..fd706e7a6 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -15,7 +15,6 @@ namespace Nz { SubMesh::SubMesh(const Mesh* parent) : - RefCounted(false), // Un SubMesh n'est pas persistant par défaut m_primitiveMode(PrimitiveMode_TriangleList), m_parent(parent), m_matIndex(0) From b058819b9d0bcc0541985c40cfdff8fb5efe6ea8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 2 Aug 2016 13:20:31 +0200 Subject: [PATCH 207/224] Revert "Fix compile" This reverts commit df4e466ee49accc9c19b2fe6da3c14e2779ca12b [formerly 752e14ea33208e0a1298a21b2be1c6aee56dfde1] [formerly a3eb1f7d2f090e0a63f64b3451198631e8d2c47e [formerly 4b89c5fafdc15330f909c62fd75a23885c7364e1]] [formerly 0b09aea025e4d8df0bdf33917571e81f1fe5c6a2 [formerly e192bf206e80f55897d26faf541bcc5afa0437fc] [formerly e9f0b2cd7d7dd709f6a0419b3ea4f6a599cbb823 [formerly 273f4a73bfed75ebec68969db3ae235ccec8600c]]]. Former-commit-id: c4f7092c80aaa52267789cffec29cd4bdd0890f5 [formerly d91460f5134fdca761c6152f72663cc8cdab7b88] [formerly 355bca8ae9dc9966992d43c2ebcdf693f1003af8 [formerly 8554f03b5f74c04ff6a7bb6c08de41eaf9cf0423]] Former-commit-id: bd6254953c20e7971e70880d8598b6063ba21395 [formerly 43e67367ed1724862e9983598e843998688e46c0] Former-commit-id: 11c10b5115995c7e96e0396032eeece6c301b90b --- src/Nazara/Utility/SubMesh.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index fd706e7a6..8b0589808 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -15,6 +15,7 @@ namespace Nz { SubMesh::SubMesh(const Mesh* parent) : + RefCounted(false), // Un SubMesh n'est pas persistant par défaut m_primitiveMode(PrimitiveMode_TriangleList), m_parent(parent), m_matIndex(0) From 6f265a1cb3ce786eda9e5d814e4cb937c4ab36ad Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 2 Aug 2016 13:20:34 +0200 Subject: [PATCH 208/224] Revert "Core/RefCounted: Remove persistent boolean" This reverts commit db2ef3e90c3871290d114a9e6437b412e96c65aa [formerly a3f6ff88a25e63374eb6ce5b18269da2ba743b06] [formerly cfa12604fbb0da76fc27288b210ee1254a8b3a38 [formerly dee6ce858398e2de38ef1af00c1c630fd0126e09]] [formerly 1a23f0fddcd80ac33030061b7a00a3cfd43cb7fe [formerly d3cb17069c71449ae3f1cba6de55ea70f509e7a4] [formerly b2f8f82e9f3427310204f2e8a61d7bdfd96202d2 [formerly 5d117720d08d6d6243b3428d4b3f8aea1abef845]]]. Former-commit-id: a7af09faec974d268de6680f2c0c16d531048935 [formerly 37761044d13cf2e2041c9eed9ff113a41efd87f8] [formerly ae05b7afb5f43daf90cd8182bf24c98067be4d16 [formerly 6633982a51ba117a749f08efda338455eabe59b3]] Former-commit-id: a4c99f7c8c26a0c1276eb5262871a1964d470bfb [formerly 741d46a0838a64e92aaa46fe563493da10d62c98] Former-commit-id: fe30e63aeb19e56fa64447bdd884766f84f305dd --- include/Nazara/Audio/SoundBuffer.inl | 2 + include/Nazara/Core/RefCounted.hpp | 7 +++- include/Nazara/Graphics/Billboard.inl | 2 + include/Nazara/Graphics/ColorBackground.inl | 2 + include/Nazara/Graphics/Material.inl | 2 + include/Nazara/Graphics/Model.inl | 2 + include/Nazara/Graphics/SkyboxBackground.inl | 2 + include/Nazara/Graphics/Sprite.inl | 2 + include/Nazara/Graphics/TextSprite.inl | 2 + include/Nazara/Graphics/TextureBackground.inl | 2 + include/Nazara/Graphics/TileMap.inl | 2 + include/Nazara/Physics/Geom.inl | 16 ++++++++ include/Nazara/Renderer/RenderBuffer.inl | 2 + include/Nazara/Renderer/Shader.inl | 2 + include/Nazara/Renderer/Texture.inl | 2 + .../Renderer/UberShaderPreprocessor.inl | 2 + include/Nazara/Utility/Animation.inl | 2 + include/Nazara/Utility/Buffer.inl | 2 + include/Nazara/Utility/Font.inl | 2 + include/Nazara/Utility/Image.inl | 2 + include/Nazara/Utility/IndexBuffer.inl | 2 + include/Nazara/Utility/Mesh.inl | 2 + include/Nazara/Utility/SkeletalMesh.inl | 2 + include/Nazara/Utility/Skeleton.inl | 2 + include/Nazara/Utility/StaticMesh.inl | 2 + include/Nazara/Utility/VertexBuffer.inl | 2 + include/Nazara/Utility/VertexDeclaration.inl | 2 + src/Nazara/Core/RefCounted.cpp | 41 +++++++++++++++++-- 28 files changed, 110 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Audio/SoundBuffer.inl b/include/Nazara/Audio/SoundBuffer.inl index 22ed4b19a..a4c42be69 100644 --- a/include/Nazara/Audio/SoundBuffer.inl +++ b/include/Nazara/Audio/SoundBuffer.inl @@ -18,6 +18,8 @@ namespace Nz SoundBufferRef SoundBuffer::New(Args&&... args) { std::unique_ptr object(new SoundBuffer(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp index 42936ff7e..542784787 100644 --- a/include/Nazara/Core/RefCounted.hpp +++ b/include/Nazara/Core/RefCounted.hpp @@ -22,7 +22,7 @@ namespace Nz class NAZARA_CORE_API RefCounted { public: - RefCounted(); + RefCounted(bool persistent = true); RefCounted(const RefCounted&) = delete; RefCounted(RefCounted&&) = default; virtual ~RefCounted(); @@ -31,12 +31,17 @@ namespace Nz unsigned int GetReferenceCount() const; + bool IsPersistent() const; + bool RemoveReference() const; + bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); + RefCounted& operator=(const RefCounted&) = delete; RefCounted& operator=(RefCounted&&) = default; private: + std::atomic_bool m_persistent; mutable std::atomic_uint m_referenceCount; }; } diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 95a0e5b87..6c4a1e0a9 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -234,6 +234,8 @@ namespace Nz BillboardRef Billboard::New(Args&&... args) { std::unique_ptr object(new Billboard(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl index 49efd4874..67b1f2558 100644 --- a/include/Nazara/Graphics/ColorBackground.inl +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -18,6 +18,8 @@ namespace Nz ColorBackgroundRef ColorBackground::New(Args&&... args) { std::unique_ptr object(new ColorBackground(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 801e341ae..6d5315640 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -1099,6 +1099,8 @@ namespace Nz MaterialRef Material::New(Args&&... args) { std::unique_ptr object(new Material(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index fba9655ec..a2b4c3967 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -18,6 +18,8 @@ namespace Nz ModelRef Model::New(Args&&... args) { std::unique_ptr object(new Model(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index 15d3eb137..6171f1e28 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -119,6 +119,8 @@ namespace Nz SkyboxBackgroundRef SkyboxBackground::New(Args&&... args) { std::unique_ptr object(new SkyboxBackground(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 166807f2b..840a930e6 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -271,6 +271,8 @@ namespace Nz SpriteRef Sprite::New(Args&&... args) { std::unique_ptr object(new Sprite(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index 48b0c061b..baeeb50db 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -210,6 +210,8 @@ namespace Nz TextSpriteRef TextSprite::New(Args&&... args) { std::unique_ptr object(new TextSprite(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl index 423ab5a81..31067f36c 100644 --- a/include/Nazara/Graphics/TextureBackground.inl +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -41,6 +41,8 @@ namespace Nz TextureBackgroundRef TextureBackground::New(Args&&... args) { std::unique_ptr object(new TextureBackground(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Graphics/TileMap.inl b/include/Nazara/Graphics/TileMap.inl index 0f7c8faca..405683f40 100644 --- a/include/Nazara/Graphics/TileMap.inl +++ b/include/Nazara/Graphics/TileMap.inl @@ -432,6 +432,8 @@ namespace Nz TileMapRef TileMap::New(Args&&... args) { std::unique_ptr object(new TileMap(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Physics/Geom.inl b/include/Nazara/Physics/Geom.inl index 0a21fbd23..9699cac96 100644 --- a/include/Nazara/Physics/Geom.inl +++ b/include/Nazara/Physics/Geom.inl @@ -11,6 +11,8 @@ namespace Nz BoxGeomRef BoxGeom::New(Args&&... args) { std::unique_ptr object(new BoxGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -18,6 +20,8 @@ namespace Nz CapsuleGeomRef CapsuleGeom::New(Args&&... args) { std::unique_ptr object(new CapsuleGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -25,6 +29,8 @@ namespace Nz CompoundGeomRef CompoundGeom::New(Args&&... args) { std::unique_ptr object(new CompoundGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -32,6 +38,8 @@ namespace Nz ConeGeomRef ConeGeom::New(Args&&... args) { std::unique_ptr object(new ConeGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -39,6 +47,8 @@ namespace Nz ConvexHullGeomRef ConvexHullGeom::New(Args&&... args) { std::unique_ptr object(new ConvexHullGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -46,6 +56,8 @@ namespace Nz CylinderGeomRef CylinderGeom::New(Args&&... args) { std::unique_ptr object(new CylinderGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -53,6 +65,8 @@ namespace Nz NullGeomRef NullGeom::New(Args&&... args) { std::unique_ptr object(new NullGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } @@ -60,6 +74,8 @@ namespace Nz SphereGeomRef SphereGeom::New(Args&&... args) { std::unique_ptr object(new SphereGeom(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Renderer/RenderBuffer.inl b/include/Nazara/Renderer/RenderBuffer.inl index 59a9a5dd8..bd81e7a17 100644 --- a/include/Nazara/Renderer/RenderBuffer.inl +++ b/include/Nazara/Renderer/RenderBuffer.inl @@ -11,6 +11,8 @@ namespace Nz RenderBufferRef RenderBuffer::New(Args&&... args) { std::unique_ptr object(new RenderBuffer(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Renderer/Shader.inl b/include/Nazara/Renderer/Shader.inl index 0e8309008..b868c540e 100644 --- a/include/Nazara/Renderer/Shader.inl +++ b/include/Nazara/Renderer/Shader.inl @@ -11,6 +11,8 @@ namespace Nz ShaderRef Shader::New(Args&&... args) { std::unique_ptr object(new Shader(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Renderer/Texture.inl b/include/Nazara/Renderer/Texture.inl index c9813ac73..4dc53464b 100644 --- a/include/Nazara/Renderer/Texture.inl +++ b/include/Nazara/Renderer/Texture.inl @@ -11,6 +11,8 @@ namespace Nz TextureRef Texture::New(Args&&... args) { std::unique_ptr object(new Texture(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.inl b/include/Nazara/Renderer/UberShaderPreprocessor.inl index fb9477030..1e6528775 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.inl +++ b/include/Nazara/Renderer/UberShaderPreprocessor.inl @@ -11,6 +11,8 @@ namespace Nz UberShaderPreprocessorRef UberShaderPreprocessor::New(Args&&... args) { std::unique_ptr object(new UberShaderPreprocessor(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Animation.inl b/include/Nazara/Utility/Animation.inl index f742e4c0e..0ae58c0f4 100644 --- a/include/Nazara/Utility/Animation.inl +++ b/include/Nazara/Utility/Animation.inl @@ -11,6 +11,8 @@ namespace Nz AnimationRef Animation::New(Args&&... args) { std::unique_ptr object(new Animation(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Buffer.inl b/include/Nazara/Utility/Buffer.inl index 39c1960f7..8703fd82c 100644 --- a/include/Nazara/Utility/Buffer.inl +++ b/include/Nazara/Utility/Buffer.inl @@ -11,6 +11,8 @@ namespace Nz BufferRef Buffer::New(Args&&... args) { std::unique_ptr object(new Buffer(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Font.inl b/include/Nazara/Utility/Font.inl index 5f8e94c2c..241915a3e 100644 --- a/include/Nazara/Utility/Font.inl +++ b/include/Nazara/Utility/Font.inl @@ -11,6 +11,8 @@ namespace Nz FontRef Font::New(Args&&... args) { std::unique_ptr object(new Font(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Image.inl b/include/Nazara/Utility/Image.inl index ca111f9e9..5cb8ef42f 100644 --- a/include/Nazara/Utility/Image.inl +++ b/include/Nazara/Utility/Image.inl @@ -11,6 +11,8 @@ namespace Nz ImageRef Image::New(Args&&... args) { std::unique_ptr object(new Image(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index 789019f91..1c1d16a18 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -11,6 +11,8 @@ namespace Nz IndexBufferRef IndexBuffer::New(Args&&... args) { std::unique_ptr object(new IndexBuffer(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Mesh.inl b/include/Nazara/Utility/Mesh.inl index 21d52bf7d..4877e03fe 100644 --- a/include/Nazara/Utility/Mesh.inl +++ b/include/Nazara/Utility/Mesh.inl @@ -11,6 +11,8 @@ namespace Nz MeshRef Mesh::New(Args&&... args) { std::unique_ptr object(new Mesh(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/SkeletalMesh.inl b/include/Nazara/Utility/SkeletalMesh.inl index f6a590902..69119dc87 100644 --- a/include/Nazara/Utility/SkeletalMesh.inl +++ b/include/Nazara/Utility/SkeletalMesh.inl @@ -11,6 +11,8 @@ namespace Nz SkeletalMeshRef SkeletalMesh::New(Args&&... args) { std::unique_ptr object(new SkeletalMesh(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/Skeleton.inl b/include/Nazara/Utility/Skeleton.inl index 839227462..4c0ef4546 100644 --- a/include/Nazara/Utility/Skeleton.inl +++ b/include/Nazara/Utility/Skeleton.inl @@ -11,6 +11,8 @@ namespace Nz SkeletonRef Skeleton::New(Args&&... args) { std::unique_ptr object(new Skeleton(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/StaticMesh.inl b/include/Nazara/Utility/StaticMesh.inl index a18ae32f5..06afcec95 100644 --- a/include/Nazara/Utility/StaticMesh.inl +++ b/include/Nazara/Utility/StaticMesh.inl @@ -11,6 +11,8 @@ namespace Nz StaticMeshRef StaticMesh::New(Args&&... args) { std::unique_ptr object(new StaticMesh(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/VertexBuffer.inl b/include/Nazara/Utility/VertexBuffer.inl index a4ebef1be..24268e9cb 100644 --- a/include/Nazara/Utility/VertexBuffer.inl +++ b/include/Nazara/Utility/VertexBuffer.inl @@ -11,6 +11,8 @@ namespace Nz VertexBufferRef VertexBuffer::New(Args&&... args) { std::unique_ptr object(new VertexBuffer(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index f74e29a7c..beed900d5 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -11,6 +11,8 @@ namespace Nz VertexDeclarationRef VertexDeclaration::New(Args&&... args) { std::unique_ptr object(new VertexDeclaration(std::forward(args)...)); + object->SetPersistent(false); + return object.release(); } } diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index f37300c32..31e749515 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -23,10 +23,13 @@ namespace Nz */ /*! - * \brief Constructs a RefCounted object + * \brief Constructs a RefCounted object with a persistance aspect + * + * \param persistent if false, object is destroyed when no more referenced */ - RefCounted::RefCounted() : + RefCounted::RefCounted(bool persistent) : + m_persistent(persistent), m_referenceCount(0) { } @@ -64,6 +67,16 @@ namespace Nz return m_referenceCount; } + /*! + * \brief Checks whether the object is persistent + * \return true if object is not destroyed when no more referenced + */ + + bool RefCounted::IsPersistent() const + { + return m_persistent; + } + /*! * \brief Removes a reference to the object * \return true if object is deleted because no more referenced @@ -81,7 +94,7 @@ namespace Nz } #endif - if (--m_referenceCount == 0) + if (--m_referenceCount == 0 && !m_persistent) { delete this; // Suicide @@ -90,4 +103,26 @@ namespace Nz else return false; } + + /*! + * \brief Sets the persistence of the object + * \return true if object is deleted because no more referenced + * + * \param persistent Sets the persistence of the object + * \param checkReferenceCount Checks if the object should be destroyed if true + */ + + bool RefCounted::SetPersistent(bool persistent, bool checkReferenceCount) + { + m_persistent = persistent; + + if (checkReferenceCount && !persistent && m_referenceCount == 0) + { + delete this; + + return true; + } + else + return false; + } } From a2fbd9f2d02f1f90a2ee923596728bc89085cb8b Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 2 Aug 2016 13:31:09 +0200 Subject: [PATCH 209/224] Improved declarations Former-commit-id: fae51c9344fd88a35b6c6ebb825ba71e6ca33f1a [formerly 75901e046e5bbe5732846eed7ba7cdc3ebcc7bb2] [formerly c14ba82b5e7849ff610789fc4dca09aa67907200 [formerly f9dd4fd281c9b68aff9affef037d5ce1a3802fd7]] Former-commit-id: 88f4d343858f42b06420f593efa6a481018e05fb [formerly 09a6ba61ac09ded89c59612aec2ab7263eb75e36] Former-commit-id: 6268a2a01d13a27f79f18f6282023cac1a8579d4 --- .../Nazara/Graphics/ParticleDeclaration.hpp | 8 ++++++-- .../Nazara/Graphics/ParticleDeclaration.inl | 18 ++++++++++++++++++ include/Nazara/Utility/VertexDeclaration.hpp | 7 ++++--- src/Nazara/Graphics/ParticleDeclaration.cpp | 14 ++++---------- src/Nazara/Utility/Formats/OBJSaver.cpp | 1 - src/Nazara/Utility/VertexDeclaration.cpp | 14 ++++---------- 6 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 include/Nazara/Graphics/ParticleDeclaration.inl diff --git a/include/Nazara/Graphics/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp index 0edfba85f..278d25961 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.hpp +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace Nz { @@ -46,6 +47,7 @@ namespace Nz static ParticleDeclaration* Get(ParticleLayout layout); static bool IsTypeSupported(ComponentType type); + template static ParticleDeclarationRef New(Args&&... args); // Signals: NazaraSignal(OnParticleDeclarationRelease, const ParticleDeclaration* /*particleDeclaration*/); @@ -68,12 +70,14 @@ namespace Nz */ }; - Component m_components[ParticleComponent_Max + 1]; + std::array m_components; unsigned int m_stride; - static ParticleDeclaration s_declarations[ParticleLayout_Max + 1]; + static std::array s_declarations; static ParticleDeclarationLibrary::LibraryMap s_library; }; } +#include + #endif // NAZARA_PARTICLEDECLARATION_HPP diff --git a/include/Nazara/Graphics/ParticleDeclaration.inl b/include/Nazara/Graphics/ParticleDeclaration.inl new file mode 100644 index 000000000..27cd92a22 --- /dev/null +++ b/include/Nazara/Graphics/ParticleDeclaration.inl @@ -0,0 +1,18 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + template + ParticleDeclarationRef ParticleDeclaration::New(Args&&... args) + { + std::unique_ptr object(new ParticleDeclaration(std::forward(args)...)); + return object.release(); + } +} + +#include diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index f5dea6457..8c1e4b55a 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace Nz { @@ -69,14 +70,14 @@ namespace Nz */ }; - Component m_components[VertexComponent_Max+1]; + std::array m_components; std::size_t m_stride; - static VertexDeclaration s_declarations[VertexLayout_Max+1]; + static std::array s_declarations; static VertexDeclarationLibrary::LibraryMap s_library; }; } -#include +#include #endif // NAZARA_VERTEXDECLARATION_HPP diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index ecd09c752..62cf321ab 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -38,9 +38,9 @@ namespace Nz ParticleDeclaration::ParticleDeclaration(const ParticleDeclaration& declaration) : RefCounted(), + m_components(declaration.m_components), m_stride(declaration.m_stride) { - std::memcpy(m_components, declaration.m_components, sizeof(Component) * (ParticleComponent_Max + 1)); } /*! @@ -205,7 +205,7 @@ namespace Nz ParticleDeclaration& ParticleDeclaration::operator=(const ParticleDeclaration& declaration) { - std::memcpy(m_components, declaration.m_components, sizeof(Component) * (ParticleComponent_Max + 1)); + m_components = declaration.m_components; m_stride = declaration.m_stride; return *this; @@ -222,13 +222,7 @@ namespace Nz ParticleDeclaration* ParticleDeclaration::Get(ParticleLayout layout) { - #ifdef NAZARA_DEBUG - if (layout > ParticleLayout_Max) - { - NazaraError("Particle layout out of enum"); - return nullptr; - } - #endif + NazaraAssert(layout <= ParticleLayout_Max, "Particle layout out of enum"); return &s_declarations[layout]; } @@ -338,6 +332,6 @@ namespace Nz ParticleDeclarationLibrary::Uninitialize(); } - ParticleDeclaration ParticleDeclaration::s_declarations[ParticleLayout_Max + 1]; + std::array ParticleDeclaration::s_declarations; ParticleDeclarationLibrary::LibraryMap ParticleDeclaration::s_library; } diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp index 9a79638bc..baf54e44b 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.cpp +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -120,7 +120,6 @@ namespace Nz MTLParser::Material* material = mtlFormat.AddMaterial(name); - bool bValue; String strVal; if (matData.HasParameter(MaterialData::CustomDefined)) { diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 998f12f8b..945888406 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -22,9 +22,9 @@ namespace Nz VertexDeclaration::VertexDeclaration(const VertexDeclaration& declaration) : RefCounted(), + m_components(declaration.m_components), m_stride(declaration.m_stride) { - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(VertexComponent_Max+1)); } VertexDeclaration::~VertexDeclaration() @@ -133,7 +133,7 @@ namespace Nz VertexDeclaration& VertexDeclaration::operator=(const VertexDeclaration& declaration) { - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(VertexComponent_Max+1)); + m_components = declaration.m_components; m_stride = declaration.m_stride; return *this; @@ -141,13 +141,7 @@ namespace Nz VertexDeclaration* VertexDeclaration::Get(VertexLayout layout) { - #ifdef NAZARA_DEBUG - if (layout > VertexLayout_Max) - { - NazaraError("Vertex layout out of enum"); - return nullptr; - } - #endif + NazaraAssert(layout <= VertexLayout_Max, "Vertex layout out of enum"); return &s_declarations[layout]; } @@ -301,6 +295,6 @@ namespace Nz VertexDeclarationLibrary::Uninitialize(); } - VertexDeclaration VertexDeclaration::s_declarations[VertexLayout_Max+1]; + std::array VertexDeclaration::s_declarations; VertexDeclarationLibrary::LibraryMap VertexDeclaration::s_library; } From ee1bd866ab79abc3daae3f68707552b8c89bdb55 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Aug 2016 13:46:42 +0200 Subject: [PATCH 210/224] SDK/StateMachine: Add GetCurrentState function Former-commit-id: 20b8c0d81deb5d5c6aafc1c8d4d261b046f260c3 [formerly 37762eaaf8bd7c0b2434b65dfc62d95d4ae2db15] [formerly 5606a74447be6048ce12a502722a75c726cbf9ef [formerly cc437974e34587cf7f63d8fb7f5447473826ee1c]] Former-commit-id: 677c22d4ebcfa8bf22a85210712fea061dedc0da [formerly 3979a42d5a2ed3c2635ed654bf6f25b88c32a00e] Former-commit-id: 0d31a924eead5ed4f384fcbdde6411054c3a9b27 --- SDK/include/NDK/StateMachine.hpp | 2 ++ SDK/include/NDK/StateMachine.inl | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/SDK/include/NDK/StateMachine.hpp b/SDK/include/NDK/StateMachine.hpp index 8e7ad2f64..c36464fea 100644 --- a/SDK/include/NDK/StateMachine.hpp +++ b/SDK/include/NDK/StateMachine.hpp @@ -23,6 +23,8 @@ namespace Ndk inline void ChangeState(std::shared_ptr state); + inline const std::shared_ptr& GetCurrentState() const; + inline bool Update(float elapsedTime); inline StateMachine& operator=(StateMachine&& fsm) = default; diff --git a/SDK/include/NDK/StateMachine.inl b/SDK/include/NDK/StateMachine.inl index fc4c7f787..7b5109ab5 100644 --- a/SDK/include/NDK/StateMachine.inl +++ b/SDK/include/NDK/StateMachine.inl @@ -26,6 +26,11 @@ namespace Ndk m_nextState = std::move(state); } + inline const std::shared_ptr& StateMachine::GetCurrentState() const + { + return m_currentState; + } + inline bool StateMachine::Update(float elapsedTime) { if (m_nextState) From 66bc8a5dde1996979705fd4e08c6f6ecffa2982a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Aug 2016 13:47:17 +0200 Subject: [PATCH 211/224] Graphics: Change ParticleStruct_Sprite position and velocity type from Vector2f to Vector3f Former-commit-id: 8697752459c0f8a99c545ae41eedf6e0382c366e [formerly a855bebde268850fba035f3981e3e907acf33232] [formerly 2894f133ef2b92b49a0642df95393939269ee50b [formerly 348a5a1f8745537e3fb20a0aeac5e89a6f831c19]] Former-commit-id: 50a4cef7ee7ac3be85cc9ccc6a6b194c4beb79f2 [formerly 49fdda2e6a597ed6251d822ff4b189442c5a9296] Former-commit-id: ee48615b811e902841ff29529c15a6910fc8e1c1 --- include/Nazara/Graphics/ParticleStruct.hpp | 4 ++-- src/Nazara/Graphics/ParticleDeclaration.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Graphics/ParticleStruct.hpp b/include/Nazara/Graphics/ParticleStruct.hpp index b68836935..72ce961b9 100644 --- a/include/Nazara/Graphics/ParticleStruct.hpp +++ b/include/Nazara/Graphics/ParticleStruct.hpp @@ -35,8 +35,8 @@ namespace Nz struct ParticleStruct_Sprite { Color color; - Vector2f position; - Vector2f velocity; + Vector3f position; + Vector3f velocity; UInt32 life; float rotation; }; diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index 62cf321ab..dff382d2c 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -308,9 +308,9 @@ namespace Nz declaration = &s_declarations[ParticleLayout_Sprite]; declaration->EnableComponent(ParticleComponent_Color, ComponentType_Color, NazaraOffsetOf(ParticleStruct_Sprite, color)); declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Sprite, life)); - declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Sprite, position)); + declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Sprite, position)); declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Sprite, rotation)); - declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Sprite, velocity)); + declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Sprite, velocity)); NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Sprite), "Invalid stride for declaration ParticleLayout_Sprite"); } From 00fb383f70db2ff6d8690118111627b0b8fec4d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Aug 2016 01:12:06 +0200 Subject: [PATCH 212/224] Utility/MaterialData: Remove CustomDefined Former-commit-id: a3051df8a12d596901043b142ee1fa55a2481644 [formerly 97b1364fc5ba7f22bb28479f0edb351db8e7cfff] [formerly 49730b561eda3f1350e87b2c99c48c04f45c849a [formerly e20bc09b46ea5a6555ef887b1db3a6f7f2b7cb3a]] Former-commit-id: 78f2eff516042ec38f0f61ab9b4263d968c0488a [formerly c6e7d6d63628402d8a58cf8e95dbb0509d07ff03] Former-commit-id: b269a6e53c5205aa27ef921f348367f1affde02e --- examples/MeshInfos/main.cpp | 7 +------ include/Nazara/Utility/MaterialData.hpp | 1 - plugins/Assimp/Plugin.cpp | 3 --- src/Nazara/Graphics/Formats/MeshLoader.cpp | 2 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 1 - src/Nazara/Utility/Formats/OBJLoader.cpp | 2 -- src/Nazara/Utility/Formats/OBJSaver.cpp | 6 +++--- 7 files changed, 5 insertions(+), 17 deletions(-) diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index 73864abaa..e95a2a4c2 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -173,12 +173,7 @@ int main() Nz::String data; if (!matData.GetStringParameter(Nz::MaterialData::FilePath, &data)) - { - if (matData.HasParameter(Nz::MaterialData::CustomDefined)) - data = ""; - else - data = ""; - } + data = ""; std::cout << "\t" << (i+1) << ": " << data << std::endl; } diff --git a/include/Nazara/Utility/MaterialData.hpp b/include/Nazara/Utility/MaterialData.hpp index 66df97689..0c1e28cdd 100644 --- a/include/Nazara/Utility/MaterialData.hpp +++ b/include/Nazara/Utility/MaterialData.hpp @@ -23,7 +23,6 @@ namespace Nz static constexpr const char* BackFaceStencilZFail = "MatBackFaceStencilZFail"; static constexpr const char* Blending = "MatBlending"; static constexpr const char* CullingSide = "MatCullingSide"; - static constexpr const char* CustomDefined = "MatCustomDefined"; static constexpr const char* ColorWrite = "MatColorWrite"; static constexpr const char* DepthBuffer = "MatDepthBuffer"; static constexpr const char* DepthFunc = "MatDepthfunc"; diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 312bbf48e..39b645c65 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -237,8 +237,6 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) 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))); } }; @@ -249,7 +247,6 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) aiTextureMapMode mapMode[3]; if (aiGetMaterialTexture(aiMat, aiType, 0, &path, nullptr, nullptr, nullptr, nullptr, &mapMode[0], nullptr) == aiReturn_SUCCESS) { - matData.SetParameter(MaterialData::CustomDefined); matData.SetParameter(textureKey, stream.GetDirectory() + String(path.data, path.length)); if (wrapKey) diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index 6769072bb..38f836e90 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -39,7 +39,7 @@ namespace Nz else NazaraWarning("Failed to load material from file " + String::Number(i)); } - else if (matData.HasParameter(MaterialData::CustomDefined)) + else { MaterialRef material = Material::New(); material->BuildFromParameters(matData, parameters.material); diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index c61dffd09..dde203482 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -102,7 +102,6 @@ namespace Nz stream.Read(skin, 68*sizeof(char)); ParameterList matData; - matData.SetParameter(MaterialData::CustomDefined); matData.SetParameter(MaterialData::DiffuseTexturePath, baseDir + skin); mesh->SetMaterialData(i, std::move(matData)); diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index 1b1835b2b..405c845ea 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -73,8 +73,6 @@ namespace Nz { ParameterList data; - data.SetParameter(MaterialData::CustomDefined); - UInt8 alphaValue = static_cast(mtlMat->alpha*255.f); Color ambientColor(mtlMat->ambient); diff --git a/src/Nazara/Utility/Formats/OBJSaver.cpp b/src/Nazara/Utility/Formats/OBJSaver.cpp index baf54e44b..a7a2cda0b 100644 --- a/src/Nazara/Utility/Formats/OBJSaver.cpp +++ b/src/Nazara/Utility/Formats/OBJSaver.cpp @@ -121,7 +121,9 @@ namespace Nz MTLParser::Material* material = mtlFormat.AddMaterial(name); String strVal; - if (matData.HasParameter(MaterialData::CustomDefined)) + if (matData.GetStringParameter(MaterialData::FilePath, &strVal)) + material->diffuseMap = strVal; + else { Color colorVal; float fValue; @@ -147,8 +149,6 @@ namespace Nz if (matData.GetStringParameter(MaterialData::SpecularTexturePath, &strVal)) material->specularMap = strVal; } - else if (matData.GetStringParameter(MaterialData::FilePath, &strVal)) - material->diffuseMap = strVal; } // Meshes From 72b8c93aa6f2c68c0622082b5f974a9923309908 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 4 Aug 2016 01:12:17 +0200 Subject: [PATCH 213/224] Plugins/Assimp: Handle assimp errors Former-commit-id: 598c4142c600d7a2a55cbb1d0dddb8ad5efb1115 [formerly c8c37bb4ed9420adff14f342058599b162f5a10c] [formerly 32e948d67abc4ade4362448c655837c5082dfc61 [formerly 6d131b24546e91376d8b2a9495b2be2a67b75cb6]] Former-commit-id: 0c94a403d0bd22654b38778211523f07a1f90b76 [formerly 83cf78c103454e517f4e6729283d7c2d1fb478d9] Former-commit-id: 7292865595966a925f49ff7ef432a05d97549c83 --- plugins/Assimp/Plugin.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/Assimp/Plugin.cpp b/plugins/Assimp/Plugin.cpp index 39b645c65..d1d0ace26 100644 --- a/plugins/Assimp/Plugin.cpp +++ b/plugins/Assimp/Plugin.cpp @@ -23,6 +23,7 @@ SOFTWARE. */ #include +#include #include #include #include @@ -130,6 +131,12 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) const aiScene* scene = aiImportFileExWithProperties(userdata.originalFilePath, postProcess, &fileIO, properties); aiReleasePropertyStore(properties); + if (!scene) + { + NazaraError("Assimp failed to import file: " + Nz::String(aiGetErrorString())); + return false; + } + std::set joints; bool animatedMesh = false; From 850f8d78c036977001b5ef97a59fa0ae6476d0e2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 09:08:45 +0200 Subject: [PATCH 214/224] Core/String: Consider tabspace as separator Former-commit-id: c8bfab3e1a921f077c58f61479ddbf2e6bf747ef [formerly 145b8a1c022c4858adf924ce4951c1838507455e] [formerly c55fb22de534afc7d5cadaddac8d0c28c2eb85a6 [formerly 14128b77407ad492722db34dbd9a0f8b5d24a6a3]] Former-commit-id: 1c100c34e020dcbc0a85318e2799b09bb97b7ab5 [formerly 3d89e9bbbb3b71ddc520600edce8be74f4c9889a] Former-commit-id: ba244fd2eb84da614f84795fb2e01030fe7455b5 --- src/Nazara/Core/String.cpp | 91 ++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 21831bcdf..fbd29c97c 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -23,6 +23,11 @@ namespace Nz { namespace Detail { + inline bool IsSpace(char32_t character) + { + return character == '\t' || Unicode::GetCategory(character) & Unicode::Category_Separator; + } + // This algorithm is inspired by the documentation of Qt inline std::size_t GetNewSize(std::size_t newSize) { @@ -1379,7 +1384,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1391,7 +1396,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*tIt)) return it.base() - m_sharedString->string.get(); else break; @@ -1421,7 +1426,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1433,7 +1438,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*tIt)) return it.base() - m_sharedString->string.get(); else break; @@ -1465,7 +1470,7 @@ namespace Nz if (ptr != m_sharedString->string.get()) { --ptr; - if (!(Unicode::GetCategory(*ptr++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*ptr++)) continue; } @@ -1475,7 +1480,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) + if (*tPtr == '\0' || Detail::IsSpace(*tPtr)) return ptr-m_sharedString->string.get(); else break; @@ -1503,7 +1508,7 @@ namespace Nz if (ptr != m_sharedString->string.get()) { --ptr; - if (!(Unicode::GetCategory(*ptr++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*ptr++)) continue; } @@ -1513,7 +1518,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) + if (*tPtr == '\0' || Detail::IsSpace(*tPtr)) return ptr-m_sharedString->string.get(); else break; @@ -1579,7 +1584,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1591,7 +1596,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*tIt)) return it.base() - m_sharedString->string.get(); else break; @@ -1621,7 +1626,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1633,7 +1638,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*tIt)) return it.base() - m_sharedString->string.get(); else break; @@ -1664,7 +1669,7 @@ namespace Nz if (Detail::ToLower(*ptr) == c) { char nextC = *(ptr + 1); - if (nextC != '\0' && (Unicode::GetCategory(nextC) & Unicode::Category_Separator_Space) == 0) + if (nextC != '\0' && (Detail::IsSpace(nextC)) == 0) continue; const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; @@ -1675,7 +1680,7 @@ namespace Nz if (p == &string.m_sharedString->string[0]) { - if (ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) + if (ptr == m_sharedString->string.get() || Detail::IsSpace(*(ptr-1))) return ptr-m_sharedString->string.get(); else break; @@ -1695,7 +1700,7 @@ namespace Nz if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) { char nextC = *(ptr + 1); - if (nextC != '\0' && (Unicode::GetCategory(nextC) & Unicode::Category_Separator_Space) == 0) + if (nextC != '\0' && !Detail::IsSpace(nextC)) continue; const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; @@ -1706,7 +1711,7 @@ namespace Nz if (p == &string.m_sharedString->string[0]) { - if (ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr - 1)) & Unicode::Category_Separator_Space) + if (ptr == m_sharedString->string.get() || Detail::IsSpace(*(ptr - 1))) return ptr-m_sharedString->string.get(); else break; @@ -1766,7 +1771,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1778,7 +1783,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*it++)) return it.base() - m_sharedString->string.get(); else break; @@ -1806,7 +1811,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1818,7 +1823,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*it++)) return it.base() - m_sharedString->string.get(); else break; @@ -1844,7 +1849,7 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr - 1)) & Unicode::Category_Separator) == 0) + if (ptr != m_sharedString->string.get() && !Detail::IsSpace(*(ptr - 1))) continue; const char* p = &string[1]; @@ -1853,7 +1858,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) + if (*tPtr == '\0' || Detail::IsSpace(*tPtr)) return ptr - m_sharedString->string.get(); else break; @@ -1875,7 +1880,7 @@ namespace Nz { if (*ptr == string[0]) { - if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator) == 0) + if (ptr != m_sharedString->string.get() && !Detail::IsSpace(*(ptr-1))) continue; const char* p = &string[1]; @@ -1884,7 +1889,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator) + if (*tPtr == '\0' || Detail::IsSpace(*tPtr)) return ptr - m_sharedString->string.get(); else break; @@ -1947,7 +1952,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1959,7 +1964,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*it++)) return it.base() - m_sharedString->string.get(); else break; @@ -1987,7 +1992,7 @@ namespace Nz if (it.base() != m_sharedString->string.get()) { --it; - if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + if (!Detail::IsSpace(*it++)) continue; } @@ -1999,7 +2004,7 @@ namespace Nz { if (*p == '\0') { - if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + if (*tIt == '\0' || Detail::IsSpace(*it++)) return it.base() - m_sharedString->string.get(); else break; @@ -2026,7 +2031,7 @@ namespace Nz { if (Detail::ToLower(*ptr) == c) { - if (ptr != m_sharedString->string.get() && (Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) == 0) + if (ptr != m_sharedString->string.get() && !Detail::IsSpace(*(ptr-1))) continue; const char* p = &string.m_sharedString->string[1]; @@ -2035,7 +2040,7 @@ namespace Nz { if (*p == '\0') { - if (*tPtr == '\0' || Unicode::GetCategory(*tPtr) & Unicode::Category_Separator_Space) + if (*tPtr == '\0' || Detail::IsSpace(*tPtr)) return ptr - m_sharedString->string.get(); else break; @@ -2056,7 +2061,7 @@ namespace Nz while ((ptr = std::strstr(ptr, string.GetConstBuffer())) != nullptr) { // If the word is really alone - if ((ptr == m_sharedString->string.get() || Unicode::GetCategory(*(ptr-1)) & Unicode::Category_Separator_Space) && (*(ptr+m_sharedString->size) == '\0' || Unicode::GetCategory(*(ptr+m_sharedString->size)) & Unicode::Category_Separator_Space)) + if ((ptr == m_sharedString->string.get() || Detail::IsSpace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || Detail::IsSpace(*(ptr+m_sharedString->size)))) return ptr - m_sharedString->string.get(); ptr++; @@ -2219,7 +2224,7 @@ namespace Nz utf8::unchecked::iterator it(ptr); do { - if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + if (Detail::IsSpace(*it)) { endPos = static_cast(it.base() - m_sharedString->string.get() - 1); break; @@ -2231,7 +2236,7 @@ namespace Nz { do { - if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) + if (Detail::IsSpace(*ptr)) { endPos = static_cast(ptr - m_sharedString->string.get() - 1); break; @@ -2265,7 +2270,7 @@ namespace Nz utf8::unchecked::iterator it(ptr); do { - if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + if (Detail::IsSpace(*it)) inWord = false; else { @@ -2283,7 +2288,7 @@ namespace Nz { do { - if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) + if (Detail::IsSpace(*ptr)) inWord = false; else { @@ -3414,7 +3419,7 @@ namespace Nz utf8::unchecked::iterator it(ptr); do { - if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + if (Detail::IsSpace(*it)) { if (inword) { @@ -3435,7 +3440,7 @@ namespace Nz const char* limit = &m_sharedString->string[m_sharedString->size]; do { - if (Unicode::GetCategory(*ptr) & Unicode::Category_Separator) + if (Detail::IsSpace(*ptr)) { if (inword) { @@ -4240,7 +4245,7 @@ namespace Nz utf8::unchecked::iterator it(m_sharedString->string.get()); do { - if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (!Detail::IsSpace(*it)) break; } while (*++it); @@ -4255,7 +4260,7 @@ namespace Nz utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); while ((it--).base() != m_sharedString->string.get()) { - if (*it != '\t' && (Unicode::GetCategory(*it) & Unicode::Category_Separator) == 0) + if (!Detail::IsSpace(*it)) break; } @@ -4271,8 +4276,8 @@ namespace Nz { for (; startPos < m_sharedString->size; ++startPos) { - char c = m_sharedString->string[startPos]; - if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[startPos]; + if (!Detail::IsSpace(c)) break; } } @@ -4282,8 +4287,8 @@ namespace Nz { for (; endPos > 0; --endPos) { - char c = m_sharedString->string[endPos]; - if (c != '\t' && (Unicode::GetCategory(c) & Unicode::Category_Separator) == 0) + char c = m_sharedString->string[endPos]; + if (!Detail::IsSpace(c)) break; } } From 3a18c4bb984bddb5c360fa8bfe1099751a4b0bf7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 09:08:56 +0200 Subject: [PATCH 215/224] Graphics/Model: Add AddToRenderQueue(renderQueue, matrix, order) overload Former-commit-id: 51b2eb160cee64341f659cb9233f7323648196ff [formerly eed84804d642972f3952ed5ea5c3991afb6c9657] [formerly 9eb1f9d149bf3eb9beeea950d780e713acbd34b1 [formerly eec842ec8bcebc5e04f2b48c18ec608ae5a82014]] Former-commit-id: 82dee95422af697ba8319c53a60f32bf98ff31da [formerly c797b9f8a5964390dcdd2a55271e7a18896a8d8f] Former-commit-id: 8c5e34da6e3686be332a84613230a6734b58966a --- include/Nazara/Graphics/Model.hpp | 1 + include/Nazara/Graphics/Model.inl | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index f119072c8..b1755c7d8 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -45,6 +45,7 @@ namespace Nz virtual ~Model(); void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + inline void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix, unsigned int renderOrder = 0); Material* GetMaterial(const String& subMeshName) const; Material* GetMaterial(unsigned int matIndex) const; diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index a2b4c3967..243611fb5 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -7,6 +7,22 @@ namespace Nz { + /*! + * \brief Adds this model to a render queue, using user-specified transform matrix and render order + * + * This can be useful when drawing particles + * + * \param renderQueue Queue to be added + * \param transformMatrix Transform matrix to be used for rendering the model + * \param renderOrder Specify the renderqueue layer to be used + */ + inline void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix, unsigned int renderOrder) + { + InstanceData instanceData(transformMatrix); + instanceData.renderOrder = renderOrder; + return AddToRenderQueue(renderQueue, instanceData); + } + /*! * \brief Creates a new Model from the arguments * \return A reference to the newly created model From 1d758d370c975d98f49ba5a9e8277e7e0e26495d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 09:09:14 +0200 Subject: [PATCH 216/224] Graphics/InstancedRenderable: Take a const reference to the matrix instead of a non-const one Former-commit-id: 148f4367351f79994f51699a656a938c6784af8f [formerly 27ef2f23da51c156f615bb33e6b3138b44f77498] [formerly 120334bc6e2bd3fcff30fde0febc901d83cdeb9b [formerly 9f4d16e134fb009ce021f4720ffc6d410cc5bd3c]] Former-commit-id: 55595b1a006dfa313e7f088f76ff6880971530c4 [formerly 7e3a37de6c217d1b7734be14df74c174f6e0b4d6] Former-commit-id: 0ebdab2df6d218a51c5ee425482bff7c660fddd8 --- SDK/include/NDK/Components/GraphicsComponent.hpp | 2 +- include/Nazara/Graphics/InstancedRenderable.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index a7ac3ebc2..92aeeed2f 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -66,7 +66,7 @@ namespace Ndk struct Renderable { - Renderable(Nz::Matrix4f& transformMatrix) : + Renderable(const Nz::Matrix4f& transformMatrix) : data(transformMatrix), dataUpdated(false) { diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index d1c07bf9b..d854a41d6 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -54,7 +54,7 @@ namespace Nz struct InstanceData { - InstanceData(Matrix4f& referenceMatrix) : + InstanceData(const Matrix4f& referenceMatrix) : transformMatrix(&referenceMatrix), flags(0) { @@ -75,7 +75,7 @@ namespace Nz std::vector data; BoundingVolumef volume; - Matrix4f* transformMatrix; + const Matrix4f* transformMatrix; UInt32 flags; int renderOrder; }; From 3cf4cd3d53b0506bcdfe46c4b0d440c45b3993de Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 21:55:26 +0200 Subject: [PATCH 217/224] Graphics/AbstractRenderQueue: Remove AddBillboard method Former-commit-id: 9429c5e127d9c4d2172d5ae224b60338d62a58ce [formerly 8e723fad4893f182a3d7b7735e5a156973ca6e59] [formerly d961c2da7c6989cd861d4a703608466dede9ba40 [formerly 20783627678843cb2f1c414862193c079d81e168]] Former-commit-id: b019c83ab483922120a9d37c16e8294694a16aa3 [formerly a651bc66c4cb96962a34ef3f2ade62d91ce1d6b7] Former-commit-id: 820dcb4d787709600d9306025c34b9feb1ced7b2 --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 1 - .../Nazara/Graphics/DeferredRenderQueue.hpp | 1 - include/Nazara/Graphics/DepthRenderQueue.hpp | 1 - .../Nazara/Graphics/ForwardRenderQueue.hpp | 1 - src/Nazara/Graphics/Billboard.cpp | 3 +- src/Nazara/Graphics/DeferredRenderQueue.cpp | 16 --------- src/Nazara/Graphics/DepthRenderQueue.cpp | 29 ---------------- src/Nazara/Graphics/ForwardRenderQueue.cpp | 34 ------------------- 8 files changed, 2 insertions(+), 84 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 50c6e0832..a245787ab 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -38,7 +38,6 @@ namespace Nz // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, // mais je n'ai pas d'autre solution tout aussi performante pour le moment... - virtual 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) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index fecd507be..6ac8e8c6c 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -29,7 +29,6 @@ namespace Nz DeferredRenderQueue(ForwardRenderQueue* forwardQueue); ~DeferredRenderQueue() = 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; diff --git a/include/Nazara/Graphics/DepthRenderQueue.hpp b/include/Nazara/Graphics/DepthRenderQueue.hpp index 0b8a1fc5d..81ec921c0 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.hpp +++ b/include/Nazara/Graphics/DepthRenderQueue.hpp @@ -26,7 +26,6 @@ namespace Nz 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; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index c358e331c..7f88e80bf 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -31,7 +31,6 @@ namespace Nz ForwardRenderQueue() = default; ~ForwardRenderQueue() = 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; diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index e06d3c921..17a2ad065 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -30,7 +30,8 @@ namespace Nz if (!m_material) return; - renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix->GetTranslation(), m_size, m_sinCos, m_color); + Nz::Vector3f position = instanceData.transformMatrix->GetTranslation(); + renderQueue->AddBillboards(instanceData.renderOrder, m_material, 1, &position, &m_size, &m_sinCos, &m_color); } /* diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 738e7b799..0b15c5a44 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -29,22 +29,6 @@ namespace Nz { } - /*! - * \brief Adds billboard to the queue - * - * \param renderOrder Order of rendering - * \param material Material of the billboard - * \param position Position of the billboard - * \param size Sizes of the billboard - * \param sinCos Rotation of the billboard - * \param color Color of the billboard - */ - - void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) - { - m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color); - } - /*! * \brief Adds multiple billboards to the queue * diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index dc31d2a45..c658fe7bd 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -28,35 +28,6 @@ namespace Nz //m_baseMaterial->SetFaceCulling(FaceSide_Front); } - /*! - * \brief Adds billboard to the queue - * - * \param renderOrder Order of rendering - * \param material Material of the billboard - * \param position Position of the billboard - * \param size Sizes of the billboard - * \param sinCos Rotation of the billboard - * \param color Color of the billboard - * - * \remark Produces a NazaraAssert if material is invalid - */ - - 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); - } - /*! * \brief Adds multiple billboards to the queue * diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 0f182a185..b9077e1b9 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -17,40 +17,6 @@ namespace Nz * \brief Graphics class that represents the rendering queue for forward rendering */ - /*! - * \brief Adds billboard to the queue - * - * \param renderOrder Order of rendering - * \param material Material of the billboard - * \param position Position of the billboard - * \param size Sizes of the billboard - * \param sinCos Rotation of the billboard - * \param color Color of the billboard - * - * \remark Produces a NazaraAssert if material is invalid - */ - - void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) - { - NazaraAssert(material, "Invalid material"); - - auto& billboards = GetLayer(renderOrder).billboards; - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - billboardVector.push_back(BillboardData{color, position, size, sinCos}); - } - /*! * \brief Adds multiple billboards to the queue * From ac25df0126a47db0f81a71c702a5bea63c365799 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 22:09:39 +0200 Subject: [PATCH 218/224] Graphics: Separate pipeline state from Material into a new class, MaterialPipeline This allows much more efficient batching, along with pipeline reusage and preparation for the Vulkan API Former-commit-id: fd2de2f0e9612ea275ee69c5578c68e7169cd05b [formerly 53bd8a5ed5695311b7543ad717df63f93fad2da6] [formerly 171740929652ac9fe30e84983709388859cedd6b [formerly 25096a76678f1052e76f67d26b458077a0632cc3]] Former-commit-id: 7978dbeb87af2eac9e5501a97afa83849648bf6e [formerly 81b6cce1ee81a2ca8873d3c70d468b2c71510c95] Former-commit-id: 6663e2721c3f79d5f1e3f33c6183174378b502f4 --- SDK/src/NDK/Console.cpp | 4 +- include/Nazara/Graphics.hpp | 3 +- include/Nazara/Graphics/Billboard.inl | 3 +- .../Nazara/Graphics/DeferredRenderQueue.hpp | 29 +- include/Nazara/Graphics/DepthRenderQueue.inl | 2 +- .../Nazara/Graphics/DepthRenderTechnique.hpp | 1 + .../Nazara/Graphics/ForwardRenderQueue.hpp | 66 +- .../Graphics/ForwardRenderTechnique.hpp | 1 + include/Nazara/Graphics/Material.hpp | 64 +- include/Nazara/Graphics/Material.inl | 783 ++++++++++++------ include/Nazara/Graphics/MaterialPipeline.hpp | 95 +++ include/Nazara/Graphics/MaterialPipeline.inl | 143 ++++ include/Nazara/Graphics/Sprite.inl | 3 +- include/Nazara/Graphics/TextSprite.inl | 7 +- include/Nazara/Renderer/RenderPipeline.hpp | 42 + include/Nazara/Renderer/RenderPipeline.inl | 48 ++ include/Nazara/Renderer/RenderStates.hpp | 7 +- include/Nazara/Renderer/RenderStates.inl | 134 ++- src/Nazara/Graphics/DeferredGeometryPass.cpp | 192 +++-- src/Nazara/Graphics/DeferredRenderQueue.cpp | 129 +-- src/Nazara/Graphics/DepthRenderQueue.cpp | 4 +- src/Nazara/Graphics/DepthRenderTechnique.cpp | 502 ++++++----- src/Nazara/Graphics/ForwardRenderQueue.cpp | 223 +++-- .../Graphics/ForwardRenderTechnique.cpp | 632 +++++++------- src/Nazara/Graphics/Graphics.cpp | 26 +- src/Nazara/Graphics/Material.cpp | 302 ++----- src/Nazara/Graphics/MaterialPipeline.cpp | 168 ++++ .../Resources/Shaders/PhongLighting/core.frag | 36 +- .../Shaders/PhongLighting/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.vert | 18 +- .../Shaders/PhongLighting/core.vert.h | 2 +- 31 files changed, 2249 insertions(+), 1422 deletions(-) create mode 100644 include/Nazara/Graphics/MaterialPipeline.hpp create mode 100644 include/Nazara/Graphics/MaterialPipeline.inl create mode 100644 include/Nazara/Renderer/RenderPipeline.hpp create mode 100644 include/Nazara/Renderer/RenderPipeline.inl create mode 100644 src/Nazara/Graphics/MaterialPipeline.cpp diff --git a/SDK/src/NDK/Console.cpp b/SDK/src/NDK/Console.cpp index 48ad10196..d157d7dbe 100644 --- a/SDK/src/NDK/Console.cpp +++ b/SDK/src/NDK/Console.cpp @@ -28,8 +28,8 @@ namespace Ndk m_characterSize(24) { Nz::MaterialRef backgroundMaterial = Nz::Material::New(); - backgroundMaterial->Enable(Nz::RendererParameter_Blend, true); - backgroundMaterial->Enable(Nz::RendererParameter_DepthBuffer, false); + backgroundMaterial->EnableBlending(true); + backgroundMaterial->EnableDepthBuffer(false); backgroundMaterial->SetDstBlend(Nz::BlendFunc_InvSrcAlpha); backgroundMaterial->SetSrcBlend(Nz::BlendFunc_SrcAlpha); diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 4809d9481..0195c123c 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 12 Jul 2016 at 17:44:43 +// This file was automatically generated on 20 Jul 2016 at 13:49:17 /* Nazara Engine - Graphics module @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 6c4a1e0a9..45c2ef918 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -121,8 +121,7 @@ namespace Nz inline void Billboard::SetDefaultMaterial() { MaterialRef material = Material::New(); - material->Enable(RendererParameter_FaceCulling, true); - material->EnableLighting(false); + material->EnableFaceCulling(true); SetMaterial(std::move(material)); } diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 6ac8e8c6c..922174df6 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -21,8 +21,6 @@ namespace Nz { - class ForwardRenderQueue; - class NAZARA_GRAPHICS_API DeferredRenderQueue : public AbstractRenderQueue { public: @@ -43,11 +41,6 @@ namespace Nz void Clear(bool fully = false) override; - struct MeshDataComparator - { - bool operator()(const MeshData& data1, const MeshData& data2) const; - }; - struct MeshInstanceEntry { NazaraSlot(IndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); @@ -56,12 +49,7 @@ namespace Nz std::vector instances; }; - typedef std::map MeshInstanceContainer; - - struct BatchedModelMaterialComparator - { - bool operator()(const Material* mat1, const Material* mat2) const; - }; + typedef std::map MeshInstanceContainer; struct BatchedModelEntry { @@ -69,14 +57,21 @@ namespace Nz MeshInstanceContainer meshMap; bool enabled = false; - bool instancingEnabled = false; }; - typedef std::map ModelBatches; + typedef std::map MeshMaterialBatches; + + struct BatchedMaterialEntry + { + std::size_t maxInstanceCount = 0; + MeshMaterialBatches materialMap; + }; + + typedef std::map MeshPipelineBatches; struct Layer { - ModelBatches opaqueModels; + MeshPipelineBatches opaqueModels; unsigned int clearCount = 0; }; diff --git a/include/Nazara/Graphics/DepthRenderQueue.inl b/include/Nazara/Graphics/DepthRenderQueue.inl index a8a8da45e..8fbce164b 100644 --- a/include/Nazara/Graphics/DepthRenderQueue.inl +++ b/include/Nazara/Graphics/DepthRenderQueue.inl @@ -18,7 +18,7 @@ namespace Nz { NazaraAssert(material, "Invalid material"); - return material->HasDepthMaterial() || (material->IsEnabled(RendererParameter_DepthBuffer) && material->IsEnabled(RendererParameter_DepthWrite) && material->IsShadowCastingEnabled()); + return material->HasDepthMaterial() || (material->IsDepthBufferEnabled() && material->IsDepthWriteEnabled() && material->IsShadowCastingEnabled()); } } diff --git a/include/Nazara/Graphics/DepthRenderTechnique.hpp b/include/Nazara/Graphics/DepthRenderTechnique.hpp index 42b7f6e0a..9d4ba601f 100644 --- a/include/Nazara/Graphics/DepthRenderTechnique.hpp +++ b/include/Nazara/Graphics/DepthRenderTechnique.hpp @@ -63,6 +63,7 @@ namespace Nz mutable std::unordered_map m_shaderUniforms; Buffer m_vertexBuffer; mutable DepthRenderQueue m_renderQueue; + Texture m_whiteTexture; VertexBuffer m_billboardPointBuffer; VertexBuffer m_spriteBuffer; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 7f88e80bf..99be2743e 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -47,6 +47,16 @@ namespace Nz void Sort(const AbstractViewer* viewer); + struct MaterialComparator + { + bool operator()(const Material* mat1, const Material* mat2) const; + }; + + struct MaterialPipelineComparator + { + bool operator()(const MaterialPipeline* pipeline1, const MaterialPipeline* pipeline2) const; + }; + /// Billboards struct BillboardData { @@ -56,11 +66,6 @@ namespace Nz Vector2f sinCos; }; - struct BatchedBillboardComparator - { - bool operator()(const Material* mat1, const Material* mat2) const; - }; - struct BatchedBillboardEntry { NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); @@ -68,7 +73,15 @@ namespace Nz std::vector billboards; }; - typedef std::map BatchedBillboardContainer; + typedef std::map BatchedBillboardContainer; + + struct BatchedBillboardPipelineEntry + { + BatchedBillboardContainer materialMap; + bool enabled = false; + }; + + typedef std::map BillboardPipelineBatches; /// Sprites struct SpriteChain_XYZ_Color_UV @@ -84,22 +97,25 @@ namespace Nz std::vector spriteChains; }; - struct BatchedSpriteMaterialComparator - { - bool operator()(const Material* mat1, const Material* mat2); - }; - - typedef std::map BasicSpriteOverlayContainer; + typedef std::map SpriteOverlayBatches; struct BatchedBasicSpriteEntry { NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); - BasicSpriteOverlayContainer overlayMap; + SpriteOverlayBatches overlayMap; bool enabled = false; }; - typedef std::map BasicSpriteBatches; + typedef std::map SpriteMaterialBatches; + + struct BatchedSpritePipelineEntry + { + SpriteMaterialBatches materialMap; + bool enabled = false; + }; + + typedef std::map SpritePipelineBatches; /// Meshes struct MeshDataComparator @@ -118,21 +134,23 @@ namespace Nz typedef std::map MeshInstanceContainer; - struct BatchedModelMaterialComparator - { - bool operator()(const Material* mat1, const Material* mat2) const; - }; - struct BatchedModelEntry { NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); MeshInstanceContainer meshMap; bool enabled = false; - bool instancingEnabled = false; }; - typedef std::map ModelBatches; + typedef std::map MeshMaterialBatches; + + struct BatchedMaterialEntry + { + std::size_t maxInstanceCount = 0; + MeshMaterialBatches materialMap; + }; + + typedef std::map MeshPipelineBatches; struct TransparentModelData { @@ -146,9 +164,9 @@ namespace Nz struct Layer { - BatchedBillboardContainer billboards; - BasicSpriteBatches basicSprites; - ModelBatches opaqueModels; + BillboardPipelineBatches billboards; + SpritePipelineBatches basicSprites; + MeshPipelineBatches opaqueModels; TransparentModelContainer transparentModels; std::vector transparentModelData; std::vector otherDrawables; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 21b3a0899..5d82c4bf9 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -84,6 +84,7 @@ namespace Nz mutable std::vector m_lights; Buffer m_vertexBuffer; mutable ForwardRenderQueue m_renderQueue; + Texture m_whiteTexture; VertexBuffer m_billboardPointBuffer; VertexBuffer m_spriteBuffer; unsigned int m_maxLightPassPerObject; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index b30c215c1..f7d15d6fe 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -58,20 +58,33 @@ namespace Nz public: inline Material(); + inline Material(const MaterialPipeline* pipeline); + inline Material(const MaterialPipelineInfo& pipelineInfo); + inline Material(const String& pipelineName); inline Material(const Material& material); inline ~Material(); - const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; + void Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams()); - inline void Enable(RendererParameter renderParameter, bool enable); + inline void Configure(const MaterialPipeline* pipeline); + inline void Configure(const MaterialPipelineInfo& pipelineInfo); + inline bool Configure(const String& pipelineName); + inline void EnableAlphaTest(bool alphaTest); + inline void EnableBlending(bool blending); + inline void EnableColorWrite(bool colorWrite); + inline void EnableDepthBuffer(bool depthBuffer); inline void EnableDepthSorting(bool depthSorting); - inline void EnableLighting(bool lighting); + inline void EnableDepthWrite(bool depthWrite); + inline void EnableFaceCulling(bool faceCulling); + inline void EnableScissorTest(bool scissorTest); inline void EnableShadowCasting(bool castShadows); inline void EnableShadowReceive(bool receiveShadows); - inline void EnableTransform(bool transform); + inline void EnableStencilTest(bool stencilTest); + + inline void EnsurePipelineUpdate() const; inline const TextureRef& GetAlphaMap() const; inline float GetAlphaThreshold() const; @@ -87,10 +100,12 @@ namespace Nz inline FaceSide GetFaceCulling() const; inline FaceFilling GetFaceFilling() const; inline const TextureRef& GetHeightMap() const; + inline float GetLineWidth() const; inline const TextureRef& GetNormalMap() const; - inline const RenderStates& GetRenderStates() const; + inline const MaterialPipeline* GetPipeline() const; + inline const MaterialPipelineInfo& GetPipelineInfo() const; + inline float GetPointSize() 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; @@ -107,12 +122,16 @@ namespace Nz inline bool HasSpecularMap() const; inline bool IsAlphaTestEnabled() const; + inline bool IsBlendingEnabled() const; + inline bool IsColorWriteEnabled() const; + inline bool IsDepthBufferEnabled() const; inline bool IsDepthSortingEnabled() const; - inline bool IsEnabled(RendererParameter renderParameter) const; - inline bool IsLightingEnabled() const; + inline bool IsDepthWriteEnabled() const; + inline bool IsFaceCullingEnabled() const; + inline bool IsScissorTestEnabled() const; + inline bool IsStencilTestEnabled() 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()); @@ -139,9 +158,10 @@ namespace Nz inline void SetFaceFilling(FaceFilling filling); inline bool SetHeightMap(const String& textureName); inline void SetHeightMap(TextureRef textureName); + inline void SetLineWidth(float lineWidth); inline bool SetNormalMap(const String& textureName); inline void SetNormalMap(TextureRef textureName); - inline void SetRenderStates(const RenderStates& states); + inline void SetPointSize(float pointSize); inline void SetShader(UberShaderConstRef uberShader); inline bool SetShader(const String& uberShaderName); inline void SetShininess(float shininess); @@ -161,16 +181,9 @@ namespace Nz NazaraSignal(OnMaterialReset, const Material* /*material*/); private: - struct ShaderInstance - { - const Shader* shader; - UberShaderInstance* uberInstance = nullptr; - int uniforms[MaterialUniform_Max + 1]; - }; - void Copy(const Material& material); - void GenerateShader(UInt32 flags) const; - inline void InvalidateShaders(); + inline void InvalidatePipeline(); + inline void UpdatePipeline() const; static bool Initialize(); static void Uninitialize(); @@ -179,7 +192,8 @@ namespace Nz Color m_diffuseColor; Color m_specularColor; MaterialRef m_depthMaterial; //< Materialception - RenderStates m_states; + mutable const MaterialPipeline* m_pipeline; + MaterialPipelineInfo m_pipelineInfo; TextureSampler m_diffuseSampler; TextureSampler m_specularSampler; TextureRef m_alphaMap; @@ -188,14 +202,8 @@ namespace Nz TextureRef m_heightMap; TextureRef m_normalMap; TextureRef m_specularMap; - UberShaderConstRef m_uberShader; - mutable ShaderInstance m_shaders[ShaderFlags_Max + 1]; - bool m_alphaTestEnabled; - bool m_depthSortingEnabled; - bool m_lightingEnabled; + mutable bool m_pipelineUpdated; 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 6d5315640..cec965e6e 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -2,26 +2,74 @@ // 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 namespace Nz { /*! - * \brief Constructs a Material object by default + * \brief Constructs a Material object with default states + * + * \see Reset */ - inline Material::Material() { Reset(); } + /*! + * \brief Constructs a Material object using a MaterialPipeline + * + * Calls Configure with the pipeline parameter + * + * \see Configure + */ + inline Material::Material(const MaterialPipeline* pipeline) + { + ErrorFlags errFlags(ErrorFlag_ThrowException, true); + + Reset(); + Configure(pipeline); + } + + /*! + * \brief Constructs a Material object using a MaterialPipelineInfo + * + * Calls Configure with the pipelineInfo parameter + * + * \see Configure + */ + inline Material::Material(const MaterialPipelineInfo& pipelineInfo) + { + ErrorFlags errFlags(ErrorFlag_ThrowException, true); + + Reset(); + Configure(pipelineInfo); + } + + /*! + * \brief Constructs a Material object using a MaterialPipeline name + * + * Calls Configure with the pipelineName parameter + * + * \remark In case of error (ie. named pipeline is not registered), throw an exception + * + * \see Configure + */ + inline Material::Material(const String& pipelineName) + { + ErrorFlags errFlags(ErrorFlag_ThrowException, true); + + Reset(); + Configure(pipelineName); + } + /*! * \brief Constructs a Material object by assignation * * \param material Material to copy into this */ - inline Material::Material(const Material& material) : RefCounted(), Resource(material) @@ -34,156 +82,325 @@ namespace Nz * * \see OnMaterialRelease */ - inline Material::~Material() { OnMaterialRelease(this); } /*! - * \brief Enables a renderer parameter + * \brief Reset material pipeline state * - * \param renderParameter Parameter for the rendering - * \param enable Should the parameter be enabled + * Sets the material pipeline * - * \remark Produces a NazaraAssert if enumeration is invalid + * \remark pipeline must be valid + * + * \see Configure */ - - inline void Material::Enable(RendererParameter renderParameter, bool enable) + inline void Material::Configure(const MaterialPipeline* pipeline) { - NazaraAssert(renderParameter <= RendererParameter_Max, "Renderer parameter out of enum"); + NazaraAssert(pipeline, "Invalid material pipeline"); - switch (renderParameter) - { - case RendererParameter_Blend: - m_states.blending = enable; - return; - - case RendererParameter_ColorWrite: - m_states.colorWrite = enable; - return; - - case RendererParameter_DepthBuffer: - m_states.depthBuffer = enable; - return; - - case RendererParameter_DepthWrite: - m_states.depthWrite = enable; - return; - - case RendererParameter_FaceCulling: - m_states.faceCulling = enable; - return; - - case RendererParameter_ScissorTest: - m_states.scissorTest = enable; - return; - - case RendererParameter_StencilTest: - m_states.stencilTest = enable; - return; - } + m_pipeline = pipeline; + m_pipelineInfo = m_pipeline->GetInfo(); + m_pipelineUpdated = true; } /*! - * \brief Enables the alpha test + * \brief Reset material pipeline state * - * \param alphaTest Should the parameter be enabled + * Sets the material pipeline using pipeline info * - * \remark Invalidates the shaders + * \remark pipeline must be valid + * + * \see Configure */ + inline void Material::Configure(const MaterialPipelineInfo& pipelineInfo) + { + m_pipelineInfo = pipelineInfo; + InvalidatePipeline(); + } + + /*! + * \brief Reset material pipeline state + * + * Sets the material pipeline using a name to lookup in the MaterialPipelineLibrary + * + * \return True if the material pipeline was found in the library + * + * \see Configure + */ + inline bool Material::Configure(const String& pipelineName) + { + MaterialPipelineRef pipeline = MaterialPipelineLibrary::Query(pipelineName); + if (!pipeline) + { + NazaraError("Failed to get pipeline \"" + pipelineName + "\""); + return false; + } + + Configure(std::move(pipeline)); + return true; + } + + /*! + * \brief Enable/Disable alpha test for this material + * + * When enabled, all objects using this material will be rendered using alpha testing, + * rejecting pixels if their alpha component is under a defined threshold. + * This allows some kind of transparency with a much cheaper cost as it doesn't prevent any optimization (as deferred rendering or batching). + * + * \param alphaTest Defines if this material will use alpha testing + * + * \remark Invalidates the pipeline + * + * \see IsAlphaTestEnabled + * \see SetAlphaThreshold + */ inline void Material::EnableAlphaTest(bool alphaTest) { - m_alphaTestEnabled = alphaTest; + m_pipelineInfo.alphaTest = alphaTest; - InvalidateShaders(); + InvalidatePipeline(); } /*! - * \brief Enables the depth sorting + * \brief Enable/Disable blending for this material * - * \param depthSorting Should the parameter be enabled + * When enabled, all objects using this material will be rendered using blending, obeying the dstBlend and srcBlend parameters + * This is useful with translucent objects, but will reduces performance as it prevents some optimizations (as deferred rendering) + * + * \param blending Defines if this material will use blending + * + * \remark Invalidates the pipeline + * + * \see IsBlendingEnabled + * \see SetDstBlend + * \see SetSrcBlend */ + inline void Material::EnableBlending(bool blending) + { + m_pipelineInfo.blending = blending; + InvalidatePipeline(); + } + + /*! + * \brief Enable/Disable color writing for this material + * + * \param colorWrite Defines if this material will use color writing + * + * \remark Invalidates the pipeline + * + * \see IsColorWritingEnabled + */ + inline void Material::EnableColorWrite(bool colorWrite) + { + m_pipelineInfo.colorWrite = colorWrite; + + InvalidatePipeline(); + } + + /*! + * \brief Enable/Disable depth buffer for this material + * + * When enabled, all objects using this material will be rendered using a depth buffer, if the RenderTarget has one. + * This will enable Depth Test, preventing further fragments to render on top of closer ones. + * + * This parameter is required for depth writing. + * + * In order to enable depth writing without enabling depth test, set the depth comparison function to RendererComparison_Never + * + * \param depthBuffer Defines if this material will use depth buffer + * + * \remark Invalidates the pipeline + * + * \see EnableDepthWrite + * \see IsDepthBufferEnabled + * \see SetDepthFunc + */ + inline void Material::EnableDepthBuffer(bool depthBuffer) + { + m_pipelineInfo.depthBuffer = depthBuffer; + + InvalidatePipeline(); + } + + /*! + * \brief Enable/Disable depth sorting for this material + * + * When enabled, all objects using this material will be rendered far from near + * This is useful with translucent objects, but will reduces performance as it breaks batching + * + * \param depthSorting Defines if this material will use depth sorting + * + * \remark Depth sorting may not be perfect (may be object-sorting instead of triangle-sorting) + * \remark Invalidates the pipeline + * + * \see IsDepthSortingEnabled + */ inline void Material::EnableDepthSorting(bool depthSorting) { - // Has no influence on shaders - m_depthSortingEnabled = depthSorting; + m_pipelineInfo.depthSorting = depthSorting; + + InvalidatePipeline(); } /*! - * \brief Enables the lighting + * \brief Enable/Disable depth writing for this material * - * \param lighting Should the parameter be enabled + * When enabled, and if depth buffer is enabled and present, all fragments generated with this material will write + * to the depth buffer if they pass depth test. * - * \remark Invalidates the shaders + * This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but + * not depth writing (which could make other translucent fragments to fail depth test) + * + * \param depthBuffer Defines if this material will use depth write + * + * \remark Invalidates the pipeline + * + * \see EnableDepthBuffer + * \see IsDepthWriteEnabled */ - - inline void Material::EnableLighting(bool lighting) + inline void Material::EnableDepthWrite(bool depthWrite) { - m_lightingEnabled = lighting; + m_pipelineInfo.depthWrite = depthWrite; - InvalidateShaders(); + InvalidatePipeline(); } /*! - * \brief Enables the shadow casting + * \brief Enable/Disable face culling for this material * - * \param castShadows Should shadow casting be enabled + * When enabled, the material prevents front and/or back faces from rendering. + * This is commonly used as an optimization to prevent processing of hidden faces by the rendering device. + * + * Use SetFaceCulling to control which side will be eliminated. + * + * \param faceCulling Defines if this material will use face culling + * + * \remark Invalidates the pipeline + * + * \see IsFaceCullingEnabled + * \see SetFaceCulling */ + inline void Material::EnableFaceCulling(bool faceCulling) + { + m_pipelineInfo.faceCulling = faceCulling; + InvalidatePipeline(); + } + + /*! + * \brief Enable/Disable scissor test for this material + * + * When enabled, the material prevents fragments out of the scissor box to be rendered. + * This can be useful with GUI, where widgets must not be rendered outside of their parent rendering area. + * + * \param scissorTest Defines if this material will use scissor test + * + * \remark Invalidates the pipeline + * + * \see IsScissorTestEnabled + */ + inline void Material::EnableScissorTest(bool scissorTest) + { + m_pipelineInfo.scissorTest = scissorTest; + + InvalidatePipeline(); + } + + /*! + * \brief Enable/Disable shadow casting for this material + * + * When enabled, all objects using this material will be allowed to cast shadows upon any objects using a material with shadow receiving enabled. + * The depth material replaces this one when rendering shadows. + * + * \param castShadows Defines if this material will be allowed to cast shadows + * + * \remark Does not invalidate the pipeline + * + * \see EnableShadowReceive + * \see IsShadowCastingEnabled + * \see SetDepthMaterial + */ inline void Material::EnableShadowCasting(bool castShadows) { - // Has no influence on shaders + // Has no influence on pipeline m_shadowCastingEnabled = castShadows; } /*! - * \brief Enables the shadow on receiving object + * \brief Enable/Disable shadow receiving for this material * - * \param receiveShadow Should receiving object have shadows enabled + * When enabled, all objects using this material will be allowed to be casted shadows upon themselves + * Disabling this can be helpful to prevent some rendering artifacts (especially with translucent objects) * - * \remark Invalidates the shaders + * \param receiveShadows Defines if this material will be able to receive shadows + * + * \remark Invalidates the pipeline + * + * \see IsShadowReceiveEnabled */ - inline void Material::EnableShadowReceive(bool receiveShadows) { - m_shadowReceiveEnabled = receiveShadows; + m_pipelineInfo.shadowReceive = receiveShadows; - InvalidateShaders(); + InvalidatePipeline(); } /*! - * \brief Enables the transformation + * \brief Enable/Disable stencil test for this material * - * \param transform Should the parameter be enabled + * When enabled, all fragments must pass the stencil test to be rendered. * - * \remark Invalidates the shaders + * \param scissorTest Defines if this material will use stencil test + * + * \remark Invalidates the pipeline + * + * \see IsStencilTestEnabled */ - - inline void Material::EnableTransform(bool transform) + inline void Material::EnableStencilTest(bool stencilTest) { - m_transformEnabled = transform; + m_pipelineInfo.stencilTest = stencilTest; - InvalidateShaders(); + InvalidatePipeline(); + } + + /*! + * \brief Ensures the pipeline gets updated + * + * When the pipeline gets invalidated, it's not updated until required (per example by calling GetPipeline). + * Using this function forces the pipeline update, making GetPipeline thread-safe as long as the pipeline does not get invalidated. + * + * \see GetPipeline + */ + inline void Material::EnsurePipelineUpdate() const + { + if (!m_pipelineUpdated) + UpdatePipeline(); } /*! * \brief Gets the alpha map + * * \return Constant reference to the current texture + * + * \see SetAlphaMap */ - inline const TextureRef& Material::GetAlphaMap() const { return m_alphaMap; } /*! - * \brief Gets the alpha threshold - * \return The threshold value for the alpha + * \brief Gets the alpha test threshold + * + * \return The threshold value for the alpha test + * + * \see EnableAlphaTest + * \see SetAlphaThreshold */ - inline float Material::GetAlphaThreshold() const { return m_alphaThreshold; @@ -191,9 +408,11 @@ namespace Nz /*! * \brief Gets the ambient color + * * \return Ambient color + * + * \see SetAmbientColor */ - inline Color Material::GetAmbientColor() const { return m_ambientColor; @@ -201,19 +420,24 @@ namespace Nz /*! * \brief Gets the function to compare depth + * * \return Function comparing the depth of two materials + * + * \see EnableDepthTest + * \see SetAmbientColor */ - inline RendererComparison Material::GetDepthFunc() const { - return m_states.depthFunc; + return m_pipelineInfo.depthFunc; } /*! * \brief Gets the depth material + * * \return Constant reference to the depth material + * + * \see EnableShadowCasting */ - inline const MaterialRef& Material::GetDepthMaterial() const { return m_depthMaterial; @@ -221,9 +445,11 @@ namespace Nz /*! * \brief Gets the diffuse color + * * \return Diffuse color + * + * \see SetDiffuseColor */ - inline Color Material::GetDiffuseColor() const { return m_diffuseColor; @@ -231,9 +457,11 @@ namespace Nz /*! * \brief Gets the diffuse sampler + * * \return Reference to the current texture sampler for the diffuse + * + * \see SetDiffuseSampler */ - inline TextureSampler& Material::GetDiffuseSampler() { return m_diffuseSampler; @@ -241,9 +469,11 @@ namespace Nz /*! * \brief Gets the diffuse sampler + * * \return Constant reference to the current texture sampler for the diffuse + * + * \see SetDiffuseSampler */ - inline const TextureSampler& Material::GetDiffuseSampler() const { return m_diffuseSampler; @@ -251,9 +481,11 @@ namespace Nz /*! * \brief Gets the diffuse map + * * \return Constant reference to the texture + * + * \see SetDiffuseMap */ - const TextureRef& Material::GetDiffuseMap() const { return m_diffuseMap; @@ -261,19 +493,23 @@ namespace Nz /*! * \brief Gets the dst in blend + * * \return Function for dst blending + * + * \see SetDstBlend */ - inline BlendFunc Material::GetDstBlend() const { - return m_states.dstBlend; + return m_pipelineInfo.dstBlend; } /*! * \brief Gets the emissive map + * * \return Constant reference to the texture + * + * \see SetEmissiveMap */ - inline const TextureRef& Material::GetEmissiveMap() const { return m_emissiveMap; @@ -281,34 +517,43 @@ namespace Nz /*! * \brief Gets the face culling + * * \return Current face culling side + * + * \see SetFaceCulling */ - inline FaceSide Material::GetFaceCulling() const { - return m_states.cullingSide; + return m_pipelineInfo.cullingSide; } /*! * \brief Gets the face filling * \return Current face filling */ - inline FaceFilling Material::GetFaceFilling() const { - return m_states.faceFilling; + return m_pipelineInfo.faceFilling; } /*! * \brief Gets the height map * \return Constant reference to the texture */ - inline const TextureRef& Material::GetHeightMap() const { return m_heightMap; } + /*! + * \brief Gets the line width of this material + * \return Line width + */ + inline float Material::GetLineWidth() const + { + return m_pipelineInfo.lineWidth; + } + /*! * \brief Gets the normal map * \return Constant reference to the texture @@ -323,43 +568,44 @@ namespace Nz * \brief Gets the render states * \return Constant reference to the render states */ - - inline const RenderStates& Material::GetRenderStates() const + inline const MaterialPipeline* Material::GetPipeline() const { - return m_states; + EnsurePipelineUpdate(); + + return m_pipeline; } /*! - * \brief Gets the shader of this material - * \return Constant pointer to the ubershader used + * \brief Gets the pipeline informations + * \return Constant reference to the pipeline info */ + inline const MaterialPipelineInfo& Material::GetPipelineInfo() const + { + return m_pipelineInfo; + } + /*! + * \brief Gets the point size of this material + * \return Point size + */ + inline float Material::GetPointSize() const + { + return m_pipelineInfo.pointSize; + } + + /*! + * \brief Gets the über-shader used by this material + * \return Constant pointer to the über-shader used + */ inline const UberShader* Material::GetShader() const { - return m_uberShader; - } - - /*! - * \brief Gets the shader instance based on the flag - * \return Constant pointer to the ubershader instance - * - * \param flags Flag of the shader - */ - - inline const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const - { - const ShaderInstance& instance = m_shaders[flags]; - if (!instance.uberInstance) - GenerateShader(flags); - - return instance.uberInstance; + return m_pipelineInfo.uberShader; } /*! * \brief Gets the shininess * \return Current shininess */ - inline float Material::GetShininess() const { return m_shininess; @@ -369,7 +615,6 @@ namespace Nz * \brief Gets the specular color * \return Specular color */ - inline Color Material::GetSpecularColor() const { return m_specularColor; @@ -379,7 +624,6 @@ namespace Nz * \brief Gets the specular map * \return Constant reference to the texture */ - inline const TextureRef& Material::GetSpecularMap() const { return m_specularMap; @@ -389,7 +633,6 @@ namespace Nz * \brief Gets the specular sampler * \return Reference to the current texture sampler for the specular */ - inline TextureSampler& Material::GetSpecularSampler() { return m_specularSampler; @@ -399,7 +642,6 @@ namespace Nz * \brief Gets the specular sampler * \return Constant reference to the current texture sampler for the specular */ - inline const TextureSampler& Material::GetSpecularSampler() const { return m_specularSampler; @@ -409,17 +651,15 @@ namespace Nz * \brief Gets the src in blend * \return Function for src blending */ - inline BlendFunc Material::GetSrcBlend() const { - return m_states.srcBlend; + return m_pipelineInfo.srcBlend; } /*! * \brief Checks whether this material has an alpha map * \return true If it is the case */ - inline bool Material::HasAlphaMap() const { return m_alphaMap.IsValid(); @@ -429,7 +669,6 @@ namespace Nz * \brief Checks whether this material has a depth material * \return true If it is the case */ - inline bool Material::HasDepthMaterial() const { return m_depthMaterial.IsValid(); @@ -439,7 +678,6 @@ namespace Nz * \brief Checks whether this material has a diffuse map * \return true If it is the case */ - inline bool Material::HasDiffuseMap() const { return m_diffuseMap.IsValid(); @@ -449,7 +687,6 @@ namespace Nz * \brief Checks whether this material has a emissive map * \return true If it is the case */ - inline bool Material::HasEmissiveMap() const { return m_emissiveMap.IsValid(); @@ -459,7 +696,6 @@ namespace Nz * \brief Checks whether this material has a height map * \return true If it is the case */ - inline bool Material::HasHeightMap() const { return m_heightMap.IsValid(); @@ -469,7 +705,6 @@ namespace Nz * \brief Checks whether this material has a normal map * \return true If it is the case */ - inline bool Material::HasNormalMap() const { return m_normalMap.IsValid(); @@ -479,7 +714,6 @@ namespace Nz * \brief Checks whether this material has a specular map * \return true If it is the case */ - inline bool Material::HasSpecularMap() const { return m_specularMap.IsValid(); @@ -489,78 +723,87 @@ namespace Nz * \brief Checks whether this material has alpha test enabled * \return true If it is the case */ - inline bool Material::IsAlphaTestEnabled() const { - return m_alphaTestEnabled; + return m_pipelineInfo.alphaTest; + } + + /*! + * \brief Checks whether this material has blending enabled + * \return true If it is the case + */ + inline bool Material::IsBlendingEnabled() const + { + return m_pipelineInfo.blending; + } + + /*! + * \brief Checks whether this material has color write enabled + * \return true If it is the case + */ + inline bool Material::IsColorWriteEnabled() const + { + return m_pipelineInfo.colorWrite; + } + + /*! + * \brief Checks whether this material has depth buffer enabled + * \return true If it is the case + */ + inline bool Material::IsDepthBufferEnabled() const + { + return m_pipelineInfo.depthBuffer; } /*! * \brief Checks whether this material has depth sorting enabled * \return true If it is the case */ - inline bool Material::IsDepthSortingEnabled() const { - return m_depthSortingEnabled; + return m_pipelineInfo.depthSorting; } /*! - * \brief Checks whether this material has the render parameter enabled + * \brief Checks whether this material has depth writing enabled * \return true If it is the case - * - * \param parameter Parameter for the rendering - * - * \remark Produces a NazaraAssert if enumeration is invalid */ - - inline bool Material::IsEnabled(RendererParameter parameter) const + inline bool Material::IsDepthWriteEnabled() const { - NazaraAssert(parameter <= RendererParameter_Max, "Renderer parameter out of enum"); - - switch (parameter) - { - case RendererParameter_Blend: - return m_states.blending; - - case RendererParameter_ColorWrite: - return m_states.colorWrite; - - case RendererParameter_DepthBuffer: - return m_states.depthBuffer; - - case RendererParameter_DepthWrite: - return m_states.depthWrite; - - case RendererParameter_FaceCulling: - return m_states.faceCulling; - - case RendererParameter_ScissorTest: - return m_states.scissorTest; - - case RendererParameter_StencilTest: - return m_states.stencilTest; - } - - NazaraInternalError("Unhandled renderer parameter: 0x" + String::Number(parameter, 16)); - return false; + return m_pipelineInfo.depthWrite; } /*! - * \brief Checks whether this material has lightning enabled + * \brief Checks whether this material has face culling enabled * \return true If it is the case */ - - inline bool Material::IsLightingEnabled() const + inline bool Material::IsFaceCullingEnabled() const { - return m_lightingEnabled; + return m_pipelineInfo.faceCulling; + } + + /*! + * \brief Checks whether this material has scissor test enabled + * \return true If it is the case + */ + inline bool Material::IsScissorTestEnabled() const + { + return m_pipelineInfo.scissorTest; + } + + /*! + * \brief Checks whether this material has stencil test enabled + * \return true If it is the case + */ + inline bool Material::IsStencilTestEnabled() const + { + return m_pipelineInfo.stencilTest; } /*! * \brief Checks whether this material cast shadow * \return true If it is the case */ - inline bool Material::IsShadowCastingEnabled() const { return m_shadowCastingEnabled; @@ -570,20 +813,9 @@ namespace Nz * \brief Checks whether this material receive shadow * \return true If it is the case */ - inline bool Material::IsShadowReceiveEnabled() const { - return m_shadowReceiveEnabled; - } - - /*! - * \brief Checks whether this material has transformation enabled - * \return true If it is the case - */ - - inline bool Material::IsTransformEnabled() const - { - return m_transformEnabled; + return m_pipelineInfo.shadowReceive; } /*! @@ -593,7 +825,6 @@ namespace Nz * \param filePath Path to the file * \param params Parameters for the material */ - inline bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) { return MaterialLoader::LoadFromFile(this, filePath, params); @@ -607,7 +838,6 @@ namespace Nz * \param size Size of the memory * \param params Parameters for the material */ - inline bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) { return MaterialLoader::LoadFromMemory(this, data, size, params); @@ -620,7 +850,6 @@ namespace Nz * \param stream Stream to the material * \param params Parameters for the material */ - inline bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) { return MaterialLoader::LoadFromStream(this, stream, params); @@ -632,7 +861,6 @@ namespace Nz * * \param textureName Named texture */ - inline bool Material::SetAlphaMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -656,14 +884,14 @@ namespace Nz * * \param alphaMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline */ - inline void Material::SetAlphaMap(TextureRef alphaMap) { m_alphaMap = std::move(alphaMap); + m_pipelineInfo.hasAlphaMap = m_alphaMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! @@ -671,7 +899,6 @@ namespace Nz * * \param alphaThreshold Threshold for the alpha */ - inline void Material::SetAlphaThreshold(float alphaThreshold) { m_alphaThreshold = alphaThreshold; @@ -682,7 +909,6 @@ namespace Nz * * \param ambient Color for ambient */ - inline void Material::SetAmbientColor(const Color& ambient) { m_ambientColor = ambient; @@ -692,11 +918,14 @@ namespace Nz * \brief Sets the depth functor * * \param depthFunc + * + * \remark Invalidates the pipeline */ - inline void Material::SetDepthFunc(RendererComparison depthFunc) { - m_states.depthFunc = depthFunc; + m_pipelineInfo.depthFunc = depthFunc; + + InvalidatePipeline(); } /*! @@ -705,7 +934,6 @@ namespace Nz * * \param depthMaterial Material for depth */ - inline void Material::SetDepthMaterial(MaterialRef depthMaterial) { m_depthMaterial = std::move(depthMaterial); @@ -716,7 +944,6 @@ namespace Nz * * \param diffuse Color for diffuse */ - inline void Material::SetDiffuseColor(const Color& diffuse) { m_diffuseColor = diffuse; @@ -727,8 +954,9 @@ namespace Nz * \return true If successful * * \param textureName Named texture + * + * \remark Invalidates the pipeline */ - inline bool Material::SetDiffuseMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -752,14 +980,14 @@ namespace Nz * * \param diffuseMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline */ - inline void Material::SetDiffuseMap(TextureRef diffuseMap) { m_diffuseMap = std::move(diffuseMap); + m_pipelineInfo.hasDiffuseMap = m_diffuseMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! @@ -777,11 +1005,14 @@ namespace Nz * \brief Sets the dst in blend * * \param func Function for dst blending + * + * \remark Invalidates the pipeline */ - inline void Material::SetDstBlend(BlendFunc func) { - m_states.dstBlend = func; + m_pipelineInfo.dstBlend = func; + + InvalidatePipeline(); } /*! @@ -789,8 +1020,9 @@ namespace Nz * \return true If successful * * \param textureName Named texture + * + * \see GetEmissiveMap */ - inline bool Material::SetEmissiveMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -814,45 +1046,52 @@ namespace Nz * * \param emissiveMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline */ - inline void Material::SetEmissiveMap(TextureRef emissiveMap) { m_emissiveMap = std::move(emissiveMap); + m_pipelineInfo.hasEmissiveMap = m_emissiveMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! * \brief Sets the face culling * * \param faceSide Face to cull + * + * \remark Invalidates the pipeline */ - inline void Material::SetFaceCulling(FaceSide faceSide) { - m_states.cullingSide = faceSide; + m_pipelineInfo.cullingSide = faceSide; + + InvalidatePipeline(); } /*! * \brief Sets the face filling * * \param filling Face to fill + * + * \remark Invalidates the pipeline */ - inline void Material::SetFaceFilling(FaceFilling filling) { - m_states.faceFilling = filling; + m_pipelineInfo.faceFilling = filling; + + InvalidatePipeline(); } /*! - * \brief Sets the height map by name + * \brief Sets the height map by path or name * \return true If successful * * \param textureName Named texture + * + * \see GetHeightMap */ - inline bool Material::SetHeightMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -872,27 +1111,49 @@ namespace Nz /*! * \brief Sets the height map with a reference to a texture - * \return true If successful * * \param heightMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline + * + * \see GetHeightMap */ - inline void Material::SetHeightMap(TextureRef heightMap) { m_heightMap = std::move(heightMap); + m_pipelineInfo.hasHeightMap = m_heightMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! - * \brief Sets the normal map by name + * \brief Sets the line width for this material + * + * This parameter is used when rendering lines, to define the width (in pixels) the line will take on the framebuffer + * + * \param lineWidth Width of the line + * + * \remark Invalidates the pipeline + * + * \see GetLineWidth + */ + inline void Material::SetLineWidth(float lineWidth) + { + m_pipelineInfo.lineWidth = lineWidth; + + InvalidatePipeline(); + } + + /*! + * \brief Sets the normal map by path or name * \return true If successful * * \param textureName Named texture + * + * \remark Invalidates the pipeline + * + * \see GetNormalMap */ - inline bool Material::SetNormalMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -916,25 +1177,34 @@ namespace Nz * * \param normalMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline + * + * \see GetNormalMap */ - inline void Material::SetNormalMap(TextureRef normalMap) { m_normalMap = std::move(normalMap); + m_pipelineInfo.hasNormalMap = m_normalMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! - * \brief Sets the render states + * \brief Sets the point size for this material * - * \param states States for the rendering + * This parameter is used when rendering points, to define the size (in pixels) the point will take on the framebuffer + * + * \param pointSize Size of the point + * + * \remark Invalidates the pipeline + * + * \see GetPointSize */ - - inline void Material::SetRenderStates(const RenderStates& states) + inline void Material::SetPointSize(float pointSize) { - m_states = states; + m_pipelineInfo.pointSize = pointSize; + + InvalidatePipeline(); } /*! @@ -942,14 +1212,15 @@ namespace Nz * * \param uberShader Uber shader to apply * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline + * + * \see GetShader */ - inline void Material::SetShader(UberShaderConstRef uberShader) { - m_uberShader = std::move(uberShader); + m_pipelineInfo.uberShader = std::move(uberShader); - InvalidateShaders(); + InvalidatePipeline(); } /*! @@ -958,7 +1229,6 @@ namespace Nz * * \param uberShaderName Named shader */ - inline bool Material::SetShader(const String& uberShaderName) { UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); @@ -974,7 +1244,6 @@ namespace Nz * * \param shininess Value of the shininess */ - inline void Material::SetShininess(float shininess) { m_shininess = shininess; @@ -985,7 +1254,6 @@ namespace Nz * * \param specular Color */ - inline void Material::SetSpecularColor(const Color& specular) { m_specularColor = specular; @@ -996,8 +1264,9 @@ namespace Nz * \return true If successful * * \param textureName Named texture + * + * \remark Invalidates the pipeline */ - inline bool Material::SetSpecularMap(const String& textureName) { TextureRef texture = TextureLibrary::Query(textureName); @@ -1021,22 +1290,25 @@ namespace Nz * * \param specularMap Texture * - * \remark Invalidates the shaders + * \remark Invalidates the pipeline + * + * \see GetSpecularMap */ - inline void Material::SetSpecularMap(TextureRef specularMap) { m_specularMap = std::move(specularMap); + m_pipelineInfo.hasSpecularMap = m_specularMap.IsValid(); - InvalidateShaders(); + InvalidatePipeline(); } /*! * \brief Sets the specular sampler * * \param sampler Specular sample + * + * \see GetSpecularSampler */ - inline void Material::SetSpecularSampler(const TextureSampler& sampler) { m_specularSampler = sampler; @@ -1046,11 +1318,16 @@ namespace Nz * \brief Sets the src in blend * * \param func Function for src blending + * + * \remark Invalidates the pipeline + * + * \see GetSrcBlend */ - inline void Material::SetSrcBlend(BlendFunc func) { - m_states.srcBlend = func; + m_pipelineInfo.srcBlend = func; + + InvalidatePipeline(); } /*! @@ -1059,7 +1336,6 @@ namespace Nz * * \param material The other Material */ - inline Material& Material::operator=(const Material& material) { Resource::operator=(material); @@ -1070,22 +1346,25 @@ namespace Nz /*! * \brief Gets the default material + * * \return Reference to the default material + * + * \remark This material should NOT be modified as it would affect all objects using it */ - inline MaterialRef Material::GetDefault() { return s_defaultMaterial; } - /*! - * \brief Invalidates the shaders - */ - - inline void Material::InvalidateShaders() + inline void Material::InvalidatePipeline() { - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; + m_pipelineUpdated = false; + } + + inline void Material::UpdatePipeline() const + { + m_pipeline = MaterialPipeline::GetPipeline(m_pipelineInfo); + m_pipelineUpdated = true; } /*! @@ -1094,7 +1373,6 @@ namespace Nz * * \param args Arguments for the material */ - template MaterialRef Material::New(Args&&... args) { @@ -1106,3 +1384,4 @@ namespace Nz } #include +#include "Material.hpp" diff --git a/include/Nazara/Graphics/MaterialPipeline.hpp b/include/Nazara/Graphics/MaterialPipeline.hpp new file mode 100644 index 000000000..cf64d5e40 --- /dev/null +++ b/include/Nazara/Graphics/MaterialPipeline.hpp @@ -0,0 +1,95 @@ +// Copyright (C) 2016 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_MATERIALPIPELINE_HPP +#define NAZARA_MATERIALPIPELINE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + struct MaterialPipelineInfo : RenderStates + { + bool alphaTest = false; + bool depthSorting = false; + bool hasAlphaMap = false; + bool hasDiffuseMap = false; + bool hasEmissiveMap = false; + bool hasHeightMap = false; + bool hasNormalMap = false; + bool hasSpecularMap = false; + bool shadowReceive = true; + + UberShaderConstRef uberShader; + }; + + inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs); + inline bool operator!=(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs); + + class MaterialPipeline; + + using MaterialPipelineConstRef = ObjectRef; + using MaterialPipelineLibrary = ObjectLibrary; + using MaterialPipelineRef = ObjectRef; + + class NAZARA_GRAPHICS_API MaterialPipeline : public RefCounted + { + friend class Graphics; + friend MaterialPipelineLibrary; + + public: + struct Instance; + + MaterialPipeline(const MaterialPipeline&) = delete; + MaterialPipeline(MaterialPipeline&&) = delete; + ~MaterialPipeline() = default; + + inline const Instance& Apply(UInt32 flags = ShaderFlags_None) const; + + MaterialPipeline& operator=(const MaterialPipeline&) = delete; + MaterialPipeline& operator=(MaterialPipeline&&) = delete; + + inline const MaterialPipelineInfo& GetInfo() const; + inline const Instance& GetInstance(UInt32 flags = ShaderFlags_None) const; + + static MaterialPipelineRef GetPipeline(const MaterialPipelineInfo& pipelineInfo); + + struct Instance + { + RenderPipeline renderPipeline; + UberShaderInstance* uberInstance = nullptr; + std::array uniforms; + }; + + private: + inline MaterialPipeline(const MaterialPipelineInfo& pipelineInfo); + + void GenerateRenderPipeline(UInt32 flags) const; + + static bool Initialize(); + template static MaterialPipelineRef New(Args&&... args); + static void Uninitialize(); + + MaterialPipelineInfo m_pipelineInfo; + mutable std::array m_instances; + + using PipelineCache = std::unordered_map; + static PipelineCache s_pipelineCache; + + static MaterialPipelineLibrary::LibraryMap s_library; + }; +} + +#include + +#endif // NAZARA_MATERIALPIPELINE_HPP diff --git a/include/Nazara/Graphics/MaterialPipeline.inl b/include/Nazara/Graphics/MaterialPipeline.inl new file mode 100644 index 000000000..ebd94a9ee --- /dev/null +++ b/include/Nazara/Graphics/MaterialPipeline.inl @@ -0,0 +1,143 @@ +// Copyright (C) 2016 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 + +namespace Nz +{ + inline MaterialPipeline::MaterialPipeline(const MaterialPipelineInfo& pipelineInfo) : + m_pipelineInfo(pipelineInfo) + { + } + + /*! + * \brief Enable pipeline states for rendering + * + * \param flags Shader flags + */ + inline const MaterialPipeline::Instance& MaterialPipeline::Apply(UInt32 flags) const + { + const Instance& instance = GetInstance(flags); + instance.uberInstance->Activate(); + + Renderer::SetRenderStates(m_pipelineInfo); + + return instance; + } + + /*! + * \brief Retrieve a MaterialPipelineInfo object describing this pipeline + * + * \return Pipeline informations + */ + const MaterialPipelineInfo& MaterialPipeline::GetInfo() const + { + return m_pipelineInfo; + } + + /*! + * \brief Retrieve (and generate if required) a pipeline instance using shader flags without applying it + * + * \param flags Shader flags + * + * \return Pipeline instance + */ + inline const MaterialPipeline::Instance& MaterialPipeline::GetInstance(UInt32 flags) const + { + const Instance& instance = m_instances[flags]; + if (!instance.uberInstance) + GenerateRenderPipeline(flags); + + return instance; + } + + bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs) + { + if (!operator==(static_cast(lhs), static_cast(rhs))) + return false; + + #define NazaraPipelineMember(field) if (lhs.##field != rhs.##field) return false + #define NazaraPipelineBoolMember NazaraPipelineMember + + NazaraPipelineBoolMember(alphaTest); + NazaraPipelineBoolMember(depthSorting); + NazaraPipelineBoolMember(hasAlphaMap); + NazaraPipelineBoolMember(hasDiffuseMap); + NazaraPipelineBoolMember(hasEmissiveMap); + NazaraPipelineBoolMember(hasHeightMap); + NazaraPipelineBoolMember(hasNormalMap); + NazaraPipelineBoolMember(hasSpecularMap); + NazaraPipelineBoolMember(shadowReceive); + + NazaraPipelineMember(uberShader); + + #undef NazaraPipelineMember + #undef NazaraPipelineBoolMember + + return true; + } + + bool operator!=(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs) + { + return !operator==(lhs, rhs); + } + + /*! + * \brief Creates a new MaterialPipeline from the arguments + * \return A reference to the newly created material pipeline + * + * \param args Arguments for the material pipeline + */ + template + MaterialPipelineRef MaterialPipeline::New(Args&&... args) + { + std::unique_ptr object(new MaterialPipeline(std::forward(args)...)); + return object.release(); + } +} + +namespace std +{ + template<> + struct hash + { + size_t operator()(const Nz::MaterialPipelineInfo& pipelineInfo) const + { + hash parentHash; + + std::size_t seed = parentHash(pipelineInfo); + + Nz::UInt16 parameterHash = 0; + Nz::UInt16 parameterIndex = 0; + + #define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.##member) + #define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++) + + NazaraPipelineBoolMember(alphaTest); + NazaraPipelineBoolMember(depthSorting); + NazaraPipelineBoolMember(hasAlphaMap); + NazaraPipelineBoolMember(hasDiffuseMap); + NazaraPipelineBoolMember(hasEmissiveMap); + NazaraPipelineBoolMember(hasHeightMap); + NazaraPipelineBoolMember(hasNormalMap); + NazaraPipelineBoolMember(hasSpecularMap); + NazaraPipelineBoolMember(shadowReceive); + + NazaraPipelineMember(uberShader); + + #undef NazaraPipelineMember + #undef NazaraPipelineBoolMember + + Nz::HashCombine(seed, parameterHash); + + return seed; + } + }; +} + +#include diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 840a930e6..f0e05c5a2 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -123,8 +123,7 @@ namespace Nz inline void Sprite::SetDefaultMaterial() { MaterialRef material = Material::New(); - material->Enable(RendererParameter_FaceCulling, false); - material->EnableLighting(false); + material->EnableFaceCulling(false); SetMaterial(std::move(material)); } diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index baeeb50db..2ed880a38 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -119,10 +119,9 @@ namespace Nz inline void TextSprite::SetDefaultMaterial() { MaterialRef material = Material::New(); - material->Enable(RendererParameter_Blend, true); - material->Enable(RendererParameter_DepthWrite, false); - material->Enable(RendererParameter_FaceCulling, false); - material->EnableLighting(false); + material->EnableBlending(true); + material->EnableDepthWrite(false); + material->EnableFaceCulling(false); material->SetDstBlend(BlendFunc_InvSrcAlpha); material->SetSrcBlend(BlendFunc_SrcAlpha); diff --git a/include/Nazara/Renderer/RenderPipeline.hpp b/include/Nazara/Renderer/RenderPipeline.hpp new file mode 100644 index 000000000..aee5584b7 --- /dev/null +++ b/include/Nazara/Renderer/RenderPipeline.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_RENDERPIPELINE_HPP +#define NAZARA_RENDERPIPELINE_HPP + +#include +#include +#include + +namespace Nz +{ + struct RenderPipelineInfo : RenderStates + { + ShaderConstRef shader; + }; + + class RenderPipeline + { + public: + inline RenderPipeline(); + inline ~RenderPipeline(); + + inline bool Create(const RenderPipelineInfo& pipelineInfo); + inline void Destroy(); + + inline const RenderPipelineInfo& GetInfo() const; + + inline bool IsValid() const; + + private: + RenderPipelineInfo m_pipelineInfo; + bool m_valid; + }; +} + +#include + +#endif // NAZARA_RENDERPIPELINE_HPP diff --git a/include/Nazara/Renderer/RenderPipeline.inl b/include/Nazara/Renderer/RenderPipeline.inl new file mode 100644 index 000000000..5982b0562 --- /dev/null +++ b/include/Nazara/Renderer/RenderPipeline.inl @@ -0,0 +1,48 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + inline RenderPipeline::RenderPipeline() : + m_valid(false) + { + } + + inline RenderPipeline::~RenderPipeline() + { + } + + inline bool RenderPipeline::Create(const RenderPipelineInfo& pipelineInfo) + { + NazaraAssert(pipelineInfo.shader, "Invalid shader"); + + m_pipelineInfo = pipelineInfo; + m_valid = true; + + return true; + } + + inline void RenderPipeline::Destroy() + { + m_valid = false; + } + + inline const RenderPipelineInfo& RenderPipeline::GetInfo() const + { + NazaraAssert(m_valid, "Invalid pipeline info"); + + return m_pipelineInfo; + } + + inline bool RenderPipeline::IsValid() const + { + return m_valid; + } +} + +#include diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index a885b2a7d..fc4d10eeb 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -7,8 +7,8 @@ #ifndef NAZARA_RENDERSTATES_HPP #define NAZARA_RENDERSTATES_HPP +#include #include -#include namespace Nz { @@ -74,10 +74,7 @@ namespace Nz float pointSize = 1.f; }; - struct RenderPipeline : RenderStates - { - ShaderConstRef shader; - }; + inline bool operator==(const RenderStates& lhs, const RenderStates& rhs); } #include diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 1f7564166..d9b6bfc31 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -3,11 +3,143 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include +#include +#include #include namespace Nz { + bool operator==(const RenderStates& lhs, const RenderStates& rhs) + { + #define NazaraRenderStateMember(field) if (lhs.##field != rhs.##field) return false + #define NazaraRenderStateBoolMember NazaraRenderStateMember + #define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.##field, rhs.##field, maxDiff)) return false + + NazaraRenderStateBoolMember(blending); + NazaraRenderStateBoolMember(colorWrite); + NazaraRenderStateBoolMember(depthBuffer); + NazaraRenderStateBoolMember(faceCulling); + NazaraRenderStateBoolMember(scissorTest); + NazaraRenderStateBoolMember(stencilTest); + + if (lhs.depthBuffer) + NazaraRenderStateBoolMember(depthWrite); + + NazaraRenderStateMember(faceFilling); + + if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending + { + NazaraRenderStateMember(dstBlend); + NazaraRenderStateMember(srcBlend); + } + + if (lhs.depthBuffer) + NazaraRenderStateMember(depthFunc); + + if (lhs.faceCulling) + NazaraRenderStateMember(cullingSide); + + if (lhs.stencilTest) + { + NazaraRenderStateMember(stencilCompare.back); + NazaraRenderStateMember(stencilCompare.front); + NazaraRenderStateMember(stencilCompareMask.back); + NazaraRenderStateMember(stencilCompareMask.front); + NazaraRenderStateMember(stencilDepthFail.back); + NazaraRenderStateMember(stencilDepthFail.front); + NazaraRenderStateMember(stencilFail.back); + NazaraRenderStateMember(stencilFail.front); + NazaraRenderStateMember(stencilPass.back); + NazaraRenderStateMember(stencilPass.front); + NazaraRenderStateMember(stencilReference.back); + NazaraRenderStateMember(stencilReference.front); + NazaraRenderStateMember(stencilWriteMask.back); + NazaraRenderStateMember(stencilWriteMask.front); + } + + NazaraRenderStateFloatMember(lineWidth, 0.001f); + NazaraRenderStateFloatMember(pointSize, 0.001f); + + #undef NazaraRenderStateMember + #undef NazaraRenderStateBoolMember + #undef NazaraRenderStateFloatMember + + return true; + } +} + +namespace std +{ + template<> + struct hash + { + size_t operator()(const Nz::RenderStates& pipelineInfo) const + { + std::size_t seed = 0; + + Nz::UInt8 parameterHash = 0; + Nz::UInt8 parameterIndex = 0; + + #define NazaraRenderStateMember(member) Nz::HashCombine(seed, pipelineInfo.##member) + #define NazaraRenderStateBoolMember(member) parameterHash |= ((pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++) + #define NazaraRenderStateBoolMemberDep(dependency, member) parameterHash |= ((pipelineInfo.##dependency && pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++) + #define NazaraRenderStateFloatMember(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.##member / maxDiff) * maxDiff) + + NazaraRenderStateBoolMember(blending); + NazaraRenderStateBoolMember(colorWrite); + NazaraRenderStateBoolMember(depthBuffer); + NazaraRenderStateBoolMember(faceCulling); + NazaraRenderStateBoolMember(scissorTest); + NazaraRenderStateBoolMember(stencilTest); + + NazaraRenderStateBoolMemberDep(depthBuffer, depthWrite); + + NazaraRenderStateMember(faceFilling); + + if (pipelineInfo.blending) //< Remember, at this time we know lhs.blending == rhs.blending + { + NazaraRenderStateMember(dstBlend); + NazaraRenderStateMember(srcBlend); + } + + if (pipelineInfo.depthBuffer) + NazaraRenderStateMember(depthFunc); + + if (pipelineInfo.faceCulling) + NazaraRenderStateMember(cullingSide); + + if (pipelineInfo.stencilTest) + { + NazaraRenderStateMember(stencilCompare.back); + NazaraRenderStateMember(stencilCompare.front); + NazaraRenderStateMember(stencilCompareMask.back); + NazaraRenderStateMember(stencilCompareMask.front); + NazaraRenderStateMember(stencilDepthFail.back); + NazaraRenderStateMember(stencilDepthFail.front); + NazaraRenderStateMember(stencilFail.back); + NazaraRenderStateMember(stencilFail.front); + NazaraRenderStateMember(stencilPass.back); + NazaraRenderStateMember(stencilPass.front); + NazaraRenderStateMember(stencilReference.back); + NazaraRenderStateMember(stencilReference.front); + NazaraRenderStateMember(stencilWriteMask.back); + NazaraRenderStateMember(stencilWriteMask.front); + } + + NazaraRenderStateFloatMember(lineWidth, 0.001f); + NazaraRenderStateFloatMember(pointSize, 0.001f); + + #undef NazaraRenderStateMember + #undef NazaraRenderStateBoolMember + #undef NazaraRenderStateBoolMemberDep + #undef NazaraRenderStateFloatMember + + Nz::HashCombine(seed, parameterHash); + + return seed; + } + }; } #include diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 86815558c..3cdcb99fe 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -73,122 +73,132 @@ namespace Nz const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& pair : m_renderQueue->layers) + for (auto& layerPair : m_renderQueue->layers) { - DeferredRenderQueue::Layer& layer = pair.second; - - for (auto& matIt : layer.opaqueModels) + for (auto& pipelinePair : layerPair.second.opaqueModels) { - auto& matEntry = matIt.second; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - if (matEntry.enabled) + if (pipelineEntry.maxInstanceCount > 0) { - DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + bool instancing = (pipelineEntry.maxInstanceCount > NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT); - if (!meshInstances.empty()) + UInt32 flags = ShaderFlags_Deferred; + if (instancing) + flags |= ShaderFlags_Instancing; + + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(flags); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) { - const Material* material = matIt.first; + // Index of uniforms in the shader + shaderUniforms = GetShaderUniforms(shader); - bool useInstancing = instancingEnabled && matEntry.instancingEnabled; + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - // We begin by getting the program for materials - UInt32 flags = ShaderFlags_Deferred; - if (useInstancing) - flags |= ShaderFlags_Instancing; + lastShader = shader; + } - const Shader* shader = material->Apply(flags); + for (auto& materialPair : pipelineEntry.materialMap) + { + const Material* material = materialPair.first; + auto& matEntry = materialPair.second; - // The uniforms are conserved in our program, there's no point to send them back if they don't change - if (shader != lastShader) + if (matEntry.enabled) { - // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); + DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - // Ambient color for the scene - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - - lastShader = shader; - } - - // Meshes - for (auto& meshIt : meshInstances) - { - const MeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; - - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + if (!meshInstances.empty()) { - const IndexBuffer* indexBuffer = meshData.indexBuffer; - const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + material->Apply(pipelineInstance); - // Handle draw call before rendering loop - Renderer::DrawCall drawFunc; - Renderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; - - if (indexBuffer) + // Meshes + for (auto& meshIt : meshInstances) { - drawFunc = Renderer::DrawIndexedPrimitives; - instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = Renderer::DrawPrimitives; - instancedDrawFunc = Renderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - Renderer::SetIndexBuffer(indexBuffer); - Renderer::SetVertexBuffer(vertexBuffer); - - if (useInstancing) - { - // We get the buffer for instance of Renderer and we configure it to work with matrices - 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(); // The number of matrices that can be hold in the buffer - - while (instanceCount > 0) + std::vector& instances = meshEntry.instances; + if (!instances.empty()) { - // We compute the number of instances that we will be able to show this time (Depending on the instance buffer size) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; + // Handle draw call before rendering loop + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - // And we show - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, 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) + { + // We get the buffer for instance of Renderer and we configure it to work with matrices + 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(); // The number of matrices that can be hold in the buffer + + while (instanceCount > 0) + { + // We compute the number of instances that we will be able to show this time (Depending on the instance buffer size) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // We fill the instancing buffer with our world matrices + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // And we show + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Without instancing, we must do one draw call for each instance + // This may be faster than instancing under a threshold + // Due to the time to modify the instancing buffer + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + + instances.clear(); } } - else - { - // Without instancing, we must do one draw call for each instance - // This may be faster than instancing under a threshold - // Due to the time to modify the instancing buffer - for (const Matrix4f& matrix : instances) - { - Renderer::SetMatrix(MatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); - } - } - - instances.clear(); } + + // And we set it back data to zero + matEntry.enabled = false; } } - // Abd we set it back data to zero - matEntry.enabled = false; - matEntry.instancingEnabled = false; + pipelineEntry.maxInstanceCount = 0; } } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 0b15c5a44..8623904a6 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -191,27 +191,39 @@ namespace Nz void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { - if (material->IsEnabled(RendererParameter_Blend)) + if (material->IsBlendingEnabled()) // One transparent material ? I don't like it, go see if I'm in the forward queue m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix); else { Layer& currentLayer = GetLayer(renderOrder); - auto& opaqueModels = currentLayer.opaqueModels; + MeshPipelineBatches& opaqueModels = currentLayer.opaqueModels; - auto it = opaqueModels.find(material); - if (it == opaqueModels.end()) + const MaterialPipeline* materialPipeline = material->GetPipeline(); + + auto pipelineIt = opaqueModels.find(materialPipeline); + if (pipelineIt == opaqueModels.end()) + { + BatchedMaterialEntry materialEntry; + pipelineIt = opaqueModels.insert(MeshPipelineBatches::value_type(materialPipeline, std::move(materialEntry))).first; + } + + BatchedMaterialEntry& materialEntry = pipelineIt->second; + MeshMaterialBatches& materialMap = materialEntry.materialMap; + + auto materialIt = materialMap.find(material); + if (materialIt == materialMap.end()) { BatchedModelEntry entry; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &DeferredRenderQueue::OnMaterialInvalidation); - it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; + materialIt = materialMap.insert(MeshMaterialBatches::value_type(material, std::move(entry))).first; } - BatchedModelEntry& entry = it->second; + BatchedModelEntry& entry = materialIt->second; entry.enabled = true; - auto& meshMap = entry.meshMap; + MeshInstanceContainer& meshMap = entry.meshMap; auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) @@ -225,13 +237,8 @@ namespace Nz it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - // We add matrices to the list of instances of this object std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); - - // Do we have enough instances to perform instancing ? - if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Thus we can activate it } } @@ -293,7 +300,7 @@ namespace Nz return layer; } - + /*! * \brief Handle the invalidation of an index buffer * @@ -306,16 +313,19 @@ namespace Nz { Layer& layer = pair.second; - for (auto& modelPair : layer.opaqueModels) + for (auto& pipelineEntry : layer.opaqueModels) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto& materialEntry : pipelineEntry.second.materialMap) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = materialEntry.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } @@ -333,7 +343,8 @@ namespace Nz { Layer& layer = pair.second; - layer.opaqueModels.erase(material); + for (auto& pipelineEntry : layer.opaqueModels) + pipelineEntry.second.materialMap.erase(material); } } @@ -348,73 +359,21 @@ namespace Nz for (auto& pair : layers) { Layer& layer = pair.second; - - for (auto& modelPair : layer.opaqueModels) + for (auto& pipelineEntry : layer.opaqueModels) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto& materialEntry : pipelineEntry.second.materialMap) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = materialEntry.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } } - - /*! - * \brief Functor to compare two batched model with material - * \return true If first material is "smaller" than the second one - * - * \param mat1 First material to compare - * \param mat2 Second material to compare - */ - - bool DeferredRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const - { - const UberShader* uberShader1 = mat1->GetShader(); - const UberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const Shader* shader1 = mat1->GetShaderInstance(ShaderFlags_Deferred)->GetShader(); - const Shader* shader2 = mat2->GetShaderInstance(ShaderFlags_Deferred)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const Texture* diffuseMap1 = mat1->GetDiffuseMap(); - const Texture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; - } - - /*! - * \brief Functor to compare two mesh data - * \return true If first mesh is "smaller" than the second one - * - * \param data1 First mesh to compare - * \param data2 Second mesh to compare - */ - - bool DeferredRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const - { - const Buffer* buffer1; - const Buffer* buffer2; - - buffer1 = (data1.indexBuffer) ? data1.indexBuffer->GetBuffer() : nullptr; - buffer2 = (data2.indexBuffer) ? data2.indexBuffer->GetBuffer() : nullptr; - if (buffer1 != buffer2) - return buffer1 < buffer2; - - buffer1 = data1.vertexBuffer->GetBuffer(); - buffer2 = data2.vertexBuffer->GetBuffer(); - if (buffer1 != buffer2) - return buffer1 < buffer2; - - return data1.primitiveMode < data2.primitiveMode; - } } diff --git a/src/Nazara/Graphics/DepthRenderQueue.cpp b/src/Nazara/Graphics/DepthRenderQueue.cpp index c658fe7bd..fbc24bb19 100644 --- a/src/Nazara/Graphics/DepthRenderQueue.cpp +++ b/src/Nazara/Graphics/DepthRenderQueue.cpp @@ -23,8 +23,8 @@ namespace Nz { // Material m_baseMaterial = Material::New(); - m_baseMaterial->Enable(RendererParameter_ColorWrite, false); - m_baseMaterial->Enable(RendererParameter_FaceCulling, false); + m_baseMaterial->EnableColorWrite(false); + m_baseMaterial->EnableFaceCulling(false); //m_baseMaterial->SetFaceCulling(FaceSide_Front); } diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 233eb9c72..46b1c3407 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -52,6 +52,10 @@ namespace Nz { ErrorFlags flags(ErrorFlag_ThrowException, true); + std::array whitePixel = {255, 255, 255, 255}; + m_whiteTexture.Create(ImageType_2D, PixelFormatType_RGBA8, 1, 1); + m_whiteTexture.Update(whitePixel.data()); + m_vertexBuffer.Create(s_vertexBufferSize, DataStorage_Hardware, BufferUsage_Dynamic); m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); @@ -208,6 +212,8 @@ namespace Nz void DepthRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -215,95 +221,102 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& matIt : layer.basicSprites) + for (auto& pipelinePair : layer.basicSprites) { - const Material* material = matIt.first; - auto& matEntry = matIt.second; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - if (matEntry.enabled) + if (pipelineEntry.enabled) { - auto& overlayMap = matEntry.overlayMap; - for (auto& overlayIt : overlayMap) + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_TextureOverlay | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) { - const Texture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second.spriteChains; + // Index of uniforms in the shader + shaderUniforms = GetShaderUniforms(shader); - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) - { - // We begin to apply the material (and get the shader activated doing so) - UInt32 flags = 0; - if (overlay) - flags |= ShaderFlags_TextureOverlay; + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - UInt8 overlayUnit; - const Shader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) - { - overlayUnit++; - Renderer::SetTexture(overlayUnit, overlay); - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } - - // Uniforms are conserved in our program, there's no point to send them back until they change - if (shader != lastShader) - { - // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); - - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); - - lastShader = shader; - } - - unsigned int spriteChain = 0; // Which chain of sprites are we treating - unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain - - do - { - // We open the buffer in writing mode - 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; - - // Have we treated the entire chain ? - 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(); - } + lastShader = shader; } - // On remet à zéro - matEntry.enabled = false; + for (auto& materialPair : pipelineEntry.materialMap) + { + const Material* material = materialPair.first; + auto& matEntry = materialPair.second; + + if (matEntry.enabled) + { + UInt8 overlayUnit; + material->Apply(pipelineInstance, 0, &overlayUnit); + overlayUnit++; + + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + + Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + + 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) + { + Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + + unsigned int spriteChain = 0; // Which chain of sprites are we treating + unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain + + do + { + // We open the buffer in writing mode + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = static_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; + + // Have we treated the entire chain ? + 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(); + } + } + + // We set it back to zero + matEntry.enabled = false; + } + } + pipelineEntry.enabled = false; } } } @@ -314,9 +327,11 @@ namespace Nz * \param sceneData Data of the scene * \param layer Layer of the rendering */ - + void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; @@ -327,17 +342,16 @@ namespace Nz Renderer::SetVertexBuffer(&s_quadVertexBuffer); - for (auto& matIt : layer.billboards) + for (auto& pipelinePair : layer.billboards) { - const Material* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (pipelineEntry.enabled) { - // We begin to apply the material (and get the shader activated doing so) - const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) @@ -345,27 +359,43 @@ namespace Nz // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } - const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do + for (auto& matIt : pipelinePair.second.materialMap) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // We begin to apply the material (and get the shader activated doing so) + material->Apply(pipelineInstance); - Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); + 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(); + } } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -374,17 +404,16 @@ namespace Nz Renderer::SetIndexBuffer(&s_quadIndexBuffer); Renderer::SetVertexBuffer(&m_billboardPointBuffer); - for (auto& matIt : layer.billboards) + for (auto& pipelinePair : layer.billboards) { - const Material* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (pipelineEntry.enabled) { - // We begin to apply the material (and get the shader activated doing so) - const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) @@ -392,63 +421,73 @@ namespace Nz // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, Renderer::GetMatrix(MatrixType_ViewProj).GetTranslation()); + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } - const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do + for (auto& matIt : pipelinePair.second.materialMap) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount() / 4); - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + unsigned int billboardCount = billboardVector.size(); + do { - const ForwardRenderQueue::BillboardData& billboard = *data++; + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount * 4); + BillboardPoint* vertices = static_cast(vertexMapper.GetPointer()); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; + 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, 0.f); - vertices++; + 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, 0.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); - vertexMapper.Unmap(); - - Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -460,116 +499,131 @@ namespace Nz * \param sceneData Data of the scene * \param layer Layer of the rendering */ - + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : layer.opaqueModels) + for (auto& pipelinePair : layer.opaqueModels) { - auto& matEntry = matIt.second; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - if (matEntry.enabled) + if (pipelineEntry.maxInstanceCount > 0) { - ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + bool instancing = (pipelineEntry.maxInstanceCount > NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply((instancing) ? ShaderFlags_Instancing : 0); - if (!meshInstances.empty()) + const Shader* shader = pipelineInstance.uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) { - const Material* material = matIt.first; + // Index of uniforms in the shader + shaderUniforms = GetShaderUniforms(shader); - bool instancing = m_instancingEnabled && matEntry.instancingEnabled; + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - // We begin to apply the material (and get the shader activated doing so) - UInt8 freeTextureUnit; - const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit); + lastShader = shader; + } - // Uniforms are conserved in our program, there's no point to send them back until they change - if (shader != lastShader) + for (auto& materialPair : pipelineEntry.materialMap) + { + const Material* material = materialPair.first; + auto& matEntry = materialPair.second; + + if (matEntry.enabled) { - // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); - lastShader = shader; - } + UInt8 freeTextureUnit; + material->Apply(pipelineInstance, 0, &freeTextureUnit); - // Meshes - for (auto& meshIt : meshInstances) - { - const MeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; - std::vector& instances = meshEntry.instances; - - if (!instances.empty()) + // Meshes + for (auto& meshIt : meshInstances) { - const IndexBuffer* indexBuffer = meshData.indexBuffer; - const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - // Handle draw call before rendering loop - Renderer::DrawCall drawFunc; - Renderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; - if (indexBuffer) + if (!instances.empty()) { - drawFunc = Renderer::DrawIndexedPrimitives; - instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = Renderer::DrawPrimitives; - instancedDrawFunc = Renderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - Renderer::SetIndexBuffer(indexBuffer); - Renderer::SetVertexBuffer(vertexBuffer); + // Handle draw call before rendering loop + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (instancing) - { - // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) - VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + if (indexBuffer) + { + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); + } - const Matrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // The maximum number of instances in one batch + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); - while (instanceCount > 0) + if (instancing) { // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Maximum number of instance in one batch - // And we draw - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + while (instanceCount > 0) + { + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // We fill the instancing buffer with our world matrices + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // And we draw + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } } - } - else - { - // Without instancing, we must do a draw call for each instance + else + { + // Without instancing, we must do a draw call for each instance // This may be faster than instancing under a certain number // Due to the time to modify the instancing buffer - for (const Matrix4f& matrix : instances) - { - Renderer::SetMatrix(MatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } } + instances.clear(); } - instances.clear(); } + + matEntry.enabled = false; } } - // And we set the data back to zero - matEntry.enabled = false; - matEntry.instancingEnabled = false; + pipelineEntry.maxInstanceCount = 0; } } } diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index b9077e1b9..882a6f61e 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -372,12 +372,11 @@ namespace Nz * * \remark Produces a NazaraAssert if material is invalid */ - void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { NazaraAssert(material, "Invalid material"); - if (material->IsEnabled(RendererParameter_Blend)) + if (material->IsBlendingEnabled()) { Layer& currentLayer = GetLayer(renderOrder); auto& transparentModels = currentLayer.transparentModels; @@ -398,21 +397,33 @@ namespace Nz else { Layer& currentLayer = GetLayer(renderOrder); - auto& opaqueModels = currentLayer.opaqueModels; + MeshPipelineBatches& opaqueModels = currentLayer.opaqueModels; - auto it = opaqueModels.find(material); - if (it == opaqueModels.end()) + const MaterialPipeline* materialPipeline = material->GetPipeline(); + + auto pipelineIt = opaqueModels.find(materialPipeline); + if (pipelineIt == opaqueModels.end()) + { + BatchedMaterialEntry materialEntry; + pipelineIt = opaqueModels.insert(MeshPipelineBatches::value_type(materialPipeline, std::move(materialEntry))).first; + } + + BatchedMaterialEntry& materialEntry = pipelineIt->second; + MeshMaterialBatches& materialMap = materialEntry.materialMap; + + auto materialIt = materialMap.find(material); + if (materialIt == materialMap.end()) { BatchedModelEntry entry; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; + materialIt = materialMap.insert(MeshMaterialBatches::value_type(material, std::move(entry))).first; } - BatchedModelEntry& entry = it->second; + BatchedModelEntry& entry = materialIt->second; entry.enabled = true; - auto& meshMap = entry.meshMap; + MeshInstanceContainer& meshMap = entry.meshMap; auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) @@ -431,9 +442,7 @@ namespace Nz std::vector& instances = it2->second.instances; instances.push_back(transformMatrix); - // Do we have enough instances to perform instancing ? - if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Thus we can activate it + materialEntry.maxInstanceCount = std::max(materialEntry.maxInstanceCount, instances.size()); } } @@ -448,21 +457,34 @@ namespace Nz * * \remark Produces a NazaraAssert if material is invalid */ - void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { NazaraAssert(material, "Invalid material"); Layer& currentLayer = GetLayer(renderOrder); - auto& basicSprites = currentLayer.basicSprites; + SpritePipelineBatches& basicSprites = currentLayer.basicSprites; - auto matIt = basicSprites.find(material); - if (matIt == basicSprites.end()) + const MaterialPipeline* materialPipeline = material->GetPipeline(); + + auto pipelineIt = basicSprites.find(materialPipeline); + if (pipelineIt == basicSprites.end()) + { + BatchedSpritePipelineEntry materialEntry; + pipelineIt = basicSprites.insert(SpritePipelineBatches::value_type(materialPipeline, std::move(materialEntry))).first; + } + + BatchedSpritePipelineEntry& pipelineEntry = pipelineIt->second; + pipelineEntry.enabled = true; + + SpriteMaterialBatches& materialMap = pipelineEntry.materialMap; + + auto matIt = materialMap.find(material); + if (matIt == materialMap.end()) { BatchedBasicSpriteEntry entry; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - matIt = basicSprites.insert(std::make_pair(material, std::move(entry))).first; + matIt = materialMap.insert(SpriteMaterialBatches::value_type(material, std::move(entry))).first; } BatchedBasicSpriteEntry& entry = matIt->second; @@ -541,19 +563,22 @@ namespace Nz return nearPlane.Distance(position1) > nearPlane.Distance(position2); }); - for (auto& pair : layer.billboards) + for (auto& pipelinePair : layer.billboards) { - const Material* mat = pair.first; - - if (mat->IsDepthSortingEnabled()) + for (auto& matPair : pipelinePair.second.materialMap) { - BatchedBillboardEntry& entry = pair.second; - auto& billboardVector = entry.billboards; + const Material* mat = matPair.first; - std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos] (const BillboardData& data1, const BillboardData& data2) + if (mat->IsDepthSortingEnabled()) { - return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); - }); + BatchedBillboardEntry& entry = matPair.second; + auto& billboardVector = entry.billboards; + + std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos] (const BillboardData& data1, const BillboardData& data2) + { + return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); + }); + } } } } @@ -571,13 +596,26 @@ namespace Nz { auto& billboards = GetLayer(renderOrder).billboards; - auto it = billboards.find(material); - if (it == billboards.end()) + const MaterialPipeline* materialPipeline = material->GetPipeline(); + + auto pipelineIt = billboards.find(materialPipeline); + if (pipelineIt == billboards.end()) + { + BatchedBillboardPipelineEntry pipelineEntry; + pipelineIt = billboards.insert(BillboardPipelineBatches::value_type(materialPipeline, std::move(pipelineEntry))).first; + } + BatchedBillboardPipelineEntry& pipelineEntry = pipelineIt->second; + pipelineEntry.enabled = true; + + BatchedBillboardContainer& materialMap = pipelineEntry.materialMap; + + auto it = materialMap.find(material); + if (it == materialMap.end()) { BatchedBillboardEntry entry; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - it = billboards.insert(std::make_pair(material, std::move(entry))).first; + it = materialMap.insert(BatchedBillboardContainer::value_type(material, std::move(entry))).first; } BatchedBillboardEntry& entry = it->second; @@ -620,16 +658,19 @@ namespace Nz { Layer& layer = pair.second; - for (auto& modelPair : layer.opaqueModels) + for (auto& pipelineEntry : layer.opaqueModels) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto& materialEntry : pipelineEntry.second.materialMap) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = materialEntry.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } @@ -647,9 +688,14 @@ namespace Nz { Layer& layer = pair.second; - layer.basicSprites.erase(material); - layer.billboards.erase(material); - layer.opaqueModels.erase(material); + for (auto& pipelineEntry : layer.basicSprites) + pipelineEntry.second.materialMap.erase(material); + + for (auto& pipelineEntry : layer.billboards) + pipelineEntry.second.materialMap.erase(material); + + for (auto& pipelineEntry : layer.opaqueModels) + pipelineEntry.second.materialMap.erase(material); } } @@ -664,10 +710,10 @@ namespace Nz for (auto& pair : layers) { Layer& layer = pair.second; - for (auto matIt = layer.basicSprites.begin(); matIt != layer.basicSprites.end(); ++matIt) + for (auto& pipelineEntry : layer.basicSprites) { - auto& overlayMap = matIt->second.overlayMap; - overlayMap.erase(texture); + for (auto& materialEntry : pipelineEntry.second.materialMap) + materialEntry.second.overlayMap.erase(texture); } } } @@ -683,41 +729,26 @@ namespace Nz for (auto& pair : layers) { Layer& layer = pair.second; - for (auto& modelPair : layer.opaqueModels) + for (auto& pipelineEntry : layer.opaqueModels) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto& materialEntry : pipelineEntry.second.materialMap) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = materialEntry.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } } - /*! - * \brief Functor to compare two batched billboard with material - * \return true If first material is "smaller" than the second one - * - * \param mat1 First material to compare - * \param mat2 Second material to compare - */ - - bool ForwardRenderQueue::BatchedBillboardComparator::operator()(const Material* mat1, const Material* mat2) const + bool ForwardRenderQueue::MaterialComparator::operator()(const Material* mat1, const Material* mat2) const { - const UberShader* uberShader1 = mat1->GetShader(); - const UberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const Shader* shader1 = mat1->GetShaderInstance(ShaderFlags_Billboard | ShaderFlags_VertexColor)->GetShader(); - const Shader* shader2 = mat2->GetShaderInstance(ShaderFlags_Billboard | ShaderFlags_VertexColor)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - const Texture* diffuseMap1 = mat1->GetDiffuseMap(); const Texture* diffuseMap2 = mat2->GetDiffuseMap(); if (diffuseMap1 != diffuseMap2) @@ -726,60 +757,14 @@ namespace Nz return mat1 < mat2; } - /*! - * \brief Functor to compare two batched model with material - * \return true If first material is "smaller" than the second one - * - * \param mat1 First material to compare - * \param mat2 Second material to compare - */ - - bool ForwardRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const + bool ForwardRenderQueue::MaterialPipelineComparator::operator()(const MaterialPipeline* pipeline1, const MaterialPipeline* pipeline2) const { - const UberShader* uberShader1 = mat1->GetShader(); - const UberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const Shader* shader1 = mat1->GetShaderInstance()->GetShader(); - const Shader* shader2 = mat2->GetShaderInstance()->GetShader(); + const Shader* shader1 = pipeline1->GetInstance().renderPipeline.GetInfo().shader; + const Shader* shader2 = pipeline2->GetInstance().renderPipeline.GetInfo().shader; if (shader1 != shader2) return shader1 < shader2; - const Texture* diffuseMap1 = mat1->GetDiffuseMap(); - const Texture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; - } - - /*! - * \brief Functor to compare two batched sprites with material - * \return true If first material is "smaller" than the second one - * - * \param mat1 First material to compare - * \param mat2 Second material to compare - */ - - bool ForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const Material* mat1, const Material* mat2) - { - const UberShader* uberShader1 = mat1->GetShader(); - const UberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const Shader* shader1 = mat1->GetShaderInstance()->GetShader(); - const Shader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const Texture* diffuseMap1 = mat1->GetDiffuseMap(); - const Texture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; + return pipeline1 < pipeline2; } /*! diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 482852347..aad29ab88 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -53,6 +53,10 @@ namespace Nz { ErrorFlags flags(ErrorFlag_ThrowException, true); + std::array whitePixel = {255, 255, 255, 255}; + m_whiteTexture.Create(ImageType_2D, PixelFormatType_RGBA8, 1, 1); + m_whiteTexture.Update(whitePixel.data()); + m_vertexBuffer.Create(s_vertexBufferSize, DataStorage_Hardware, BufferUsage_Dynamic); m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); @@ -297,97 +301,102 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& matIt : layer.basicSprites) + for (auto& pipelinePair : layer.basicSprites) { - const Material* material = matIt.first; - auto& matEntry = matIt.second; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - if (matEntry.enabled) + if (pipelineEntry.enabled) { - auto& overlayMap = matEntry.overlayMap; - for (auto& overlayIt : overlayMap) + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_TextureOverlay | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) { - const Texture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second.spriteChains; + // Index of uniforms in the shader + shaderUniforms = GetShaderUniforms(shader); - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) - { - // We begin to apply the material (and get the shader activated doing so) - UInt32 flags = ShaderFlags_VertexColor; - if (overlay) - flags |= ShaderFlags_TextureOverlay; + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - UInt8 overlayUnit; - const Shader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) - { - overlayUnit++; - Renderer::SetTexture(overlayUnit, overlay); - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } - - // Uniforms are conserved in our program, there's no point to send them back until they change - if (shader != lastShader) - { - // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); - - // Ambiant color of the scene - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - - lastShader = shader; - } - - unsigned int spriteChain = 0; // Which chain of sprites are we treating - unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain - - do - { - // We open the buffer in writing mode - BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); - VertexStruct_XYZ_Color_UV* vertices = static_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; - - // Have we treated the entire chain ? - 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(); - } + lastShader = shader; } - // We set it back to zero - matEntry.enabled = false; + for (auto& materialPair : pipelineEntry.materialMap) + { + const Material* material = materialPair.first; + auto& matEntry = materialPair.second; + + if (matEntry.enabled) + { + UInt8 overlayUnit; + material->Apply(pipelineInstance, 0, &overlayUnit); + overlayUnit++; + + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + + Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + + 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) + { + Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + + unsigned int spriteChain = 0; // Which chain of sprites are we treating + unsigned int spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain + + do + { + // We open the buffer in writing mode + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = static_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; + + // Have we treated the entire chain ? + 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(); + } + } + + // We set it back to zero + matEntry.enabled = false; + } + } + pipelineEntry.enabled = false; } } } @@ -415,17 +424,16 @@ namespace Nz Renderer::SetVertexBuffer(&s_quadVertexBuffer); - for (auto& matIt : layer.billboards) + for (auto& pipelinePair : layer.billboards) { - const Material* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (pipelineEntry.enabled) { - // We begin to apply the material (and get the shader activated doing so) - const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) @@ -441,21 +449,35 @@ namespace Nz lastShader = shader; } - const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do + for (auto& matIt : pipelinePair.second.materialMap) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // We begin to apply the material (and get the shader activated doing so) + material->Apply(pipelineInstance); - Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); + 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(); + } } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -464,17 +486,16 @@ namespace Nz Renderer::SetIndexBuffer(&s_quadIndexBuffer); Renderer::SetVertexBuffer(&m_billboardPointBuffer); - for (auto& matIt : layer.billboards) + for (auto& pipelinePair : layer.billboards) { - const Material* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (pipelineEntry.enabled) { - // We begin to apply the material (and get the shader activated doing so) - const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + + const Shader* shader = pipelineInstance.uberInstance->GetShader(); // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) @@ -490,57 +511,65 @@ namespace Nz lastShader = shader; } - const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount() / 4); - - do + for (auto& matIt : pipelinePair.second.materialMap) { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; - BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount * 4); - BillboardPoint* vertices = static_cast(vertexMapper.GetPointer()); + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount() / 4); - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + unsigned int billboardCount = billboardVector.size(); + do { - const ForwardRenderQueue::BillboardData& billboard = *data++; + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount * 4); + BillboardPoint* vertices = static_cast(vertexMapper.GetPointer()); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; + 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, 0.f); - vertices++; + 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, 0.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); - vertexMapper.Unmap(); - - Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount * 6); + billboardVector.clear(); } - while (billboardCount > 0); - - billboardVector.clear(); } } } @@ -562,158 +591,98 @@ namespace Nz const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : layer.opaqueModels) + for (auto& pipelinePair : layer.opaqueModels) { - auto& matEntry = matIt.second; + const MaterialPipeline* pipeline = pipelinePair.first; + auto& pipelineEntry = pipelinePair.second; - if (matEntry.enabled) + if (pipelineEntry.maxInstanceCount > 0) { - ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + bool instancing = (pipelineEntry.maxInstanceCount > NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT); + const MaterialPipeline::Instance& pipelineInstance = pipeline->Apply((instancing) ? ShaderFlags_Instancing : 0); - if (!meshInstances.empty()) + const Shader* shader = pipelineInstance.uberInstance->GetShader(); + + // Uniforms are conserved in our program, there's no point to send them back until they change + if (shader != lastShader) { - const Material* material = matIt.first; + // Index of uniforms in the shader + shaderUniforms = GetShaderUniforms(shader); - // We only use instancing when no light (other than directional) is active - // This is because instancing is not compatible with the search of nearest lights - // Deferred shading does not have this problem - bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); - bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; + // Ambiant color of the scene + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position of the camera + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - // We begin to apply the material (and get the shader activated doing so) - UInt8 freeTextureUnit; - const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0, 0, &freeTextureUnit); + lastShader = shader; + } - // Uniforms are conserved in our program, there's no point to send them back until they change - if (shader != lastShader) + for (auto& materialPair : pipelineEntry.materialMap) + { + const Material* material = materialPair.first; + auto& matEntry = materialPair.second; + + if (matEntry.enabled) { - // Index of uniforms in the shader - shaderUniforms = GetShaderUniforms(shader); + UInt8 freeTextureUnit; + material->Apply(pipelineInstance, 0, &freeTextureUnit); - // Ambiant color of the scene - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position of the camera - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - 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()) + // Meshes + for (auto& meshIt : meshInstances) { - const IndexBuffer* indexBuffer = meshData.indexBuffer; - const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - // Handle draw call before rendering loop - Renderer::DrawCall drawFunc; - Renderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; - if (indexBuffer) + if (!instances.empty()) { - drawFunc = Renderer::DrawIndexedPrimitives; - instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = Renderer::DrawPrimitives; - instancedDrawFunc = Renderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - Renderer::SetIndexBuffer(indexBuffer); - Renderer::SetVertexBuffer(vertexBuffer); + // Handle draw call before rendering loop + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (instancing) - { - // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) - VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - - // With instancing, impossible to select the lights for each object - // So, it's only activated for directional lights - unsigned int lightCount = m_renderQueue.directionalLights.size(); - unsigned int lightIndex = 0; - RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); - - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; - for (unsigned int pass = 0; pass < passCount; ++pass) + if (indexBuffer) { - if (shaderUniforms->hasLightUniforms) - { - unsigned int renderedLightCount = std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); - lightCount -= renderedLightCount; - - if (pass == 1) - { - // To add the result of light computations - // We won't interfeer with materials parameters because we only render opaques objects - // (A.K.A., without blending) - // About the depth function, it must be applied only the first time - Renderer::Enable(RendererParameter_Blend, true); - Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); - Renderer::SetDepthFunc(RendererComparison_Equal); - } - - // Sends the uniforms - for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i); - - // And we give them to draw - drawFunc(meshData.primitiveMode, 0, indexCount); - } - - const Matrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Maximum number of instance in one batch - - while (instanceCount > 0) - { - // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; - - // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; - - // And we draw - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); - } + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); } - // We don't forget to disable the blending to avoid to interfeer with the rest of the rendering - Renderer::Enable(RendererParameter_Blend, false); - Renderer::SetDepthFunc(oldDepthFunc); - } - else - { - if (shaderUniforms->hasLightUniforms) + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (instancing) { - for (const Matrix4f& matrix : instances) + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + // With instancing, impossible to select the lights for each object + // So, it's only activated for directional lights + unsigned int lightCount = m_renderQueue.directionalLights.size(); + unsigned int lightIndex = 0; + RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); + + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + for (unsigned int pass = 0; pass < passCount; ++pass) { - // Choose the lights depending on an object position and apparent radius - ChooseLights(Spheref(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius)); - - unsigned int lightCount = m_lights.size(); - - Renderer::SetMatrix(MatrixType_World, matrix); - unsigned int lightIndex = 0; - RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // In the case where we have to change it - - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; - for (unsigned int pass = 0; pass < passCount; ++pass) + if (shaderUniforms->hasLightUniforms) { - lightCount -= std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + unsigned int renderedLightCount = std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + lightCount -= renderedLightCount; if (pass == 1) { @@ -726,38 +695,98 @@ namespace Nz Renderer::SetDepthFunc(RendererComparison_Equal); } - // Sends the light uniforms to the shader + // Sends the uniforms for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); - - // And we draw - drawFunc(meshData.primitiveMode, 0, indexCount); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i); } - Renderer::Enable(RendererParameter_Blend, false); - Renderer::SetDepthFunc(oldDepthFunc); + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Maximum number of instance in one batch + + while (instanceCount > 0) + { + // We compute the number of instances that we will be able to draw this time (depending on the instancing buffer size) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // We fill the instancing buffer with our world matrices + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // And we draw + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } } + + // We don't forget to disable the blending to avoid to interferering with the rest of the rendering + Renderer::Enable(RendererParameter_Blend, false); + Renderer::SetDepthFunc(oldDepthFunc); } else { - // Without instancing, we must do a draw call for each instance - // This may be faster than instancing under a certain number - // Due to the time to modify the instancing buffer - for (const Matrix4f& matrix : instances) + if (shaderUniforms->hasLightUniforms) { - Renderer::SetMatrix(MatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + for (const Matrix4f& matrix : instances) + { + // Choose the lights depending on an object position and apparent radius + ChooseLights(Spheref(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius)); + + unsigned int lightCount = m_lights.size(); + + Renderer::SetMatrix(MatrixType_World, matrix); + unsigned int lightIndex = 0; + RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // In the case where we have to change it + + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount - 1) / NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + for (unsigned int pass = 0; pass < passCount; ++pass) + { + lightCount -= std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + + if (pass == 1) + { + // To add the result of light computations + // We won't interfeer with materials parameters because we only render opaques objects + // (A.K.A., without blending) + // About the depth function, it must be applied only the first time + Renderer::Enable(RendererParameter_Blend, true); + Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); + Renderer::SetDepthFunc(RendererComparison_Equal); + } + + // 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, freeTextureUnit + i); + + // And we draw + drawFunc(meshData.primitiveMode, 0, indexCount); + } + + Renderer::Enable(RendererParameter_Blend, false); + Renderer::SetDepthFunc(oldDepthFunc); + } + } + else + { + // Without instancing, we must do a draw call for each instance + // This may be faster than instancing under a certain number + // Due to the time to modify the instancing buffer + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } } } + instances.clear(); } - instances.clear(); } + + matEntry.enabled = false; } } - // And we set the data back to zero - matEntry.enabled = false; - matEntry.instancingEnabled = false; + pipelineEntry.maxInstanceCount = 0; } } } @@ -775,6 +804,8 @@ namespace Nz { NazaraAssert(sceneData.viewer, "Invalid viewer"); + const MaterialPipeline* lastPipeline = nullptr; + const MaterialPipeline::Instance* pipelineInstance = nullptr; const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; unsigned int lightCount = 0; @@ -786,9 +817,16 @@ namespace Nz // Material const Material* material = modelData.material; + const MaterialPipeline* pipeline = material->GetPipeline(); + if (pipeline != lastPipeline) + { + pipelineInstance = &pipeline->Apply(); + lastPipeline = pipeline; + } + // We begin to apply the material (and get the shader activated doing so) UInt8 freeTextureUnit; - const Shader* shader = material->Apply(0, 0, &freeTextureUnit); + const Shader* shader = material->Apply(*pipelineInstance, 0, &freeTextureUnit); // Uniforms are conserved in our program, there's no point to send them back until they change if (shader != lastShader) diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 5e6cd72b7..6e1c3ee5f 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -63,12 +63,20 @@ namespace Nz // Initialisation of the module CallOnExit onExit(Graphics::Uninitialize); + // Materials + if (!MaterialPipeline::Initialize()) + { + NazaraError("Failed to initialize material pipelines"); + return false; + } + if (!Material::Initialize()) { NazaraError("Failed to initialize materials"); return false; } + // Renderables if (!ParticleController::Initialize()) { NazaraError("Failed to initialize particle controllers"); @@ -121,7 +129,7 @@ namespace Nz Loaders::RegisterMesh(); Loaders::RegisterTexture(); - // RenderTechniques + // Render techniques if (!DepthRenderTechnique::Initialize()) { NazaraError("Failed to initialize Depth Rendering"); @@ -213,19 +221,25 @@ namespace Nz Loaders::UnregisterMesh(); Loaders::UnregisterTexture(); - DeferredRenderTechnique::Uninitialize(); - DepthRenderTechnique::Uninitialize(); - ForwardRenderTechnique::Uninitialize(); - SkinningManager::Uninitialize(); + // Renderables ParticleRenderer::Uninitialize(); ParticleGenerator::Uninitialize(); ParticleDeclaration::Uninitialize(); ParticleController::Uninitialize(); - Material::Uninitialize(); SkyboxBackground::Uninitialize(); Sprite::Uninitialize(); TileMap::Uninitialize(); + // Render techniques + DeferredRenderTechnique::Uninitialize(); + DepthRenderTechnique::Uninitialize(); + ForwardRenderTechnique::Uninitialize(); + SkinningManager::Uninitialize(); + + // Materials + Material::Uninitialize(); + MaterialPipeline::Uninitialize(); + NazaraNotice("Uninitialized: Graphics module"); // Free of dependances diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 53e0e3e3e..b81bd82b4 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -2,40 +2,15 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#ifndef NAZARA_RENDERER_OPENGL -#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers -#endif - #include #include -#include #include -#include #include #include #include namespace Nz { - namespace - { - const UInt8 r_basicFragmentShader[] = { - #include - }; - - const UInt8 r_basicVertexShader[] = { - #include - }; - - const UInt8 r_phongLightingFragmentShader[] = { - #include - }; - - const UInt8 r_phongLightingVertexShader[] = { - #include - }; - } - /*! * \ingroup graphics * \class Nz::Material @@ -46,7 +21,6 @@ namespace Nz * \brief Checks whether the parameters for the material are correct * \return true If parameters are valid */ - bool MaterialParams::IsValid() const { if (!UberShaderLibrary::Has(shaderName)) @@ -57,41 +31,35 @@ namespace Nz /*! * \brief Applies shader to the material - * \return Constant pointer to the shader * - * \param shaderFlags Flags for the shader + * \param instance Pipeline instance to update * \param textureUnit Unit for the texture GL_TEXTURE"i" * \param lastUsedUnit Optional argument to get the last texture unit */ - - const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const + void Material::Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit, UInt8* lastUsedUnit) const { - const ShaderInstance& instance = m_shaders[shaderFlags]; - if (!instance.uberInstance) - GenerateShader(shaderFlags); - - instance.uberInstance->Activate(); + const Shader* shader = instance.renderPipeline.GetInfo().shader; if (instance.uniforms[MaterialUniform_AlphaThreshold] != -1) - instance.shader->SendFloat(instance.uniforms[MaterialUniform_AlphaThreshold], m_alphaThreshold); + shader->SendFloat(instance.uniforms[MaterialUniform_AlphaThreshold], m_alphaThreshold); if (instance.uniforms[MaterialUniform_Ambient] != -1) - instance.shader->SendColor(instance.uniforms[MaterialUniform_Ambient], m_ambientColor); + shader->SendColor(instance.uniforms[MaterialUniform_Ambient], m_ambientColor); if (instance.uniforms[MaterialUniform_Diffuse] != -1) - instance.shader->SendColor(instance.uniforms[MaterialUniform_Diffuse], m_diffuseColor); + shader->SendColor(instance.uniforms[MaterialUniform_Diffuse], m_diffuseColor); if (instance.uniforms[MaterialUniform_Shininess] != -1) - instance.shader->SendFloat(instance.uniforms[MaterialUniform_Shininess], m_shininess); + shader->SendFloat(instance.uniforms[MaterialUniform_Shininess], m_shininess); if (instance.uniforms[MaterialUniform_Specular] != -1) - instance.shader->SendColor(instance.uniforms[MaterialUniform_Specular], m_specularColor); + shader->SendColor(instance.uniforms[MaterialUniform_Specular], m_specularColor); if (m_alphaMap && instance.uniforms[MaterialUniform_AlphaMap] != -1) { Renderer::SetTexture(textureUnit, m_alphaMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], textureUnit); textureUnit++; } @@ -99,7 +67,7 @@ namespace Nz { Renderer::SetTexture(textureUnit, m_diffuseMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], textureUnit); textureUnit++; } @@ -107,7 +75,7 @@ namespace Nz { Renderer::SetTexture(textureUnit, m_emissiveMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], textureUnit); textureUnit++; } @@ -115,7 +83,7 @@ namespace Nz { Renderer::SetTexture(textureUnit, m_heightMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], textureUnit); textureUnit++; } @@ -123,7 +91,7 @@ namespace Nz { Renderer::SetTexture(textureUnit, m_normalMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], textureUnit); textureUnit++; } @@ -131,25 +99,20 @@ namespace Nz { Renderer::SetTexture(textureUnit, m_specularMap); Renderer::SetTextureSampler(textureUnit, m_specularSampler); - instance.shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], textureUnit); + shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], textureUnit); textureUnit++; } - Renderer::SetRenderStates(m_states); - if (lastUsedUnit) *lastUsedUnit = textureUnit; - - return instance.shader; } /*! - * \brief Builds the material from parameters + * \brief Builds the material from a parameter list * * \param matData Data information for the material - * \param matParams Parameters for the material + * \param matParams Additional parameters for the material */ - void Material::BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams) { Color color; @@ -160,7 +123,6 @@ namespace Nz ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled, true); - if (matData.GetFloatParameter(MaterialData::AlphaThreshold, &fValue)) SetAlphaThreshold(fValue); @@ -188,14 +150,11 @@ namespace Nz if (matData.GetIntegerParameter(MaterialData::FaceFilling, &iValue)) SetFaceFilling(static_cast(iValue)); - if (matData.GetBooleanParameter(MaterialData::Lighting, &isEnabled)) - EnableLighting(isEnabled); - if (matData.GetFloatParameter(MaterialData::LineWidth, &fValue)) - m_states.lineWidth = fValue; + SetLineWidth(fValue); if (matData.GetFloatParameter(MaterialData::PointSize, &fValue)) - m_states.pointSize = fValue; + SetPointSize(fValue); if (matData.GetColorParameter(MaterialData::SpecularColor, &color)) SetSpecularColor(color); @@ -206,30 +165,27 @@ namespace Nz if (matData.GetIntegerParameter(MaterialData::SrcBlend, &iValue)) SetSrcBlend(static_cast(iValue)); - if (matData.GetBooleanParameter(MaterialData::Transform, &isEnabled)) - EnableTransform(isEnabled); - // RendererParameter if (matData.GetBooleanParameter(MaterialData::Blending, &isEnabled)) - Enable(RendererParameter_Blend, isEnabled); + EnableBlending(isEnabled); if (matData.GetBooleanParameter(MaterialData::ColorWrite, &isEnabled)) - Enable(RendererParameter_ColorWrite, isEnabled); + EnableColorWrite(isEnabled); if (matData.GetBooleanParameter(MaterialData::DepthBuffer, &isEnabled)) - Enable(RendererParameter_DepthBuffer, isEnabled); + EnableDepthBuffer(isEnabled); if (matData.GetBooleanParameter(MaterialData::DepthWrite, &isEnabled)) - Enable(RendererParameter_DepthWrite, isEnabled); + EnableDepthWrite(isEnabled); if (matData.GetBooleanParameter(MaterialData::FaceCulling, &isEnabled)) - Enable(RendererParameter_FaceCulling, isEnabled); + EnableFaceCulling(isEnabled); if (matData.GetBooleanParameter(MaterialData::ScissorTest, &isEnabled)) - Enable(RendererParameter_ScissorTest, isEnabled); + EnableScissorTest(isEnabled); if (matData.GetBooleanParameter(MaterialData::StencilTest, &isEnabled)) - Enable(RendererParameter_StencilTest, isEnabled); + EnableStencilTest(isEnabled); // Samplers if (matData.GetIntegerParameter(MaterialData::DiffuseAnisotropyLevel, &iValue)) @@ -252,41 +208,43 @@ namespace Nz // Stencil if (matData.GetIntegerParameter(MaterialData::StencilCompare, &iValue)) - m_states.stencilCompare.front = static_cast(iValue); + m_pipelineInfo.stencilCompare.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilFail, &iValue)) - m_states.stencilFail.front = static_cast(iValue); + m_pipelineInfo.stencilFail.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilPass, &iValue)) - m_states.stencilPass.front = static_cast(iValue); + m_pipelineInfo.stencilPass.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilZFail, &iValue)) - m_states.stencilDepthFail.front = static_cast(iValue); + m_pipelineInfo.stencilDepthFail.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilMask, &iValue)) - m_states.stencilWriteMask.front = static_cast(iValue); + m_pipelineInfo.stencilWriteMask.front = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::StencilReference, &iValue)) - m_states.stencilReference.front = static_cast(iValue); + m_pipelineInfo.stencilReference.front = static_cast(iValue); // Stencil (back) if (matData.GetIntegerParameter(MaterialData::BackFaceStencilCompare, &iValue)) - m_states.stencilCompare.back = static_cast(iValue); + m_pipelineInfo.stencilCompare.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilFail, &iValue)) - m_states.stencilFail.back = static_cast(iValue); + m_pipelineInfo.stencilFail.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilPass, &iValue)) - m_states.stencilPass.back = static_cast(iValue); + m_pipelineInfo.stencilPass.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilZFail, &iValue)) - m_states.stencilDepthFail.back = static_cast(iValue); + m_pipelineInfo.stencilDepthFail.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilMask, &iValue)) - m_states.stencilWriteMask.back = static_cast(iValue); + m_pipelineInfo.stencilWriteMask.back = static_cast(iValue); if (matData.GetIntegerParameter(MaterialData::BackFaceStencilReference, &iValue)) - m_states.stencilReference.back = static_cast(iValue); + m_pipelineInfo.stencilReference.back = static_cast(iValue); + + InvalidatePipeline(); // Textures if (matParams.loadAlphaMap && matData.GetStringParameter(MaterialData::AlphaTexturePath, &path)) @@ -310,6 +268,11 @@ namespace Nz SetShader(matParams.shaderName); } + /*! + * \brief Builds a ParameterList with material data + * + * \param matData Destination parameter list which will receive material data + */ void Material::SaveToParameters(ParameterList* matData) { NazaraAssert(matData, "Invalid ParameterList"); @@ -323,22 +286,20 @@ namespace Nz matData->SetParameter(MaterialData::DiffuseColor, GetDiffuseColor()); matData->SetParameter(MaterialData::DstBlend, int(GetDstBlend())); matData->SetParameter(MaterialData::FaceFilling, int(GetFaceFilling())); - matData->SetParameter(MaterialData::Lighting, IsLightingEnabled()); - matData->SetParameter(MaterialData::LineWidth, GetRenderStates().lineWidth); - matData->SetParameter(MaterialData::PointSize, GetRenderStates().pointSize); + matData->SetParameter(MaterialData::LineWidth, GetLineWidth()); + matData->SetParameter(MaterialData::PointSize, GetPointSize()); matData->SetParameter(MaterialData::Shininess, GetShininess()); matData->SetParameter(MaterialData::SpecularColor, GetSpecularColor()); matData->SetParameter(MaterialData::SrcBlend, int(GetSrcBlend())); - matData->SetParameter(MaterialData::Transform, IsTransformEnabled()); // RendererParameter - matData->SetParameter(MaterialData::Blending, GetRenderStates().blending); - matData->SetParameter(MaterialData::ColorWrite, GetRenderStates().colorWrite); - matData->SetParameter(MaterialData::DepthBuffer, GetRenderStates().depthBuffer); - matData->SetParameter(MaterialData::DepthWrite, GetRenderStates().depthWrite); - matData->SetParameter(MaterialData::FaceCulling, GetRenderStates().faceCulling); - matData->SetParameter(MaterialData::ScissorTest, GetRenderStates().scissorTest); - matData->SetParameter(MaterialData::StencilTest, GetRenderStates().stencilTest); + matData->SetParameter(MaterialData::Blending, IsBlendingEnabled()); + matData->SetParameter(MaterialData::ColorWrite, IsColorWriteEnabled()); + matData->SetParameter(MaterialData::DepthBuffer, IsDepthBufferEnabled()); + matData->SetParameter(MaterialData::DepthWrite, IsDepthWriteEnabled()); + matData->SetParameter(MaterialData::FaceCulling, IsFaceCullingEnabled()); + matData->SetParameter(MaterialData::ScissorTest, IsScissorTestEnabled()); + matData->SetParameter(MaterialData::StencilTest, IsStencilTestEnabled()); // Samplers matData->SetParameter(MaterialData::DiffuseAnisotropyLevel, int(GetDiffuseSampler().GetAnisotropicLevel())); @@ -350,20 +311,20 @@ namespace Nz matData->SetParameter(MaterialData::SpecularWrap, int(GetSpecularSampler().GetWrapMode())); // Stencil - matData->SetParameter(MaterialData::StencilCompare, int(GetRenderStates().stencilCompare.front)); - matData->SetParameter(MaterialData::StencilFail, int(GetRenderStates().stencilFail.front)); - matData->SetParameter(MaterialData::StencilPass, int(GetRenderStates().stencilPass.front)); - matData->SetParameter(MaterialData::StencilZFail, int(GetRenderStates().stencilDepthFail.front)); - matData->SetParameter(MaterialData::StencilMask, int(GetRenderStates().stencilWriteMask.front)); - matData->SetParameter(MaterialData::StencilReference, int(GetRenderStates().stencilReference.front)); + matData->SetParameter(MaterialData::StencilCompare, int(GetPipelineInfo().stencilCompare.front)); + matData->SetParameter(MaterialData::StencilFail, int(GetPipelineInfo().stencilFail.front)); + matData->SetParameter(MaterialData::StencilPass, int(GetPipelineInfo().stencilPass.front)); + matData->SetParameter(MaterialData::StencilZFail, int(GetPipelineInfo().stencilDepthFail.front)); + matData->SetParameter(MaterialData::StencilMask, int(GetPipelineInfo().stencilWriteMask.front)); + matData->SetParameter(MaterialData::StencilReference, int(GetPipelineInfo().stencilReference.front)); // Stencil (back) - matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetRenderStates().stencilCompare.back)); - matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetRenderStates().stencilFail.back)); - matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetRenderStates().stencilPass.back)); - matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetRenderStates().stencilDepthFail.back)); - matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetRenderStates().stencilWriteMask.back)); - matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetRenderStates().stencilReference.back)); + matData->SetParameter(MaterialData::BackFaceStencilCompare, int(GetPipelineInfo().stencilCompare.back)); + matData->SetParameter(MaterialData::BackFaceStencilFail, int(GetPipelineInfo().stencilFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilPass, int(GetPipelineInfo().stencilPass.back)); + matData->SetParameter(MaterialData::BackFaceStencilZFail, int(GetPipelineInfo().stencilDepthFail.back)); + matData->SetParameter(MaterialData::BackFaceStencilMask, int(GetPipelineInfo().stencilWriteMask.back)); + matData->SetParameter(MaterialData::BackFaceStencilReference, int(GetPipelineInfo().stencilReference.back)); // Textures if (HasAlphaMap()) @@ -411,6 +372,8 @@ namespace Nz /*! * \brief Resets the material, cleans everything + * + * \remark Invalidates the pipeline */ void Material::Reset() { @@ -423,29 +386,22 @@ namespace Nz m_heightMap.Reset(); m_normalMap.Reset(); m_specularMap.Reset(); - m_uberShader.Reset(); - - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; m_alphaThreshold = 0.2f; - m_alphaTestEnabled = false; m_ambientColor = Color(128, 128, 128); - m_depthSortingEnabled = false; 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(); - m_states = RenderStates(); - m_states.depthBuffer = true; - m_states.faceCulling = true; - m_transformEnabled = true; + m_pipelineInfo = MaterialPipelineInfo(); + m_pipelineInfo.depthBuffer = true; + m_pipelineInfo.faceCulling = true; SetShader("Basic"); + + InvalidatePipeline(); } /*! @@ -453,24 +409,18 @@ namespace Nz * * \param material Material to copy into this */ - void Material::Copy(const Material& material) { // Copy of base states - 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_pipelineInfo = material.m_pipelineInfo; 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; // Copy of reference to the textures m_alphaMap = material.m_alphaMap; @@ -480,61 +430,8 @@ namespace Nz m_heightMap = material.m_heightMap; m_normalMap = material.m_normalMap; m_specularMap = material.m_specularMap; - m_uberShader = material.m_uberShader; - // We copy the instances of the shader too - std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max + 1) * sizeof(ShaderInstance)); - } - - /*! - * \brief Generates the shader based on flag - * - * \param flags Flag for the shaer - */ - - void Material::GenerateShader(UInt32 flags) const - { - ParameterList list; - list.SetParameter("ALPHA_MAPPING", m_alphaMap.IsValid()); - list.SetParameter("ALPHA_TEST", m_alphaTestEnabled); - list.SetParameter("COMPUTE_TBNMATRIX", m_normalMap.IsValid() || m_heightMap.IsValid()); - list.SetParameter("DIFFUSE_MAPPING", m_diffuseMap.IsValid()); - list.SetParameter("EMISSIVE_MAPPING", m_emissiveMap.IsValid()); - 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() || - flags & ShaderFlags_TextureOverlay); - list.SetParameter("TRANSFORM", m_transformEnabled); - - list.SetParameter("FLAG_BILLBOARD", static_cast((flags & ShaderFlags_Billboard) != 0)); - list.SetParameter("FLAG_DEFERRED", static_cast((flags & ShaderFlags_Deferred) != 0)); - list.SetParameter("FLAG_INSTANCING", static_cast((flags & ShaderFlags_Instancing) != 0)); - list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & ShaderFlags_TextureOverlay) != 0)); - list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & ShaderFlags_VertexColor) != 0)); - - ShaderInstance& instance = m_shaders[flags]; - instance.uberInstance = m_uberShader->Get(list); - instance.shader = instance.uberInstance->GetShader(); - - #define CacheUniform(name) instance.uniforms[MaterialUniform_##name] = instance.shader->GetUniformLocation("Material" #name) - - CacheUniform(AlphaMap); - CacheUniform(AlphaThreshold); - CacheUniform(Ambient); - CacheUniform(Diffuse); - CacheUniform(DiffuseMap); - CacheUniform(EmissiveMap); - CacheUniform(HeightMap); - CacheUniform(NormalMap); - CacheUniform(Shininess); - CacheUniform(Specular); - CacheUniform(SpecularMap); - - #undef CacheUniform + InvalidatePipeline(); } /*! @@ -543,7 +440,6 @@ namespace Nz * * \remark Produces a NazaraError if the material library failed to be initialized */ - bool Material::Initialize() { if (!MaterialLibrary::Initialize()) @@ -558,67 +454,21 @@ namespace Nz return false; } - // Basic shader - { - UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); - - String fragmentShader(reinterpret_cast(r_basicFragmentShader), sizeof(r_basicFragmentShader)); - String vertexShader(reinterpret_cast(r_basicVertexShader), sizeof(r_basicVertexShader)); - - uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); - uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); - - UberShaderLibrary::Register("Basic", uberShader); - } - - // PhongLighting shader - { - UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); - - 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 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); - } - - // Once the base shaders are registered, we can now set some default materials s_defaultMaterial = New(); - s_defaultMaterial->Enable(RendererParameter_FaceCulling, false); + s_defaultMaterial->EnableFaceCulling(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; } /*! * \brief Uninitializes the material librairies */ - void Material::Uninitialize() { s_defaultMaterial.Reset(); - UberShaderLibrary::Unregister("PhongLighting"); - UberShaderLibrary::Unregister("Basic"); + MaterialManager::Uninitialize(); MaterialLibrary::Uninitialize(); } diff --git a/src/Nazara/Graphics/MaterialPipeline.cpp b/src/Nazara/Graphics/MaterialPipeline.cpp new file mode 100644 index 000000000..01e9ffe5d --- /dev/null +++ b/src/Nazara/Graphics/MaterialPipeline.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2016 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 + +#ifndef NAZARA_RENDERER_OPENGL +#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers +#endif + +#include +#include +#include + +namespace Nz +{ + namespace + { + const UInt8 r_basicFragmentShader[] = { + #include + }; + + const UInt8 r_basicVertexShader[] = { + #include + }; + + const UInt8 r_phongLightingFragmentShader[] = { + #include + }; + + const UInt8 r_phongLightingVertexShader[] = { + #include + }; + } + + /*! + * \ingroup graphics + * \class Nz::MaterialPipeline + * + * \brief Graphics class used to contains all rendering states that are not allowed to change individually on rendering devices + */ + + /*! + * \brief Returns a reference to a MaterialPipeline built with MaterialPipelineInfo + * + * This function is using a cache, calling it multiples times with the same MaterialPipelineInfo will returns references to a single MaterialPipeline + * + * \param pipelineInfo Pipeline informations used to build/retrieve a MaterialPipeline object + */ + MaterialPipelineRef MaterialPipeline::GetPipeline(const MaterialPipelineInfo& pipelineInfo) + { + auto it = s_pipelineCache.lower_bound(pipelineInfo); + if (it == s_pipelineCache.end() || it->first != pipelineInfo) + it = s_pipelineCache.insert(it, PipelineCache::value_type(pipelineInfo, New(pipelineInfo))); + + return it->second; + } + + void MaterialPipeline::GenerateRenderPipeline(UInt32 flags) const + { + ParameterList list; + list.SetParameter("ALPHA_MAPPING", m_pipelineInfo.hasAlphaMap); + list.SetParameter("ALPHA_TEST", m_pipelineInfo.alphaTest); + list.SetParameter("COMPUTE_TBNMATRIX", m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap); + list.SetParameter("DIFFUSE_MAPPING", m_pipelineInfo.hasDiffuseMap); + list.SetParameter("EMISSIVE_MAPPING", m_pipelineInfo.hasEmissiveMap); + list.SetParameter("NORMAL_MAPPING", m_pipelineInfo.hasNormalMap); + list.SetParameter("PARALLAX_MAPPING", m_pipelineInfo.hasHeightMap); + list.SetParameter("SHADOW_MAPPING", m_pipelineInfo.shadowReceive); + list.SetParameter("SPECULAR_MAPPING", m_pipelineInfo.hasSpecularMap); + list.SetParameter("TEXTURE_MAPPING", m_pipelineInfo.hasAlphaMap || m_pipelineInfo.hasDiffuseMap || m_pipelineInfo.hasEmissiveMap || + m_pipelineInfo.hasNormalMap || m_pipelineInfo.hasHeightMap || m_pipelineInfo.hasSpecularMap || + flags & ShaderFlags_TextureOverlay); + list.SetParameter("TRANSFORM", true); + + list.SetParameter("FLAG_BILLBOARD", static_cast((flags & ShaderFlags_Billboard) != 0)); + list.SetParameter("FLAG_DEFERRED", static_cast((flags & ShaderFlags_Deferred) != 0)); + list.SetParameter("FLAG_INSTANCING", static_cast((flags & ShaderFlags_Instancing) != 0)); + list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & ShaderFlags_TextureOverlay) != 0)); + list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & ShaderFlags_VertexColor) != 0)); + + Instance& instance = m_instances[flags]; + instance.uberInstance = m_pipelineInfo.uberShader->Get(list); + + RenderPipelineInfo renderPipelineInfo; + static_cast(renderPipelineInfo).operator=(m_pipelineInfo); // Not my proudest line + + renderPipelineInfo.shader = instance.uberInstance->GetShader(); + + instance.renderPipeline.Create(renderPipelineInfo); + + #define CacheUniform(name) instance.uniforms[MaterialUniform_##name] = renderPipelineInfo.shader->GetUniformLocation("Material" #name) + + CacheUniform(AlphaMap); + CacheUniform(AlphaThreshold); + CacheUniform(Ambient); + CacheUniform(Diffuse); + CacheUniform(DiffuseMap); + CacheUniform(EmissiveMap); + CacheUniform(HeightMap); + CacheUniform(NormalMap); + CacheUniform(Shininess); + CacheUniform(Specular); + CacheUniform(SpecularMap); + + #undef CacheUniform + } + + bool MaterialPipeline::Initialize() + { + // Basic shader + { + UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); + + String fragmentShader(reinterpret_cast(r_basicFragmentShader), sizeof(r_basicFragmentShader)); + String vertexShader(reinterpret_cast(r_basicVertexShader), sizeof(r_basicVertexShader)); + + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); + uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + + UberShaderLibrary::Register("Basic", uberShader); + } + + // PhongLighting shader + { + UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); + + 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 NORMAL_MAPPING PARALLAX_MAPPING SHADOW_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX PARALLAX_MAPPING SHADOW_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + + UberShaderLibrary::Register("PhongLighting", uberShader); + } + + // Once the base shaders are registered, we can now set some default materials + MaterialPipelineInfo pipelineInfo; + + // Basic 2D - No depth write/face culling + pipelineInfo.depthWrite = false; + pipelineInfo.faceCulling = false; + + MaterialPipelineLibrary::Register("Basic2D", GetPipeline(pipelineInfo)); + + // Translucent 2D - Alpha blending with no depth write/face culling + pipelineInfo.blending = false; + pipelineInfo.depthWrite = false; + pipelineInfo.faceCulling = false; + pipelineInfo.dstBlend = BlendFunc_InvSrcAlpha; + pipelineInfo.srcBlend = BlendFunc_SrcAlpha; + + MaterialPipelineLibrary::Register("Translucent2D", GetPipeline(pipelineInfo)); + + return true; + } + + void MaterialPipeline::Uninitialize() + { + s_pipelineCache.clear(); + UberShaderLibrary::Unregister("PhongLighting"); + UberShaderLibrary::Unregister("Basic"); + MaterialPipelineLibrary::Uninitialize(); + } + + MaterialPipelineLibrary::LibraryMap MaterialPipeline::s_library; + MaterialPipeline::PipelineCache MaterialPipeline::s_pipelineCache; +} \ 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 61ed69632..a3391be91 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -132,7 +132,7 @@ void main() vec2 texCoord = vTexCoord; #endif -#if LIGHTING && PARALLAX_MAPPING +#if PARALLAX_MAPPING float height = texture(MaterialHeightMap, texCoord).r; float v = height*ParallaxScale + ParallaxBias; @@ -159,17 +159,16 @@ void main() discard; #endif // ALPHA_TEST - #if LIGHTING - #if NORMAL_MAPPING + #if NORMAL_MAPPING vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); - #else + #else vec3 normal = normalize(vNormal); - #endif // NORMAL_MAPPING + #endif // NORMAL_MAPPING vec3 specularColor = MaterialSpecular.rgb; - #if SPECULAR_MAPPING + #if SPECULAR_MAPPING specularColor *= texture(MaterialSpecularMap, texCoord).rgb; - #endif + #endif /* Texture0: Diffuse Color + Specular @@ -179,9 +178,6 @@ void main() RenderTarget0 = vec4(diffuseColor.rgb, dot(specularColor, vec3(0.3, 0.59, 0.11))); RenderTarget1 = vec4(EncodeNormal(normal)); RenderTarget2 = vec4(FloatToColor(gl_FragCoord.z), (MaterialShininess == 0.0) ? 0.0 : max(log2(MaterialShininess), 0.1)/10.5); // http://www.guerrilla-games.com/publications/dr_kz2_rsx_dev07.pdf - #else // LIGHTING - RenderTarget0 = vec4(diffuseColor.rgb, 0.0); - #endif #else // FLAG_DEFERRED #if ALPHA_MAPPING diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; @@ -192,16 +188,15 @@ void main() discard; #endif - #if LIGHTING vec3 lightAmbient = vec3(0.0); vec3 lightDiffuse = vec3(0.0); vec3 lightSpecular = vec3(0.0); - #if NORMAL_MAPPING + #if NORMAL_MAPPING vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); - #else + #else vec3 normal = normalize(vNormal); - #endif + #endif if (MaterialShininess > 0.0) { @@ -459,24 +454,21 @@ void main() } lightSpecular *= MaterialSpecular.rgb; - #if SPECULAR_MAPPING + #if SPECULAR_MAPPING lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens - #endif + #endif vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); vec4 fragmentColor = vec4(lightColor, 1.0) * diffuseColor; - #if EMISSIVE_MAPPING + #if EMISSIVE_MAPPING float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11)); vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, texCoord).rgb; RenderTarget0 = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a); - #else - RenderTarget0 = fragmentColor; - #endif // EMISSIVE_MAPPING #else - RenderTarget0 = diffuseColor; - #endif // LIGHTING + RenderTarget0 = fragmentColor; + #endif // EMISSIVE_MAPPING #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 6f1495308..c77a33db2 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,118,101,99,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,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,9,98,111,111,108,32,115,104,97,100,111,119,77,97,112,112,105,110,103,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,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,13,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,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,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,13,10,123,13,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,13,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,13,10,13,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,13,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,13,10,125,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,123,13,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,13,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,13,10,125,13,10,13,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,13,10,123,13,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,13,10,125,13,10,13,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,13,10,123,13,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,13,10,13,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,13,10,9,102,108,111,97,116,32,120,44,121,59,13,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,13,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,13,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,13,10,13,10,9,118,105,115,105,98,105,108,105,116,121,32,47,61,32,54,52,46,48,59,13,10,9,13,10,9,114,101,116,117,114,110,32,118,105,115,105,98,105,108,105,116,121,59,13,10,125,13,10,35,101,110,100,105,102,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,108,105,103,104,116,67,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,108,105,103,104,116,67,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,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,13,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,13,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,13,10,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,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,13,10,13,10,9,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,49,46,48,59,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,13,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,13,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,13,10,9,9,9,9,9,13,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,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,119,111,114,108,100,84,111,76,105,103,104,116,41,59,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,50,46,120,121,122,59,13,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,13,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,13,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,13,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,13,10,13,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,13,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,13,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,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,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,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,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,13,10,13,10,9,9,9,9,9,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,10,9,9,9,9,9,123,13,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,13,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,13,10,9,9,9,9,9,9,9,98,114,101,97,107,59,13,10,9,9,9,9,9,9,9,13,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,13,10,9,9,9,9,9,125,13,10,9,9,9,9,9,35,101,110,100,105,102,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,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,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,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,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,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,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,119,111,114,108,100,84,111,76,105,103,104,116,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,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,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,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,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,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,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,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,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,35,101,110,100,105,102,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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 0f4c869a6..8943c5935 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -12,6 +12,7 @@ in vec3 VertexPosition; in vec3 VertexNormal; in vec3 VertexTangent; in vec2 VertexTexCoord; +in vec4 VertexUserdata0; /********************Sortant********************/ out vec4 vColor; @@ -27,6 +28,7 @@ uniform vec3 EyePosition; uniform mat4 InvViewMatrix; uniform mat4 LightViewProjMatrix[3]; uniform float VertexDepth; +uniform mat4 ViewMatrix; uniform mat4 ViewProjMatrix; uniform mat4 WorldMatrix; uniform mat4 WorldViewProjMatrix; @@ -107,21 +109,19 @@ void main() vColor = color; -#if LIGHTING - #if FLAG_INSTANCING +#if FLAG_INSTANCING mat3 rotationMatrix = mat3(InstanceData0); - #else +#else mat3 rotationMatrix = mat3(WorldMatrix); - #endif +#endif - #if COMPUTE_TBNMATRIX +#if COMPUTE_TBNMATRIX vec3 binormal = cross(VertexNormal, VertexTangent); vLightToWorld[0] = normalize(rotationMatrix * VertexTangent); vLightToWorld[1] = normalize(rotationMatrix * binormal); vLightToWorld[2] = normalize(rotationMatrix * VertexNormal); - #else +#else vNormal = normalize(rotationMatrix * VertexNormal); - #endif #endif #if SHADOW_MAPPING @@ -133,12 +133,12 @@ void main() vTexCoord = VertexTexCoord; #endif -#if LIGHTING && PARALLAX_MAPPING +#if PARALLAX_MAPPING vViewDir = EyePosition - VertexPosition; vViewDir *= vLightToWorld; #endif -#if LIGHTING && !FLAG_DEFERRED +#if !FLAG_DEFERRED #if FLAG_INSTANCING vWorldPos = vec3(InstanceData0 * vec4(VertexPosition, 1.0)); #else diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index c1611105a..bed6edcab 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,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,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,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,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,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,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,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,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,109,97,116,52,32,73,110,118,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,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,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,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,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,13,10,35,105,102,32,76,73,71,72,84,73,78,71,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,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,13,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,13,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,13,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,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,13,10,35,101,110,100,105,102,13,10,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,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,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,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,13,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,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,33,70,76,65,71,95,68,69,70,69,82,82,69,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,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,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,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,105,110,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,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,52,32,118,76,105,103,104,116,83,112,97,99,101,80,111,115,91,51,93,59,13,10,111,117,116,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,111,117,116,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,111,117,116,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,51,32,118,86,105,101,119,68,105,114,59,13,10,111,117,116,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,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,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,109,97,116,52,32,73,110,118,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,76,105,103,104,116,86,105,101,119,80,114,111,106,77,97,116,114,105,120,91,51,93,59,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,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,13,10,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,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,13,10,35,101,108,115,101,13,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,13,10,35,101,110,100,105,102,13,10,9,13,10,35,105,102,32,67,79,77,80,85,84,69,95,84,66,78,77,65,84,82,73,88,13,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,13,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,13,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,13,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,13,10,35,101,108,115,101,13,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,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,83,72,65,68,79,87,95,77,65,80,80,73,78,71,13,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,13,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,13,10,35,101,110,100,105,102,13,10,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,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,35,105,102,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,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,13,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,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,33,70,76,65,71,95,68,69,70,69,82,82,69,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,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,13,10,9,35,101,108,115,101,13,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,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file From dda41dbd8aa8c62600554ebc698748ddc2a424c9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 5 Aug 2016 22:58:14 +0200 Subject: [PATCH 219/224] Graphics: Fix build Former-commit-id: f9ff831dc3b5f09e829a949ff213020998a4fd82 [formerly 64dd5b86643363bc6a07d36c666d7f8172e21535] [formerly 288bc4600c43227953960f0ad59633aaa01fa598 [formerly f6a908db55d46775566395b11f719a05a1e9e7e2]] Former-commit-id: 6cf4ad619557497865bee10757bf41eeeddc73e0 [formerly 19c535c963d5240de50733b1593fb201171f0c93] Former-commit-id: fb64e1f4f1dfdd34d6431ec99f7a78a2c33e53ed --- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index aad29ab88..91507ee68 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -824,11 +824,12 @@ namespace Nz lastPipeline = pipeline; } - // We begin to apply the material (and get the shader activated doing so) + // We begin to apply the material UInt8 freeTextureUnit; - const Shader* shader = material->Apply(*pipelineInstance, 0, &freeTextureUnit); + material->Apply(*pipelineInstance, 0, &freeTextureUnit); // Uniforms are conserved in our program, there's no point to send them back until they change + const Shader* shader = pipelineInstance->uberInstance->GetShader(); if (shader != lastShader) { // Index of uniforms in the shader From 218dfc9bb1edc113cc127952d393793ba8966422 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Aug 2016 01:07:09 +0200 Subject: [PATCH 220/224] Graphics/ParticleGroup: Emitters are now updated in case of move and removed in case of release Former-commit-id: 2aeee76d912fe28845cf3654374a70f6035f115b [formerly e5bc7e35688b44ed78e6b76cd2a448ec0f1bb89e] [formerly e2924ddad7955a7b4aa0b11932a4019bddfdf19e [formerly 30651b18c45b8da9bcfda621a6b21d42520e85a1]] Former-commit-id: 205e52c5da9e9da01a48285f71f9b9dc7603f29b [formerly a4040aaacf0c0eb7625ab739123116e18a4a07a8] Former-commit-id: abb37a852646924793a2cfd00b74a05c00479cb3 --- include/Nazara/Graphics/ParticleEmitter.hpp | 4 +- include/Nazara/Graphics/ParticleGroup.hpp | 12 +++++- src/Nazara/Graphics/ParticleEmitter.cpp | 8 ++++ src/Nazara/Graphics/ParticleGroup.cpp | 42 ++++++++++++++++++--- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index b7a168262..8bd26a4bd 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -20,7 +20,7 @@ namespace Nz { public: ParticleEmitter(); - ParticleEmitter(const ParticleEmitter& emitter) = default; + ParticleEmitter(const ParticleEmitter& emitter); ParticleEmitter(ParticleEmitter&& emitter); virtual ~ParticleEmitter(); @@ -40,7 +40,7 @@ namespace Nz ParticleEmitter& operator=(ParticleEmitter&& emitter); // Signals: - NazaraSignal(OnParticleEmitterMove, const ParticleEmitter* /*oldParticleEmitter*/, const ParticleEmitter* /*newParticleEmitter*/); + NazaraSignal(OnParticleEmitterMove, ParticleEmitter* /*oldParticleEmitter*/, ParticleEmitter* /*newParticleEmitter*/); NazaraSignal(OnParticleEmitterRelease, const ParticleEmitter* /*particleEmitter*/); private: diff --git a/include/Nazara/Graphics/ParticleGroup.hpp b/include/Nazara/Graphics/ParticleGroup.hpp index 4d4704171..9e48d5797 100644 --- a/include/Nazara/Graphics/ParticleGroup.hpp +++ b/include/Nazara/Graphics/ParticleGroup.hpp @@ -68,12 +68,22 @@ namespace Nz private: void MakeBoundingVolume() const override; + void OnEmitterMove(ParticleEmitter* oldEmitter, ParticleEmitter* newEmitter); + void OnEmitterRelease(const ParticleEmitter* emitter); void ResizeBuffer(); + struct EmitterEntry + { + NazaraSlot(ParticleEmitter, OnParticleEmitterMove, moveSlot); + NazaraSlot(ParticleEmitter, OnParticleEmitterRelease, releaseSlot); + + ParticleEmitter* emitter; + }; + std::set> m_dyingParticles; mutable std::vector m_buffer; std::vector m_controllers; - std::vector m_emitters; + std::vector m_emitters; std::vector m_generators; ParticleDeclarationConstRef m_declaration; ParticleRendererRef m_renderer; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 10f057dce..fe27575e7 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -32,6 +32,14 @@ namespace Nz { } + ParticleEmitter::ParticleEmitter(const ParticleEmitter& emitter) : + m_lagCompensationEnabled(emitter.m_lagCompensationEnabled), + m_emissionAccumulator(0.f), + m_emissionRate(emitter.m_emissionRate), + m_emissionCount(emitter.m_emissionCount) + { + } + ParticleEmitter::ParticleEmitter(ParticleEmitter&& emitter) : m_lagCompensationEnabled(emitter.m_lagCompensationEnabled), m_emissionAccumulator(0.f), diff --git a/src/Nazara/Graphics/ParticleGroup.cpp b/src/Nazara/Graphics/ParticleGroup.cpp index 87dbb390c..5aca6c2b4 100644 --- a/src/Nazara/Graphics/ParticleGroup.cpp +++ b/src/Nazara/Graphics/ParticleGroup.cpp @@ -109,7 +109,12 @@ namespace Nz { NazaraAssert(emitter, "Invalid particle emitter"); - m_emitters.emplace_back(emitter); + EmitterEntry entry; + entry.emitter = emitter; + entry.moveSlot.Connect(emitter->OnParticleEmitterMove, this, &ParticleGroup::OnEmitterMove); + entry.releaseSlot.Connect(emitter->OnParticleEmitterRelease, this, &ParticleGroup::OnEmitterRelease); + + m_emitters.emplace_back(std::move(entry)); } /*! @@ -336,9 +341,14 @@ namespace Nz void ParticleGroup::RemoveEmitter(ParticleEmitter* emitter) { - auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); - if (it != m_emitters.end()) - m_emitters.erase(it); + for (auto it = m_emitters.begin(); it != m_emitters.end(); ++it) + { + if (it->emitter == emitter) + { + m_emitters.erase(it); + break; + } + } } /*! @@ -374,8 +384,8 @@ namespace Nz void ParticleGroup::Update(float elapsedTime) { // Emission - for (ParticleEmitter* emitter : m_emitters) - emitter->Emit(*this, elapsedTime); + for (const EmitterEntry& entry : m_emitters) + entry.emitter->Emit(*this, elapsedTime); // Update if (m_particleCount > 0) @@ -443,6 +453,26 @@ namespace Nz m_boundingVolume.MakeInfinite(); } + void ParticleGroup::OnEmitterMove(ParticleEmitter* oldEmitter, ParticleEmitter* newEmitter) + { + for (EmitterEntry& entry : m_emitters) + { + if (entry.emitter == oldEmitter) + entry.emitter = newEmitter; + } + } + + void ParticleGroup::OnEmitterRelease(const ParticleEmitter* emitter) + { + for (auto it = m_emitters.begin(); it != m_emitters.end();) + { + if (it->emitter == emitter) + it = m_emitters.erase(it); + else + ++it; + } + } + /*! * \brief Resizes the internal buffer * From 8f61e2f27814dca44d837f8a77cf943707acc1a3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Aug 2016 01:09:13 +0200 Subject: [PATCH 221/224] Sdk/ParticleEmitterComponent: Update emitter (they are no longer attached to groups) They are no longer attached to groups, groups attach emitters Former-commit-id: 9a586151ac4ce932cda5d6c36c3e40718aef7f2c [formerly 830dd96bb020bec7dc7b652acca43fdef2d01971] [formerly 26cf67777c40ca4a6bcc0643a8dea76d46debd30 [formerly d4d7e62390be2a4d44b5a67c5fbabc11aa080de5]] Former-commit-id: 653b321e01aa182a3dcb0531319cb9a053aadfa8 [formerly c4e742f3aab61f0941729a5739a80a838c6163cd] Former-commit-id: 6572d614b19d85cbc0844745c45c3bc92deef051 --- .../Components/ParticleEmitterComponent.hpp | 17 +++---- .../Components/ParticleEmitterComponent.inl | 10 ++++ .../Components/ParticleEmitterComponent.cpp | 46 +------------------ 3 files changed, 18 insertions(+), 55 deletions(-) diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp index 8d93e0495..6ad3e3981 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.hpp +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.hpp @@ -19,28 +19,23 @@ namespace Ndk public: using SetupFunc = std::function; - ParticleEmitterComponent(Nz::ParticleGroup* group); - ParticleEmitterComponent(const ParticleEmitterComponent& emitter); - ParticleEmitterComponent(ParticleEmitterComponent&& emitter); - ~ParticleEmitterComponent(); + inline ParticleEmitterComponent(); + ParticleEmitterComponent(const ParticleEmitterComponent& emitter) = default; + ParticleEmitterComponent(ParticleEmitterComponent&& emitter) = default; + ~ParticleEmitterComponent() = default; + + void Enable(bool active = true); inline bool IsActive() const; - void SetActive(bool active = true); - void SetGroup(Nz::ParticleGroup* group); inline void SetSetupFunc(SetupFunc func); static ComponentIndex componentIndex; private: - void OnParticleGroupRelease(const Nz::ParticleGroup* particleGroup); - void SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const override; - NazaraSlot(Nz::ParticleGroup, OnParticleGroupRelease, m_particleGroupRelease); - SetupFunc m_setupFunc; - Nz::ParticleGroup* m_particleGroup; bool m_isActive; }; } diff --git a/SDK/include/NDK/Components/ParticleEmitterComponent.inl b/SDK/include/NDK/Components/ParticleEmitterComponent.inl index 6cc9e8c29..342b5e56f 100644 --- a/SDK/include/NDK/Components/ParticleEmitterComponent.inl +++ b/SDK/include/NDK/Components/ParticleEmitterComponent.inl @@ -6,6 +6,16 @@ namespace Ndk { + inline ParticleEmitterComponent::ParticleEmitterComponent() : + m_isActive(true) + { + } + + inline void Ndk::ParticleEmitterComponent::Enable(bool active) + { + m_isActive = active; + } + inline bool ParticleEmitterComponent::IsActive() const { return m_isActive; diff --git a/SDK/src/NDK/Components/ParticleEmitterComponent.cpp b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp index 6a3cfeb7e..2ae4365e6 100644 --- a/SDK/src/NDK/Components/ParticleEmitterComponent.cpp +++ b/SDK/src/NDK/Components/ParticleEmitterComponent.cpp @@ -7,51 +7,9 @@ namespace Ndk { - ParticleEmitterComponent::ParticleEmitterComponent(Nz::ParticleGroup* group) : - m_particleGroup(group), - m_isActive(true) + void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const { - if (m_particleGroup) - m_particleGroup->AddEmitter(this); - } - - ParticleEmitterComponent::ParticleEmitterComponent(const ParticleEmitterComponent& emitter) : - m_particleGroup(emitter.m_particleGroup), - m_isActive(emitter.m_isActive) - { - if (m_isActive) - m_particleGroup->AddEmitter(this); - } - - ParticleEmitterComponent::~ParticleEmitterComponent() - { - m_particleGroup->RemoveEmitter(this); - } - - inline void Ndk::ParticleEmitterComponent::SetActive(bool active) - { - if (m_isActive != active) - { - if (active) - m_particleGroup->AddEmitter(this); - else - m_particleGroup->RemoveEmitter(this); - } - } - - void ParticleEmitterComponent::SetGroup(Nz::ParticleGroup* group) - { - if (m_particleGroup) - m_particleGroup->RemoveEmitter(this); - - m_particleGroup = group; - if (m_particleGroup && m_isActive) - m_particleGroup = group; - } - - inline void ParticleEmitterComponent::SetupParticles(Nz::ParticleMapper& mapper, unsigned int count) const - { - if (m_setupFunc) + if (m_isActive && m_setupFunc) m_setupFunc(m_entity, mapper, count); } From 7edbbf2e8c0782b3d4acfd950b2765737e696b37 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Aug 2016 01:11:05 +0200 Subject: [PATCH 222/224] Sdk/LuaBinding: Fix Vector3 constructor Former-commit-id: 63937c7bf56fdba5c8110fd6f9933c1e2b80a694 [formerly f1ad76d6b00a36651f6e1a5ad552d57e08e66076] [formerly fece1db56138b83df1103a3f5734a6f1e815e5c6 [formerly 363175ca2e012187d2c2ee2e784544d52d4489aa]] Former-commit-id: abea614206ce31a06edfa92b379925435587ac78 [formerly f2d23bf3b7dce3c6916dc013b400c65fd95f3ada] Former-commit-id: 96062b0207c426b008f5cc5d74e603f4bccf3298 --- SDK/src/NDK/LuaBinding_Math.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SDK/src/NDK/LuaBinding_Math.cpp b/SDK/src/NDK/LuaBinding_Math.cpp index 7db9ae9e2..c1d7b487e 100644 --- a/SDK/src/NDK/LuaBinding_Math.cpp +++ b/SDK/src/NDK/LuaBinding_Math.cpp @@ -205,7 +205,7 @@ namespace Ndk { case Nz::LuaType_Number: { - long long index = lua.CheckInteger(1); + auto index = lua.CheckBoundInteger(1); if (index < 1 || index > 4) return false; @@ -258,7 +258,7 @@ namespace Ndk { case Nz::LuaType_Number: { - long long index = lua.CheckInteger(1); + auto index = lua.CheckBoundInteger(1); if (index < 1 || index > 4) return false; @@ -537,11 +537,12 @@ namespace Ndk case 0: case 3: Nz::PlacementNew(vector, lua.CheckNumber(1, 0.0), lua.CheckNumber(2, 0.0), lua.CheckNumber(3, 0.0)); + return true; case 1: { if (lua.IsOfType(1, Nz::LuaType_Number)) - Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast(lua.ToUserdata(1))); + Nz::PlacementNew(vector, lua.CheckNumber(1), *static_cast(lua.CheckUserdata(1, "Vector2"))); else if (lua.IsOfType(1, "Vector2")) Nz::PlacementNew(vector, *static_cast(lua.ToUserdata(1))); else if (lua.IsOfType(1, "Vector3")) From 7fe5710dd3315563d5a627f92b18975537f0425b Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 9 Aug 2016 00:08:31 +0200 Subject: [PATCH 223/224] Utility/OBJParser: Fix failure to load some OBJ because of their "high error rate" Former-commit-id: f9041ec52283dc0bdc83869c1d032303a1e200e8 [formerly be218c9edb44bf7e4bd075a60694febaff823c03] [formerly 7f7d145fd94379ba2ad3a853ccb2fe9f7d940397 [formerly 92ee9fda6879f5e85f6106bc30af475cebc3f78f]] Former-commit-id: 75d958c182fd859499881bde919f57e3baa1db0f [formerly a4d130067033e98e00904ebce6ba5ae372717bd3] Former-commit-id: a59ed77ae02e7d05de12c4d5d90755c8aef08af0 --- include/Nazara/Utility/Formats/OBJParser.inl | 2 +- src/Nazara/Utility/Formats/OBJParser.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Utility/Formats/OBJParser.inl b/include/Nazara/Utility/Formats/OBJParser.inl index 054d57754..b04506fdf 100644 --- a/include/Nazara/Utility/Formats/OBJParser.inl +++ b/include/Nazara/Utility/Formats/OBJParser.inl @@ -179,7 +179,7 @@ namespace Nz m_errorCount++; - if (m_lineCount > 20 && (m_errorCount * 100 / m_lineCount) > 50) + if (m_errorCount > 10 && (m_errorCount * 100 / m_lineCount) > 50) { NazaraError("Aborting parsing because of error percentage"); return false; //< Abort parsing if error percentage is too high diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 7d3019c39..403950a97 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -31,6 +31,7 @@ namespace Nz String matName, meshName; matName = meshName = "default"; + m_errorCount = 0; m_keepLastLine = false; m_lineCount = 0; m_meshes.clear(); From f130b841768f9b8ab62b9a4179db16dabe5768ef Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 9 Aug 2016 00:08:57 +0200 Subject: [PATCH 224/224] SDK/VelocitySystem: Make VelocitySystem move the node in the global space Former-commit-id: 0d4fcd5d387bca9f8be8267951dfd7e862abc1b2 [formerly fe1a2fe36aaa79e5ae8aadb35dad9ead040dec95] [formerly f4c9472b944a37b42510b8c54eb9daed6d2c254b [formerly 3ed39592efc153cd2ca03e30408b7ec510ee3470]] Former-commit-id: f6c52aee5578ff849f8d9e771eb593a65beec43a [formerly 828ff673ee84618e011d92613d94b81b0b71abb1] Former-commit-id: bc722f914f5362c2b4bb514d0a638db48c5c51db --- SDK/src/NDK/Systems/VelocitySystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/src/NDK/Systems/VelocitySystem.cpp b/SDK/src/NDK/Systems/VelocitySystem.cpp index 882b45728..2d3264039 100644 --- a/SDK/src/NDK/Systems/VelocitySystem.cpp +++ b/SDK/src/NDK/Systems/VelocitySystem.cpp @@ -22,7 +22,7 @@ namespace Ndk NodeComponent& node = entity->GetComponent(); const VelocityComponent& velocity = entity->GetComponent(); - node.Move(velocity.linearVelocity * elapsedTime); + node.Move(velocity.linearVelocity * elapsedTime, Nz::CoordSys_Global); } }