Gets dynamic rendering mostly working
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
#include "engine/assets/model/Model.hpp"
|
||||
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
||||
#include "engine/camera/Camera.hpp"
|
||||
#include "engine/camera/CameraSwapchain.hpp"
|
||||
#include "engine/camera/GBufferSwapchain.hpp"
|
||||
#include "engine/filesystem/scanner/FileScanner.hpp"
|
||||
#include "engine/filesystem/types.hpp"
|
||||
#include "engine/gameobjects/components/ModelComponent.hpp"
|
||||
@@ -53,9 +53,7 @@ namespace fgl::engine::gui
|
||||
|
||||
obj.addFlag( IsEntity | IsVisible );
|
||||
|
||||
auto component {
|
||||
std::make_unique< ModelComponent >( std::move( model ) )
|
||||
};
|
||||
auto component { std::make_unique< ModelComponent >( std::move( model ) ) };
|
||||
|
||||
obj.addComponent( std::move( component ) );
|
||||
|
||||
@@ -208,16 +206,17 @@ namespace fgl::engine::gui
|
||||
default:
|
||||
[[fallthrough]];
|
||||
case Composite:
|
||||
camera.getSwapchain().m_g_buffer_composite_img[ frame_index ]->drawImGui( target_size );
|
||||
camera.getCompositeSwapchain().m_gbuffer_target[ frame_index ]->drawImGui( target_size );
|
||||
// camera.getSwapchain().m_g_buffer_composite_img[ frame_index ]->drawImGui( target_size );
|
||||
break;
|
||||
case Albedo:
|
||||
camera.getSwapchain().m_g_buffer_color_img[ frame_index ]->drawImGui( target_size );
|
||||
// camera.getSwapchain().m_g_buffer_color_img[ frame_index ]->drawImGui( target_size );
|
||||
break;
|
||||
case Normal:
|
||||
camera.getSwapchain().m_g_buffer_normal_img[ frame_index ]->drawImGui( target_size );
|
||||
// camera.getSwapchain().m_g_buffer_normal_img[ frame_index ]->drawImGui( target_size );
|
||||
break;
|
||||
case Position:
|
||||
camera.getSwapchain().m_g_buffer_position_img[ frame_index ]->drawImGui( target_size );
|
||||
// camera.getSwapchain().m_g_buffer_position_img[ frame_index ]->drawImGui( target_size );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,46 +35,53 @@ int main()
|
||||
|
||||
log::debug( "Vulkan instance version: {}.{}.{}.{}", major, minor, patch, minor );
|
||||
|
||||
EngineContext engine_ctx {};
|
||||
|
||||
// We start by hooking into the imgui rendering.
|
||||
engine_ctx.hookInitImGui( gui::initGui );
|
||||
engine_ctx.hookPreFrame( gui::startDrawImGui );
|
||||
engine_ctx.hookEarlyFrame( gui::drawImGui );
|
||||
engine_ctx.hookLateFrame( gui::endDrawImGui );
|
||||
engine_ctx.hookDestruction( gui::cleanupImGui );
|
||||
|
||||
// Now we need to create the camera for the editor.
|
||||
CameraManager& camera_manager { engine_ctx.cameraManager() };
|
||||
|
||||
auto& editor_camera { camera_manager.getPrimary() };
|
||||
|
||||
editor_camera->setFOV( glm::radians( 90.0f ) );
|
||||
|
||||
//! Will be true until the window says it wants to close.
|
||||
while ( engine_ctx.good() )
|
||||
try
|
||||
{
|
||||
debug::timing::reset();
|
||||
engine_ctx.tickDeltaTime();
|
||||
EngineContext engine_ctx {};
|
||||
|
||||
engine_ctx.handleTransfers();
|
||||
// We start by hooking into the imgui rendering.
|
||||
engine_ctx.hookInitImGui( gui::initGui );
|
||||
engine_ctx.hookPreFrame( gui::startDrawImGui );
|
||||
engine_ctx.hookEarlyFrame( gui::drawImGui );
|
||||
engine_ctx.hookLateFrame( gui::endDrawImGui );
|
||||
engine_ctx.hookDestruction( gui::cleanupImGui );
|
||||
|
||||
// Process input
|
||||
engine_ctx.processInput();
|
||||
// Now we need to create the camera for the editor.
|
||||
CameraManager& camera_manager { engine_ctx.cameraManager() };
|
||||
|
||||
// Here we can decide if we want to tick fully or not.
|
||||
auto& editor_camera { camera_manager.getPrimary() };
|
||||
|
||||
// Simulate step
|
||||
engine_ctx.tickSimulation();
|
||||
editor_camera->setFOV( glm::radians( 90.0f ) );
|
||||
|
||||
// Update the viewer camera
|
||||
//! Will be true until the window says it wants to close.
|
||||
while ( engine_ctx.good() )
|
||||
{
|
||||
debug::timing::reset();
|
||||
engine_ctx.tickDeltaTime();
|
||||
|
||||
// Render step
|
||||
engine_ctx.renderFrame();
|
||||
engine_ctx.handleTransfers();
|
||||
|
||||
engine_ctx.finishFrame();
|
||||
// This will 'end' the root node, Which is created on 'reset'
|
||||
debug::timing::internal::pop();
|
||||
// Process input
|
||||
engine_ctx.processInput();
|
||||
|
||||
// Here we can decide if we want to tick fully or not.
|
||||
|
||||
// Simulate step
|
||||
engine_ctx.tickSimulation();
|
||||
|
||||
// Update the viewer camera
|
||||
|
||||
// Render step
|
||||
engine_ctx.renderFrame();
|
||||
|
||||
engine_ctx.finishFrame();
|
||||
// This will 'end' the root node, Which is created on 'reset'
|
||||
debug::timing::internal::pop();
|
||||
}
|
||||
}
|
||||
catch ( const vk::LayerNotPresentError& e )
|
||||
{
|
||||
log::info( "{}:{}", e.code().message(), e.what() );
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "assets/material/Material.hpp"
|
||||
#include "camera/Camera.hpp"
|
||||
#include "camera/CameraManager.hpp"
|
||||
#include "camera/CameraRenderer.hpp"
|
||||
#include "camera/GBufferRenderer.hpp"
|
||||
#include "debug/timing/FlameGraph.hpp"
|
||||
#include "engine/assets/model/builders/SceneBuilder.hpp"
|
||||
#include "engine/assets/transfer/TransferManager.hpp"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "FrameInfo.hpp"
|
||||
|
||||
#include "camera/Camera.hpp"
|
||||
#include "camera/CameraSwapchain.hpp"
|
||||
#include "camera/GBufferSwapchain.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
//clang-format: off
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <tracy/TracyVulkan.hpp>
|
||||
//clang-format: on
|
||||
|
||||
|
||||
@@ -11,17 +11,188 @@ namespace fgl::engine
|
||||
|
||||
std::shared_ptr< ImageView > Image::getView()
|
||||
{
|
||||
if ( !view.expired() )
|
||||
return view.lock();
|
||||
if ( !m_view.expired() )
|
||||
return m_view.lock();
|
||||
else
|
||||
{
|
||||
assert( m_handle );
|
||||
auto ptr { std::make_shared< ImageView >( m_handle ) };
|
||||
view = ptr;
|
||||
m_view = ptr;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr vk::AccessFlags getAccessFlags( const vk::ImageLayout layout )
|
||||
{
|
||||
switch ( layout )
|
||||
{
|
||||
case vk::ImageLayout::eUndefined:
|
||||
return vk::AccessFlags( 0 );
|
||||
case vk::ImageLayout::eGeneral:
|
||||
break;
|
||||
case vk::ImageLayout::eColorAttachmentOptimal:
|
||||
return vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eShaderReadOnlyOptimal:
|
||||
return vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eInputAttachmentRead;
|
||||
case vk::ImageLayout::eTransferSrcOptimal:
|
||||
return vk::AccessFlagBits::eTransferRead;
|
||||
case vk::ImageLayout::eTransferDstOptimal:
|
||||
return vk::AccessFlagBits::eTransferWrite;
|
||||
case vk::ImageLayout::ePreinitialized:
|
||||
return vk::AccessFlagBits::eHostWrite;
|
||||
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthReadOnlyOptimal:
|
||||
[[fallthrough]];
|
||||
case vk::ImageLayout::eDepthAttachmentOptimal:
|
||||
return vk::AccessFlagBits::eDepthStencilAttachmentRead
|
||||
| vk::AccessFlagBits::eDepthStencilAttachmentWrite;
|
||||
case vk::ImageLayout::eStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::ePresentSrcKHR:
|
||||
return vk::AccessFlags( 0 );
|
||||
case vk::ImageLayout::eVideoDecodeDstKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoDecodeSrcKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoDecodeDpbKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eSharedPresentKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
|
||||
break;
|
||||
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
|
||||
return vk::AccessFlagBits::eFragmentShadingRateAttachmentReadKHR;
|
||||
case vk::ImageLayout::eRenderingLocalReadKHR:
|
||||
return vk::AccessFlagBits::eColorAttachmentWrite;
|
||||
case vk::ImageLayout::eVideoEncodeDstKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoEncodeSrcKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoEncodeDpbKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
|
||||
break;
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
constexpr vk::PipelineStageFlags getPipelineStageFlags( const vk::ImageLayout layout )
|
||||
{
|
||||
switch ( layout )
|
||||
{
|
||||
default:
|
||||
FGL_UNREACHABLE();
|
||||
case vk::ImageLayout::eUndefined:
|
||||
return vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
case vk::ImageLayout::eGeneral:
|
||||
break;
|
||||
case vk::ImageLayout::eColorAttachmentOptimal:
|
||||
return vk::PipelineStageFlagBits::eColorAttachmentOutput;
|
||||
case vk::ImageLayout::eDepthStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eShaderReadOnlyOptimal:
|
||||
return vk::PipelineStageFlagBits::eVertexShader | vk::PipelineStageFlagBits::eFragmentShader;
|
||||
case vk::ImageLayout::eTransferSrcOptimal:
|
||||
[[fallthrough]];
|
||||
case vk::ImageLayout::eTransferDstOptimal:
|
||||
return vk::PipelineStageFlagBits::eTransfer;
|
||||
case vk::ImageLayout::ePreinitialized:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eDepthReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eStencilAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eStencilReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eReadOnlyOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::eAttachmentOptimal:
|
||||
break;
|
||||
case vk::ImageLayout::ePresentSrcKHR:
|
||||
return vk::PipelineStageFlagBits::eBottomOfPipe;
|
||||
case vk::ImageLayout::eVideoDecodeDstKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoDecodeSrcKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoDecodeDpbKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eSharedPresentKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eFragmentDensityMapOptimalEXT:
|
||||
break;
|
||||
case vk::ImageLayout::eFragmentShadingRateAttachmentOptimalKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eRenderingLocalReadKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoEncodeDstKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoEncodeSrcKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eVideoEncodeDpbKHR:
|
||||
break;
|
||||
case vk::ImageLayout::eAttachmentFeedbackLoopOptimalEXT:
|
||||
break;
|
||||
}
|
||||
|
||||
FGL_UNREACHABLE();
|
||||
}
|
||||
|
||||
vk::ImageMemoryBarrier Image::transitionTo(
|
||||
const vk::ImageLayout old_layout,
|
||||
const vk::ImageLayout new_layout,
|
||||
const vk::ImageSubresourceRange& range ) const
|
||||
{
|
||||
vk::ImageMemoryBarrier barrier {};
|
||||
barrier.srcAccessMask = getAccessFlags( old_layout );
|
||||
barrier.dstAccessMask = getAccessFlags( new_layout );
|
||||
|
||||
barrier.oldLayout = old_layout;
|
||||
barrier.newLayout = new_layout;
|
||||
|
||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
|
||||
barrier.subresourceRange = range;
|
||||
|
||||
barrier.setImage( this->getVkImage() );
|
||||
|
||||
return barrier;
|
||||
}
|
||||
|
||||
vk::ImageMemoryBarrier Image::transitionTo(
|
||||
const vk::ImageLayout old_layout, const vk::ImageLayout new_layout, const vk::ImageAspectFlags aspect )
|
||||
{
|
||||
const vk::ImageSubresourceRange subresource { aspect, 0, 1, 0, 1 };
|
||||
|
||||
const vk::ImageMemoryBarrier barrier { transitionTo( old_layout, new_layout, subresource ) };
|
||||
|
||||
return barrier;
|
||||
}
|
||||
|
||||
Image::Image(
|
||||
const vk::Extent2D extent,
|
||||
const vk::Format format,
|
||||
@@ -44,7 +215,7 @@ namespace fgl::engine
|
||||
Image& Image::operator=( const Image& other )
|
||||
{
|
||||
m_handle = other.m_handle;
|
||||
view = {};
|
||||
m_view = {};
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -56,7 +227,7 @@ namespace fgl::engine
|
||||
Image& Image::operator=( Image&& other ) noexcept
|
||||
{
|
||||
m_handle = std::move( other.m_handle );
|
||||
view = std::move( other.view );
|
||||
m_view = std::move( other.m_view );
|
||||
m_extent = other.m_extent;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace fgl::engine
|
||||
class Image
|
||||
{
|
||||
std::shared_ptr< ImageHandle > m_handle;
|
||||
std::weak_ptr< ImageView > view {};
|
||||
std::weak_ptr< ImageView > m_view {};
|
||||
vk::Extent2D m_extent;
|
||||
|
||||
friend class memory::TransferManager;
|
||||
@@ -54,6 +54,16 @@ namespace fgl::engine
|
||||
const vk::Extent2D& getExtent() const { return m_extent; }
|
||||
|
||||
[[nodiscard]] std::shared_ptr< ImageView > getView();
|
||||
|
||||
vk::ImageMemoryBarrier transitionTo(
|
||||
vk::ImageLayout old_layout, vk::ImageLayout new_layout, const vk::ImageSubresourceRange& range ) const;
|
||||
|
||||
vk::ImageMemoryBarrier transitionTo( vk::ImageLayout old_layout, vk::ImageLayout new_layout, vk::ImageAspectFlags aspect );
|
||||
|
||||
inline vk::ImageMemoryBarrier transitionColorTo(vk::ImageLayout old_layout, vk::ImageLayout new_layout)
|
||||
{
|
||||
return transitionTo( old_layout, new_layout, vk::ImageAspectFlagBits::eColor );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -109,12 +109,13 @@ namespace fgl::engine
|
||||
|
||||
Texture::Texture( std::vector< std::byte >&& data, const vk::Extent2D extent, const vk::Format format ) :
|
||||
m_texture_id( texture_id_pool.getID() ),
|
||||
m_image( std::make_shared< Image >(
|
||||
extent,
|
||||
format,
|
||||
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal ) ),
|
||||
m_image(
|
||||
std::make_shared< Image >(
|
||||
extent,
|
||||
format,
|
||||
vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eShaderReadOnlyOptimal ) ),
|
||||
m_image_view( m_image->getView() ),
|
||||
m_extent( extent ),
|
||||
m_name( "Default Texture Name" )
|
||||
@@ -147,6 +148,11 @@ namespace fgl::engine
|
||||
texture_id_pool.markUnused( m_texture_id );
|
||||
}
|
||||
|
||||
Image& Texture::getImageRef()
|
||||
{
|
||||
return *m_image;
|
||||
}
|
||||
|
||||
vk::DescriptorImageInfo Texture::getDescriptor() const
|
||||
{
|
||||
return m_image_view->descriptorInfo( vk::ImageLayout::eGeneral );
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace fgl::engine
|
||||
|
||||
~Texture();
|
||||
|
||||
Image& getImageRef();
|
||||
|
||||
Texture( const Texture& ) = delete;
|
||||
Texture& operator=( const Texture& ) = delete;
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#include "CameraInfo.hpp"
|
||||
#include "CameraRenderer.hpp"
|
||||
#include "CameraSwapchain.hpp"
|
||||
#include "GBufferRenderer.hpp"
|
||||
#include "GBufferSwapchain.hpp"
|
||||
#include "engine/debug/timing/FlameGraph.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
@@ -69,11 +69,11 @@ namespace fgl::engine
|
||||
{
|
||||
ZoneScopedN( "Camera::pass" );
|
||||
auto timer = debug::timing::push( "Camera" );
|
||||
if ( m_cold && m_swapchain )
|
||||
if ( m_cold && m_gbuffer_swapchain )
|
||||
{
|
||||
//TODO: Make some way to destroy the swapchain in a deffered manner.
|
||||
m_old_swapchain = m_swapchain;
|
||||
m_swapchain = nullptr;
|
||||
// m_old_swapchain = m_gbuffer_swapchain;
|
||||
m_gbuffer_swapchain = nullptr;
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
@@ -82,19 +82,25 @@ namespace fgl::engine
|
||||
assert( frame_info.camera == nullptr );
|
||||
frame_info.camera = this;
|
||||
|
||||
if ( m_swapchain->getExtent() != m_target_extent )
|
||||
if ( m_gbuffer_swapchain->getExtent() != m_target_extent )
|
||||
{
|
||||
remakeSwapchain( m_target_extent );
|
||||
}
|
||||
|
||||
updateInfo( frame_info.frame_idx );
|
||||
m_camera_renderer->pass( frame_info, *m_swapchain );
|
||||
FGL_ASSERT( m_camera_renderer, "Camera renderer should not be nullptr" );
|
||||
m_camera_renderer->pass( frame_info, *m_gbuffer_swapchain );
|
||||
frame_info.camera = nullptr;
|
||||
}
|
||||
|
||||
CameraSwapchain& Camera::getSwapchain() const
|
||||
GBufferSwapchain& Camera::getSwapchain() const
|
||||
{
|
||||
return *m_swapchain;
|
||||
return *m_gbuffer_swapchain;
|
||||
}
|
||||
|
||||
CompositeSwapchain& Camera::getCompositeSwapchain() const
|
||||
{
|
||||
return *m_composite_swapchain;
|
||||
}
|
||||
|
||||
void Camera::setViewport( const vk::raii::CommandBuffer& command_buffer )
|
||||
@@ -103,7 +109,7 @@ namespace fgl::engine
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
|
||||
const auto& [ width, height ] = m_swapchain->getExtent();
|
||||
const auto& [ width, height ] = m_gbuffer_swapchain->getExtent();
|
||||
viewport.width = static_cast< float >( width );
|
||||
viewport.height = static_cast< float >( height );
|
||||
viewport.minDepth = 0.0f;
|
||||
@@ -116,7 +122,7 @@ namespace fgl::engine
|
||||
|
||||
void Camera::setScissor( const vk::raii::CommandBuffer& command_buffer )
|
||||
{
|
||||
const vk::Rect2D scissor { { 0, 0 }, m_swapchain->getExtent() };
|
||||
const vk::Rect2D scissor { { 0, 0 }, m_gbuffer_swapchain->getExtent() };
|
||||
|
||||
const std::vector< vk::Rect2D > scissors { scissor };
|
||||
|
||||
@@ -126,8 +132,9 @@ namespace fgl::engine
|
||||
void Camera::remakeSwapchain( vk::Extent2D extent )
|
||||
{
|
||||
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
||||
m_old_swapchain = m_swapchain;
|
||||
m_swapchain = std::make_shared< CameraSwapchain >( m_camera_renderer->getRenderpass(), extent );
|
||||
|
||||
m_composite_swapchain = std::make_unique< CompositeSwapchain >( extent );
|
||||
m_gbuffer_swapchain = std::make_unique< GBufferSwapchain >( extent );
|
||||
}
|
||||
|
||||
void Camera::setName( const std::string_view str )
|
||||
@@ -137,15 +144,16 @@ namespace fgl::engine
|
||||
|
||||
float Camera::aspectRatio() const
|
||||
{
|
||||
return m_swapchain->getAspectRatio();
|
||||
return m_gbuffer_swapchain->getAspectRatio();
|
||||
}
|
||||
|
||||
void Camera::
|
||||
copyOutput( const vk::raii::CommandBuffer& command_buffer, const FrameIndex frame_index, Image& target )
|
||||
{
|
||||
assert( m_swapchain->getExtent() == target.getExtent() );
|
||||
assert( m_gbuffer_swapchain->getExtent() == target.getExtent() );
|
||||
|
||||
Image& source { this->getSwapchain().getOutput( frame_index ) };
|
||||
Texture& source_tex { *m_composite_swapchain->m_gbuffer_target[ frame_index ] };
|
||||
Image& source { source_tex.getImageRef() };
|
||||
|
||||
vk::ImageSubresourceRange range {};
|
||||
range.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||
@@ -192,7 +200,7 @@ namespace fgl::engine
|
||||
{ barrier_from_source } );
|
||||
|
||||
vk::ImageCopy region {};
|
||||
region.extent = vk::Extent3D( m_swapchain->getExtent(), 1 );
|
||||
region.extent = vk::Extent3D( m_gbuffer_swapchain->getExtent(), 1 );
|
||||
|
||||
region.srcSubresource.aspectMask = vk::ImageAspectFlagBits::eColor;
|
||||
region.srcSubresource.layerCount = 1;
|
||||
@@ -318,14 +326,14 @@ namespace fgl::engine
|
||||
return camera_descriptor_set;
|
||||
}
|
||||
|
||||
Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer, std::unique_ptr< CameraRenderer >& renderer ) :
|
||||
m_camera_renderer( renderer ),
|
||||
m_transform(),
|
||||
Camera::Camera( const vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer ) :
|
||||
m_target_extent( extent ),
|
||||
m_camera_frame_info( buffer, SwapChain::MAX_FRAMES_IN_FLIGHT ),
|
||||
m_swapchain( std::make_shared< CameraSwapchain >( m_camera_renderer->getRenderpass(), m_target_extent ) ),
|
||||
m_name()
|
||||
m_composite_swapchain( std::make_unique< CompositeSwapchain >( m_target_extent ) ),
|
||||
m_gbuffer_swapchain( std::make_unique< GBufferSwapchain >( m_target_extent ) ),
|
||||
m_camera_renderer( renderer ),
|
||||
m_camera_frame_info( buffer, SwapChain::MAX_FRAMES_IN_FLIGHT )
|
||||
{
|
||||
FGL_ASSERT( renderer, "Camera renderer is null" );
|
||||
this->setPerspectiveProjection( m_fov_y, aspectRatio(), constants::NEAR_PLANE, constants::FAR_PLANE );
|
||||
this->setView( WorldCoordinate( constants::CENTER ), Rotation( 0.0f, 0.0f, 0.0f ) );
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#include "CompositeSwapchain.hpp"
|
||||
#include "engine/descriptors/DescriptorSet.hpp"
|
||||
#include "engine/memory/buffers/HostSingleT.hpp"
|
||||
#include "engine/memory/buffers/UniqueFrameSuballocation.hpp"
|
||||
@@ -34,10 +35,10 @@ namespace fgl::engine
|
||||
}
|
||||
class Image;
|
||||
struct FrameInfo;
|
||||
class CameraRenderer;
|
||||
class GBufferRenderer;
|
||||
|
||||
struct CameraInfo;
|
||||
class CameraSwapchain;
|
||||
class GBufferSwapchain;
|
||||
class Camera;
|
||||
|
||||
FrustumBase createFrustum( float aspect, float fovy, float near, float far );
|
||||
@@ -48,7 +49,12 @@ namespace fgl::engine
|
||||
{
|
||||
inline static CameraIDX m_camera_counter { 0 };
|
||||
|
||||
std::unique_ptr< CameraRenderer >& m_camera_renderer;
|
||||
vk::Extent2D m_target_extent;
|
||||
|
||||
std::unique_ptr< CompositeSwapchain > m_composite_swapchain;
|
||||
std::unique_ptr< GBufferSwapchain > m_gbuffer_swapchain;
|
||||
|
||||
std::shared_ptr< GBufferRenderer > m_camera_renderer;
|
||||
|
||||
//! True if the camera is active and to be rendered
|
||||
bool m_active { true };
|
||||
@@ -73,7 +79,6 @@ namespace fgl::engine
|
||||
|
||||
WorldTransform m_transform;
|
||||
|
||||
vk::Extent2D m_target_extent;
|
||||
float m_fov_y { glm::radians( 90.0f ) };
|
||||
|
||||
PerFrameSuballocation< HostSingleT< CameraInfo > > m_camera_frame_info;
|
||||
@@ -81,10 +86,6 @@ namespace fgl::engine
|
||||
// Camera info is expected at binding 0
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_camera_info_descriptors {};
|
||||
|
||||
// TODO: Remove this old swapchain and instead do a proper deffered cleanup of it.
|
||||
std::shared_ptr< CameraSwapchain > m_old_swapchain { nullptr };
|
||||
std::shared_ptr< CameraSwapchain > m_swapchain;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
Matrix< MatrixType::ModelToWorld > frustumTranslationMatrix() const;
|
||||
@@ -96,7 +97,7 @@ namespace fgl::engine
|
||||
Camera( vk::Extent2D test_extent ) : m_target_extent( test_extent ) {}
|
||||
#endif
|
||||
|
||||
Camera( vk::Extent2D extent, memory::Buffer& buffer, std::unique_ptr< CameraRenderer >& renderer );
|
||||
Camera( vk::Extent2D extent, memory::Buffer& buffer, const std::shared_ptr< GBufferRenderer >& renderer );
|
||||
|
||||
friend class CameraManager;
|
||||
|
||||
@@ -114,8 +115,6 @@ namespace fgl::engine
|
||||
|
||||
const std::string& getName() const;
|
||||
|
||||
static void initCameraRenderer();
|
||||
|
||||
void setExtent( vk::Extent2D extent );
|
||||
|
||||
const Rotation& getRotation() const { return m_transform.rotation; }
|
||||
@@ -171,7 +170,8 @@ namespace fgl::engine
|
||||
|
||||
FGL_FORCE_INLINE NormalVector getDown() const
|
||||
{
|
||||
return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) ); }
|
||||
return NormalVector( glm::vec3( m_inverse_view_matrix[ 1 ] ) );
|
||||
}
|
||||
|
||||
//! Updates the required info for rendering
|
||||
void updateInfo( FrameIndex frame_index );
|
||||
@@ -182,7 +182,8 @@ namespace fgl::engine
|
||||
//! Performs the render pass for this camera
|
||||
void pass( FrameInfo& frame_info );
|
||||
|
||||
CameraSwapchain& getSwapchain() const;
|
||||
GBufferSwapchain& getSwapchain() const;
|
||||
CompositeSwapchain& getCompositeSwapchain() const;
|
||||
void setViewport( const vk::raii::CommandBuffer& command_buffer );
|
||||
void setScissor( const vk::raii::CommandBuffer& command_buffer );
|
||||
|
||||
@@ -204,6 +205,4 @@ namespace fgl::engine
|
||||
#endif
|
||||
};
|
||||
|
||||
descriptors::DescriptorSetLayout& getCameraDescriptorSet();
|
||||
|
||||
} // namespace fgl::engine
|
||||
|
||||
46
src/engine/camera/Camera.puml
Normal file
46
src/engine/camera/Camera.puml
Normal file
@@ -0,0 +1,46 @@
|
||||
@startuml
|
||||
'https://plantuml.com/component-diagram
|
||||
|
||||
|
||||
package "Some Group" {
|
||||
HTTP - [First Component]
|
||||
[Another Component]
|
||||
}
|
||||
|
||||
node "Other Groups" {
|
||||
FTP - [Second Component]
|
||||
[First Component] --> FTP
|
||||
}
|
||||
|
||||
cloud {
|
||||
[Example 1]
|
||||
}
|
||||
|
||||
|
||||
database "MySql" {
|
||||
folder "This is my folder" {
|
||||
[Folder 3]
|
||||
}
|
||||
frame "Foo" {
|
||||
[Frame 4]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Another Component] --> [Example 1]
|
||||
[Example 1] --> [Folder 3]
|
||||
[Folder 3] --> [Frame 4]
|
||||
|
||||
node "GBufferSwapchain" {
|
||||
node "Albedo"
|
||||
node "Metallic"
|
||||
node "Position & Depth 16F4"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "CameraManager.hpp"
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "CameraRenderer.hpp"
|
||||
#include "GBufferRenderer.hpp"
|
||||
#include "engine/debug/DEBUG_NAMES.hpp"
|
||||
#include "engine/math/literals/size.hpp"
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace fgl::engine
|
||||
}
|
||||
|
||||
CameraManager::CameraManager() :
|
||||
m_renderer( std::make_unique< CameraRenderer >() ),
|
||||
m_renderer( std::make_shared< GBufferRenderer >() ),
|
||||
m_data_buffer( 4_KiB, vk::BufferUsageFlagBits::eUniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible )
|
||||
{
|
||||
m_primary_camera = createCamera( { 1920, 1080 } );
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace fgl::engine
|
||||
|
||||
class CameraManager
|
||||
{
|
||||
std::unique_ptr< CameraRenderer > m_renderer;
|
||||
std::shared_ptr< GBufferRenderer > m_renderer;
|
||||
memory::Buffer m_data_buffer;
|
||||
|
||||
std::shared_ptr< Camera > m_primary_camera { nullptr };
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 7/21/24.
|
||||
//
|
||||
|
||||
#include "CameraRenderer.hpp"
|
||||
|
||||
#include "CameraSwapchain.hpp"
|
||||
#include "engine/rendering/renderpass/RenderPass.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class CameraSwapchain;
|
||||
|
||||
vk::raii::RenderPass CameraRenderer::createRenderPass()
|
||||
{
|
||||
rendering::RenderPassBuilder builder {};
|
||||
|
||||
builder.setAttachmentCount( 7 );
|
||||
|
||||
// Set formats for each item in the swapchain
|
||||
|
||||
//XYZ in world space
|
||||
auto position { builder.attachment( POSITION_INDEX ) };
|
||||
position.setFormat( pickPositionFormat() ); // position
|
||||
position.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
position.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
//RGBA
|
||||
auto normal { builder.attachment( NORMAL_INDEX ) };
|
||||
normal.setFormat( pickNormalFormat() ); // normal
|
||||
normal.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
normal.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
// RGBA
|
||||
auto color { builder.attachment( COLOR_INDEX ) };
|
||||
color.setFormat( pickColorFormat() ); // color
|
||||
color.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
color.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
// Metallic, Roughness, Occlusion
|
||||
auto metallic_roughness { builder.attachment( METALLIC_INDEX ) };
|
||||
metallic_roughness.setFormat( pickMetallicFormat() );
|
||||
metallic_roughness.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
metallic_roughness.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
// RGB
|
||||
auto emissive { builder.attachment( EMISSIVE_INDEX ) };
|
||||
emissive.setFormat( pickEmissiveFormat() );
|
||||
emissive.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
emissive.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
auto composite { builder.attachment( COMPOSITE_INDEX ) };
|
||||
//TODO: For HDR I think this needs to be a bigger range then 8bits per channel.
|
||||
composite.setFormat( pickCompositeFormat() ); // composite
|
||||
composite.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
composite.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
auto depth { builder.attachment( DEPTH_INDEX ) };
|
||||
depth.setLayouts( vk::ImageLayout::eUndefined, vk::ImageLayout::eDepthStencilReadOnlyOptimal );
|
||||
depth.setFormat( pickDepthFormat() ); // depth
|
||||
depth.setOps( vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore );
|
||||
|
||||
auto& g_buffer_subpass { builder.createSubpass( 0 ) };
|
||||
g_buffer_subpass.setDepthLayout( DEPTH_INDEX, vk::ImageLayout::eDepthStencilAttachmentOptimal );
|
||||
g_buffer_subpass.addRenderLayout( COLOR_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
g_buffer_subpass.addRenderLayout( POSITION_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
g_buffer_subpass.addRenderLayout( NORMAL_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
g_buffer_subpass.addRenderLayout( METALLIC_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
g_buffer_subpass.addRenderLayout( EMISSIVE_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
|
||||
g_buffer_subpass.addDependencyFromExternal(
|
||||
vk::AccessFlagBits::eDepthStencilAttachmentWrite,
|
||||
vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests );
|
||||
|
||||
g_buffer_subpass.addDependencyFromExternal(
|
||||
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
|
||||
|
||||
auto& composite_subpass { builder.createSubpass( 1 ) };
|
||||
composite_subpass.addRenderLayout( COMPOSITE_INDEX, vk::ImageLayout::eColorAttachmentOptimal );
|
||||
composite_subpass.addInputLayout( COLOR_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
composite_subpass.addInputLayout( POSITION_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
composite_subpass.addInputLayout( NORMAL_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
composite_subpass.addInputLayout( METALLIC_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
composite_subpass.addInputLayout( EMISSIVE_INDEX, vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
composite_subpass.addDependency(
|
||||
g_buffer_subpass,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite,
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::AccessFlagBits::eInputAttachmentRead,
|
||||
vk::PipelineStageFlagBits::eFragmentShader );
|
||||
|
||||
composite_subpass.addDependencyFromExternal(
|
||||
vk::AccessFlagBits::eColorAttachmentWrite, vk::PipelineStageFlagBits::eColorAttachmentOutput );
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
void CameraRenderer::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
vk::Viewport viewport {};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast< float >( extent.width );
|
||||
viewport.height = static_cast< float >( extent.height );
|
||||
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
const std::vector< vk::Viewport > viewports { viewport };
|
||||
|
||||
command_buffer.setViewport( 0, viewports );
|
||||
}
|
||||
|
||||
void CameraRenderer::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
const vk::Rect2D scissor { { 0, 0 }, extent };
|
||||
|
||||
const std::vector< vk::Rect2D > scissors { scissor };
|
||||
|
||||
command_buffer.setScissor( 0, scissors );
|
||||
}
|
||||
|
||||
void CameraRenderer::beginRenderPass(
|
||||
const vk::raii::CommandBuffer& command_buffer, CameraSwapchain& swapchain, const FrameIndex index )
|
||||
{
|
||||
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
|
||||
|
||||
command_buffer.beginRendering( info );
|
||||
|
||||
/*
|
||||
vk::RenderPassBeginInfo info {};
|
||||
info.renderPass = m_renderpass;
|
||||
info.framebuffer = swapchain.getFramebuffer( index );
|
||||
info.renderArea = { .offset = { 0, 0 }, .extent = swapchain.getExtent() };
|
||||
|
||||
info.setClearValues( swapchain.getClearValues() );
|
||||
*/
|
||||
|
||||
// command_buffer.beginRenderPass( info, vk::SubpassContents::eInline );
|
||||
|
||||
setViewport( command_buffer, swapchain.getExtent() );
|
||||
setScissor( command_buffer, swapchain.getExtent() );
|
||||
}
|
||||
|
||||
void CameraRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer )
|
||||
{
|
||||
command_buffer.endRendering();
|
||||
// command_buffer.endRenderPass();
|
||||
}
|
||||
|
||||
void CameraRenderer::pass( FrameInfo& frame_info, CameraSwapchain& camera_swapchain )
|
||||
{
|
||||
ZoneScopedN( "CameraRenderer::pass" );
|
||||
m_culling_system.startPass( frame_info );
|
||||
|
||||
auto& command_buffer { frame_info.command_buffer };
|
||||
|
||||
camera_swapchain.transitionImages( command_buffer, CameraSwapchain::INITAL, frame_info.frame_idx );
|
||||
|
||||
beginRenderPass( command_buffer, camera_swapchain, frame_info.frame_idx );
|
||||
|
||||
// Transition the gbuffer to it's inital state
|
||||
|
||||
m_culling_system.wait();
|
||||
|
||||
//m_terrain_system.pass( frame_info );
|
||||
|
||||
m_entity_renderer.pass( frame_info );
|
||||
m_line_drawer.pass( frame_info );
|
||||
|
||||
endRenderPass( command_buffer );
|
||||
|
||||
m_composition_system.pass( frame_info );
|
||||
}
|
||||
|
||||
vk::raii::RenderPass& CameraRenderer::getRenderpass()
|
||||
{
|
||||
return m_renderpass;
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -1,284 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 7/11/24.
|
||||
//
|
||||
|
||||
#include "CameraSwapchain.hpp"
|
||||
|
||||
#include "engine/descriptors/DescriptorSet.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > CameraSwapchain::createGBufferDescriptors()
|
||||
{
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {};
|
||||
data.resize( SwapChain::MAX_FRAMES_IN_FLIGHT );
|
||||
|
||||
for ( PresentIndex i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||
{
|
||||
//auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
|
||||
auto set { gbuffer_set.create() };
|
||||
|
||||
set->bindAttachment( 0, m_gbuffer.m_color.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eShaderReadOnlyOptimal );
|
||||
|
||||
set->update();
|
||||
|
||||
data[ i ] = std::move( set );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
vk::ImageMemoryBarrier createColorImageBarrier(
|
||||
const Image& image,
|
||||
const vk::ImageLayout old_layout,
|
||||
const vk::ImageLayout new_layout,
|
||||
const vk::AccessFlags flags )
|
||||
{
|
||||
vk::ImageMemoryBarrier barrier {};
|
||||
|
||||
barrier.setImage( image.getVkImage() );
|
||||
barrier.setOldLayout( old_layout );
|
||||
barrier.setNewLayout( new_layout );
|
||||
barrier.setSrcAccessMask( flags );
|
||||
|
||||
constexpr vk::ImageSubresourceRange subresource { vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1 };
|
||||
|
||||
barrier.setSubresourceRange( subresource );
|
||||
|
||||
return barrier;
|
||||
}
|
||||
|
||||
vk::ImageMemoryBarrier createDepthImageBarrier(
|
||||
const Image& image, const vk::ImageLayout old_layout, const vk::ImageLayout new_layout )
|
||||
{
|
||||
vk::ImageMemoryBarrier barrier {};
|
||||
barrier.setImage( image.getVkImage() );
|
||||
barrier.setOldLayout( old_layout );
|
||||
barrier.setNewLayout( new_layout );
|
||||
constexpr vk::ImageSubresourceRange subresource {
|
||||
vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1,
|
||||
};
|
||||
|
||||
barrier.setSubresourceRange( subresource );
|
||||
return barrier;
|
||||
}
|
||||
|
||||
void CameraSwapchain::transitionImages(
|
||||
vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index )
|
||||
{
|
||||
switch ( stage_id )
|
||||
{
|
||||
default:
|
||||
throw std::invalid_argument( "Invalid Stage ID" );
|
||||
case INITAL:
|
||||
{
|
||||
const std::vector< vk::ImageMemoryBarrier > barriers {
|
||||
createColorImageBarrier(
|
||||
m_gbuffer.m_color.getImage( index ),
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eColorAttachmentOptimal,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
|
||||
createColorImageBarrier(
|
||||
m_gbuffer.m_emissive.getImage( index ),
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eColorAttachmentOptimal,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
|
||||
createColorImageBarrier(
|
||||
m_gbuffer.m_metallic.getImage( index ),
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eColorAttachmentOptimal,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
|
||||
createColorImageBarrier(
|
||||
m_gbuffer.m_position.getImage( index ),
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eColorAttachmentOptimal,
|
||||
vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead ),
|
||||
createDepthImageBarrier(
|
||||
m_gbuffer.m_depth.getImage( index ),
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eDepthStencilAttachmentOptimal )
|
||||
};
|
||||
|
||||
command_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::PipelineStageFlagBits::eBottomOfPipe,
|
||||
vk::DependencyFlags( 0 ),
|
||||
{},
|
||||
{},
|
||||
barriers );
|
||||
|
||||
return;
|
||||
}
|
||||
case FINAL:
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vk::RenderingInfo CameraSwapchain::getRenderingInfo( const FrameIndex frame_index )
|
||||
{
|
||||
// This should be safe to have as static as the information used here will only capable of being used in a single frame.
|
||||
static thread_local std::vector< vk::RenderingAttachmentInfo > color_attachment_infos {};
|
||||
static thread_local vk::RenderingAttachmentInfo depth_attachment_infos {};
|
||||
|
||||
depth_attachment_infos = m_gbuffer.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal );
|
||||
|
||||
color_attachment_infos.clear();
|
||||
color_attachment_infos = {
|
||||
m_gbuffer.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_position.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_normal.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_metallic.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_emissive.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal )
|
||||
};
|
||||
|
||||
vk::RenderingInfo rendering_info {};
|
||||
|
||||
rendering_info.setRenderArea( { { 0, 0 }, m_extent } );
|
||||
|
||||
rendering_info.setLayerCount( 1 );
|
||||
|
||||
rendering_info.setColorAttachments( color_attachment_infos );
|
||||
rendering_info.setPDepthAttachment( &depth_attachment_infos );
|
||||
// rendering_info.setPStencilAttachment( &depth_attachment_infos );
|
||||
|
||||
return rendering_info;
|
||||
}
|
||||
|
||||
const std::vector< vk::ClearValue >& CameraSwapchain::getClearValues()
|
||||
{
|
||||
assert( !m_clear_values.empty() );
|
||||
return m_clear_values;
|
||||
}
|
||||
|
||||
std::vector< vk::raii::Framebuffer > CameraSwapchain::createFrambuffers()
|
||||
{
|
||||
constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT };
|
||||
|
||||
m_gbuffer.m_color.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_position.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_normal.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_metallic.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_emissive.createResources( image_count, m_extent );
|
||||
|
||||
m_gbuffer.m_composite.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc );
|
||||
m_gbuffer.m_depth.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
|
||||
|
||||
std::vector< vk::raii::Framebuffer > buffers {};
|
||||
buffers.reserve( image_count );
|
||||
|
||||
for ( FrameIndex i = 0; i < image_count; ++i )
|
||||
{
|
||||
std::vector< vk::ImageView > attachments { getViewsForFrame(
|
||||
i,
|
||||
m_gbuffer.m_color,
|
||||
m_gbuffer.m_position,
|
||||
m_gbuffer.m_normal,
|
||||
m_gbuffer.m_metallic,
|
||||
m_gbuffer.m_emissive,
|
||||
m_gbuffer.m_composite,
|
||||
m_gbuffer.m_depth ) };
|
||||
|
||||
vk::FramebufferCreateInfo info {};
|
||||
info.renderPass = m_renderpass;
|
||||
info.setAttachments( attachments );
|
||||
info.width = m_extent.width;
|
||||
info.height = m_extent.height;
|
||||
info.layers = 1;
|
||||
|
||||
buffers.emplace_back( Device::getInstance()->createFramebuffer( info ) );
|
||||
|
||||
m_g_buffer_color_img.emplace_back(
|
||||
std::make_unique< Texture >( m_gbuffer.m_color.m_attachment_resources.m_images[ i ]
|
||||
->setName( "GBufferColor" ) ) );
|
||||
|
||||
auto& position_resources { m_gbuffer.m_position.m_attachment_resources };
|
||||
assert( position_resources.m_images[ i ] );
|
||||
assert( position_resources.m_image_views[ i ] );
|
||||
auto& position_image { *position_resources.m_images[ i ] };
|
||||
position_image.setName( format_ns::format( "GBufferPosition: {}", i ) );
|
||||
m_g_buffer_position_img.emplace_back( std::make_unique< Texture >( position_image ) );
|
||||
|
||||
m_g_buffer_normal_img.emplace_back(
|
||||
std::make_unique< Texture >( m_gbuffer.m_normal.m_attachment_resources.m_images[ i ]
|
||||
->setName( "GBufferNormal" ) ) );
|
||||
|
||||
m_g_buffer_metallic_img.emplace_back(
|
||||
std::make_unique< Texture >( m_gbuffer.m_metallic.m_attachment_resources.m_images[ i ]
|
||||
->setName( "GBufferMetallic" ) ) );
|
||||
|
||||
m_g_buffer_emissive_img.emplace_back(
|
||||
std::make_unique< Texture >( m_gbuffer.m_emissive.m_attachment_resources.m_images[ i ]
|
||||
->setName( "GBufferEmissive" ) ) );
|
||||
|
||||
m_g_buffer_composite_img.emplace_back(
|
||||
std::make_unique< Texture >( m_gbuffer.m_composite.m_attachment_resources.m_images[ i ]
|
||||
->setName( "GBufferComposite" ) ) );
|
||||
}
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
||||
descriptors::DescriptorSet& CameraSwapchain::getGBufferDescriptor( const FrameIndex frame_index )
|
||||
{
|
||||
return *m_gbuffer_descriptor_set[ frame_index ];
|
||||
}
|
||||
|
||||
vk::raii::Framebuffer& CameraSwapchain::getFramebuffer( const FrameIndex frame_index )
|
||||
{
|
||||
return m_framebuffers[ frame_index ];
|
||||
}
|
||||
|
||||
vk::Extent2D CameraSwapchain::getExtent() const
|
||||
{
|
||||
return m_extent;
|
||||
}
|
||||
|
||||
Image& CameraSwapchain::getOutput( const FrameIndex index )
|
||||
{
|
||||
assert( index <= this->m_gbuffer.m_composite.m_attachment_resources.m_images.size() );
|
||||
return *m_gbuffer.m_composite.m_attachment_resources.m_images[ index ];
|
||||
}
|
||||
|
||||
float CameraSwapchain::getAspectRatio()
|
||||
{
|
||||
return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height );
|
||||
}
|
||||
|
||||
CameraSwapchain::CameraSwapchain( vk::raii::RenderPass& renderpass, const vk::Extent2D extent ) :
|
||||
m_extent( extent ),
|
||||
m_renderpass( renderpass ),
|
||||
m_framebuffers( createFrambuffers() ),
|
||||
m_clear_values( gatherClearValues(
|
||||
m_gbuffer.m_color,
|
||||
m_gbuffer.m_position,
|
||||
m_gbuffer.m_normal,
|
||||
m_gbuffer.m_metallic,
|
||||
m_gbuffer.m_emissive,
|
||||
m_gbuffer.m_composite,
|
||||
m_gbuffer.m_depth ) ),
|
||||
m_gbuffer_descriptor_set( createGBufferDescriptors() )
|
||||
{
|
||||
m_gbuffer.m_depth.setName( "Depth" );
|
||||
}
|
||||
|
||||
CameraSwapchain::~CameraSwapchain()
|
||||
{
|
||||
for ( auto& descriptor : m_gbuffer_descriptor_set )
|
||||
{
|
||||
descriptors::queueDescriptorDeletion( std::move( descriptor ) );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
91
src/engine/camera/CompositeSwapchain.cpp
Normal file
91
src/engine/camera/CompositeSwapchain.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// Created by kj16609 on 1/13/25.
|
||||
//
|
||||
#include "CompositeSwapchain.hpp"
|
||||
|
||||
#include "engine/rendering/SwapChain.hpp"
|
||||
#include "engine/rendering/pipelines/Attachment.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class Texture;
|
||||
|
||||
void CompositeSwapchain::
|
||||
transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index )
|
||||
{
|
||||
switch ( stage_id )
|
||||
{
|
||||
default:
|
||||
throw std::runtime_error( "Invalid StageID" );
|
||||
case INITAL:
|
||||
{
|
||||
const std::vector< vk::ImageMemoryBarrier > barriers {
|
||||
m_buffer.m_target.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
};
|
||||
|
||||
command_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eTopOfPipe,
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::DependencyFlags( 0 ),
|
||||
{},
|
||||
{},
|
||||
barriers );
|
||||
|
||||
return;
|
||||
}
|
||||
case FINAL:
|
||||
{
|
||||
const std::vector< vk::ImageMemoryBarrier > barriers {
|
||||
m_buffer.m_target.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::ePresentSrcKHR ),
|
||||
};
|
||||
|
||||
command_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::PipelineStageFlagBits::eBottomOfPipe,
|
||||
vk::DependencyFlags( 0 ),
|
||||
{},
|
||||
{},
|
||||
barriers );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vk::RenderingInfo CompositeSwapchain::getRenderingInfo( const FrameIndex index )
|
||||
{
|
||||
static thread_local std::vector< vk::RenderingAttachmentInfo > infos {};
|
||||
|
||||
infos.clear();
|
||||
|
||||
infos = { m_buffer.m_target.renderInfo( index, vk::ImageLayout::eColorAttachmentOptimal ) };
|
||||
|
||||
vk::RenderingInfo rendering_info {};
|
||||
|
||||
rendering_info.setRenderArea( { { 0, 0 }, m_extent } );
|
||||
|
||||
rendering_info.setLayerCount( 1 );
|
||||
|
||||
rendering_info.setColorAttachments( infos );
|
||||
|
||||
return rendering_info;
|
||||
}
|
||||
|
||||
CompositeSwapchain::CompositeSwapchain( vk::Extent2D extent ) : m_extent( extent )
|
||||
{
|
||||
constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT };
|
||||
|
||||
m_buffer.m_target.createResources( image_count, m_extent, vk::ImageUsageFlagBits::eTransferSrc );
|
||||
|
||||
for ( const auto& image : m_buffer.m_target.m_attachment_resources.m_images )
|
||||
{
|
||||
m_gbuffer_target.emplace_back( std::make_unique< Texture >( *image ) );
|
||||
}
|
||||
}
|
||||
|
||||
CompositeSwapchain::~CompositeSwapchain()
|
||||
{}
|
||||
|
||||
} // namespace fgl::engine
|
||||
44
src/engine/camera/CompositeSwapchain.hpp
Normal file
44
src/engine/camera/CompositeSwapchain.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by kj16609 on 1/13/25.
|
||||
//
|
||||
#pragma once
|
||||
#include "engine/rendering/RenderingFormats.hpp"
|
||||
#include "engine/rendering/pipelines/Attachment.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class Texture;
|
||||
|
||||
class CompositeSwapchain
|
||||
{
|
||||
vk::Extent2D m_extent;
|
||||
|
||||
struct
|
||||
{
|
||||
ColorAttachment< 0 > m_target { pickCompositeFormat() };
|
||||
} m_buffer {};
|
||||
|
||||
public:
|
||||
|
||||
FGL_DELETE_COPY( CompositeSwapchain );
|
||||
FGL_DELETE_MOVE( CompositeSwapchain );
|
||||
|
||||
std::vector< std::unique_ptr< Texture > > m_gbuffer_target {};
|
||||
|
||||
enum StageID : std::uint16_t
|
||||
{
|
||||
INITAL,
|
||||
FINAL,
|
||||
};
|
||||
|
||||
void transitionImages( vk::raii::CommandBuffer& command_buffer, StageID stage_id, FrameIndex index );
|
||||
|
||||
vk::RenderingInfo getRenderingInfo( FrameIndex index );
|
||||
|
||||
vk::Extent2D getExtent() const { return m_extent; }
|
||||
|
||||
CompositeSwapchain( vk::Extent2D extent );
|
||||
~CompositeSwapchain();
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
99
src/engine/camera/GBufferCompositor.cpp
Normal file
99
src/engine/camera/GBufferCompositor.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Created by kj16609 on 1/13/25.
|
||||
//
|
||||
#include "GBufferCompositor.hpp"
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "CompositeSwapchain.hpp"
|
||||
#include "GBufferSwapchain.hpp"
|
||||
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
void GBufferCompositor::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
vk::Viewport viewport {};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast< float >( extent.width );
|
||||
viewport.height = static_cast< float >( extent.height );
|
||||
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
const std::vector< vk::Viewport > viewports { viewport };
|
||||
|
||||
command_buffer.setViewport( 0, viewports );
|
||||
}
|
||||
|
||||
void GBufferCompositor::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
const vk::Rect2D scissor { { 0, 0 }, extent };
|
||||
|
||||
const std::vector< vk::Rect2D > scissors { scissor };
|
||||
|
||||
command_buffer.setScissor( 0, scissors );
|
||||
}
|
||||
|
||||
void GBufferCompositor::
|
||||
beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index )
|
||||
{
|
||||
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
|
||||
|
||||
cmd.beginRendering( info );
|
||||
|
||||
setViewport( cmd, swapchain.getExtent() );
|
||||
setScissor( cmd, swapchain.getExtent() );
|
||||
}
|
||||
|
||||
void GBufferCompositor::endPass( vk::raii::CommandBuffer& cmd )
|
||||
{
|
||||
cmd.endRendering();
|
||||
}
|
||||
|
||||
GBufferCompositor::GBufferCompositor( const CompositeFlags flags ) : m_flags( flags )
|
||||
{
|
||||
PipelineBuilder builder { 0 };
|
||||
|
||||
builder.addDescriptorSet( gbuffer_set );
|
||||
builder.addDescriptorSet( Camera::getDescriptorLayout() );
|
||||
|
||||
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
|
||||
|
||||
builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) );
|
||||
|
||||
builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) );
|
||||
builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) );
|
||||
|
||||
builder.disableCulling();
|
||||
builder.disableVertexInput();
|
||||
|
||||
m_pipeline = builder.create();
|
||||
|
||||
m_pipeline->setDebugName( "Composition pipeline" );
|
||||
}
|
||||
|
||||
void GBufferCompositor::
|
||||
composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, const FrameIndex frame_index )
|
||||
{
|
||||
auto& gbuffer_swapchain { camera.getSwapchain() };
|
||||
auto& composite_swapchain { camera.getCompositeSwapchain() };
|
||||
|
||||
composite_swapchain.transitionImages( command_buffer, CompositeSwapchain::INITAL, frame_index );
|
||||
|
||||
beginPass( command_buffer, composite_swapchain, frame_index );
|
||||
|
||||
m_pipeline->bind( command_buffer );
|
||||
|
||||
m_pipeline->bindDescriptor( command_buffer, gbuffer_swapchain.getGBufferDescriptor( frame_index ) );
|
||||
m_pipeline->bindDescriptor( command_buffer, camera.getDescriptor( frame_index ) );
|
||||
|
||||
m_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control );
|
||||
|
||||
command_buffer.draw( 3, 1, 0, 0 );
|
||||
|
||||
endPass( command_buffer );
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
56
src/engine/camera/GBufferCompositor.hpp
Normal file
56
src/engine/camera/GBufferCompositor.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Created by kj16609 on 1/13/25.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||
#include "engine/rendering/types.hpp"
|
||||
#include "engine/systems/composition/Control.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class CompositeSwapchain;
|
||||
class Image;
|
||||
class GBufferSwapchain;
|
||||
using CompositeFlags = std::uint16_t;
|
||||
|
||||
enum CompositeFlagBits : CompositeFlags
|
||||
{
|
||||
CompositeFlagBits_None = 0,
|
||||
CompositeFlagBits_NormalOnly = 1 << 0,
|
||||
//! The final output should be transformed into a presenting valid format.
|
||||
CompositeFlagBits_PresentTarget = 1 << 1,
|
||||
|
||||
CompositeFlagBits_Standard = CompositeFlagBits_None,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Composites a GBuffer input
|
||||
*/
|
||||
class GBufferCompositor
|
||||
{
|
||||
CompositeFlags m_flags;
|
||||
|
||||
std::unique_ptr< Pipeline > m_pipeline { nullptr };
|
||||
|
||||
void setViewport( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d );
|
||||
void setScissor( const vk::raii::CommandBuffer& cmd, vk::Extent2D extent_2d );
|
||||
|
||||
void beginPass( vk::raii::CommandBuffer& cmd, CompositeSwapchain& swapchain, const FrameIndex& index );
|
||||
void endPass( vk::raii::CommandBuffer& cmd );
|
||||
|
||||
CompositionControl m_control {};
|
||||
|
||||
public:
|
||||
|
||||
GBufferCompositor( CompositeFlags flags = CompositeFlagBits_Standard );
|
||||
|
||||
void composite( vk::raii::CommandBuffer& command_buffer, Camera& camera, FrameIndex frame_index );
|
||||
|
||||
inline void switchMode( const CompositeFlags flags ) { m_flags = flags; }
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
82
src/engine/camera/GBufferRenderer.cpp
Normal file
82
src/engine/camera/GBufferRenderer.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by kj16609 on 7/21/24.
|
||||
//
|
||||
|
||||
#include "GBufferRenderer.hpp"
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "engine/rendering/renderpass/RenderPass.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class GBufferSwapchain;
|
||||
|
||||
void GBufferRenderer::setViewport( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
vk::Viewport viewport {};
|
||||
viewport.x = 0.0f;
|
||||
viewport.y = 0.0f;
|
||||
viewport.width = static_cast< float >( extent.width );
|
||||
viewport.height = static_cast< float >( extent.height );
|
||||
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
|
||||
const std::vector< vk::Viewport > viewports { viewport };
|
||||
|
||||
command_buffer.setViewport( 0, viewports );
|
||||
}
|
||||
|
||||
void GBufferRenderer::setScissor( const vk::raii::CommandBuffer& command_buffer, const vk::Extent2D extent )
|
||||
{
|
||||
const vk::Rect2D scissor { { 0, 0 }, extent };
|
||||
|
||||
const std::vector< vk::Rect2D > scissors { scissor };
|
||||
|
||||
command_buffer.setScissor( 0, scissors );
|
||||
}
|
||||
|
||||
void GBufferRenderer::beginRenderPass(
|
||||
const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, const FrameIndex index )
|
||||
{
|
||||
const vk::RenderingInfo info { swapchain.getRenderingInfo( index ) };
|
||||
|
||||
command_buffer.beginRendering( info );
|
||||
|
||||
setViewport( command_buffer, swapchain.getExtent() );
|
||||
setScissor( command_buffer, swapchain.getExtent() );
|
||||
}
|
||||
|
||||
void GBufferRenderer::endRenderPass( const vk::raii::CommandBuffer& command_buffer )
|
||||
{
|
||||
command_buffer.endRendering();
|
||||
}
|
||||
|
||||
void GBufferRenderer::pass( FrameInfo& frame_info, GBufferSwapchain& camera_swapchain )
|
||||
{
|
||||
ZoneScopedN( "CameraRenderer::pass" );
|
||||
m_culling_system.startPass( frame_info );
|
||||
|
||||
auto& command_buffer { frame_info.command_buffer };
|
||||
|
||||
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::INITAL, frame_info.frame_idx );
|
||||
|
||||
beginRenderPass( command_buffer, camera_swapchain, frame_info.frame_idx );
|
||||
|
||||
// Transition the gbuffer to it's inital state
|
||||
|
||||
m_culling_system.wait();
|
||||
|
||||
//m_terrain_system.pass( frame_info );
|
||||
|
||||
m_entity_renderer.pass( frame_info );
|
||||
m_line_drawer.pass( frame_info );
|
||||
|
||||
endRenderPass( command_buffer );
|
||||
|
||||
camera_swapchain.transitionImages( command_buffer, GBufferSwapchain::FINAL, frame_info.frame_idx );
|
||||
|
||||
m_compositor.composite( command_buffer, *frame_info.camera, frame_info.frame_idx );
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CameraSwapchain.hpp"
|
||||
#include "engine/systems/composition/CompositionSystem.hpp"
|
||||
#include "GBufferCompositor.hpp"
|
||||
#include "GBufferSwapchain.hpp"
|
||||
#include "engine/systems/prerender/CullingSystem.hpp"
|
||||
#include "engine/systems/render/EntityRendererSystem.hpp"
|
||||
#include "engine/systems/render/LineDrawer.hpp"
|
||||
@@ -13,11 +13,10 @@
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
class CameraRenderer
|
||||
class GBufferRenderer
|
||||
{
|
||||
vk::raii::RenderPass m_renderpass;
|
||||
GBufferCompositor m_compositor;
|
||||
|
||||
static vk::raii::RenderPass createRenderPass();
|
||||
void setViewport( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent );
|
||||
void setScissor( const vk::raii::CommandBuffer& command_buffer, vk::Extent2D extent );
|
||||
|
||||
@@ -25,24 +24,22 @@ namespace fgl::engine
|
||||
|
||||
// SubPass 0
|
||||
//TerrainSystem m_terrain_system { Device::getInstance(), m_renderpass };
|
||||
EntityRendererSystem m_entity_renderer { m_renderpass };
|
||||
LineDrawer m_line_drawer { m_renderpass };
|
||||
EntityRendererSystem m_entity_renderer {};
|
||||
LineDrawer m_line_drawer {};
|
||||
|
||||
// SubPass 1
|
||||
CompositionSystem m_composition_system { m_renderpass };
|
||||
// CompositionSystem m_composition_system {};
|
||||
|
||||
void beginRenderPass(
|
||||
const vk::raii::CommandBuffer& command_buffer, CameraSwapchain& swapchain, const FrameIndex index );
|
||||
const vk::raii::CommandBuffer& command_buffer, GBufferSwapchain& swapchain, FrameIndex index );
|
||||
|
||||
void endRenderPass( const vk::raii::CommandBuffer& command_buffer );
|
||||
|
||||
public:
|
||||
|
||||
void pass( FrameInfo& frame_info, CameraSwapchain& camera_swapchain );
|
||||
void pass( FrameInfo& frame_info, GBufferSwapchain& camera_swapchain );
|
||||
|
||||
vk::raii::RenderPass& getRenderpass();
|
||||
|
||||
CameraRenderer() : m_renderpass( createRenderPass() ) {}
|
||||
GBufferRenderer() = default;
|
||||
};
|
||||
|
||||
} // namespace fgl::engine
|
||||
189
src/engine/camera/GBufferSwapchain.cpp
Normal file
189
src/engine/camera/GBufferSwapchain.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
//
|
||||
// Created by kj16609 on 7/11/24.
|
||||
//
|
||||
|
||||
#include "GBufferSwapchain.hpp"
|
||||
|
||||
#include "engine/descriptors/DescriptorSet.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > GBufferSwapchain::createGBufferDescriptors()
|
||||
{
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > data {};
|
||||
data.resize( SwapChain::MAX_FRAMES_IN_FLIGHT );
|
||||
|
||||
for ( PresentIndex i = 0; i < SwapChain::MAX_FRAMES_IN_FLIGHT; ++i )
|
||||
{
|
||||
//auto set { std::make_unique< descriptors::DescriptorSet >( GBufferDescriptorSet::createLayout() ) };
|
||||
auto set { gbuffer_set.create() };
|
||||
|
||||
set->bindAttachment( 0, m_gbuffer.m_color.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR );
|
||||
|
||||
set->bindAttachment( 1, m_gbuffer.m_position.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR );
|
||||
|
||||
set->bindAttachment( 2, m_gbuffer.m_normal.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR );
|
||||
|
||||
set->bindAttachment( 3, m_gbuffer.m_metallic.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR );
|
||||
|
||||
set->bindAttachment( 4, m_gbuffer.m_emissive.getView( i ), vk::ImageLayout::eRenderingLocalReadKHR );
|
||||
|
||||
set->update();
|
||||
|
||||
data[ i ] = std::move( set );
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void GBufferSwapchain::transitionImages(
|
||||
vk::raii::CommandBuffer& command_buffer, const std::uint16_t stage_id, const FrameIndex index )
|
||||
{
|
||||
switch ( stage_id )
|
||||
{
|
||||
default:
|
||||
throw std::invalid_argument( "Invalid Stage ID" );
|
||||
case INITAL:
|
||||
{
|
||||
const std::vector< vk::ImageMemoryBarrier > barriers {
|
||||
m_gbuffer.m_color.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_emissive.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_metallic.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_position.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_normal.getImage( index )
|
||||
.transitionColorTo( vk::ImageLayout::eUndefined, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_depth.getImage( index ).transitionTo(
|
||||
vk::ImageLayout::eUndefined,
|
||||
vk::ImageLayout::eDepthAttachmentOptimal,
|
||||
vk::ImageAspectFlagBits::eDepth ),
|
||||
};
|
||||
|
||||
command_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eTopOfPipe,
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput
|
||||
| vk::PipelineStageFlagBits::eEarlyFragmentTests
|
||||
| vk::PipelineStageFlagBits::eLateFragmentTests,
|
||||
vk::DependencyFlags( 0 ),
|
||||
{},
|
||||
{},
|
||||
barriers );
|
||||
|
||||
return;
|
||||
}
|
||||
case FINAL:
|
||||
{
|
||||
// Final should turn all of these into readonly in order to be used for other render targets.
|
||||
const std::vector< vk::ImageMemoryBarrier > barriers {
|
||||
m_gbuffer.m_color.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ),
|
||||
m_gbuffer.m_emissive.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ),
|
||||
m_gbuffer.m_metallic.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ),
|
||||
m_gbuffer.m_position.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ),
|
||||
m_gbuffer.m_normal.getImage( index ).transitionColorTo(
|
||||
vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eShaderReadOnlyOptimal )
|
||||
// It might be useful to properly transition this for other post processing effects later
|
||||
// m_gbuffer.m_depth.getImage( index ).transitionTo(
|
||||
// vk::ImageLayout::eDepthAttachmentOptimal,
|
||||
// vk::ImageLayout::eDepthReadOnlyOptimal,
|
||||
// vk::ImageAspectFlagBits::eDepth ),
|
||||
};
|
||||
|
||||
command_buffer.pipelineBarrier(
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput,
|
||||
vk::PipelineStageFlagBits::eFragmentShader,
|
||||
vk::DependencyFlags( 0 ),
|
||||
{},
|
||||
{},
|
||||
barriers );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vk::RenderingInfo GBufferSwapchain::getRenderingInfo( const FrameIndex frame_index )
|
||||
{
|
||||
// This should be safe to have as static as the information used here will only capable of being used in a single frame.
|
||||
static thread_local std::vector< vk::RenderingAttachmentInfo > color_attachment_infos {};
|
||||
static thread_local vk::RenderingAttachmentInfo depth_attachment_infos {};
|
||||
|
||||
depth_attachment_infos = m_gbuffer.m_depth.renderInfo( frame_index, vk::ImageLayout::eDepthAttachmentOptimal );
|
||||
|
||||
color_attachment_infos.clear();
|
||||
color_attachment_infos = {
|
||||
m_gbuffer.m_color.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_position.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_normal.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_metallic.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal ),
|
||||
m_gbuffer.m_emissive.renderInfo( frame_index, vk::ImageLayout::eColorAttachmentOptimal )
|
||||
};
|
||||
|
||||
vk::RenderingInfo rendering_info {};
|
||||
|
||||
rendering_info.setRenderArea( { { 0, 0 }, m_extent } );
|
||||
|
||||
rendering_info.setLayerCount( 1 );
|
||||
|
||||
rendering_info.setColorAttachments( color_attachment_infos );
|
||||
rendering_info.setPDepthAttachment( &depth_attachment_infos );
|
||||
// rendering_info.setPStencilAttachment( &depth_attachment_infos );
|
||||
|
||||
return rendering_info;
|
||||
}
|
||||
|
||||
descriptors::DescriptorSet& GBufferSwapchain::getGBufferDescriptor( const FrameIndex frame_index )
|
||||
{
|
||||
return *m_gbuffer_descriptor_set[ frame_index ];
|
||||
}
|
||||
|
||||
vk::Extent2D GBufferSwapchain::getExtent() const
|
||||
{
|
||||
return m_extent;
|
||||
}
|
||||
|
||||
float GBufferSwapchain::getAspectRatio()
|
||||
{
|
||||
return static_cast< float >( m_extent.width ) / static_cast< float >( m_extent.height );
|
||||
}
|
||||
|
||||
GBufferSwapchain::GBufferSwapchain( const vk::Extent2D extent ) : m_extent( extent )
|
||||
// m_gbuffer_descriptor_set( createGBufferDescriptors() )
|
||||
{
|
||||
constexpr auto image_count { SwapChain::MAX_FRAMES_IN_FLIGHT };
|
||||
|
||||
m_gbuffer.m_color.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_position.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_normal.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_metallic.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_emissive.createResources( image_count, m_extent );
|
||||
|
||||
m_gbuffer.m_depth.createResources( image_count, m_extent );
|
||||
m_gbuffer.m_depth.setClear( vk::ClearDepthStencilValue( 1.0f, 0 ) );
|
||||
|
||||
m_gbuffer.m_color.setName( "Color" );
|
||||
m_gbuffer.m_position.setName( "Position" );
|
||||
m_gbuffer.m_normal.setName( "Normal" );
|
||||
m_gbuffer.m_metallic.setName( "Metallic" );
|
||||
m_gbuffer.m_emissive.setName( "Emissive" );
|
||||
m_gbuffer.m_depth.setName( "Depth" );
|
||||
|
||||
m_gbuffer_descriptor_set = createGBufferDescriptors();
|
||||
}
|
||||
|
||||
GBufferSwapchain::~GBufferSwapchain()
|
||||
{
|
||||
for ( auto& descriptor : m_gbuffer_descriptor_set )
|
||||
{
|
||||
descriptors::queueDescriptorDeletion( std::move( descriptor ) );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -21,7 +21,7 @@ namespace fgl::engine
|
||||
constexpr std::size_t COMPOSITE_INDEX { 5 };
|
||||
constexpr std::size_t DEPTH_INDEX { 6 };
|
||||
|
||||
class CameraSwapchain
|
||||
class GBufferSwapchain
|
||||
{
|
||||
struct
|
||||
{
|
||||
@@ -30,31 +30,16 @@ namespace fgl::engine
|
||||
ColorAttachment< NORMAL_INDEX > m_normal { pickNormalFormat() };
|
||||
ColorAttachment< METALLIC_INDEX > m_metallic { pickMetallicFormat() };
|
||||
ColorAttachment< EMISSIVE_INDEX > m_emissive { pickEmissiveFormat() };
|
||||
|
||||
ColorAttachment< COMPOSITE_INDEX > m_composite { pickCompositeFormat() };
|
||||
//TODO: Move depth into m_position A channel
|
||||
DepthAttachment< DEPTH_INDEX > m_depth { pickDepthFormat() };
|
||||
|
||||
// ColorAttachment< COMPOSITE_INDEX > m_composite { pickCompositeFormat() };
|
||||
} m_gbuffer {};
|
||||
|
||||
public:
|
||||
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_color_img {};
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_position_img {};
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_normal_img {};
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_metallic_img {};
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_emissive_img {};
|
||||
|
||||
std::vector< std::unique_ptr< Texture > > m_g_buffer_composite_img {};
|
||||
|
||||
private:
|
||||
|
||||
vk::Extent2D m_extent;
|
||||
|
||||
vk::raii::RenderPass& m_renderpass;
|
||||
|
||||
std::vector< vk::raii::Framebuffer > m_framebuffers;
|
||||
|
||||
std::vector< vk::ClearValue > m_clear_values;
|
||||
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > m_gbuffer_descriptor_set {};
|
||||
|
||||
std::vector< std::unique_ptr< descriptors::DescriptorSet > > createGBufferDescriptors();
|
||||
@@ -63,28 +48,21 @@ namespace fgl::engine
|
||||
|
||||
enum StageID : std::uint16_t
|
||||
{
|
||||
INITAL = 0,
|
||||
FINAL = std::numeric_limits< std::uint16_t >::max()
|
||||
INITAL,
|
||||
COMPOSITE,
|
||||
FINAL
|
||||
};
|
||||
|
||||
void transitionImages( vk::raii::CommandBuffer& command_buffer, std::uint16_t stage_id, FrameIndex index );
|
||||
vk::RenderingInfo getRenderingInfo( const FrameIndex frame_index );
|
||||
|
||||
CameraSwapchain( vk::raii::RenderPass& renderpass, vk::Extent2D extent );
|
||||
~CameraSwapchain();
|
||||
|
||||
const std::vector< vk::ClearValue >& getClearValues();
|
||||
|
||||
std::vector< vk::raii::Framebuffer > createFrambuffers();
|
||||
GBufferSwapchain( vk::Extent2D extent );
|
||||
~GBufferSwapchain();
|
||||
|
||||
descriptors::DescriptorSet& getGBufferDescriptor( FrameIndex frame_index );
|
||||
|
||||
vk::raii::Framebuffer& getFramebuffer( FrameIndex frame_index );
|
||||
|
||||
vk::Extent2D getExtent() const;
|
||||
|
||||
Image& getOutput( const FrameIndex index );
|
||||
|
||||
float getAspectRatio();
|
||||
};
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace fgl::engine
|
||||
info.pEngineName = "titor";
|
||||
info.engineVersion = VK_MAKE_VERSION( 1, 0, 0 );
|
||||
|
||||
info.apiVersion = VK_API_VERSION_1_4;
|
||||
info.apiVersion = VK_API_VERSION_1_3;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
24
src/engine/rendering/RenderProcess.puml
Normal file
24
src/engine/rendering/RenderProcess.puml
Normal file
@@ -0,0 +1,24 @@
|
||||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
autonumber
|
||||
|
||||
|
||||
box "GBuffer" #LightBlue
|
||||
participant Depth
|
||||
participant Albedo
|
||||
participant Depth
|
||||
|
||||
|
||||
end box
|
||||
|
||||
|
||||
Alice -> Bob: Authentication Request
|
||||
Bob --> Alice: Authentication Response
|
||||
|
||||
Alice -> Bob: Another authentication Request
|
||||
Alice <-- Bob: another authentication Response
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
@@ -75,6 +75,8 @@ namespace fgl::engine
|
||||
{
|
||||
m_dynamic_rendering_features.setDynamicRendering( VK_TRUE );
|
||||
m_dynamic_rendering_local_read_features.setDynamicRenderingLocalRead( VK_TRUE );
|
||||
m_dynamic_rendering_unused_features.setDynamicRenderingUnusedAttachments( VK_TRUE );
|
||||
m_info_chain.unlink< vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT >();
|
||||
}
|
||||
|
||||
std::vector< vk::DeviceQueueCreateInfo > Device::DeviceCreateInfo::
|
||||
|
||||
@@ -51,7 +51,8 @@ namespace fgl::engine
|
||||
using InfoChain = vk::StructureChain<
|
||||
vk::DeviceCreateInfo,
|
||||
vk::PhysicalDeviceDynamicRenderingFeatures,
|
||||
vk::PhysicalDeviceDynamicRenderingLocalReadFeatures,
|
||||
vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR,
|
||||
vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT,
|
||||
vk::PhysicalDeviceDescriptorIndexingFeatures >;
|
||||
|
||||
InfoChain m_info_chain;
|
||||
@@ -70,14 +71,18 @@ namespace fgl::engine
|
||||
m_info_chain.get< vk::PhysicalDeviceDescriptorIndexingFeatures >()
|
||||
};
|
||||
|
||||
vk::PhysicalDeviceDynamicRenderingLocalReadFeatures& m_dynamic_rendering_local_read_features {
|
||||
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingLocalReadFeatures >()
|
||||
vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR& m_dynamic_rendering_local_read_features {
|
||||
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingLocalReadFeaturesKHR >()
|
||||
};
|
||||
|
||||
vk::PhysicalDeviceDynamicRenderingFeatures& m_dynamic_rendering_features {
|
||||
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingFeatures >()
|
||||
};
|
||||
|
||||
vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT& m_dynamic_rendering_unused_features {
|
||||
m_info_chain.get< vk::PhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT >()
|
||||
};
|
||||
|
||||
DeviceCreateInfo( PhysicalDevice& );
|
||||
|
||||
} device_creation_info;
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace fgl::engine
|
||||
}
|
||||
|
||||
//! Creates a resource that is used across all frames
|
||||
void createResourceSpread(
|
||||
void createSharedResources(
|
||||
const std::uint32_t count, vk::Extent2D extent, vk::ImageUsageFlags extra_flags = vk::ImageUsageFlags( 0 ) )
|
||||
{
|
||||
auto image { std::make_shared< Image >(
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 3/11/24.
|
||||
//
|
||||
|
||||
#include "CompositionSystem.hpp"
|
||||
|
||||
#include "Control.hpp"
|
||||
#include "editor/src/gui/safe_include.hpp"
|
||||
#include "engine/camera/Camera.hpp"
|
||||
#include "engine/rendering/RenderingFormats.hpp"
|
||||
#include "engine/rendering/pipelines/v2/AttachmentBuilder.hpp"
|
||||
#include "engine/rendering/pipelines/v2/Pipeline.hpp"
|
||||
#include "engine/rendering/pipelines/v2/PipelineBuilder.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
|
||||
CompositionSystem::CompositionSystem( vk::raii::RenderPass& render_pass )
|
||||
{
|
||||
PipelineBuilder builder { 0 };
|
||||
|
||||
builder.addDescriptorSet( gbuffer_set );
|
||||
builder.addDescriptorSet( Camera::getDescriptorLayout() );
|
||||
|
||||
builder.addColorAttachment().setFormat( pickColorFormat() ).finish();
|
||||
|
||||
builder.setPushConstant( vk::ShaderStageFlagBits::eFragment, sizeof( CompositionControl ) );
|
||||
|
||||
builder.setVertexShader( Shader::loadVertex( "shaders/fullscreen.vert" ) );
|
||||
builder.setFragmentShader( Shader::loadFragment( "shaders/composition.frag" ) );
|
||||
|
||||
builder.disableCulling();
|
||||
builder.disableVertexInput();
|
||||
|
||||
m_composite_pipeline = builder.create();
|
||||
|
||||
m_composite_pipeline->setDebugName( "Composition pipeline" );
|
||||
}
|
||||
|
||||
CompositionSystem::~CompositionSystem()
|
||||
{}
|
||||
|
||||
vk::raii::CommandBuffer& CompositionSystem::setupSystem( FrameInfo& info )
|
||||
{
|
||||
auto& command_buffer { info.command_buffer };
|
||||
|
||||
m_composite_pipeline->bind( command_buffer );
|
||||
|
||||
m_composite_pipeline->bindDescriptor( command_buffer, info.getGBufferDescriptor() );
|
||||
m_composite_pipeline->bindDescriptor( command_buffer, info.getCameraDescriptor() );
|
||||
|
||||
ImGui::Begin( "Composition" );
|
||||
|
||||
ImGui::InputInt( "Selection", &m_control.m_flags );
|
||||
|
||||
ImGui::End();
|
||||
|
||||
m_composite_pipeline->pushConstant( command_buffer, vk::ShaderStageFlagBits::eFragment, m_control );
|
||||
|
||||
return info.command_buffer;
|
||||
}
|
||||
|
||||
void CompositionSystem::pass( FrameInfo& info )
|
||||
{
|
||||
auto& command_buffer { setupSystem( info ) };
|
||||
TracyVkZone( info.tracy_ctx, *command_buffer, "Composition Pass" );
|
||||
|
||||
command_buffer.draw( 3, 1, 0, 0 );
|
||||
}
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -1,33 +0,0 @@
|
||||
//
|
||||
// Created by kj16609 on 3/11/24.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Control.hpp"
|
||||
#include "engine/FrameInfo.hpp"
|
||||
#include "engine/systems/concepts.hpp"
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
class Pipeline;
|
||||
|
||||
class CompositionSystem
|
||||
{
|
||||
std::unique_ptr< Pipeline > m_composite_pipeline { nullptr };
|
||||
|
||||
vk::raii::CommandBuffer& setupSystem( FrameInfo& info );
|
||||
|
||||
CompositionControl m_control {};
|
||||
|
||||
public:
|
||||
|
||||
CompositionSystem( vk::raii::RenderPass& render_pass );
|
||||
~CompositionSystem();
|
||||
|
||||
void pass( FrameInfo& info );
|
||||
};
|
||||
|
||||
static_assert( is_system< CompositionSystem > );
|
||||
|
||||
} // namespace fgl::engine
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace fgl::engine
|
||||
{
|
||||
EntityRendererSystem::EntityRendererSystem( vk::raii::RenderPass& render_pass )
|
||||
EntityRendererSystem::EntityRendererSystem( )
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace fgl::engine
|
||||
void texturelessPass( const FrameInfo& info );
|
||||
void texturedPass( const FrameInfo& info );
|
||||
|
||||
EntityRendererSystem( vk::raii::RenderPass& render_pass );
|
||||
EntityRendererSystem();
|
||||
~EntityRendererSystem();
|
||||
EntityRendererSystem( EntityRendererSystem&& other ) = delete;
|
||||
EntityRendererSystem( const EntityRendererSystem& other ) = delete;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace fgl::engine
|
||||
|
||||
inline static std::vector< VertexLine > m_lines {};
|
||||
|
||||
LineDrawer::LineDrawer( vk::raii::RenderPass& render_pass )
|
||||
LineDrawer::LineDrawer( )
|
||||
{
|
||||
PipelineBuilder builder { 0 };
|
||||
|
||||
|
||||
@@ -22,12 +22,13 @@ namespace fgl::engine
|
||||
|
||||
public:
|
||||
|
||||
FGL_DELETE_ALL_RO5( LineDrawer );
|
||||
FGL_DELETE_COPY( LineDrawer );
|
||||
FGL_DELETE_MOVE( LineDrawer );
|
||||
|
||||
vk::raii::CommandBuffer& setupSystem( FrameInfo& info );
|
||||
void pass( FrameInfo& info );
|
||||
|
||||
LineDrawer( vk::raii::RenderPass& render_pass );
|
||||
LineDrawer();
|
||||
|
||||
~LineDrawer();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user