mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
add static rendering
This commit is contained in:
parent
f008b8a9ee
commit
c86809af66
@ -8,6 +8,7 @@
|
|||||||
#include <glm/trigonometric.hpp>
|
#include <glm/trigonometric.hpp>
|
||||||
|
|
||||||
#include "gfx_device.h"
|
#include "gfx_device.h"
|
||||||
|
#include "systems/mesh_render_system.h"
|
||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
@ -31,7 +32,8 @@ class Renderer {
|
|||||||
|
|
||||||
void PreRender(bool window_is_resized, glm::mat4 camera_transform);
|
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
|
// getters
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ class SceneManager {
|
|||||||
// creates an empty scene and sets it as active
|
// creates an empty scene and sets it as active
|
||||||
Scene* CreateEmptyScene();
|
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(); }
|
Scene* GetActiveScene() { return scenes_.at(active_scene_index_).get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
struct MeshRenderListEntry {
|
struct StaticRenderListEntry {
|
||||||
const gfx::Pipeline* pipeline;
|
const gfx::Pipeline* pipeline;
|
||||||
const gfx::Buffer* vertex_buffer;
|
const gfx::Buffer* vertex_buffer;
|
||||||
const gfx::Buffer* index_buffer;
|
const gfx::Buffer* index_buffer;
|
||||||
@ -18,18 +18,21 @@ struct MeshRenderListEntry {
|
|||||||
uint32_t index_count;
|
uint32_t index_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using StaticRenderList = std::vector<StaticRenderListEntry>;
|
||||||
|
|
||||||
class MeshRenderSystem : public System {
|
class MeshRenderSystem : public System {
|
||||||
public:
|
public:
|
||||||
MeshRenderSystem(Scene* scene);
|
MeshRenderSystem(Scene* scene);
|
||||||
~MeshRenderSystem();
|
~MeshRenderSystem();
|
||||||
|
|
||||||
void RebuildRenderList();
|
void RebuildRenderList();
|
||||||
|
const StaticRenderList* GetStaticRenderList() const { return &static_render_list_; }
|
||||||
|
|
||||||
void OnComponentInsert(uint32_t entity) override;
|
void OnComponentInsert(uint32_t entity) override;
|
||||||
void OnUpdate(float ts) override;
|
void OnUpdate(float ts) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MeshRenderListEntry> static_render_list_;
|
StaticRenderList static_render_list_;
|
||||||
bool list_needs_rebuild_ = false;
|
bool list_needs_rebuild_ = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
namespace engine {
|
namespace engine {
|
||||||
namespace util {
|
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 util
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
#include "resources/mesh.h"
|
#include "resources/mesh.h"
|
||||||
#include "resources/shader.h"
|
#include "resources/shader.h"
|
||||||
#include "resources/texture.h"
|
#include "resources/texture.h"
|
||||||
|
#include "systems/mesh_render_system.h"
|
||||||
|
#include "components/transform.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "scene_manager.h"
|
#include "scene_manager.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
@ -148,8 +150,7 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
Application::~Application() {}
|
||||||
}
|
|
||||||
|
|
||||||
void Application::GameLoop() {
|
void Application::GameLoop() {
|
||||||
LOG_DEBUG("Begin game loop...");
|
LOG_DEBUG("Begin game loop...");
|
||||||
@ -165,19 +166,24 @@ void Application::GameLoop() {
|
|||||||
// single-threaded game loop
|
// single-threaded game loop
|
||||||
while (window_->IsRunning()) {
|
while (window_->IsRunning()) {
|
||||||
/* logic */
|
/* logic */
|
||||||
scene_manager_->UpdateActiveScene(window_->dt());
|
Scene* scene = scene_manager_->UpdateActiveScene(window_->dt());
|
||||||
|
|
||||||
uint64_t now = window_->GetNanos();
|
uint64_t now = window_->GetNanos();
|
||||||
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
||||||
lastTick = now;
|
lastTick = now;
|
||||||
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
||||||
//renderer()->GetDevice()->LogPerformanceInfo();
|
// renderer()->GetDevice()->LogPerformanceInfo();
|
||||||
window_->ResetAvgFPS();
|
window_->ResetAvgFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* render */
|
/* render */
|
||||||
renderer_->PreRender(window()->GetWindowResized(), glm::mat4{1.0f});
|
renderer_->PreRender(window()->GetWindowResized(), scene->GetComponent<TransformComponent>(scene->GetEntity("camera"))->world_matrix);
|
||||||
renderer_->Render();
|
|
||||||
|
const StaticRenderList* staticList = nullptr;
|
||||||
|
if (scene) {
|
||||||
|
staticList = scene->GetSystem<MeshRenderSystem>()->GetStaticRenderList();
|
||||||
|
}
|
||||||
|
renderer_->Render(staticList);
|
||||||
|
|
||||||
/* poll events */
|
/* poll events */
|
||||||
window_->GetInputAndEvents();
|
window_->GetInputAndEvents();
|
||||||
@ -190,7 +196,7 @@ void Application::GameLoop() {
|
|||||||
endFrame = beginFrame + FRAMETIME_LIMIT;
|
endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer()->GetDevice()->WaitIdle();
|
renderer_->GetDevice()->WaitIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -90,10 +90,39 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform) {
|
|||||||
&frame_uniform.uniform_buffer_data);
|
&frame_uniform.uniform_buffer_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Render()
|
void Renderer::Render(const StaticRenderList* staticList) {
|
||||||
{
|
|
||||||
gfx::DrawBuffer* draw_buffer = device_->BeginRender();
|
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);
|
device_->FinishRender(draw_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,12 +22,16 @@ namespace engine {
|
|||||||
return scenes_.back().get();
|
return scenes_.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneManager::UpdateActiveScene(float ts)
|
Scene* SceneManager::UpdateActiveScene(float ts)
|
||||||
{
|
{
|
||||||
if (active_scene_index_ >= 0) [[likely]] {
|
if (active_scene_index_ >= 0) [[likely]] {
|
||||||
assert((size_t)active_scene_index_ < scenes_.size());
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ void MeshRenderSystem::RebuildRenderList() {
|
|||||||
const gfx::Pipeline* pipeline =
|
const gfx::Pipeline* pipeline =
|
||||||
renderable->material->GetShader()->GetPipeline();
|
renderable->material->GetShader()->GetPipeline();
|
||||||
|
|
||||||
static_render_list_.emplace_back(MeshRenderListEntry{
|
static_render_list_.emplace_back(StaticRenderListEntry{
|
||||||
.pipeline = pipeline,
|
.pipeline = pipeline,
|
||||||
.vertex_buffer = renderable->mesh->GetVB(),
|
.vertex_buffer = renderable->mesh->GetVB(),
|
||||||
.index_buffer = renderable->mesh->GetIB(),
|
.index_buffer = renderable->mesh->GetIB(),
|
||||||
@ -47,8 +47,8 @@ void MeshRenderSystem::RebuildRenderList() {
|
|||||||
|
|
||||||
// sort the meshes by pipeline
|
// sort the meshes by pipeline
|
||||||
auto sort_by_pipeline = [&render_orders](
|
auto sort_by_pipeline = [&render_orders](
|
||||||
const MeshRenderListEntry& e1,
|
const StaticRenderListEntry& e1,
|
||||||
const MeshRenderListEntry& e2) -> bool {
|
const StaticRenderListEntry& e2) -> bool {
|
||||||
return (render_orders.at(e1.pipeline) < render_orders.at(e2.pipeline));
|
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 MeshRenderSystem::OnComponentInsert(uint32_t entity) {
|
||||||
|
(void)entity;
|
||||||
list_needs_rebuild_ = true;
|
list_needs_rebuild_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ namespace engine::util {
|
|||||||
const std::map<int, std::shared_ptr<resources::Texture>>& textures,
|
const std::map<int, std::shared_ptr<resources::Texture>>& textures,
|
||||||
const std::vector<std::shared_ptr<resources::Mesh>>& meshes,
|
const std::vector<std::shared_ptr<resources::Mesh>>& meshes,
|
||||||
const std::vector<unsigned int>& meshTextureIndices,
|
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
|
// convert to glm column major
|
||||||
@ -71,10 +71,12 @@ namespace engine::util {
|
|||||||
parentTransform->position = position;
|
parentTransform->position = position;
|
||||||
parentTransform->scale = scale;
|
parentTransform->scale = scale;
|
||||||
parentTransform->rotation = rotation;
|
parentTransform->rotation = rotation;
|
||||||
|
parentTransform->is_static = is_static;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) {
|
for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) {
|
||||||
// create child node for each mesh
|
// create child node for each mesh
|
||||||
auto child = scene->CreateEntity("_mesh" + std::to_string(i), parentObj);
|
auto child = scene->CreateEntity("_mesh" + std::to_string(i), parentObj);
|
||||||
|
scene->GetComponent<TransformComponent>(child)->is_static = is_static;
|
||||||
auto childRenderer = scene->AddComponent<RenderableComponent>(child);
|
auto childRenderer = scene->AddComponent<RenderableComponent>(child);
|
||||||
childRenderer->mesh = meshes[parentNode->mMeshes[i]];
|
childRenderer->mesh = meshes[parentNode->mMeshes[i]];
|
||||||
childRenderer->material = std::make_shared<resources::Material>(scene->app()->GetResource<resources::Shader>("builtin.standard"));
|
childRenderer->material = std::make_shared<resources::Material>(scene->app()->GetResource<resources::Shader>("builtin.standard"));
|
||||||
@ -92,12 +94,12 @@ namespace engine::util {
|
|||||||
meshTextureIndices,
|
meshTextureIndices,
|
||||||
parentNode->mChildren[i],
|
parentNode->mChildren[i],
|
||||||
scene,
|
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;
|
Assimp::Importer importer;
|
||||||
|
|
||||||
@ -231,7 +233,7 @@ namespace engine::util {
|
|||||||
|
|
||||||
uint32_t obj = parent->CreateEntity(scene->GetShortFilename(path.c_str()));
|
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());
|
LOG_INFO("Loaded model: {}, meshes: {}, textures: {}", scene->GetShortFilename(path.c_str()), meshes.size(), textures.size());
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ void PlayGame(GameSettings settings) {
|
|||||||
|
|
||||||
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphics_settings);
|
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphics_settings);
|
||||||
app.SetFrameLimiter(settings.enable_frame_limiter);
|
app.SetFrameLimiter(settings.enable_frame_limiter);
|
||||||
app.window()->SetRelativeMouseMode(false);
|
app.window()->SetRelativeMouseMode(true);
|
||||||
ConfigureInputs(app.input_manager());
|
ConfigureInputs(app.input_manager());
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -79,14 +79,14 @@ void PlayGame(GameSettings settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* shared resources */
|
/* 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"),
|
app.renderer(), app.GetResourcePath("textures/grass.jpg"),
|
||||||
engine::resources::Texture::Filtering::kAnisotropic);
|
engine::resources::Texture::Filtering::kAnisotropic);
|
||||||
|
|
||||||
auto space_texture = std::make_shared<engine::resources::Texture>(
|
auto space_texture = std::make_shared<engine::resources::Texture>(
|
||||||
app.renderer(), app.GetResourcePath("textures/space2.png"),
|
app.renderer(), app.GetResourcePath("textures/space2.png"),
|
||||||
engine::resources::Texture::Filtering::kAnisotropic);
|
engine::resources::Texture::Filtering::kAnisotropic);
|
||||||
*/
|
|
||||||
/* skybox */
|
/* skybox */
|
||||||
{
|
{
|
||||||
uint32_t skybox = my_scene->CreateEntity("skybox");
|
uint32_t skybox = my_scene->CreateEntity("skybox");
|
||||||
@ -97,7 +97,7 @@ void PlayGame(GameSettings settings) {
|
|||||||
std::make_unique<engine::resources::Material>(
|
std::make_unique<engine::resources::Material>(
|
||||||
app.GetResource<engine::resources::Shader>("builtin.skybox"));
|
app.GetResource<engine::resources::Shader>("builtin.skybox"));
|
||||||
skybox_renderable->material->texture_ =
|
skybox_renderable->material->texture_ =
|
||||||
app.GetResource<engine::resources::Texture>("builtin.white");
|
space_texture;
|
||||||
skybox_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
skybox_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||||
10.0f, 10.0f, 10.0f, 1.0f, true);
|
10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ void PlayGame(GameSettings settings) {
|
|||||||
std::make_shared<engine::resources::Material>(
|
std::make_shared<engine::resources::Material>(
|
||||||
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
||||||
floor_renderable->material->texture_ =
|
floor_renderable->material->texture_ =
|
||||||
app.GetResource<engine::resources::Texture>("builtin.white");
|
grass_texture;
|
||||||
floor_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
floor_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||||
100.0f, 0.1f, 100.0f, 100.0f);
|
100.0f, 0.1f, 100.0f, 100.0f);
|
||||||
|
|
||||||
@ -135,20 +135,20 @@ void PlayGame(GameSettings settings) {
|
|||||||
// engine::util::LoadMeshFromFile(my_scene,
|
// engine::util::LoadMeshFromFile(my_scene,
|
||||||
// app.GetResourcePath("models/test_scene.dae"));
|
// app.GetResourcePath("models/test_scene.dae"));
|
||||||
|
|
||||||
//auto cobbleHouse = engine::util::LoadMeshFromFile(
|
auto cobbleHouse = engine::util::LoadMeshFromFile(
|
||||||
// my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"));
|
my_scene, app.GetResourcePath("models/cobble_house/cobble_house.dae"), true);
|
||||||
//my_scene->GetComponent<engine::TransformComponent>(cobbleHouse)->position +=
|
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse)->position +=
|
||||||
// glm::vec3{33.0f, 0.1f, 35.0f};
|
glm::vec3{33.0f, 0.1f, 35.0f};
|
||||||
//auto cobbleCustom =
|
auto cobbleCustom =
|
||||||
// my_scene->AddComponent<engine::CustomComponent>(cobbleHouse);
|
my_scene->AddComponent<engine::CustomComponent>(cobbleHouse);
|
||||||
//cobbleCustom->onInit = [](void) {
|
cobbleCustom->onInit = [](void) {
|
||||||
// LOG_INFO("Cobble house spin component initialised!");
|
LOG_INFO("Cobble house spin component initialised!");
|
||||||
//};
|
};
|
||||||
//cobbleCustom->onUpdate = [&](float ts) {
|
cobbleCustom->onUpdate = [&](float ts) {
|
||||||
// static auto t =
|
static auto t =
|
||||||
// my_scene->GetComponent<engine::TransformComponent>(cobbleHouse);
|
my_scene->GetComponent<engine::TransformComponent>(cobbleHouse);
|
||||||
// t->rotation *= glm::angleAxis(ts, glm::vec3{0.0f, 0.0f, 1.0f});
|
t->rotation *= glm::angleAxis(ts, glm::vec3{0.0f, 0.0f, 1.0f});
|
||||||
//};
|
};
|
||||||
|
|
||||||
/* some text */
|
/* some text */
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user