mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Render dynamic meshes
This commit is contained in:
parent
c86809af66
commit
977da197e2
@ -33,7 +33,7 @@ class Renderer {
|
||||
void PreRender(bool window_is_resized, glm::mat4 camera_transform);
|
||||
|
||||
// staticList can be nullptr to render nothing
|
||||
void Render(const StaticRenderList* staticList);
|
||||
void Render(const RenderList* static_list, const RenderList* dynamic_list);
|
||||
|
||||
// getters
|
||||
|
||||
@ -88,6 +88,10 @@ class Renderer {
|
||||
const gfx::DescriptorSetLayout* material_set_layout; // set 2
|
||||
|
||||
float viewport_aspect_ratio_ = 1.0f;
|
||||
|
||||
const gfx::Pipeline* last_bound_pipeline_ = nullptr;
|
||||
|
||||
void DrawRenderList(gfx::DrawBuffer* draw_buffer, const RenderList& render_list);
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct StaticRenderListEntry {
|
||||
struct RenderListEntry {
|
||||
const gfx::Pipeline* pipeline;
|
||||
const gfx::Buffer* vertex_buffer;
|
||||
const gfx::Buffer* index_buffer;
|
||||
@ -18,23 +18,29 @@ struct StaticRenderListEntry {
|
||||
uint32_t index_count;
|
||||
};
|
||||
|
||||
using StaticRenderList = std::vector<StaticRenderListEntry>;
|
||||
using RenderList = std::vector<RenderListEntry>;
|
||||
|
||||
class MeshRenderSystem : public System {
|
||||
public:
|
||||
MeshRenderSystem(Scene* scene);
|
||||
~MeshRenderSystem();
|
||||
|
||||
void RebuildRenderList();
|
||||
const StaticRenderList* GetStaticRenderList() const { return &static_render_list_; }
|
||||
void RebuildStaticRenderList();
|
||||
const RenderList* GetStaticRenderList() const { return &static_render_list_; }
|
||||
const RenderList* GetDynamicRenderList() const { return &dynamic_render_list_; }
|
||||
|
||||
void OnComponentInsert(uint32_t entity) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
private:
|
||||
StaticRenderList static_render_list_;
|
||||
RenderList static_render_list_;
|
||||
RenderList dynamic_render_list_;
|
||||
bool list_needs_rebuild_ = false;
|
||||
|
||||
// with_static_entities = false, build list of dynamic meshes
|
||||
// with_static_entities = true, build list of static meshes
|
||||
void BuildRenderList(RenderList& render_list, bool with_static_entities);
|
||||
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
@ -179,11 +179,12 @@ void Application::GameLoop() {
|
||||
/* render */
|
||||
renderer_->PreRender(window()->GetWindowResized(), scene->GetComponent<TransformComponent>(scene->GetEntity("camera"))->world_matrix);
|
||||
|
||||
const StaticRenderList* staticList = nullptr;
|
||||
if (scene) {
|
||||
staticList = scene->GetSystem<MeshRenderSystem>()->GetStaticRenderList();
|
||||
auto mesh_render_system = scene->GetSystem<MeshRenderSystem>();
|
||||
const RenderList* static_list = mesh_render_system->GetStaticRenderList();
|
||||
const RenderList* dynamic_list = mesh_render_system->GetDynamicRenderList();
|
||||
renderer_->Render(static_list, dynamic_list);
|
||||
}
|
||||
renderer_->Render(staticList);
|
||||
|
||||
/* poll events */
|
||||
window_->GetInputAndEvents();
|
||||
|
@ -90,40 +90,52 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform) {
|
||||
&frame_uniform.uniform_buffer_data);
|
||||
}
|
||||
|
||||
void Renderer::Render(const StaticRenderList* staticList) {
|
||||
void Renderer::Render(const RenderList* static_list,
|
||||
const RenderList* dynamic_list) {
|
||||
assert(static_list != nullptr);
|
||||
assert(dynamic_list != nullptr);
|
||||
|
||||
last_bound_pipeline_ = nullptr;
|
||||
|
||||
gfx::DrawBuffer* draw_buffer = device_->BeginRender();
|
||||
|
||||
if (staticList && !staticList->empty()) {
|
||||
const gfx::Pipeline* const first_pipeline = staticList->begin()->pipeline;
|
||||
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline,
|
||||
global_uniform.set, 0);
|
||||
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline,
|
||||
frame_uniform.set, 1);
|
||||
|
||||
device_->CmdBindPipeline(draw_buffer, first_pipeline);
|
||||
const gfx::Pipeline* last_bound_pipeline = first_pipeline;
|
||||
|
||||
for (const auto& entry : *staticList) {
|
||||
if (entry.pipeline != last_bound_pipeline) {
|
||||
device_->CmdBindPipeline(draw_buffer, entry.pipeline);
|
||||
last_bound_pipeline = entry.pipeline;
|
||||
}
|
||||
device_->CmdBindDescriptorSet(draw_buffer, entry.pipeline,
|
||||
entry.base_colour_texture, 2);
|
||||
device_->CmdPushConstants(draw_buffer, entry.pipeline, 0,
|
||||
sizeof(entry.model_matrix),
|
||||
&entry.model_matrix);
|
||||
if (entry.vertex_buffer) {
|
||||
device_->CmdBindVertexBuffer(draw_buffer, 0, entry.vertex_buffer);
|
||||
}
|
||||
if (entry.index_buffer) {
|
||||
device_->CmdBindIndexBuffer(draw_buffer, entry.index_buffer);
|
||||
}
|
||||
device_->CmdDrawIndexed(draw_buffer, entry.index_count, 1, 0, 0, 0);
|
||||
if (!static_list->empty()) {
|
||||
DrawRenderList(draw_buffer, *static_list);
|
||||
}
|
||||
if (!dynamic_list->empty()) {
|
||||
DrawRenderList(draw_buffer, *dynamic_list);
|
||||
}
|
||||
|
||||
device_->FinishRender(draw_buffer);
|
||||
}
|
||||
|
||||
void Renderer::DrawRenderList(gfx::DrawBuffer* draw_buffer,
|
||||
const RenderList& render_list) {
|
||||
// if a pipeline hasn't been bound yet at all
|
||||
if (last_bound_pipeline_ == nullptr) {
|
||||
const gfx::Pipeline* first_pipeline = render_list.begin()->pipeline;
|
||||
// these bindings persist between all pipelines
|
||||
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline,
|
||||
global_uniform.set, 0);
|
||||
device_->CmdBindDescriptorSet(draw_buffer, first_pipeline,
|
||||
frame_uniform.set, 1);
|
||||
device_->CmdBindPipeline(draw_buffer, first_pipeline);
|
||||
last_bound_pipeline_ = first_pipeline;
|
||||
}
|
||||
|
||||
for (const auto& entry : render_list) {
|
||||
if (entry.pipeline != last_bound_pipeline_) {
|
||||
device_->CmdBindPipeline(draw_buffer, entry.pipeline);
|
||||
last_bound_pipeline_ = entry.pipeline;
|
||||
}
|
||||
device_->CmdBindDescriptorSet(draw_buffer, entry.pipeline,
|
||||
entry.base_colour_texture, 2);
|
||||
device_->CmdPushConstants(draw_buffer, entry.pipeline, 0,
|
||||
sizeof(entry.model_matrix), &entry.model_matrix);
|
||||
device_->CmdBindVertexBuffer(draw_buffer, 0, entry.vertex_buffer);
|
||||
device_->CmdBindIndexBuffer(draw_buffer, entry.index_buffer);
|
||||
device_->CmdDrawIndexed(draw_buffer, entry.index_count, 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace engine
|
@ -14,24 +14,44 @@ MeshRenderSystem::MeshRenderSystem(Scene* scene)
|
||||
|
||||
MeshRenderSystem::~MeshRenderSystem() {}
|
||||
|
||||
void MeshRenderSystem::RebuildRenderList() {
|
||||
static_render_list_.clear();
|
||||
static_render_list_.reserve(entities_.size());
|
||||
void MeshRenderSystem::RebuildStaticRenderList() {
|
||||
BuildRenderList(static_render_list_, true);
|
||||
list_needs_rebuild_ = false;
|
||||
}
|
||||
|
||||
void MeshRenderSystem::OnComponentInsert(uint32_t entity) {
|
||||
(void)entity;
|
||||
list_needs_rebuild_ = true;
|
||||
}
|
||||
|
||||
void MeshRenderSystem::OnUpdate(float ts) {
|
||||
// do stuff
|
||||
(void)ts;
|
||||
if (list_needs_rebuild_) {
|
||||
RebuildStaticRenderList();
|
||||
}
|
||||
BuildRenderList(dynamic_render_list_, false);
|
||||
}
|
||||
|
||||
void MeshRenderSystem::BuildRenderList(RenderList& render_list,
|
||||
bool with_static_entities) {
|
||||
render_list.clear();
|
||||
render_list.reserve(entities_.size());
|
||||
|
||||
std::unordered_map<const gfx::Pipeline*, int> render_orders;
|
||||
|
||||
for (uint32_t entity : entities_) {
|
||||
auto transform = scene_->GetComponent<engine::TransformComponent>(entity);
|
||||
|
||||
if (transform->is_static == false) continue;
|
||||
if (transform->is_static != with_static_entities) continue;
|
||||
|
||||
auto renderable = scene_->GetComponent<engine::RenderableComponent>(entity);
|
||||
|
||||
const gfx::Pipeline* pipeline =
|
||||
renderable->material->GetShader()->GetPipeline();
|
||||
|
||||
static_render_list_.emplace_back(StaticRenderListEntry{
|
||||
.pipeline = pipeline,
|
||||
render_list.emplace_back(
|
||||
RenderListEntry{.pipeline = pipeline,
|
||||
.vertex_buffer = renderable->mesh->GetVB(),
|
||||
.index_buffer = renderable->mesh->GetIB(),
|
||||
.base_colour_texture =
|
||||
@ -46,18 +66,16 @@ void MeshRenderSystem::RebuildRenderList() {
|
||||
}
|
||||
|
||||
// sort the meshes by pipeline
|
||||
auto sort_by_pipeline = [&render_orders](
|
||||
const StaticRenderListEntry& e1,
|
||||
const StaticRenderListEntry& e2) -> bool {
|
||||
auto sort_by_pipeline = [&render_orders](const RenderListEntry& e1,
|
||||
const RenderListEntry& e2) -> bool {
|
||||
return (render_orders.at(e1.pipeline) < render_orders.at(e2.pipeline));
|
||||
};
|
||||
|
||||
std::sort(static_render_list_.begin(), static_render_list_.end(),
|
||||
sort_by_pipeline);
|
||||
std::sort(render_list.begin(), render_list.end(), sort_by_pipeline);
|
||||
|
||||
#ifndef NDEBUG
|
||||
LOG_TRACE("\nPRINTING RENDER LIST:\n");
|
||||
for (const auto& entry : static_render_list_) {
|
||||
#if 0
|
||||
LOG_TRACE("\nPRINTING RENDER LIST ({})\n", with_static_entities ? "STATIC" : "DYNAMIC");
|
||||
for (const auto& entry : render_list) {
|
||||
LOG_TRACE("pipeline: {}", static_cast<const void*>(entry.pipeline));
|
||||
LOG_TRACE("vertex_buffer: {}",
|
||||
static_cast<const void*>(entry.vertex_buffer));
|
||||
@ -69,19 +87,6 @@ void MeshRenderSystem::RebuildRenderList() {
|
||||
}
|
||||
LOG_TRACE("\nRENDER LIST END\n");
|
||||
#endif
|
||||
|
||||
list_needs_rebuild_ = false;
|
||||
}
|
||||
|
||||
void MeshRenderSystem::OnComponentInsert(uint32_t entity) {
|
||||
(void)entity;
|
||||
list_needs_rebuild_ = true;
|
||||
}
|
||||
|
||||
void MeshRenderSystem::OnUpdate(float ts) {
|
||||
// do stuff
|
||||
(void)ts;
|
||||
if (list_needs_rebuild_) RebuildRenderList();
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
@ -136,7 +136,7 @@ void PlayGame(GameSettings settings) {
|
||||
// app.GetResourcePath("models/test_scene.dae"));
|
||||
|
||||
auto cobbleHouse = engine::util::LoadMeshFromFile(
|
||||
my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"), true);
|
||||
my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"), false);
|
||||
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse)->position +=
|
||||
glm::vec3{33.0f, 0.1f, 35.0f};
|
||||
auto cobbleCustom =
|
||||
@ -148,6 +148,9 @@ void PlayGame(GameSettings settings) {
|
||||
static auto t =
|
||||
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse);
|
||||
t->rotation *= glm::angleAxis(ts, glm::vec3{0.0f, 0.0f, 1.0f});
|
||||
if (app.window()->GetKeyPress(engine::inputs::Key::K_F)) {
|
||||
my_scene->GetSystem<engine::MeshRenderSystem>()->RebuildStaticRenderList();
|
||||
}
|
||||
};
|
||||
|
||||
/* some text */
|
||||
|
Loading…
Reference in New Issue
Block a user