Implement model rendering based on textures

This commit is contained in:
2024-01-24 05:40:30 -05:00
parent 63c439f6bc
commit 09d8196180

View File

@@ -62,96 +62,92 @@ namespace fgl::engine
void EntityRendererSystem::pass( FrameInfo& info )
{
auto& command_buffer { info.command_buffer };
TracyVkZone( info.tracy_ctx, command_buffer, "Render game objects" );
//TracyVkZone( m_device.getCurrentTracyCTX(), command_buffer, "Render game objects" );
m_pipeline->bind( command_buffer );
m_pipeline->bindDescriptor( command_buffer, 0, info.global_descriptor_set );
m_pipeline->bindDescriptor( command_buffer, 1, Texture::getTextureDescriptorSet() );
std::vector< vk::DrawIndexedIndirectCommand > draw_commands;
std::vector< ModelMatrixInfo > model_matrices;
GameObject* previous { nullptr };
auto previous_end { draw_commands.end() };
for ( auto& [ key, obj ] : info.game_objects )
{
TracyVkZone( info.tracy_ctx, command_buffer, "Render game object" );
if ( obj.model == nullptr ) continue;
TracyVkZone( info.tracy_ctx, command_buffer, "Render game objects" );
const ModelMatrixInfo matrix_info { .model_matrix = obj.transform.mat4() };
//.normal_matrix = obj.transform.normalMatrix() };
//TracyVkZone( m_device.getCurrentTracyCTX(), command_buffer, "Render game objects" );
m_pipeline->bind( command_buffer );
// If the previous model is identical to the current one then we can simply add a count to the previous commands instead of adding our own
if ( previous && previous->model == obj.model )
m_pipeline->bindDescriptor( command_buffer, 0, info.global_descriptor_set );
m_pipeline->bindDescriptor( command_buffer, 1, Texture::getTextureDescriptorSet() );
std::vector< vk::DrawIndexedIndirectCommand > draw_commands;
std::vector< ModelMatrixInfo > model_matrices;
for ( auto& [ key, obj ] : info.game_objects )
{
//Simply push the model matrix back and add to the counter
auto func = []( vk::DrawIndexedIndirectCommand& cmd ) { cmd.instanceCount++; };
TracyVkZone( info.tracy_ctx, command_buffer, "Render game object" );
if ( obj.model == nullptr ) continue;
std::for_each( previous_end, draw_commands.end(), func );
for ( const auto& primitive : obj.model->m_primitives )
{
const ModelMatrixInfo matrix_info { .model_matrix = obj.transform.mat4(),
.texture_idx = primitive.m_texture->getID() };
//.normal_matrix = obj.transform.normalMatrix() };
vk::DrawIndexedIndirectCommand cmd;
cmd.firstIndex = primitive.m_index_buffer.getOffsetCount();
cmd.indexCount = primitive.m_index_buffer.count();
cmd.vertexOffset = primitive.m_vertex_buffer.getOffsetCount();
cmd.firstInstance = model_matrices.size();
cmd.instanceCount = 1;
draw_commands.emplace_back( cmd );
model_matrices.emplace_back( matrix_info );
}
}
assert( draw_commands.size() > 0 && "No draw commands to render" );
auto& draw_parameter_buffer { m_draw_parameter_buffers[ info.frame_idx ] };
if ( draw_parameter_buffer == nullptr || draw_parameter_buffer->count() != draw_commands.size() )
{
draw_parameter_buffer =
std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands );
}
else
{
std::vector< vk::DrawIndexedIndirectCommand > cmds {
obj.model->getDrawCommand( model_matrices.size() )
};
assert( cmds.size() > 0 && "Expected at least 1 draw command from model" );
previous = &obj;
previous_end = draw_commands.insert( draw_commands.end(), cmds.begin(), cmds.end() );
//Simply set and flush
*draw_parameter_buffer = draw_commands;
}
model_matrices.push_back( matrix_info );
draw_parameter_buffer->flush();
auto& model_matrix_info_buffer { m_model_matrix_info_buffers[ info.frame_idx ] };
model_matrix_info_buffer =
std::make_unique< ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matrices );
model_matrix_info_buffer->flush();
auto& model_matricies_suballoc { model_matrix_info_buffer };
auto& draw_params { draw_parameter_buffer };
std::vector< vk::Buffer > vertex_buffers { m_vertex_buffer->getVkBuffer(),
model_matricies_suballoc->getVkBuffer() };
command_buffer.bindVertexBuffers( 0, vertex_buffers, { 0, model_matricies_suballoc->getOffset() } );
command_buffer.bindIndexBuffer( m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer.drawIndexedIndirect(
draw_params->getVkBuffer(), draw_params->getOffset(), draw_params->count(), draw_params->stride() );
command_buffer.nextSubpass( vk::SubpassContents::eInline );
}
assert( draw_commands.size() > 0 && "No draw commands to render" );
auto& draw_parameter_buffer { m_draw_parameter_buffers[ info.frame_idx ] };
if ( draw_parameter_buffer == nullptr || draw_parameter_buffer->count() != draw_commands.size() )
{
draw_parameter_buffer =
std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands );
//Composition pass
TracyVkZone( info.tracy_ctx, command_buffer, "Composition pass" );
m_composition_pipeline->bind( command_buffer );
m_composition_pipeline->bindDescriptor( command_buffer, 0, info.gbuffer_descriptor_set );
command_buffer.draw( 3, 1, 0, 0 );
}
else
{
//Simply set and flush
*draw_parameter_buffer = draw_commands;
}
draw_parameter_buffer->flush();
auto& model_matrix_info_buffer { m_model_matrix_info_buffers[ info.frame_idx ] };
model_matrix_info_buffer =
std::make_unique< ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matrices );
model_matrix_info_buffer->flush();
auto& model_matricies_suballoc { model_matrix_info_buffer };
auto& draw_params { draw_parameter_buffer };
std::vector< vk::Buffer > vertex_buffers { m_vertex_buffer->getVkBuffer(),
model_matricies_suballoc->getVkBuffer() };
command_buffer.bindVertexBuffers( 0, vertex_buffers, { 0, model_matricies_suballoc->getOffset() } );
command_buffer.bindIndexBuffer( m_index_buffer->getVkBuffer(), 0, vk::IndexType::eUint32 );
command_buffer.drawIndexedIndirect(
draw_params->getVkBuffer(), draw_params->getOffset(), draw_params->count(), draw_params->stride() );
command_buffer.nextSubpass( vk::SubpassContents::eInline );
//Composition pass
TracyVkZone( info.tracy_ctx, command_buffer, "Composition pass" );
m_composition_pipeline->bind( command_buffer );
m_composition_pipeline->bindDescriptor( command_buffer, 0, info.gbuffer_descriptor_set );
command_buffer.draw( 3, 1, 0, 0 );
}
} // namespace fgl::engine