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 "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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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,19 +166,24 @@ 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]] {
|
||||
lastTick = now;
|
||||
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
||||
//renderer()->GetDevice()->LogPerformanceInfo();
|
||||
// renderer()->GetDevice()->LogPerformanceInfo();
|
||||
window_->ResetAvgFPS();
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -22,12 +22,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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 */
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user