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} PRIVATE DEFINITIONS "ENGINE_EXPORTS")
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PUBLIC DEFINITIONS "VMA_DEBUG_LOG=printf")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "NOMINMAX") # stop windows.h conflicting with 'std::max'
|
target_compile_definitions(${PROJECT_NAME} PRIVATE DEFINITIONS "NOMINMAX") # stop windows.h conflicting with 'std::max'
|
||||||
endif()
|
endif()
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
|
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
#include "gfx_device.h"
|
#include "renderer.h"
|
||||||
#include "input_manager.h"
|
#include "input_manager.h"
|
||||||
#include "resource_manager.h"
|
#include "resource_manager.h"
|
||||||
#include "scene_manager.h"
|
#include "scene_manager.h"
|
||||||
@ -19,31 +19,6 @@
|
|||||||
|
|
||||||
namespace engine {
|
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 {
|
class Application {
|
||||||
public:
|
public:
|
||||||
Application(const char* app_name, const char* app_version,
|
Application(const char* app_name, const char* app_version,
|
||||||
@ -82,20 +57,19 @@ class Application {
|
|||||||
|
|
||||||
/* getters */
|
/* getters */
|
||||||
Window* window() { return window_.get(); }
|
Window* window() { return window_.get(); }
|
||||||
GFXDevice* gfxdev() { return render_data_.gfxdev.get(); }
|
|
||||||
InputManager* input_manager() { return input_manager_.get(); }
|
InputManager* input_manager() { return input_manager_.get(); }
|
||||||
SceneManager* scene_manager() { return scene_manager_.get(); }
|
SceneManager* scene_manager() { return scene_manager_.get(); }
|
||||||
|
Renderer* renderer() { return renderer_.get(); }
|
||||||
|
|
||||||
std::string GetResourcePath(const std::string relative_path) {
|
std::string GetResourcePath(const std::string relative_path) {
|
||||||
return (resources_path_ / relative_path).string();
|
return (resources_path_ / relative_path).string();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderData render_data_{};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Window> window_;
|
std::unique_ptr<Window> window_;
|
||||||
std::unique_ptr<InputManager> input_manager_;
|
std::unique_ptr<InputManager> input_manager_;
|
||||||
std::unique_ptr<SceneManager> scene_manager_;
|
std::unique_ptr<SceneManager> scene_manager_;
|
||||||
|
std::unique_ptr<Renderer> renderer_;
|
||||||
std::unordered_map<size_t, std::unique_ptr<IResourceManager>>
|
std::unordered_map<size_t, std::unique_ptr<IResourceManager>>
|
||||||
resource_managers_{};
|
resource_managers_{};
|
||||||
std::filesystem::path resources_path_;
|
std::filesystem::path resources_path_;
|
||||||
|
@ -1,8 +1,78 @@
|
|||||||
#ifndef ENGINE_INCLUDE_RENDERER_H_
|
#ifndef ENGINE_INCLUDE_RENDERER_H_
|
||||||
#define ENGINE_INCLUDE_RENDERER_H_
|
#define ENGINE_INCLUDE_RENDERER_H_
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
|
||||||
|
#include "gfx_device.h"
|
||||||
|
|
||||||
namespace engine {
|
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
|
} // namespace engine
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -28,7 +28,7 @@ class Shader {
|
|||||||
|
|
||||||
static constexpr int kHighestRenderOrder = 1;
|
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);
|
const ShaderSettings& settings);
|
||||||
~Shader();
|
~Shader();
|
||||||
Shader(const Shader&) = delete;
|
Shader(const Shader&) = delete;
|
||||||
|
@ -18,9 +18,9 @@ class Texture {
|
|||||||
kAnisotropic,
|
kAnisotropic,
|
||||||
};
|
};
|
||||||
|
|
||||||
Texture(RenderData* render_data, const std::string& path,
|
Texture(Renderer* renderer, const std::string& path,
|
||||||
Filtering filtering);
|
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);
|
Filtering filtering);
|
||||||
|
|
||||||
~Texture();
|
~Texture();
|
||||||
|
@ -16,7 +16,6 @@ struct MeshRenderListEntry {
|
|||||||
const gfx::DescriptorSet* base_colour_texture;
|
const gfx::DescriptorSet* base_colour_texture;
|
||||||
glm::mat4 model_matrix;
|
glm::mat4 model_matrix;
|
||||||
uint32_t index_count;
|
uint32_t index_count;
|
||||||
// 100 bytes
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MeshRenderSystem : public System {
|
class MeshRenderSystem : public System {
|
||||||
|
@ -76,57 +76,9 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
RegisterResourceManager<resources::Material>();
|
RegisterResourceManager<resources::Material>();
|
||||||
RegisterResourceManager<resources::Mesh>();
|
RegisterResourceManager<resources::Mesh>();
|
||||||
|
|
||||||
// initialise the render data
|
renderer_ = std::make_unique<Renderer>(
|
||||||
render_data_.gfxdev = std::make_unique<GFXDevice>(
|
|
||||||
appName, appVersion, window_->GetHandle(), graphicsSettings);
|
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 */
|
/* default fonts */
|
||||||
{
|
{
|
||||||
auto monoFont = std::make_unique<resources::Font>(
|
auto monoFont = std::make_unique<resources::Font>(
|
||||||
@ -147,7 +99,7 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
shaderSettings.write_z = true;
|
shaderSettings.write_z = true;
|
||||||
shaderSettings.render_order = 0;
|
shaderSettings.render_order = 0;
|
||||||
auto texturedShader = std::make_unique<resources::Shader>(
|
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(),
|
GetResourcePath("engine/shaders/standard.frag").c_str(),
|
||||||
shaderSettings);
|
shaderSettings);
|
||||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
@ -164,7 +116,7 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
shaderSettings.write_z = true;
|
shaderSettings.write_z = true;
|
||||||
shaderSettings.render_order = 0;
|
shaderSettings.render_order = 0;
|
||||||
auto skyboxShader = std::make_unique<resources::Shader>(
|
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);
|
GetResourcePath("engine/shaders/skybox.frag").c_str(), shaderSettings);
|
||||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
"builtin.skybox", std::move(skyboxShader));
|
"builtin.skybox", std::move(skyboxShader));
|
||||||
@ -180,7 +132,7 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
shaderSettings.write_z = false;
|
shaderSettings.write_z = false;
|
||||||
shaderSettings.render_order = 1;
|
shaderSettings.render_order = 1;
|
||||||
auto quadShader = std::make_unique<resources::Shader>(
|
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);
|
GetResourcePath("engine/shaders/quad.frag").c_str(), shaderSettings);
|
||||||
GetResourceManager<resources::Shader>()->AddPersistent(
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
"builtin.quad", std::move(quadShader));
|
"builtin.quad", std::move(quadShader));
|
||||||
@ -189,25 +141,14 @@ Application::Application(const char* appName, const char* appVersion,
|
|||||||
/* default textures */
|
/* default textures */
|
||||||
{
|
{
|
||||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||||
&render_data_, GetResourcePath("engine/textures/white.png"),
|
renderer(), GetResourcePath("engine/textures/white.png"),
|
||||||
resources::Texture::Filtering::kOff);
|
resources::Texture::Filtering::kOff);
|
||||||
GetResourceManager<resources::Texture>()->AddPersistent(
|
GetResourceManager<resources::Texture>()->AddPersistent(
|
||||||
"builtin.white", std::move(whiteTexture));
|
"builtin.white", std::move(whiteTexture));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::GameLoop() {
|
void Application::GameLoop() {
|
||||||
LOG_TRACE("Begin game loop...");
|
LOG_TRACE("Begin game loop...");
|
||||||
@ -229,13 +170,12 @@ void Application::GameLoop() {
|
|||||||
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());
|
||||||
gfxdev()->LogPerformanceInfo();
|
renderer()->GetDevice()->LogPerformanceInfo();
|
||||||
window_->ResetAvgFPS();
|
window_->ResetAvgFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* render */
|
/* render */
|
||||||
|
|
||||||
|
|
||||||
/* poll events */
|
/* poll events */
|
||||||
window_->GetInputAndEvents();
|
window_->GetInputAndEvents();
|
||||||
|
|
||||||
@ -247,7 +187,7 @@ void Application::GameLoop() {
|
|||||||
endFrame = beginFrame + FRAMETIME_LIMIT;
|
endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxdev()->WaitIdle();
|
renderer()->GetDevice()->WaitIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -2,4 +2,64 @@
|
|||||||
|
|
||||||
namespace engine {
|
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
|
} // namespace engine
|
@ -8,10 +8,11 @@
|
|||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
Shader::Shader(RenderData* renderData, const char* vertPath,
|
Shader::Shader(Renderer* renderer, const char* vertPath, const char* fragPath,
|
||||||
const char* fragPath, const ShaderSettings& settings)
|
const ShaderSettings& settings)
|
||||||
: gfx_(renderData->gfxdev.get()), render_order_(settings.render_order) {
|
: gfx_(renderer->GetDevice()), render_order_(settings.render_order) {
|
||||||
assert(settings.render_order <= kHighestRenderOrder && settings.render_order >= 0);
|
assert(settings.render_order <= kHighestRenderOrder &&
|
||||||
|
settings.render_order >= 0);
|
||||||
uint32_t index = 0;
|
uint32_t index = 0;
|
||||||
uint32_t stride = 0;
|
uint32_t stride = 0;
|
||||||
gfx::VertexFormat vertFormat{};
|
gfx::VertexFormat vertFormat{};
|
||||||
@ -49,9 +50,9 @@ Shader::Shader(RenderData* renderData, const char* vertPath,
|
|||||||
info.alpha_blending = settings.alpha_blending;
|
info.alpha_blending = settings.alpha_blending;
|
||||||
info.backface_culling = settings.cull_backface;
|
info.backface_culling = settings.cull_backface;
|
||||||
info.write_z = settings.write_z;
|
info.write_z = settings.write_z;
|
||||||
info.descriptor_set_layouts.push_back(renderData->global_set_layout);
|
info.descriptor_set_layouts.push_back(renderer->GetGlobalSetLayout());
|
||||||
info.descriptor_set_layouts.push_back(renderData->frame_set_layout);
|
info.descriptor_set_layouts.push_back(renderer->GetFrameSetLayout());
|
||||||
info.descriptor_set_layouts.push_back(renderData->material_set_layout);
|
info.descriptor_set_layouts.push_back(renderer->GetMaterialSetLayout());
|
||||||
|
|
||||||
pipeline_ = gfx_->CreatePipeline(info);
|
pipeline_ = gfx_->CreatePipeline(info);
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
namespace engine::resources {
|
namespace engine::resources {
|
||||||
|
|
||||||
Texture::Texture(RenderData* renderData, const std::string& path,
|
Texture::Texture(Renderer* renderer, const std::string& path,
|
||||||
Filtering filtering)
|
Filtering filtering)
|
||||||
: gfx_(renderData->gfxdev.get()) {
|
: gfx_(renderer->GetDevice()) {
|
||||||
int width, height;
|
int width, height;
|
||||||
std::unique_ptr<std::vector<uint8_t>> texbuf =
|
std::unique_ptr<std::vector<uint8_t>> texbuf =
|
||||||
util::ReadImageFile(path, &width, &height);
|
util::ReadImageFile(path, &width, &height);
|
||||||
@ -41,23 +41,23 @@ Texture::Texture(RenderData* renderData, const std::string& path,
|
|||||||
samplerInfo.anisotropic_filtering = true;
|
samplerInfo.anisotropic_filtering = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderData->samplers.contains(samplerInfo) == false) {
|
if (renderer->samplers.contains(samplerInfo) == false) {
|
||||||
renderData->samplers.insert(
|
renderer->samplers.insert(
|
||||||
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
image_ = gfx_->CreateImage(width, height, texbuf->data());
|
image_ = gfx_->CreateImage(width, height, texbuf->data());
|
||||||
descriptor_set_ =
|
descriptor_set_ =
|
||||||
gfx_->AllocateDescriptorSet(renderData->material_set_layout);
|
gfx_->AllocateDescriptorSet(renderer->GetMaterialSetLayout());
|
||||||
gfx_->UpdateDescriptorCombinedImageSampler(
|
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);
|
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)
|
int height, Filtering filtering)
|
||||||
: gfx_(render_data->gfxdev.get()) {
|
: gfx_(renderer->GetDevice()) {
|
||||||
gfx::SamplerInfo samplerInfo{};
|
gfx::SamplerInfo samplerInfo{};
|
||||||
|
|
||||||
samplerInfo.magnify = gfx::Filter::kLinear;
|
samplerInfo.magnify = gfx::Filter::kLinear;
|
||||||
@ -84,16 +84,16 @@ Texture::Texture(RenderData* render_data, const uint8_t* bitmap, int width,
|
|||||||
samplerInfo.anisotropic_filtering = true;
|
samplerInfo.anisotropic_filtering = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (render_data->samplers.contains(samplerInfo) == false) {
|
if (renderer->samplers.contains(samplerInfo) == false) {
|
||||||
render_data->samplers.insert(
|
renderer->samplers.insert(
|
||||||
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
std::make_pair(samplerInfo, gfx_->CreateSampler(samplerInfo)));
|
||||||
}
|
}
|
||||||
|
|
||||||
image_ = gfx_->CreateImage(width, height, bitmap);
|
image_ = gfx_->CreateImage(width, height, bitmap);
|
||||||
descriptor_set_ =
|
descriptor_set_ =
|
||||||
gfx_->AllocateDescriptorSet(render_data->material_set_layout);
|
gfx_->AllocateDescriptorSet(renderer->GetMaterialSetLayout());
|
||||||
gfx_->UpdateDescriptorCombinedImageSampler(
|
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);
|
LOG_INFO("Loaded texture: BITMAP, width: {} height: {}", width, height);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,9 @@ void MeshRenderSystem::RebuildRenderList() {
|
|||||||
|
|
||||||
for (uint32_t entity : entities_) {
|
for (uint32_t entity : entities_) {
|
||||||
auto transform = scene_->GetComponent<engine::TransformComponent>(entity);
|
auto transform = scene_->GetComponent<engine::TransformComponent>(entity);
|
||||||
|
|
||||||
|
if (transform->is_static == false) continue;
|
||||||
|
|
||||||
auto renderable = scene_->GetComponent<engine::RenderableComponent>(entity);
|
auto renderable = scene_->GetComponent<engine::RenderableComponent>(entity);
|
||||||
|
|
||||||
const gfx::Pipeline* pipeline =
|
const gfx::Pipeline* pipeline =
|
||||||
@ -52,21 +55,20 @@ void MeshRenderSystem::RebuildRenderList() {
|
|||||||
std::sort(static_render_list_.begin(), static_render_list_.end(),
|
std::sort(static_render_list_.begin(), static_render_list_.end(),
|
||||||
sort_by_pipeline);
|
sort_by_pipeline);
|
||||||
|
|
||||||
LOG_INFO("\nPRINTING RENDER LIST:\n");
|
#ifndef NDEBUG
|
||||||
|
LOG_TRACE("\nPRINTING RENDER LIST:\n");
|
||||||
// DEBUG PRINT
|
|
||||||
for (const auto& entry : static_render_list_) {
|
for (const auto& entry : static_render_list_) {
|
||||||
LOG_INFO("pipeline: {}", static_cast<const void*>(entry.pipeline));
|
LOG_TRACE("pipeline: {}", static_cast<const void*>(entry.pipeline));
|
||||||
LOG_INFO("vertex_buffer: {}",
|
LOG_TRACE("vertex_buffer: {}",
|
||||||
static_cast<const void*>(entry.vertex_buffer));
|
static_cast<const void*>(entry.vertex_buffer));
|
||||||
LOG_INFO("index_buffer: {}", static_cast<const void*>(entry.index_buffer));
|
LOG_TRACE("index_buffer: {}", static_cast<const void*>(entry.index_buffer));
|
||||||
LOG_INFO("base_color_texture: {}",
|
LOG_TRACE("base_color_texture: {}",
|
||||||
static_cast<const void*>(entry.base_colour_texture));
|
static_cast<const void*>(entry.base_colour_texture));
|
||||||
LOG_INFO("transform position: {}, {}, {}", entry.model_matrix[3][0],
|
LOG_TRACE("transform position: {}, {}, {}", entry.model_matrix[3][0],
|
||||||
entry.model_matrix[3][1], entry.model_matrix[3][2]);
|
entry.model_matrix[3][1], entry.model_matrix[3][2]);
|
||||||
}
|
}
|
||||||
|
LOG_TRACE("\nRENDER LIST END\n");
|
||||||
LOG_INFO("\nRENDER LIST END\n");
|
#endif
|
||||||
|
|
||||||
list_needs_rebuild_ = false;
|
list_needs_rebuild_ = false;
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,13 @@
|
|||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
TransformSystem::TransformSystem(Scene* scene)
|
TransformSystem::TransformSystem(Scene* scene)
|
||||||
: System(scene, { typeid(TransformComponent).hash_code() })
|
: System(scene, {typeid(TransformComponent).hash_code()}) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransformSystem::OnUpdate(float ts)
|
void TransformSystem::OnUpdate(float ts) {
|
||||||
{
|
|
||||||
(void)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;
|
||||||
@ -30,15 +26,19 @@ namespace engine {
|
|||||||
transform = glm::scale(transform, t->scale);
|
transform = glm::scale(transform, t->scale);
|
||||||
|
|
||||||
if (t->parent != 0) {
|
if (t->parent != 0) {
|
||||||
transform = scene_->GetComponent<TransformComponent>(t->parent)->world_matrix * transform;
|
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;
|
t->world_matrix = transform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t TransformSystem::GetChildEntity(uint32_t parent, const std::string& tag)
|
uint32_t TransformSystem::GetChildEntity(uint32_t parent,
|
||||||
{
|
const std::string& tag) {
|
||||||
for (uint32_t entity : entities_) {
|
for (uint32_t entity : entities_) {
|
||||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||||
if (t->parent == parent) {
|
if (t->parent == parent) {
|
||||||
@ -48,9 +48,6 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace engine
|
||||||
|
@ -182,7 +182,8 @@ namespace engine::util {
|
|||||||
absPath /= texPath.C_Str();
|
absPath /= texPath.C_Str();
|
||||||
try {
|
try {
|
||||||
textures[i] = std::make_shared<resources::Texture>(
|
textures[i] = std::make_shared<resources::Texture>(
|
||||||
&parent->app()->render_data_, absPath.string(),
|
parent->app()->renderer(),
|
||||||
|
absPath.string(),
|
||||||
resources::Texture::Filtering::kTrilinear);
|
resources::Texture::Filtering::kTrilinear);
|
||||||
} catch (const std::runtime_error&) {
|
} catch (const std::runtime_error&) {
|
||||||
textures[i] = parent->app()->GetResource<resources::Texture>("builtin.white");
|
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 + 1] = m->mFaces[j].mIndices[1];
|
||||||
indices[(size_t)j * 3 + 2] = m->mFaces[j].mIndices[2];
|
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()));
|
uint32_t obj = parent->CreateEntity(scene->GetShortFilename(path.c_str()));
|
||||||
|
@ -56,6 +56,7 @@ void PlayGame(GameSettings settings) {
|
|||||||
app.window()->SetRelativeMouseMode(false);
|
app.window()->SetRelativeMouseMode(false);
|
||||||
ConfigureInputs(app.input_manager());
|
ConfigureInputs(app.input_manager());
|
||||||
|
|
||||||
|
{
|
||||||
auto my_scene = app.scene_manager()->CreateEmptyScene();
|
auto my_scene = app.scene_manager()->CreateEmptyScene();
|
||||||
|
|
||||||
/* create camera */
|
/* create camera */
|
||||||
@ -73,45 +74,56 @@ void PlayGame(GameSettings settings) {
|
|||||||
camera_collider->aabb = {{-0.2f, -1.5f, -0.2f},
|
camera_collider->aabb = {{-0.2f, -1.5f, -0.2f},
|
||||||
{0.2f, 0.2f, 0.2f}}; // Origin is at eye level
|
{0.2f, 0.2f, 0.2f}}; // Origin is at eye level
|
||||||
my_scene->AddComponent<CameraControllerComponent>(camera);
|
my_scene->AddComponent<CameraControllerComponent>(camera);
|
||||||
auto render_system = my_scene->GetSystem<engine::MeshRenderSystem>();
|
// auto render_system = my_scene->GetSystem<engine::MeshRenderSystem>();
|
||||||
// render_system->SetCameraEntity(camera);
|
// render_system->SetCameraEntity(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* shared resources */
|
/* shared resources */
|
||||||
auto grass_texture = std::make_shared<engine::resources::Texture>(
|
auto grass_texture = std::make_shared<engine::resources::Texture>(
|
||||||
&app.render_data_, 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.render_data_, 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");
|
||||||
|
|
||||||
auto skybox_renderable =
|
auto skybox_renderable =
|
||||||
my_scene->AddComponent<engine::RenderableComponent>(skybox);
|
my_scene->AddComponent<engine::RenderableComponent>(skybox);
|
||||||
skybox_renderable->material = std::make_unique<engine::resources::Material>(
|
skybox_renderable->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_ = space_texture;
|
skybox_renderable->material->texture_ = space_texture;
|
||||||
skybox_renderable->mesh =
|
skybox_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||||
GenCuboidMesh(app.gfxdev(), 10.0f, 10.0f, 10.0f, 1.0f, true);
|
10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||||
my_scene->GetComponent<engine::TransformComponent>(skybox)->position = {
|
|
||||||
-5.0f, -5.0f, -5.0f};
|
auto skybox_transform =
|
||||||
|
my_scene->GetComponent<engine::TransformComponent>(skybox);
|
||||||
|
skybox_transform->is_static = true;
|
||||||
|
skybox_transform->position = {-5.0f, -5.0f, -5.0f};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* floor */
|
/* floor */
|
||||||
{
|
{
|
||||||
uint32_t floor = my_scene->CreateEntity("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_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 =
|
auto floor_renderable =
|
||||||
my_scene->AddComponent<engine::RenderableComponent>(floor);
|
my_scene->AddComponent<engine::RenderableComponent>(floor);
|
||||||
floor_renderable->material = std::make_shared<engine::resources::Material>(
|
floor_renderable->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_ = grass_texture;
|
floor_renderable->material->texture_ = grass_texture;
|
||||||
floor_renderable->mesh =
|
floor_renderable->mesh = GenCuboidMesh(app.renderer()->GetDevice(),
|
||||||
GenCuboidMesh(app.gfxdev(), 100.0f, 0.1f, 100.0f, 100.0f);
|
100.0f, 0.1f, 100.0f, 100.0f);
|
||||||
|
|
||||||
auto floor_collider =
|
auto floor_collider =
|
||||||
my_scene->AddComponent<engine::ColliderComponent>(floor);
|
my_scene->AddComponent<engine::ColliderComponent>(floor);
|
||||||
floor_collider->is_static = true;
|
floor_collider->is_static = true;
|
||||||
@ -121,20 +133,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"));
|
||||||
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 */
|
||||||
{
|
{
|
||||||
@ -157,4 +169,5 @@ void PlayGame(GameSettings settings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.GameLoop();
|
app.GameLoop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user