mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
write out renderer class
This commit is contained in:
parent
6a8c8b1c3e
commit
0145bf187d
@ -92,6 +92,8 @@ source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}/include" PREFIX "Include" FILES $
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "ENGINE_EXPORTS")
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC DEFINITIONS "VMA_DEBUG_LOG=printf")
|
||||
|
||||
if (WIN32)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "NOMINMAX") # stop windows.h conflicting with 'std::max'
|
||||
endif()
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include "gfx.h"
|
||||
#include "gfx_device.h"
|
||||
#include "renderer.h"
|
||||
#include "input_manager.h"
|
||||
#include "resource_manager.h"
|
||||
#include "scene_manager.h"
|
||||
@ -19,31 +19,6 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
struct RenderData {
|
||||
std::unique_ptr<GFXDevice> gfxdev;
|
||||
gfx::DrawBuffer* draw_buffer = nullptr;
|
||||
|
||||
/* uniforms for engine globals */
|
||||
const gfx::DescriptorSetLayout* global_set_layout;
|
||||
const gfx::DescriptorSet* global_set;
|
||||
struct GlobalSetUniformBuffer {
|
||||
glm::mat4 proj;
|
||||
};
|
||||
gfx::UniformBuffer* global_set_uniform_buffer;
|
||||
|
||||
/* uniforms for per-frame data */
|
||||
const gfx::DescriptorSetLayout* frame_set_layout;
|
||||
const gfx::DescriptorSet* frame_set;
|
||||
struct FrameSetUniformBuffer {
|
||||
glm::mat4 view;
|
||||
};
|
||||
gfx::UniformBuffer* frame_set_uniform_buffer;
|
||||
|
||||
/* this descriptor set is bound per-material */
|
||||
const gfx::DescriptorSetLayout* material_set_layout;
|
||||
std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers{};
|
||||
};
|
||||
|
||||
class Application {
|
||||
public:
|
||||
Application(const char* app_name, const char* app_version,
|
||||
@ -82,20 +57,19 @@ class Application {
|
||||
|
||||
/* getters */
|
||||
Window* window() { return window_.get(); }
|
||||
GFXDevice* gfxdev() { return render_data_.gfxdev.get(); }
|
||||
InputManager* input_manager() { return input_manager_.get(); }
|
||||
SceneManager* scene_manager() { return scene_manager_.get(); }
|
||||
Renderer* renderer() { return renderer_.get(); }
|
||||
|
||||
std::string GetResourcePath(const std::string relative_path) {
|
||||
return (resources_path_ / relative_path).string();
|
||||
}
|
||||
|
||||
RenderData render_data_{};
|
||||
|
||||
private:
|
||||
std::unique_ptr<Window> window_;
|
||||
std::unique_ptr<InputManager> input_manager_;
|
||||
std::unique_ptr<SceneManager> scene_manager_;
|
||||
std::unique_ptr<Renderer> renderer_;
|
||||
std::unordered_map<size_t, std::unique_ptr<IResourceManager>>
|
||||
resource_managers_{};
|
||||
std::filesystem::path resources_path_;
|
||||
|
@ -1,8 +1,78 @@
|
||||
#ifndef ENGINE_INCLUDE_RENDERER_H_
|
||||
#define ENGINE_INCLUDE_RENDERER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include "gfx_device.h"
|
||||
|
||||
namespace engine {
|
||||
|
||||
|
||||
// A uniform struct that holds data of type T
|
||||
template <typename T>
|
||||
struct UniformDescriptor {
|
||||
const gfx::DescriptorSetLayout* layout;
|
||||
const gfx::DescriptorSet* set;
|
||||
struct UniformBufferData {
|
||||
T data;
|
||||
} uniform_buffer_data;
|
||||
gfx::UniformBuffer* uniform_buffer;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(const char* app_name, const char* app_version, SDL_Window* window,
|
||||
gfx::GraphicsSettings settings);
|
||||
|
||||
~Renderer();
|
||||
|
||||
GFXDevice* GetDevice() { return device_.get(); }
|
||||
|
||||
const gfx::DescriptorSetLayout* GetGlobalSetLayout() {
|
||||
return global_uniform.layout;
|
||||
}
|
||||
|
||||
const gfx::DescriptorSetLayout* GetFrameSetLayout() {
|
||||
return frame_uniform.layout;
|
||||
}
|
||||
|
||||
const gfx::DescriptorSetLayout* GetMaterialSetLayout() {
|
||||
return material_set_layout;
|
||||
}
|
||||
|
||||
std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers;
|
||||
|
||||
private:
|
||||
std::unique_ptr<GFXDevice> device_;
|
||||
|
||||
// ALL vertex shaders must begin with:
|
||||
/*
|
||||
layout(set = 0, binding = 0) uniform GlobalSetUniformBuffer {
|
||||
mat4 proj;
|
||||
} globalSetUniformBuffer;
|
||||
|
||||
layout(set = 1, binding = 0) uniform FrameSetUniformBuffer {
|
||||
mat4 view;
|
||||
} frameSetUniformBuffer;
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
} constants;
|
||||
*/
|
||||
// ALL fragment shaders must begin with:
|
||||
/*
|
||||
layout(set = 2, binding = 0) uniform sampler2D materialSetSampler;
|
||||
*/
|
||||
|
||||
// in vertex shader
|
||||
UniformDescriptor<glm::mat4> global_uniform; // rarely updates; set 0
|
||||
UniformDescriptor<glm::mat4> frame_uniform; // updates once per frame; set 1
|
||||
// in fragment shader
|
||||
const gfx::DescriptorSetLayout* material_set_layout; // set 2
|
||||
};
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -28,7 +28,7 @@ class Shader {
|
||||
|
||||
static constexpr int kHighestRenderOrder = 1;
|
||||
|
||||
Shader(RenderData* render_data, const char* vert_path, const char* frag_path,
|
||||
Shader(Renderer* renderer, const char* vert_path, const char* frag_path,
|
||||
const ShaderSettings& settings);
|
||||
~Shader();
|
||||
Shader(const Shader&) = delete;
|
||||
|
@ -18,9 +18,9 @@ class Texture {
|
||||
kAnisotropic,
|
||||
};
|
||||
|
||||
Texture(RenderData* render_data, const std::string& path,
|
||||
Texture(Renderer* renderer, const std::string& path,
|
||||
Filtering filtering);
|
||||
Texture(RenderData* render_data, const uint8_t* bitmap, int width, int height,
|
||||
Texture(Renderer* renderer, const uint8_t* bitmap, int width, int height,
|
||||
Filtering filtering);
|
||||
|
||||
~Texture();
|
||||
|
@ -16,7 +16,6 @@ struct MeshRenderListEntry {
|
||||
const gfx::DescriptorSet* base_colour_texture;
|
||||
glm::mat4 model_matrix;
|
||||
uint32_t index_count;
|
||||
// 100 bytes
|
||||
};
|
||||
|
||||
class MeshRenderSystem : public System {
|
||||
|
@ -76,57 +76,9 @@ Application::Application(const char* appName, const char* appVersion,
|
||||
RegisterResourceManager<resources::Material>();
|
||||
RegisterResourceManager<resources::Mesh>();
|
||||
|
||||
// initialise the render data
|
||||
render_data_.gfxdev = std::make_unique<GFXDevice>(
|
||||
renderer_ = std::make_unique<Renderer>(
|
||||
appName, appVersion, window_->GetHandle(), graphicsSettings);
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings;
|
||||
{
|
||||
auto& binding0 = globalSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
render_data_.global_set_layout =
|
||||
gfxdev()->CreateDescriptorSetLayout(globalSetBindings);
|
||||
render_data_.global_set =
|
||||
gfxdev()->AllocateDescriptorSet(render_data_.global_set_layout);
|
||||
RenderData::GlobalSetUniformBuffer globalSetUniformBufferData{
|
||||
.proj = glm::mat4{1.0f},
|
||||
};
|
||||
render_data_.global_set_uniform_buffer = gfxdev()->CreateUniformBuffer(
|
||||
sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData);
|
||||
gfxdev()->UpdateDescriptorUniformBuffer(
|
||||
render_data_.global_set, 0, render_data_.global_set_uniform_buffer, 0,
|
||||
sizeof(RenderData::GlobalSetUniformBuffer));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
|
||||
{
|
||||
auto& binding0 = frameSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
render_data_.frame_set_layout =
|
||||
gfxdev()->CreateDescriptorSetLayout(frameSetBindings);
|
||||
render_data_.frame_set =
|
||||
gfxdev()->AllocateDescriptorSet(render_data_.frame_set_layout);
|
||||
RenderData::FrameSetUniformBuffer initialSetOneData{
|
||||
.view = glm::mat4{1.0f},
|
||||
};
|
||||
render_data_.frame_set_uniform_buffer = gfxdev()->CreateUniformBuffer(
|
||||
sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData);
|
||||
gfxdev()->UpdateDescriptorUniformBuffer(
|
||||
render_data_.frame_set, 0, render_data_.frame_set_uniform_buffer, 0,
|
||||
sizeof(RenderData::FrameSetUniformBuffer));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
|
||||
{
|
||||
auto& binding0 = materialSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kFragment;
|
||||
}
|
||||
render_data_.material_set_layout =
|
||||
gfxdev()->CreateDescriptorSetLayout(materialSetBindings);
|
||||
|
||||
/* default fonts */
|
||||
{
|
||||
auto monoFont = std::make_unique<resources::Font>(
|
||||
@ -147,7 +99,7 @@ Application::Application(const char* appName, const char* appVersion,
|
||||
shaderSettings.write_z = true;
|
||||
shaderSettings.render_order = 0;
|
||||
auto texturedShader = std::make_unique<resources::Shader>(
|
||||
&render_data_, GetResourcePath("engine/shaders/standard.vert").c_str(),
|
||||
renderer(), GetResourcePath("engine/shaders/standard.vert").c_str(),
|
||||
GetResourcePath("engine/shaders/standard.frag").c_str(),
|
||||
shaderSettings);
|
||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||
@ -164,7 +116,7 @@ Application::Application(const char* appName, const char* appVersion,
|
||||
shaderSettings.write_z = true;
|
||||
shaderSettings.render_order = 0;
|
||||
auto skyboxShader = std::make_unique<resources::Shader>(
|
||||
&render_data_, GetResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||
renderer(), GetResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||
GetResourcePath("engine/shaders/skybox.frag").c_str(), shaderSettings);
|
||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||
"builtin.skybox", std::move(skyboxShader));
|
||||
@ -180,7 +132,7 @@ Application::Application(const char* appName, const char* appVersion,
|
||||
shaderSettings.write_z = false;
|
||||
shaderSettings.render_order = 1;
|
||||
auto quadShader = std::make_unique<resources::Shader>(
|
||||
&render_data_, GetResourcePath("engine/shaders/quad.vert").c_str(),
|
||||
renderer(), GetResourcePath("engine/shaders/quad.vert").c_str(),
|
||||
GetResourcePath("engine/shaders/quad.frag").c_str(), shaderSettings);
|
||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||
"builtin.quad", std::move(quadShader));
|
||||
@ -189,25 +141,14 @@ Application::Application(const char* appName, const char* appVersion,
|
||||
/* default textures */
|
||||
{
|
||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||
&render_data_, GetResourcePath("engine/textures/white.png"),
|
||||
renderer(), GetResourcePath("engine/textures/white.png"),
|
||||
resources::Texture::Filtering::kOff);
|
||||
GetResourceManager<resources::Texture>()->AddPersistent(
|
||||
"builtin.white", std::move(whiteTexture));
|
||||
}
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
for (const auto& [info, sampler] : render_data_.samplers) {
|
||||
gfxdev()->DestroySampler(sampler);
|
||||
}
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.material_set_layout);
|
||||
|
||||
gfxdev()->DestroyUniformBuffer(render_data_.frame_set_uniform_buffer);
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.frame_set_layout);
|
||||
|
||||
gfxdev()->DestroyUniformBuffer(render_data_.global_set_uniform_buffer);
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.global_set_layout);
|
||||
}
|
||||
Application::~Application() {}
|
||||
|
||||
void Application::GameLoop() {
|
||||
LOG_TRACE("Begin game loop...");
|
||||
@ -229,12 +170,11 @@ void Application::GameLoop() {
|
||||
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
||||
lastTick = now;
|
||||
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
||||
gfxdev()->LogPerformanceInfo();
|
||||
renderer()->GetDevice()->LogPerformanceInfo();
|
||||
window_->ResetAvgFPS();
|
||||
}
|
||||
|
||||
/* render */
|
||||
|
||||
|
||||
/* poll events */
|
||||
window_->GetInputAndEvents();
|
||||
@ -247,7 +187,7 @@ void Application::GameLoop() {
|
||||
endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||
}
|
||||
|
||||
gfxdev()->WaitIdle();
|
||||
renderer()->GetDevice()->WaitIdle();
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
@ -1,5 +1,65 @@
|
||||
#include "renderer.h"
|
||||
|
||||
namespace engine {
|
||||
|
||||
|
||||
Renderer::Renderer(const char* app_name, const char* app_version,
|
||||
SDL_Window* window, gfx::GraphicsSettings settings) {
|
||||
device_ =
|
||||
std::make_unique<GFXDevice>(app_name, app_version, window, settings);
|
||||
|
||||
// sort out descriptor set layouts:
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings;
|
||||
{
|
||||
auto& binding0 = globalSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
global_uniform.layout = device_->CreateDescriptorSetLayout(globalSetBindings);
|
||||
global_uniform.set = device_->AllocateDescriptorSet(global_uniform.layout);
|
||||
global_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
|
||||
global_uniform.uniform_buffer =
|
||||
device_->CreateUniformBuffer(sizeof(global_uniform.uniform_buffer_data),
|
||||
&global_uniform.uniform_buffer_data);
|
||||
device_->UpdateDescriptorUniformBuffer(
|
||||
global_uniform.set, 0, global_uniform.uniform_buffer, 0,
|
||||
sizeof(global_uniform.uniform_buffer_data));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
|
||||
{
|
||||
auto& binding0 = frameSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
frame_uniform.layout = device_->CreateDescriptorSetLayout(frameSetBindings);
|
||||
frame_uniform.set = device_->AllocateDescriptorSet(frame_uniform.layout);
|
||||
frame_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
|
||||
frame_uniform.uniform_buffer =
|
||||
device_->CreateUniformBuffer(sizeof(frame_uniform.uniform_buffer_data),
|
||||
&frame_uniform.uniform_buffer_data);
|
||||
device_->UpdateDescriptorUniformBuffer(
|
||||
frame_uniform.set, 0, frame_uniform.uniform_buffer, 0,
|
||||
sizeof(frame_uniform.uniform_buffer_data));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
|
||||
{
|
||||
auto& binding0 = materialSetBindings.emplace_back();
|
||||
binding0.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kFragment;
|
||||
}
|
||||
material_set_layout = device_->CreateDescriptorSetLayout(materialSetBindings);
|
||||
};
|
||||
|
||||
Renderer::~Renderer() {
|
||||
for (const auto& [info, sampler] : samplers) {
|
||||
device_->DestroySampler(sampler);
|
||||
}
|
||||
device_->DestroyDescriptorSetLayout(material_set_layout);
|
||||
|
||||
device_->DestroyUniformBuffer(frame_uniform.uniform_buffer);
|
||||
device_->DestroyDescriptorSetLayout(frame_uniform.layout);
|
||||
|
||||
device_->DestroyUniformBuffer(global_uniform.uniform_buffer);
|
||||
device_->DestroyDescriptorSetLayout(global_uniform.layout);
|
||||
}
|
||||
|
||||
} // namespace engine
|
@ -8,10 +8,11 @@
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
Shader::Shader(RenderData* renderData, const char* vertPath,
|
||||
const char* fragPath, const ShaderSettings& settings)
|
||||
: gfx_(renderData->gfxdev.get()), render_order_(settings.render_order) {
|
||||
assert(settings.render_order <= kHighestRenderOrder && settings.render_order >= 0);
|
||||
Shader::Shader(Renderer* renderer, const char* vertPath, const char* fragPath,
|
||||
const ShaderSettings& settings)
|
||||
: gfx_(renderer->GetDevice()), render_order_(settings.render_order) {
|
||||
assert(settings.render_order <= kHighestRenderOrder &&
|
||||
settings.render_order >= 0);
|
||||
uint32_t index = 0;
|
||||
uint32_t stride = 0;
|
||||
gfx::VertexFormat vertFormat{};
|
||||
@ -49,9 +50,9 @@ Shader::Shader(RenderData* renderData, const char* vertPath,
|
||||
info.alpha_blending = settings.alpha_blending;
|
||||
info.backface_culling = settings.cull_backface;
|
||||
info.write_z = settings.write_z;
|
||||
info.descriptor_set_layouts.push_back(renderData->global_set_layout);
|
||||
info.descriptor_set_layouts.push_back(renderData->frame_set_layout);
|
||||
info.descriptor_set_layouts.push_back(renderData->material_set_layout);
|
||||
info.descriptor_set_layouts.push_back(renderer->GetGlobalSetLayout());
|
||||
info.descriptor_set_layouts.push_back(renderer->GetFrameSetLayout());
|
||||
info.descriptor_set_layouts.push_back(renderer->GetMaterialSetLayout());
|
||||
|
||||
pipeline_ = gfx_->CreatePipeline(info);
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
namespace engine::resources {
|
||||
|
||||
Texture::Texture(RenderData* renderData, const std::string& path,
|
||||
Texture::Texture(Renderer* renderer, const std::string& path,
|
||||
Filtering filtering)
|
||||
: gfx_(renderData->gfxdev.get()) {
|
||||
: gfx_(renderer->GetDevice()) {
|
||||
int width, height;
|
||||
std::unique_ptr<std::vector<uint8_t>> texbuf =
|
||||
util::ReadImageFile(path, &width, &height);
|
||||
@ -41,23 +41,23 @@ Texture::Texture(RenderData* renderData, const std::string& path,
|
||||
samplerInfo.anisotropic_filtering = true;
|
||||
}
|
||||
|
||||
if (renderData->samplers.contains(samplerInfo) == false) {
|
||||
renderData->samplers.insert(
|
||||
if (renderer->samplers.contains(samplerInfo) == false) {
|
||||
renderer->samplers.insert(
|
||||
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
||||
}
|
||||
|
||||
image_ = gfx_->CreateImage(width, height, texbuf->data());
|
||||
descriptor_set_ =
|
||||
gfx_->AllocateDescriptorSet(renderData->material_set_layout);
|
||||
gfx_->AllocateDescriptorSet(renderer->GetMaterialSetLayout());
|
||||
gfx_->UpdateDescriptorCombinedImageSampler(
|
||||
descriptor_set_, 0, image_, renderData->samplers.at(samplerInfo));
|
||||
descriptor_set_, 0, image_, renderer->samplers.at(samplerInfo));
|
||||
|
||||
LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
|
||||
}
|
||||
|
||||
Texture::Texture(RenderData* render_data, const uint8_t* bitmap, int width,
|
||||
Texture::Texture(Renderer* renderer, const uint8_t* bitmap, int width,
|
||||
int height, Filtering filtering)
|
||||
: gfx_(render_data->gfxdev.get()) {
|
||||
: gfx_(renderer->GetDevice()) {
|
||||
gfx::SamplerInfo samplerInfo{};
|
||||
|
||||
samplerInfo.magnify = gfx::Filter::kLinear;
|
||||
@ -84,16 +84,16 @@ Texture::Texture(RenderData* render_data, const uint8_t* bitmap, int width,
|
||||
samplerInfo.anisotropic_filtering = true;
|
||||
}
|
||||
|
||||
if (render_data->samplers.contains(samplerInfo) == false) {
|
||||
render_data->samplers.insert(
|
||||
if (renderer->samplers.contains(samplerInfo) == false) {
|
||||
renderer->samplers.insert(
|
||||
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
||||
}
|
||||
|
||||
image_ = gfx_->CreateImage(width, height, bitmap);
|
||||
descriptor_set_ =
|
||||
gfx_->AllocateDescriptorSet(render_data->material_set_layout);
|
||||
gfx_->AllocateDescriptorSet(renderer->GetMaterialSetLayout());
|
||||
gfx_->UpdateDescriptorCombinedImageSampler(
|
||||
descriptor_set_, 0, image_, render_data->samplers.at(samplerInfo));
|
||||
descriptor_set_, 0, image_, renderer->samplers.at(samplerInfo));
|
||||
|
||||
LOG_INFO("Loaded texture: BITMAP, width: {} height: {}", width, height);
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ void MeshRenderSystem::RebuildRenderList() {
|
||||
|
||||
for (uint32_t entity : entities_) {
|
||||
auto transform = scene_->GetComponent<engine::TransformComponent>(entity);
|
||||
|
||||
if (transform->is_static == false) continue;
|
||||
|
||||
auto renderable = scene_->GetComponent<engine::RenderableComponent>(entity);
|
||||
|
||||
const gfx::Pipeline* pipeline =
|
||||
@ -52,21 +55,20 @@ void MeshRenderSystem::RebuildRenderList() {
|
||||
std::sort(static_render_list_.begin(), static_render_list_.end(),
|
||||
sort_by_pipeline);
|
||||
|
||||
LOG_INFO("\nPRINTING RENDER LIST:\n");
|
||||
|
||||
// DEBUG PRINT
|
||||
#ifndef NDEBUG
|
||||
LOG_TRACE("\nPRINTING RENDER LIST:\n");
|
||||
for (const auto& entry : static_render_list_) {
|
||||
LOG_INFO("pipeline: {}", static_cast<const void*>(entry.pipeline));
|
||||
LOG_INFO("vertex_buffer: {}",
|
||||
static_cast<const void*>(entry.vertex_buffer));
|
||||
LOG_INFO("index_buffer: {}", static_cast<const void*>(entry.index_buffer));
|
||||
LOG_INFO("base_color_texture: {}",
|
||||
static_cast<const void*>(entry.base_colour_texture));
|
||||
LOG_INFO("transform position: {}, {}, {}", entry.model_matrix[3][0],
|
||||
entry.model_matrix[3][1], entry.model_matrix[3][2]);
|
||||
LOG_TRACE("pipeline: {}", static_cast<const void*>(entry.pipeline));
|
||||
LOG_TRACE("vertex_buffer: {}",
|
||||
static_cast<const void*>(entry.vertex_buffer));
|
||||
LOG_TRACE("index_buffer: {}", static_cast<const void*>(entry.index_buffer));
|
||||
LOG_TRACE("base_color_texture: {}",
|
||||
static_cast<const void*>(entry.base_colour_texture));
|
||||
LOG_TRACE("transform position: {}, {}, {}", entry.model_matrix[3][0],
|
||||
entry.model_matrix[3][1], entry.model_matrix[3][2]);
|
||||
}
|
||||
|
||||
LOG_INFO("\nRENDER LIST END\n");
|
||||
LOG_TRACE("\nRENDER LIST END\n");
|
||||
#endif
|
||||
|
||||
list_needs_rebuild_ = false;
|
||||
}
|
||||
|
@ -7,50 +7,47 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
TransformSystem::TransformSystem(Scene* scene)
|
||||
: System(scene, { typeid(TransformComponent).hash_code() })
|
||||
{
|
||||
}
|
||||
TransformSystem::TransformSystem(Scene* scene)
|
||||
: System(scene, {typeid(TransformComponent).hash_code()}) {}
|
||||
|
||||
void TransformSystem::OnUpdate(float ts)
|
||||
{
|
||||
(void)ts;
|
||||
void TransformSystem::OnUpdate(float ts) {
|
||||
(void)ts;
|
||||
|
||||
for (uint32_t entity : entities_) {
|
||||
for (uint32_t entity : entities_) {
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
glm::mat4 transform;
|
||||
|
||||
glm::mat4 transform;
|
||||
|
||||
// rotation
|
||||
transform = glm::mat4_cast(t->rotation);
|
||||
// position
|
||||
reinterpret_cast<glm::vec3&>(transform[3]) = t->position;
|
||||
// scale (effectively applied first)
|
||||
transform = glm::scale(transform, t->scale);
|
||||
|
||||
if (t->parent != 0) {
|
||||
transform = scene_->GetComponent<TransformComponent>(t->parent)->world_matrix * transform;
|
||||
}
|
||||
|
||||
t->world_matrix = transform;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TransformSystem::GetChildEntity(uint32_t parent, const std::string& tag)
|
||||
{
|
||||
for (uint32_t entity : entities_) {
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
if (t->parent == parent) {
|
||||
if (t->tag == tag) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// rotation
|
||||
transform = glm::mat4_cast(t->rotation);
|
||||
// position
|
||||
reinterpret_cast<glm::vec3&>(transform[3]) = t->position;
|
||||
// scale (effectively applied first)
|
||||
transform = glm::scale(transform, t->scale);
|
||||
|
||||
if (t->parent != 0) {
|
||||
auto parent_t = scene_->GetComponent<TransformComponent>(t->parent);
|
||||
transform = parent_t->world_matrix * transform;
|
||||
|
||||
// (debug builds only) ensure static objects have static parents
|
||||
assert(t->is_static == false || parent_t->is_static == true);
|
||||
}
|
||||
|
||||
t->world_matrix = transform;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t TransformSystem::GetChildEntity(uint32_t parent,
|
||||
const std::string& tag) {
|
||||
for (uint32_t entity : entities_) {
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
if (t->parent == parent) {
|
||||
if (t->tag == tag) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
@ -182,7 +182,8 @@ namespace engine::util {
|
||||
absPath /= texPath.C_Str();
|
||||
try {
|
||||
textures[i] = std::make_shared<resources::Texture>(
|
||||
&parent->app()->render_data_, absPath.string(),
|
||||
parent->app()->renderer(),
|
||||
absPath.string(),
|
||||
resources::Texture::Filtering::kTrilinear);
|
||||
} catch (const std::runtime_error&) {
|
||||
textures[i] = parent->app()->GetResource<resources::Texture>("builtin.white");
|
||||
@ -223,7 +224,9 @@ namespace engine::util {
|
||||
indices[(size_t)j * 3 + 1] = m->mFaces[j].mIndices[1];
|
||||
indices[(size_t)j * 3 + 2] = m->mFaces[j].mIndices[2];
|
||||
}
|
||||
meshes.push_back(std::make_shared<resources::Mesh>(parent->app()->gfxdev(), vertices, indices));
|
||||
meshes.push_back(std::make_shared<resources::Mesh>(
|
||||
parent->app()->renderer()->GetDevice(), vertices,
|
||||
indices));
|
||||
}
|
||||
|
||||
uint32_t obj = parent->CreateEntity(scene->GetShortFilename(path.c_str()));
|
||||
|
@ -56,105 +56,118 @@ void PlayGame(GameSettings settings) {
|
||||
app.window()->SetRelativeMouseMode(false);
|
||||
ConfigureInputs(app.input_manager());
|
||||
|
||||
auto my_scene = app.scene_manager()->CreateEmptyScene();
|
||||
|
||||
/* create camera */
|
||||
{
|
||||
my_scene->RegisterComponent<CameraControllerComponent>();
|
||||
my_scene->RegisterSystem<CameraControllerSystem>();
|
||||
auto my_scene = app.scene_manager()->CreateEmptyScene();
|
||||
|
||||
auto camera = my_scene->CreateEntity("camera");
|
||||
my_scene->GetComponent<engine::TransformComponent>(camera)->position = {
|
||||
0.0f, 10.0f, 0.0f};
|
||||
auto camera_collider =
|
||||
my_scene->AddComponent<engine::ColliderComponent>(camera);
|
||||
camera_collider->is_static = false;
|
||||
camera_collider->is_trigger = false;
|
||||
camera_collider->aabb = {{-0.2f, -1.5f, -0.2f},
|
||||
{0.2f, 0.2f, 0.2f}}; // Origin is at eye level
|
||||
my_scene->AddComponent<CameraControllerComponent>(camera);
|
||||
auto render_system = my_scene->GetSystem<engine::MeshRenderSystem>();
|
||||
// render_system->SetCameraEntity(camera);
|
||||
/* create camera */
|
||||
{
|
||||
my_scene->RegisterComponent<CameraControllerComponent>();
|
||||
my_scene->RegisterSystem<CameraControllerSystem>();
|
||||
|
||||
auto camera = my_scene->CreateEntity("camera");
|
||||
my_scene->GetComponent<engine::TransformComponent>(camera)->position = {
|
||||
0.0f, 10.0f, 0.0f};
|
||||
auto camera_collider =
|
||||
my_scene->AddComponent<engine::ColliderComponent>(camera);
|
||||
camera_collider->is_static = false;
|
||||
camera_collider->is_trigger = false;
|
||||
camera_collider->aabb = {{-0.2f, -1.5f, -0.2f},
|
||||
{0.2f, 0.2f, 0.2f}}; // Origin is at eye level
|
||||
my_scene->AddComponent<CameraControllerComponent>(camera);
|
||||
// auto render_system = my_scene->GetSystem<engine::MeshRenderSystem>();
|
||||
// render_system->SetCameraEntity(camera);
|
||||
}
|
||||
|
||||
/* shared resources */
|
||||
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");
|
||||
|
||||
auto skybox_renderable =
|
||||
my_scene->AddComponent<engine::RenderableComponent>(skybox);
|
||||
skybox_renderable->material =
|
||||
std::make_unique<engine::resources::Material>(
|
||||
app.GetResource<engine::resources::Shader>("builtin.skybox"));
|
||||
skybox_renderable->material->texture_ = space_texture;
|
||||
skybox_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||
10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||
|
||||
auto skybox_transform =
|
||||
my_scene->GetComponent<engine::TransformComponent>(skybox);
|
||||
skybox_transform->is_static = true;
|
||||
skybox_transform->position = {-5.0f, -5.0f, -5.0f};
|
||||
}
|
||||
|
||||
/* floor */
|
||||
{
|
||||
uint32_t floor = my_scene->CreateEntity("floor");
|
||||
|
||||
auto floor_transform =
|
||||
my_scene->GetComponent<engine::TransformComponent>(floor);
|
||||
floor_transform->is_static = true;
|
||||
floor_transform->position = glm::vec3{-50.0f, -0.1f, -50.0f};
|
||||
|
||||
auto floor_renderable =
|
||||
my_scene->AddComponent<engine::RenderableComponent>(floor);
|
||||
floor_renderable->material =
|
||||
std::make_shared<engine::resources::Material>(
|
||||
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
||||
floor_renderable->material->texture_ = grass_texture;
|
||||
floor_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||
100.0f, 0.1f, 100.0f, 100.0f);
|
||||
|
||||
auto floor_collider =
|
||||
my_scene->AddComponent<engine::ColliderComponent>(floor);
|
||||
floor_collider->is_static = true;
|
||||
floor_collider->aabb = {{0.0f, 0.0f, 0.0f}, {100.0f, 0.1f, 100.0f}};
|
||||
}
|
||||
|
||||
// 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});
|
||||
//};
|
||||
|
||||
/* some text */
|
||||
{
|
||||
uint32_t textbox =
|
||||
my_scene->CreateEntity("textbox", 0, glm::vec3{0.0f, 0.8f, 0.0f});
|
||||
auto textboxComponent =
|
||||
my_scene->AddComponent<engine::CustomComponent>(textbox);
|
||||
textboxComponent->onInit = [](void) {
|
||||
LOG_INFO("Textbox custom component initialised!");
|
||||
};
|
||||
|
||||
textboxComponent->onUpdate = [](float ts) {
|
||||
static float time_elapsed;
|
||||
time_elapsed += ts;
|
||||
if (time_elapsed >= 1.0f) {
|
||||
time_elapsed = 0.0f;
|
||||
LOG_INFO("COMPONENT UPDATE");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
app.GameLoop();
|
||||
}
|
||||
|
||||
/* shared resources */
|
||||
auto grass_texture = std::make_shared<engine::resources::Texture>(
|
||||
&app.render_data_, app.GetResourcePath("textures/grass.jpg"),
|
||||
engine::resources::Texture::Filtering::kAnisotropic);
|
||||
|
||||
auto space_texture = std::make_shared<engine::resources::Texture>(
|
||||
&app.render_data_, app.GetResourcePath("textures/space2.png"),
|
||||
engine::resources::Texture::Filtering::kAnisotropic);
|
||||
|
||||
/* skybox */
|
||||
{
|
||||
uint32_t skybox = my_scene->CreateEntity("skybox");
|
||||
auto skybox_renderable =
|
||||
my_scene->AddComponent<engine::RenderableComponent>(skybox);
|
||||
skybox_renderable->material = std::make_unique<engine::resources::Material>(
|
||||
app.GetResource<engine::resources::Shader>("builtin.skybox"));
|
||||
skybox_renderable->material->texture_ = space_texture;
|
||||
skybox_renderable->mesh =
|
||||
GenCuboidMesh(app.gfxdev(), 10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||
my_scene->GetComponent<engine::TransformComponent>(skybox)->position = {
|
||||
-5.0f, -5.0f, -5.0f};
|
||||
}
|
||||
|
||||
/* floor */
|
||||
{
|
||||
uint32_t floor = my_scene->CreateEntity("floor");
|
||||
my_scene->GetComponent<engine::TransformComponent>(floor)->position =
|
||||
glm::vec3{-50.0f, -0.1f, -50.0f};
|
||||
auto floor_renderable =
|
||||
my_scene->AddComponent<engine::RenderableComponent>(floor);
|
||||
floor_renderable->material = std::make_shared<engine::resources::Material>(
|
||||
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
||||
floor_renderable->material->texture_ = grass_texture;
|
||||
floor_renderable->mesh =
|
||||
GenCuboidMesh(app.gfxdev(), 100.0f, 0.1f, 100.0f, 100.0f);
|
||||
auto floor_collider =
|
||||
my_scene->AddComponent<engine::ColliderComponent>(floor);
|
||||
floor_collider->is_static = true;
|
||||
floor_collider->aabb = {{0.0f, 0.0f, 0.0f}, {100.0f, 0.1f, 100.0f}};
|
||||
}
|
||||
|
||||
// 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});
|
||||
};
|
||||
|
||||
/* some text */
|
||||
{
|
||||
uint32_t textbox =
|
||||
my_scene->CreateEntity("textbox", 0, glm::vec3{0.0f, 0.8f, 0.0f});
|
||||
auto textboxComponent =
|
||||
my_scene->AddComponent<engine::CustomComponent>(textbox);
|
||||
textboxComponent->onInit = [](void) {
|
||||
LOG_INFO("Textbox custom component initialised!");
|
||||
};
|
||||
|
||||
textboxComponent->onUpdate = [](float ts) {
|
||||
static float time_elapsed;
|
||||
time_elapsed += ts;
|
||||
if (time_elapsed >= 1.0f) {
|
||||
time_elapsed = 0.0f;
|
||||
LOG_INFO("COMPONENT UPDATE");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
app.GameLoop();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user