Graphics: Add ViewerInstance class

This commit is contained in:
Jérôme Leclercq 2021-06-05 19:06:02 +02:00
parent 743f8eeb24
commit e26c1f8e68
4 changed files with 199 additions and 26 deletions

View File

@ -3,6 +3,7 @@
#include <Nazara/Math/Angle.hpp> #include <Nazara/Math/Angle.hpp>
#include <Nazara/Graphics.hpp> #include <Nazara/Graphics.hpp>
#include <Nazara/Graphics/FrameGraph.hpp> #include <Nazara/Graphics/FrameGraph.hpp>
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Renderer.hpp> #include <Nazara/Renderer.hpp>
#include <Nazara/Shader.hpp> #include <Nazara/Shader.hpp>
#include <Nazara/Shader/SpirvConstantCache.hpp> #include <Nazara/Shader/SpirvConstantCache.hpp>
@ -209,15 +210,11 @@ int main()
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets(); Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets(); Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
std::vector<std::uint8_t> viewerDataBuffer(viewerUboOffsets.totalSize);
Nz::Vector2ui windowSize = window.GetSize(); Nz::Vector2ui windowSize = window.GetSize();
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.viewMatrixOffset) = Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1); Nz::ViewerInstance viewerInstance;
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.projMatrixOffset) = Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f); viewerInstance.UpdateTargetSize(Nz::Vector2f(windowSize));
Nz::AccessByOffset<Nz::Vector2f&>(viewerDataBuffer.data(), viewerUboOffsets.invTargetSizeOffset) = 1.f / Nz::Vector2f(window.GetSize().x, window.GetSize().y); viewerInstance.UpdateProjViewMatrices(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f), Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1));
std::vector<std::uint8_t> instanceDataBuffer(instanceUboOffsets.totalSize);
Nz::ModelInstance modelInstance1(spaceshipMat->GetSettings()); Nz::ModelInstance modelInstance1(spaceshipMat->GetSettings());
spaceshipMat->UpdateShaderBinding(modelInstance1.GetShaderBinding()); spaceshipMat->UpdateShaderBinding(modelInstance1.GetShaderBinding());
@ -520,7 +517,6 @@ int main()
std::shared_ptr<Nz::ShaderBinding> finalBlitBinding = fullscreenPipelineInfo.pipelineLayout->AllocateShaderBinding(); std::shared_ptr<Nz::ShaderBinding> finalBlitBinding = fullscreenPipelineInfo.pipelineLayout->AllocateShaderBinding();
bool viewerUboUpdate = true;
bool lightUpdate = true; bool lightUpdate = true;
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({}); std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
@ -670,7 +666,7 @@ int main()
Nz::FramePass& lightingPass = graph.AddPass("Lighting pass"); Nz::FramePass& lightingPass = graph.AddPass("Lighting pass");
lightingPass.SetExecutionCallback([&] lightingPass.SetExecutionCallback([&]
{ {
return (viewerUboUpdate) ? Nz::FramePassExecution::UpdateAndExecute : Nz::FramePassExecution::Execute; return (lightUpdate) ? Nz::FramePassExecution::UpdateAndExecute : Nz::FramePassExecution::Execute;
}); });
lightingPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder) lightingPass.SetCommandCallback([&](Nz::CommandBufferBuilder& builder)
@ -1005,8 +1001,6 @@ int main()
camAngles.pitch = Nz::Clamp(camAngles.pitch + event.mouseMove.deltaY*sensitivity, -89.f, 89.f); camAngles.pitch = Nz::Clamp(camAngles.pitch + event.mouseMove.deltaY*sensitivity, -89.f, 89.f);
camQuat = camAngles; camQuat = camAngles;
viewerUboUpdate = true;
break; break;
} }
@ -1035,8 +1029,7 @@ int main()
case Nz::WindowEventType::Resized: case Nz::WindowEventType::Resized:
{ {
Nz::Vector2ui windowSize = window.GetSize(); Nz::Vector2ui windowSize = window.GetSize();
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.projMatrixOffset) = Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f); viewerInstance.UpdateProjViewMatrices(Nz::Matrix4f::Perspective(Nz::DegreeAnglef(70.f), float(windowSize.x) / windowSize.y, 0.1f, 1000.f), Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1));
viewerUboUpdate = true;
break; break;
} }
@ -1073,7 +1066,7 @@ int main()
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RControl)) if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RControl))
viewerPos += Nz::Vector3f::Down() * cameraSpeed; viewerPos += Nz::Vector3f::Down() * cameraSpeed;
viewerUboUpdate = true; viewerInstance.UpdateViewMatrix(Nz::Matrix4f::ViewMatrix(viewerPos, camQuat));
} }
Nz::RenderFrame frame = windowImpl->Acquire(); Nz::RenderFrame frame = windowImpl->Acquire();
@ -1083,12 +1076,8 @@ int main()
if (frame.IsFramebufferInvalidated()) if (frame.IsFramebufferInvalidated())
RebuildCommandBuffer(); RebuildCommandBuffer();
if (viewerUboUpdate || lightAnimation || lightUpdate) if (lightAnimation || lightUpdate)
{ {
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.viewMatrixOffset) = Nz::Matrix4f::ViewMatrix(viewerPos, camAngles);
//Nz::AccessByOffset<Nz::Vector3f&>(lightData.data(), colorOffset) = Nz::Vector3f(std::sin(totalFrameCount / 10000.f) * 0.5f + 0.5f, std::cos(totalFrameCount / 1000.f) * 0.5f + 0.5f, std::sin(totalFrameCount / 100.f) * 0.5f + 0.5f);
Nz::UploadPool& uploadPool = frame.GetUploadPool(); Nz::UploadPool& uploadPool = frame.GetUploadPool();
frame.Execute([&](Nz::CommandBufferBuilder& builder) frame.Execute([&](Nz::CommandBufferBuilder& builder)
@ -1097,12 +1086,11 @@ int main()
{ {
builder.PreTransferBarrier(); builder.PreTransferBarrier();
if (viewerUboUpdate) modelInstance1.UpdateBuffers(uploadPool, builder);
{ modelInstance2.UpdateBuffers(uploadPool, builder);
auto& viewerDataAllocation = uploadPool.Allocate(viewerDataBuffer.size()); planeInstance.UpdateBuffers(uploadPool, builder);
std::memcpy(viewerDataAllocation.mappedPtr, viewerDataBuffer.data(), viewerDataBuffer.size());
builder.CopyBuffer(viewerDataAllocation, viewerDataUBO.get()); viewerInstance.UpdateViewBuffer(uploadPool, builder);
}
if (!spotLights.empty() && (lightUpdate || lightAnimation)) if (!spotLights.empty() && (lightUpdate || lightAnimation))
{ {
@ -1151,7 +1139,7 @@ int main()
window.Display(); window.Display();
viewerUboUpdate = false; lightUpdate = false;
// On incrémente le compteur de FPS improvisé // On incrémente le compteur de FPS improvisé
fps++; fps++;

View File

@ -0,0 +1,57 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VIEWERINSTANCE_HPP
#define NAZARA_VIEWERINSTANCE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <memory>
namespace Nz
{
class AbstractBuffer;
class CommandBufferBuilder;
class MaterialSettings;
class UploadPool;
class NAZARA_GRAPHICS_API ViewerInstance
{
public:
ViewerInstance();
ViewerInstance(const ViewerInstance&) = delete;
ViewerInstance(ViewerInstance&&) noexcept = default;
~ViewerInstance() = default;
void UpdateViewBuffer(UploadPool& uploadPool, CommandBufferBuilder& builder);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix);
inline void UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& viewMatrix);
inline void UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix);
inline void UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix, const Matrix4f& viewProjMatrix, const Matrix4f& invViewProjMatrix);
inline void UpdateTargetSize(const Vector2f& targetSize);
inline void UpdateViewMatrix(const Matrix4f& viewMatrix);
inline void UpdateViewMatrix(const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix);
ViewerInstance& operator=(const ViewerInstance&) = delete;
ViewerInstance& operator=(ViewerInstance&&) noexcept = default;
private:
Matrix4f m_invProjectionMatrix;
Matrix4f m_invViewProjMatrix;
Matrix4f m_invViewMatrix;
Matrix4f m_projectionMatrix;
Matrix4f m_viewProjMatrix;
Matrix4f m_viewMatrix;
Vector2f m_targetSize;
};
}
#include <Nazara/Graphics/ViewerInstance.inl>
#endif // NAZARA_VIEWERINSTANCE_HPP

View File

@ -0,0 +1,82 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
{
m_projectionMatrix = projectionMatrix;
if (!m_projectionMatrix.GetInverse(&m_invProjectionMatrix))
NazaraError("failed to inverse projection matrix");
}
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix)
{
m_projectionMatrix = projectionMatrix;
m_invProjectionMatrix = invProjectionMatrix;
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& viewMatrix)
{
m_projectionMatrix = projectionMatrix;
if (!m_projectionMatrix.GetInverse(&m_invProjectionMatrix))
NazaraError("failed to inverse projection matrix");
m_viewMatrix = viewMatrix;
if (!m_viewMatrix.GetInverseAffine(&m_invViewMatrix))
NazaraError("failed to inverse view matrix");
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
{
m_projectionMatrix = projectionMatrix;
m_viewMatrix = viewMatrix;
m_invProjectionMatrix = invProjectionMatrix;
m_invViewMatrix = invViewMatrix;
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix, const Matrix4f& viewProjMatrix, const Matrix4f& invViewProjMatrix)
{
m_projectionMatrix = projectionMatrix;
m_viewMatrix = viewMatrix;
m_invProjectionMatrix = invProjectionMatrix;
m_invViewMatrix = invViewMatrix;
m_viewProjMatrix = viewProjMatrix;
m_invViewProjMatrix = invViewProjMatrix;
}
inline void ViewerInstance::UpdateTargetSize(const Vector2f& targetSize)
{
m_targetSize = targetSize;
}
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix)
{
m_viewMatrix = viewMatrix;
if (!m_viewMatrix.GetInverseAffine(&m_invViewMatrix))
NazaraError("failed to inverse view matrix");
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
}
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
{
m_viewMatrix = viewMatrix;
m_invViewMatrix = invViewMatrix;
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,46 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
#include <Nazara/Renderer/UploadPool.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
ViewerInstance::ViewerInstance() :
m_invProjectionMatrix(Nz::Matrix4f::Identity()),
m_invViewProjMatrix(Nz::Matrix4f::Identity()),
m_invViewMatrix(Nz::Matrix4f::Identity()),
m_projectionMatrix(Nz::Matrix4f::Identity()),
m_viewProjMatrix(Nz::Matrix4f::Identity()),
m_viewMatrix(Nz::Matrix4f::Identity()),
m_targetSize(Nz::Vector2f(0.f, 0.f))
{
}
void ViewerInstance::UpdateViewBuffer(UploadPool& uploadPool, CommandBufferBuilder& builder)
{
Nz::PredefinedViewerData viewerDataOffsets = Nz::PredefinedViewerData::GetOffsets();
auto& allocation = uploadPool.Allocate(viewerDataOffsets.totalSize);
Nz::AccessByOffset<Nz::Vector3f&>(allocation.mappedPtr, viewerDataOffsets.eyePositionOffset) = m_viewMatrix.GetTranslation();
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.invTargetSizeOffset) = 1.f / m_targetSize;
Nz::AccessByOffset<Nz::Vector2f&>(allocation.mappedPtr, viewerDataOffsets.targetSizeOffset) = m_targetSize;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invProjMatrixOffset) = m_invProjectionMatrix;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewMatrixOffset) = m_invViewMatrix;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.invViewProjMatrixOffset) = m_invViewProjMatrix;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.projMatrixOffset) = m_projectionMatrix;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewProjMatrixOffset) = m_viewProjMatrix;
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, viewerDataOffsets.viewMatrixOffset) = m_viewMatrix;
const std::shared_ptr<AbstractBuffer>& instanceDataUBO = Graphics::Instance()->GetViewerDataUBO();
builder.CopyBuffer(allocation, instanceDataUBO.get());
}
}