diff --git a/src/engine/systems/EntityRendererSystem.cpp b/src/engine/systems/EntityRendererSystem.cpp index 0a88b42..f44c664 100644 --- a/src/engine/systems/EntityRendererSystem.cpp +++ b/src/engine/systems/EntityRendererSystem.cpp @@ -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