add static rendering

This commit is contained in:
Bailey Harrison 2023-08-31 10:51:12 +01:00
parent f008b8a9ee
commit c86809af66
10 changed files with 91 additions and 43 deletions

View File

@ -8,6 +8,7 @@
#include <glm/trigonometric.hpp>
#include "gfx_device.h"
#include "systems/mesh_render_system.h"
namespace engine {
@ -31,7 +32,8 @@ class Renderer {
void PreRender(bool window_is_resized, glm::mat4 camera_transform);
void Render();
// staticList can be nullptr to render nothing
void Render(const StaticRenderList* staticList);
// getters

View File

@ -21,7 +21,8 @@ class SceneManager {
// creates an empty scene and sets it as active
Scene* CreateEmptyScene();
void UpdateActiveScene(float ts);
// returns active scene, nullptr if no scene active
Scene* UpdateActiveScene(float ts);
Scene* GetActiveScene() { return scenes_.at(active_scene_index_).get(); }
private:

View File

@ -9,7 +9,7 @@
namespace engine {
struct MeshRenderListEntry {
struct StaticRenderListEntry {
const gfx::Pipeline* pipeline;
const gfx::Buffer* vertex_buffer;
const gfx::Buffer* index_buffer;
@ -18,18 +18,21 @@ struct MeshRenderListEntry {
uint32_t index_count;
};
using StaticRenderList = std::vector<StaticRenderListEntry>;
class MeshRenderSystem : public System {
public:
MeshRenderSystem(Scene* scene);
~MeshRenderSystem();
void RebuildRenderList();
const StaticRenderList* GetStaticRenderList() const { return &static_render_list_; }
void OnComponentInsert(uint32_t entity) override;
void OnUpdate(float ts) override;
private:
std::vector<MeshRenderListEntry> static_render_list_;
StaticRenderList static_render_list_;
bool list_needs_rebuild_ = false;
};

View File

@ -8,7 +8,7 @@
namespace engine {
namespace util {
uint32_t LoadMeshFromFile(Scene* parent, const std::string& path);
uint32_t LoadMeshFromFile(Scene* parent, const std::string& path, bool is_static = false);
} // namespace util
} // namespace engine

View File

@ -17,6 +17,8 @@
#include "resources/mesh.h"
#include "resources/shader.h"
#include "resources/texture.h"
#include "systems/mesh_render_system.h"
#include "components/transform.h"
#include "scene.h"
#include "scene_manager.h"
#include "window.h"
@ -148,8 +150,7 @@ Application::Application(const char* appName, const char* appVersion,
}
}
Application::~Application() {
}
Application::~Application() {}
void Application::GameLoop() {
LOG_DEBUG("Begin game loop...");
@ -165,7 +166,7 @@ void Application::GameLoop() {
// single-threaded game loop
while (window_->IsRunning()) {
/* logic */
scene_manager_->UpdateActiveScene(window_->dt());
Scene* scene = scene_manager_->UpdateActiveScene(window_->dt());
uint64_t now = window_->GetNanos();
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
@ -176,8 +177,13 @@ void Application::GameLoop() {
}
/* render */
renderer_->PreRender(window()->GetWindowResized(), glm::mat4{1.0f});
renderer_->Render();
renderer_->PreRender(window()->GetWindowResized(), scene->GetComponent<TransformComponent>(scene->GetEntity("camera"))->world_matrix);
const StaticRenderList* staticList = nullptr;
if (scene) {
staticList = scene->GetSystem<MeshRenderSystem>()->GetStaticRenderList();
}
renderer_->Render(staticList);
/* poll events */
window_->GetInputAndEvents();
@ -190,7 +196,7 @@ void Application::GameLoop() {
endFrame = beginFrame + FRAMETIME_LIMIT;
}
renderer()->GetDevice()->WaitIdle();
renderer_->GetDevice()->WaitIdle();
}
} // namespace engine

View File

@ -90,10 +90,39 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform) {
&frame_uniform.uniform_buffer_data);
}
void Renderer::Render()
{
void Renderer::Render(const StaticRenderList* staticList) {
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);
}
}
device_->FinishRender(draw_buffer);
}

View File

@ -22,11 +22,15 @@ namespace engine {
return scenes_.back().get();
}
void SceneManager::UpdateActiveScene(float ts)
Scene* SceneManager::UpdateActiveScene(float ts)
{
if (active_scene_index_ >= 0) [[likely]] {
assert((size_t)active_scene_index_ < scenes_.size());
scenes_[active_scene_index_]->Update(ts);
Scene* activeScene = scenes_[active_scene_index_].get();
activeScene->Update(ts);
return activeScene;
} else {
return nullptr;
}
}

View File

@ -30,7 +30,7 @@ void MeshRenderSystem::RebuildRenderList() {
const gfx::Pipeline* pipeline =
renderable->material->GetShader()->GetPipeline();
static_render_list_.emplace_back(MeshRenderListEntry{
static_render_list_.emplace_back(StaticRenderListEntry{
.pipeline = pipeline,
.vertex_buffer = renderable->mesh->GetVB(),
.index_buffer = renderable->mesh->GetIB(),
@ -47,8 +47,8 @@ void MeshRenderSystem::RebuildRenderList() {
// sort the meshes by pipeline
auto sort_by_pipeline = [&render_orders](
const MeshRenderListEntry& e1,
const MeshRenderListEntry& e2) -> bool {
const StaticRenderListEntry& e1,
const StaticRenderListEntry& e2) -> bool {
return (render_orders.at(e1.pipeline) < render_orders.at(e2.pipeline));
};
@ -74,6 +74,7 @@ void MeshRenderSystem::RebuildRenderList() {
}
void MeshRenderSystem::OnComponentInsert(uint32_t entity) {
(void)entity;
list_needs_rebuild_ = true;
}

View File

@ -31,7 +31,7 @@ namespace engine::util {
const std::map<int, std::shared_ptr<resources::Texture>>& textures,
const std::vector<std::shared_ptr<resources::Mesh>>& meshes,
const std::vector<unsigned int>& meshTextureIndices,
aiNode* parentNode, Scene* scene, uint32_t parentObj)
aiNode* parentNode, Scene* scene, uint32_t parentObj, bool is_static)
{
// convert to glm column major
@ -71,10 +71,12 @@ namespace engine::util {
parentTransform->position = position;
parentTransform->scale = scale;
parentTransform->rotation = rotation;
parentTransform->is_static = is_static;
for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) {
// create child node for each mesh
auto child = scene->CreateEntity("_mesh" + std::to_string(i), parentObj);
scene->GetComponent<TransformComponent>(child)->is_static = is_static;
auto childRenderer = scene->AddComponent<RenderableComponent>(child);
childRenderer->mesh = meshes[parentNode->mMeshes[i]];
childRenderer->material = std::make_shared<resources::Material>(scene->app()->GetResource<resources::Shader>("builtin.standard"));
@ -92,12 +94,12 @@ namespace engine::util {
meshTextureIndices,
parentNode->mChildren[i],
scene,
scene->CreateEntity("child" + std::to_string(i), parentObj)
scene->CreateEntity("child" + std::to_string(i), parentObj), is_static
);
}
}
uint32_t LoadMeshFromFile(Scene* parent, const std::string& path)
uint32_t LoadMeshFromFile(Scene* parent, const std::string& path, bool is_static)
{
Assimp::Importer importer;
@ -231,7 +233,7 @@ namespace engine::util {
uint32_t obj = parent->CreateEntity(scene->GetShortFilename(path.c_str()));
buildGraph(textures, meshes, meshMaterialIndices, scene->mRootNode, parent, obj);
buildGraph(textures, meshes, meshMaterialIndices, scene->mRootNode, parent, obj, is_static);
LOG_INFO("Loaded model: {}, meshes: {}, textures: {}", scene->GetShortFilename(path.c_str()), meshes.size(), textures.size());

View File

@ -53,7 +53,7 @@ void PlayGame(GameSettings settings) {
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphics_settings);
app.SetFrameLimiter(settings.enable_frame_limiter);
app.window()->SetRelativeMouseMode(false);
app.window()->SetRelativeMouseMode(true);
ConfigureInputs(app.input_manager());
{
@ -79,14 +79,14 @@ void PlayGame(GameSettings settings) {
}
/* shared resources */
/* auto grass_texture = std::make_shared<engine::resources::Texture>(
auto grass_texture = std::make_shared<engine::resources::Texture>(
app.renderer(), app.GetResourcePath("textures/grass.jpg"),
engine::resources::Texture::Filtering::kAnisotropic);
auto space_texture = std::make_shared<engine::resources::Texture>(
app.renderer(), app.GetResourcePath("textures/space2.png"),
engine::resources::Texture::Filtering::kAnisotropic);
*/
/* skybox */
{
uint32_t skybox = my_scene->CreateEntity("skybox");
@ -97,7 +97,7 @@ void PlayGame(GameSettings settings) {
std::make_unique<engine::resources::Material>(
app.GetResource<engine::resources::Shader>("builtin.skybox"));
skybox_renderable->material->texture_ =
app.GetResource<engine::resources::Texture>("builtin.white");
space_texture;
skybox_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
10.0f, 10.0f, 10.0f, 1.0f, true);
@ -122,7 +122,7 @@ void PlayGame(GameSettings settings) {
std::make_shared<engine::resources::Material>(
app.GetResource<engine::resources::Shader>("builtin.standard"));
floor_renderable->material->texture_ =
app.GetResource<engine::resources::Texture>("builtin.white");
grass_texture;
floor_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
100.0f, 0.1f, 100.0f, 100.0f);
@ -135,20 +135,20 @@ void PlayGame(GameSettings settings) {
// engine::util::LoadMeshFromFile(my_scene,
// app.GetResourcePath("models/test_scene.dae"));
//auto cobbleHouse = engine::util::LoadMeshFromFile(
// my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"));
//my_scene->GetComponent<engine::TransformComponent>(cobbleHouse)->position +=
// glm::vec3{33.0f, 0.1f, 35.0f};
//auto cobbleCustom =
// my_scene->AddComponent<engine::CustomComponent>(cobbleHouse);
//cobbleCustom->onInit = [](void) {
// LOG_INFO("Cobble house spin component initialised!");
//};
//cobbleCustom->onUpdate = [&](float ts) {
// static auto t =
// my_scene->GetComponent<engine::TransformComponent>(cobbleHouse);
// t->rotation *= glm::angleAxis(ts, glm::vec3{0.0f, 0.0f, 1.0f});
//};
auto cobbleHouse = engine::util::LoadMeshFromFile(
my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"), true);
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse)->position +=
glm::vec3{33.0f, 0.1f, 35.0f};
auto cobbleCustom =
my_scene->AddComponent<engine::CustomComponent>(cobbleHouse);
cobbleCustom->onInit = [](void) {
LOG_INFO("Cobble house spin component initialised!");
};
cobbleCustom->onUpdate = [&](float ts) {
static auto t =
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse);
t->rotation *= glm::angleAxis(ts, glm::vec3{0.0f, 0.0f, 1.0f});
};
/* some text */
{