Add render resouce
This commit is contained in:
143
openVulkanoCpp/Base/Render/RenderResource.hpp
Normal file
143
openVulkanoCpp/Base/Render/RenderResource.hpp
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <concepts>
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace OpenVulkano
|
||||||
|
{
|
||||||
|
class RenderResource;
|
||||||
|
|
||||||
|
class IRenderResourceHelper
|
||||||
|
{
|
||||||
|
friend class RenderResource;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void UpdateRenderResource(RenderResource& resource);
|
||||||
|
|
||||||
|
void ResetRenderResource(RenderResource& resource);
|
||||||
|
|
||||||
|
virtual void Release() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
concept Renderable = std::is_convertible_v<T, RenderResource&>;
|
||||||
|
|
||||||
|
class RenderResource final
|
||||||
|
{
|
||||||
|
friend class IRenderResourceHelper;
|
||||||
|
|
||||||
|
IRenderResourceHelper* renderObject = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RenderResource() = default;
|
||||||
|
RenderResource(const RenderResource& ignored) { /* Do not copy, copy will be created by renderer */ }
|
||||||
|
RenderResource(RenderResource&& move) : renderObject(move.renderObject) { move.renderObject = nullptr; }
|
||||||
|
|
||||||
|
~RenderResource()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Release()
|
||||||
|
{
|
||||||
|
if (!renderObject) return;
|
||||||
|
renderObject->Release();
|
||||||
|
renderObject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T* As() { return static_cast<T*>(renderObject); }
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
operator T() { return static_cast<T>(renderObject); }
|
||||||
|
|
||||||
|
operator bool() const { return renderObject; }
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void IRenderResourceHelper::UpdateRenderResource(RenderResource& resource)
|
||||||
|
{
|
||||||
|
resource.renderObject = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IRenderResourceHelper::ResetRenderResource(RenderResource& resource)
|
||||||
|
{
|
||||||
|
resource.renderObject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Renderable API_INDEPENDENT_CLASS>
|
||||||
|
class IRenderResource : public IRenderResourceHelper
|
||||||
|
{
|
||||||
|
API_INDEPENDENT_CLASS* m_owner;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IRenderResource(API_INDEPENDENT_CLASS* owner) : m_owner(owner)
|
||||||
|
{
|
||||||
|
if (m_owner) UpdateRenderResource(GetOwnerResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
IRenderResource(const IRenderResource<API_INDEPENDENT_CLASS>& copy) = delete;
|
||||||
|
|
||||||
|
IRenderResource(IRenderResource<API_INDEPENDENT_CLASS>&& move)
|
||||||
|
: m_owner(move.m_owner)
|
||||||
|
{
|
||||||
|
if (m_owner) UpdateRenderResource(GetOwnerResource());
|
||||||
|
move.m_owner = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderResource& GetOwnerResource() { return static_cast<RenderResource&>(*m_owner); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~IRenderResource()
|
||||||
|
{
|
||||||
|
if (m_owner) ResetRenderResource(GetOwnerResource());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAddress(API_INDEPENDENT_CLASS* owner)
|
||||||
|
{
|
||||||
|
m_owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator API_INDEPENDENT_CLASS*() const { return m_owner; }
|
||||||
|
|
||||||
|
API_INDEPENDENT_CLASS* GetOwner() const { return m_owner; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a convenience class to create a Renderable class.
|
||||||
|
* You can also just create a RenderResource instance a conversion operator inside your own class to make it Renderable; and you probably want to delete your move constructor in that case.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
class RenderResourceHolder
|
||||||
|
{
|
||||||
|
RenderResource renderResource;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RenderResourceHolder() = default;
|
||||||
|
RenderResourceHolder(const RenderResourceHolder& ignored) {}
|
||||||
|
RenderResourceHolder(RenderResourceHolder&& move)
|
||||||
|
: renderResource(std::move(move.renderResource))
|
||||||
|
{
|
||||||
|
if (IRenderResource<T>* renderRes = renderResource)
|
||||||
|
renderRes->UpdateAddress(static_cast<T*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
~RenderResourceHolder() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
operator RenderResource&() { return renderResource; }
|
||||||
|
|
||||||
|
RenderResource& GetRenderResource() { return renderResource; }
|
||||||
|
|
||||||
|
template<Renderable RT>
|
||||||
|
operator RT() const { return renderResource; }
|
||||||
|
|
||||||
|
bool HasRenderResource() const { return renderResource; }
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -37,7 +37,7 @@ namespace OpenVulkano::Scene
|
|||||||
void Node::Close()
|
void Node::Close()
|
||||||
{
|
{
|
||||||
children.clear();
|
children.clear();
|
||||||
if (renderNode) renderNode->Close();
|
GetRenderResource().Release();
|
||||||
parent = nullptr;
|
parent = nullptr;
|
||||||
scene = nullptr;
|
scene = nullptr;
|
||||||
enabled = false;
|
enabled = false;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Base/ICloseable.hpp"
|
#include "Base/ICloseable.hpp"
|
||||||
|
#include "Base/Render/RenderResource.hpp"
|
||||||
#include "Math/Math.hpp"
|
#include "Math/Math.hpp"
|
||||||
#include "Math/Pose.hpp"
|
#include "Math/Pose.hpp"
|
||||||
#include "Drawable.hpp"
|
#include "Drawable.hpp"
|
||||||
@@ -19,7 +20,7 @@ namespace OpenVulkano::Scene
|
|||||||
{
|
{
|
||||||
class Scene;
|
class Scene;
|
||||||
|
|
||||||
class Node : public ICloseable
|
class Node : public RenderResourceHolder<Node>, public ICloseable
|
||||||
{
|
{
|
||||||
friend Scene;
|
friend Scene;
|
||||||
|
|
||||||
@@ -33,7 +34,6 @@ namespace OpenVulkano::Scene
|
|||||||
std::vector<Node*> children;
|
std::vector<Node*> children;
|
||||||
std::vector<Drawable*> drawables;
|
std::vector<Drawable*> drawables;
|
||||||
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
|
UpdateFrequency matrixUpdateFrequency = UpdateFrequency::Never;
|
||||||
ICloseable* renderNode = nullptr;
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ namespace OpenVulkano::Vulkan
|
|||||||
VulkanNode* ResourceManager::PrepareNode(Scene::Node* node)
|
VulkanNode* ResourceManager::PrepareNode(Scene::Node* node)
|
||||||
{
|
{
|
||||||
const std::unique_lock lock(mutex);
|
const std::unique_lock lock(mutex);
|
||||||
if (!node->renderNode)
|
if (!node->HasRenderResource())
|
||||||
{
|
{
|
||||||
UniformBuffer* uBuffer = new UniformBuffer();
|
UniformBuffer* uBuffer = new UniformBuffer();
|
||||||
ManagedBuffer::Ptr buffer;
|
ManagedBuffer::Ptr buffer;
|
||||||
@@ -193,23 +193,22 @@ namespace OpenVulkano::Vulkan
|
|||||||
if (node->GetUpdateFrequency() != Scene::UpdateFrequency::Never)
|
if (node->GetUpdateFrequency() != Scene::UpdateFrequency::Never)
|
||||||
{
|
{
|
||||||
frameSize = allocSize;
|
frameSize = allocSize;
|
||||||
vkNode = new VulkanNodeDynamic();
|
vkNode = new VulkanNodeDynamic(node, uBuffer);
|
||||||
const uint32_t imgs = context->swapChain.GetImageCount();
|
const uint32_t imgs = context->swapChain.GetImageCount();
|
||||||
buffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
buffer = memPool.CreateBuffer(imgs * allocSize, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
|
||||||
buffer->Map();
|
buffer->Map();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vkNode = new VulkanNode();
|
|
||||||
buffer = CreateDeviceOnlyBufferWithData(Scene::Node::SIZE, vk::BufferUsageFlagBits::eUniformBuffer, &node->worldMat);
|
buffer = CreateDeviceOnlyBufferWithData(Scene::Node::SIZE, vk::BufferUsageFlagBits::eUniformBuffer, &node->worldMat);
|
||||||
|
vkNode = new VulkanNode(node, uBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
uBuffer->Init(std::move(buffer), frameSize, allocSize, GetDescriptorLayoutSet(Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING, 0);
|
uBuffer->Init(std::move(buffer), frameSize, allocSize, GetDescriptorLayoutSet(Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Node::DESCRIPTOR_SET_LAYOUT_BINDING, 0);
|
||||||
vkNode->Init(node, uBuffer);
|
|
||||||
node->renderNode = vkNode;
|
|
||||||
nodes.emplace_back(vkNode);
|
nodes.emplace_back(vkNode);
|
||||||
|
return vkNode;
|
||||||
}
|
}
|
||||||
return static_cast<VulkanNode*>(node->renderNode);
|
return node->GetRenderResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanCamera* ResourceManager::PrepareCamera(Scene::Camera* camera)
|
VulkanCamera* ResourceManager::PrepareCamera(Scene::Camera* camera)
|
||||||
|
|||||||
@@ -6,28 +6,23 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Base/ICloseable.hpp"
|
#include "Base/Render/RenderResource.hpp"
|
||||||
#include "IRecordable.hpp"
|
#include "IRecordable.hpp"
|
||||||
#include "Scene/Camera.hpp"
|
#include "Scene/Camera.hpp"
|
||||||
#include "Vulkan/Resources/UniformBuffer.hpp"
|
#include "Vulkan/Resources/UniformBuffer.hpp"
|
||||||
|
|
||||||
namespace OpenVulkano::Vulkan
|
namespace OpenVulkano::Vulkan
|
||||||
{
|
{
|
||||||
class VulkanNode : public IRecordable, public ICloseable
|
class VulkanNode : public IRenderResource<Scene::Node>, public IRecordable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scene::Node* node = nullptr;
|
Unique<UniformBuffer> buffer = nullptr;
|
||||||
UniformBuffer* buffer = nullptr;
|
|
||||||
|
|
||||||
~VulkanNode() override
|
~VulkanNode() override = default;
|
||||||
{
|
|
||||||
if (node) VulkanNode::Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Init(Scene::Node* node, UniformBuffer* uniformBuffer)
|
VulkanNode(Scene::Node* node, UniformBuffer* uniformBuffer)
|
||||||
|
: IRenderResource<Scene::Node>(node), buffer(uniformBuffer)
|
||||||
{
|
{
|
||||||
this->node = node;
|
|
||||||
this->buffer = uniformBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Record(VulkanDrawContext* context) override
|
void Record(VulkanDrawContext* context) override
|
||||||
@@ -35,12 +30,9 @@ namespace OpenVulkano::Vulkan
|
|||||||
buffer->Record(context);
|
buffer->Record(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close() override
|
void Release() override
|
||||||
{
|
{
|
||||||
if (node) node->renderNode = nullptr;
|
//TODO
|
||||||
delete buffer;
|
|
||||||
node = nullptr;
|
|
||||||
buffer = nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,18 +40,16 @@ namespace OpenVulkano::Vulkan
|
|||||||
{
|
{
|
||||||
//uint32_t lastUpdate = -1;
|
//uint32_t lastUpdate = -1;
|
||||||
|
|
||||||
void Init(Scene::Node* node, UniformBuffer* uniformBuffer) override
|
VulkanNodeDynamic(Scene::Node* node, UniformBuffer* uniformBuffer)
|
||||||
{
|
: VulkanNode(node, uniformBuffer)
|
||||||
VulkanNode::Init(node, uniformBuffer);
|
{}
|
||||||
//lastUpdate = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Record(VulkanDrawContext* context) override
|
void Record(VulkanDrawContext* context) override
|
||||||
{
|
{
|
||||||
//if(context->currentImageId != lastUpdate) //TODO fix
|
//if(context->currentImageId != lastUpdate) //TODO fix
|
||||||
{
|
{
|
||||||
//lastUpdate = bufferId;
|
//lastUpdate = bufferId;
|
||||||
buffer->Update(&node->worldMat, sizeof(Math::Matrix4f), context->currentImageId);
|
buffer->Update(&GetOwner()->worldMat, sizeof(Math::Matrix4f), context->currentImageId);
|
||||||
}
|
}
|
||||||
buffer->Record(context);
|
buffer->Record(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace OpenVulkano::Vulkan
|
|||||||
|
|
||||||
void VulkanDrawContext::EncodeNode(Scene::Node* node)
|
void VulkanDrawContext::EncodeNode(Scene::Node* node)
|
||||||
{
|
{
|
||||||
VulkanNode* vkNode = static_cast<VulkanNode*>(node->renderNode);
|
VulkanNode* vkNode = node->GetRenderResource();
|
||||||
if (!vkNode)
|
if (!vkNode)
|
||||||
{
|
{
|
||||||
vkNode = renderer->GetResourceManager().PrepareNode(node);
|
vkNode = renderer->GetResourceManager().PrepareNode(node);
|
||||||
|
|||||||
Reference in New Issue
Block a user