Files
FGL-Engine/src/engine/systems/EntityRendererSystem.cpp

157 lines
5.8 KiB
C++

//
// Created by kj16609 on 11/27/23.
//
#include "EntityRendererSystem.hpp"
#include <tracy/TracyC.h>
#include <vulkan/vulkan.hpp>
#include "DrawPair.hpp"
#include "engine/camera/Camera.hpp"
#include "engine/literals/size.hpp"
#include "engine/tree/octtree/OctTreeNode.hpp"
namespace fgl::engine
{
std::unique_ptr< memory::Buffer > m_global_draw_parameter_buffer { nullptr };
void initDrawParameterBuffer( std::uint32_t size )
{
m_global_draw_parameter_buffer = std::make_unique< memory::Buffer >(
size,
vk::BufferUsageFlagBits::eIndirectBuffer,
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eDeviceLocal );
}
EntityRendererSystem::EntityRendererSystem( Device& device, vk::raii::RenderPass& render_pass ) : m_device( device )
{
ZoneScoped;
PipelineConfigInfo standard_info { render_pass };
for ( int i = 0; i < 3; ++i ) PipelineConfigInfo::addColorAttachmentConfig( standard_info );
standard_info.subpass = 0;
m_standard_pipeline = std::make_unique< StandardPipeline >( m_device, std::move( standard_info ) );
m_standard_pipeline->setDebugName( "Standard entity pipeline" );
PipelineConfigInfo textured_info { render_pass };
for ( int i = 0; i < 3; ++i ) PipelineConfigInfo::addColorAttachmentConfig( textured_info );
textured_info.subpass = 0;
m_textured_pipeline = std::make_unique< TexturedPipeline >( m_device, std::move( textured_info ) );
m_textured_pipeline->setDebugName( "Textured entity pipeline" );
using namespace fgl::literals::size_literals;
initDrawParameterBuffer( 1_KiB );
}
vk::raii::CommandBuffer& EntityRendererSystem::setupSystem( FrameInfo& info )
{
auto& command_buffer { info.command_buffer };
//This function becomes a dummy since we have multiple pipelines.
//We will instead bind the pipeline and descriptors for each stage of this pass.
//m_pipeline->bind( command_buffer );
//m_pipeline->bindDescriptor( command_buffer, 0, info.global_descriptor_set );
//m_pipeline->bindDescriptor( command_buffer, 1, Texture::getTextureDescriptorSet() );
return command_buffer;
}
void EntityRendererSystem::pass( FrameInfo& info )
{
ZoneScopedN( "Entity pass" );
auto& command_buffer { setupSystem( info ) };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render entities" );
texturelessPass( info );
texturedPass( info );
}
void EntityRendererSystem::texturelessPass( FrameInfo& info )
{
ZoneScopedN( "Textureless pass" );
auto& command_buffer { info.command_buffer };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render textureless entities" );
//Bind pipeline
m_standard_pipeline->bind( command_buffer );
m_standard_pipeline
->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.getCameraDescriptor() );
//Get all commands for drawing anything without a texture
auto [ draw_commands, model_matricies ] = getDrawCallsFromTree(
info.game_objects, info.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY, IS_TEXTURELESS );
//TODO: Filter Textureless models (#6)
if ( draw_commands.size() == 0 ) return;
auto& model_matrix_info_buffer { m_simple_model_matrix_info_buffers[ info.frame_idx ] };
model_matrix_info_buffer =
std::make_unique< ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matricies );
auto& draw_parameter_buffer { m_draw_simple_parameter_buffers[ info.frame_idx ] };
draw_parameter_buffer =
std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands );
const std::vector< vk::Buffer > vert_buffers { info.model_vertex_buffer.getVkBuffer(),
model_matrix_info_buffer->getVkBuffer() };
command_buffer.bindVertexBuffers( 0, vert_buffers, { 0, model_matrix_info_buffer->getOffset() } );
command_buffer.bindIndexBuffer( info.model_index_buffer.getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer.drawIndexedIndirect(
draw_parameter_buffer->getVkBuffer(),
draw_parameter_buffer->getOffset(),
draw_parameter_buffer->size(),
draw_parameter_buffer->stride() );
}
void EntityRendererSystem::texturedPass( FrameInfo& info )
{
ZoneScopedN( "Textured pass" );
auto& command_buffer { info.command_buffer };
TracyVkZone( info.tracy_ctx, *command_buffer, "Render textured entities" );
m_textured_pipeline->bind( command_buffer );
// Since the camera was bound in the textureless pass we shouldn't need to bind it here too.
// m_textured_pipeline
// ->bindDescriptor( command_buffer, CameraDescriptorSet::m_set_idx, info.global_descriptor_set );
m_textured_pipeline
->bindDescriptor( command_buffer, TextureDescriptorSet::m_set_idx, Texture::getTextureDescriptorSet() );
auto [ draw_commands, model_matricies ] =
getDrawCallsFromTree( info.game_objects, info.camera->getFrustumBounds(), IS_VISIBLE | IS_ENTITY );
if ( draw_commands.empty() ) return;
auto& model_matrix_info_buffer { m_textured_model_matrix_info_buffers[ info.frame_idx ] };
model_matrix_info_buffer =
std::make_unique< ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matricies );
auto& draw_parameter_buffer { m_draw_textured_parameter_buffers[ info.frame_idx ] };
draw_parameter_buffer =
std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands );
const std::vector< vk::Buffer > vert_buffers { info.model_vertex_buffer.getVkBuffer(),
model_matrix_info_buffer->getVkBuffer() };
command_buffer.bindVertexBuffers( 0, vert_buffers, { 0, model_matrix_info_buffer->getOffset() } );
command_buffer.bindIndexBuffer( info.model_index_buffer.getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer.drawIndexedIndirect(
draw_parameter_buffer->getVkBuffer(),
draw_parameter_buffer->getOffset(),
draw_parameter_buffer->size(),
draw_parameter_buffer->stride() );
};
} // namespace fgl::engine