mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Begin full text rendering support
This commit is contained in:
parent
f9099e9ddf
commit
5ddcb90ad2
@ -26,9 +26,7 @@ set(SRC_FILES
|
|||||||
"src/scene_manager.cpp"
|
"src/scene_manager.cpp"
|
||||||
"src/systems/collisions.cpp"
|
"src/systems/collisions.cpp"
|
||||||
"src/systems/render.cpp"
|
"src/systems/render.cpp"
|
||||||
"src/systems/render2d.cpp"
|
|
||||||
"src/systems/transform.cpp"
|
"src/systems/transform.cpp"
|
||||||
"src/systems/ui.cpp"
|
|
||||||
"src/util/files.cpp"
|
"src/util/files.cpp"
|
||||||
"src/util/model_loader.cpp"
|
"src/util/model_loader.cpp"
|
||||||
"src/vulkan/device.cpp"
|
"src/vulkan/device.cpp"
|
||||||
@ -45,10 +43,8 @@ set(SRC_FILES
|
|||||||
set(INCLUDE_FILES
|
set(INCLUDE_FILES
|
||||||
"include/application.h"
|
"include/application.h"
|
||||||
"include/components/collider.h"
|
"include/components/collider.h"
|
||||||
"include/components/renderable_text.h"
|
|
||||||
"include/components/renderable.h"
|
"include/components/renderable.h"
|
||||||
"include/components/transform.h"
|
"include/components/transform.h"
|
||||||
"include/components/ui_element.h"
|
|
||||||
"include/ecs_system.h"
|
"include/ecs_system.h"
|
||||||
"include/engine_api.h"
|
"include/engine_api.h"
|
||||||
"include/event_system.h"
|
"include/event_system.h"
|
||||||
@ -69,9 +65,7 @@ set(INCLUDE_FILES
|
|||||||
"include/scene_manager.h"
|
"include/scene_manager.h"
|
||||||
"include/systems/collisions.h"
|
"include/systems/collisions.h"
|
||||||
"include/systems/render.h"
|
"include/systems/render.h"
|
||||||
"include/systems/render2d.h"
|
|
||||||
"include/systems/transform.h"
|
"include/systems/transform.h"
|
||||||
"include/systems/ui.h"
|
|
||||||
"include/util.h"
|
"include/util.h"
|
||||||
"include/util/files.h"
|
"include/util/files.h"
|
||||||
"include/util/model_loader.h"
|
"include/util/model_loader.h"
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef ENGINE_INCLUDE_COMPONENTS_RENDERABLE_TEXT_H_
|
|
||||||
#define ENGINE_INCLUDE_COMPONENTS_RENDERABLE_TEXT_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "resources/texture.h"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
struct RenderableTextComponent {
|
|
||||||
void SetText(const std::string& text) {
|
|
||||||
text_ = text;
|
|
||||||
invalidated_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string text_{"hello world"};
|
|
||||||
bool invalidated_ =
|
|
||||||
true; // text has been changed, texture must be regenerated
|
|
||||||
std::unique_ptr<resources::Texture> texture_{};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace engine
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||||||
#ifndef ENGINE_INCLUDE_COMPONENTS_UI_ELEMENT_H_
|
|
||||||
#define ENGINE_INCLUDE_COMPONENTS_UI_ELEMENT_H_
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
struct UIElementComponent {
|
|
||||||
int n;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace engine
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef ENGINE_INCLUDE_SYSTEMS_RENDER2D_H_
|
|
||||||
#define ENGINE_INCLUDE_SYSTEMS_RENDER2D_H_
|
|
||||||
|
|
||||||
#include "ecs_system.h"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
class Render2DSystem : public System {
|
|
||||||
public:
|
|
||||||
Render2DSystem(Scene* scene);
|
|
||||||
~Render2DSystem();
|
|
||||||
|
|
||||||
void OnUpdate(float ts) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace engine
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,19 +0,0 @@
|
|||||||
#ifndef ENGINE_INCLUDE_SYSTEMS_UI_H_
|
|
||||||
#define ENGINE_INCLUDE_SYSTEMS_UI_H_
|
|
||||||
|
|
||||||
#include "ecs_system.h"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
class UISystem : public System {
|
|
||||||
public:
|
|
||||||
UISystem(Scene* scene);
|
|
||||||
|
|
||||||
void OnUpdate(float ts) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace engine
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||||||
#version 450
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 fragUV;
|
|
||||||
|
|
||||||
layout(location = 0) out vec4 outColor;
|
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform sampler2D texSampler;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
outColor = texture(texSampler, fragUV);
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
|||||||
#version 450
|
|
||||||
|
|
||||||
layout( push_constant ) uniform Constants {
|
|
||||||
mat4 model;
|
|
||||||
vec2 atlas_top_left;
|
|
||||||
vec2 atlas_bottom_right;
|
|
||||||
vec2 offset;
|
|
||||||
vec2 size;
|
|
||||||
} constants;
|
|
||||||
|
|
||||||
layout(location = 0) in vec3 inPosition;
|
|
||||||
layout(location = 1) in vec3 inNorm;
|
|
||||||
layout(location = 2) in vec2 inUV;
|
|
||||||
|
|
||||||
layout(location = 0) out vec2 fragUV;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 position = inPosition.xy * constants.size + constants.offset;
|
|
||||||
position *= 0.001;
|
|
||||||
gl_Position = constants.model * vec4(position, 0.0, 1.0);
|
|
||||||
fragUV = constants.atlas_top_left + (inUV * (constants.atlas_bottom_right - constants.atlas_top_left));
|
|
||||||
}
|
|
13
res/engine/shaders/quad.frag
Normal file
13
res/engine/shaders/quad.frag
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform sampler2D materialSetSampler;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 fragUV;
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
outColor = texture(materialSetSampler, fragUV);
|
||||||
|
}
|
||||||
|
|
42
res/engine/shaders/quad.vert
Normal file
42
res/engine/shaders/quad.vert
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 inPosition;
|
||||||
|
layout(location = 1) in vec3 inNorm;
|
||||||
|
layout(location = 2) in vec2 inUV;
|
||||||
|
|
||||||
|
layout(location = 0) out vec2 fragUV;
|
||||||
|
|
||||||
|
vec2 positions[6] = vec2[](
|
||||||
|
vec2( 1.0, 1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, 1.0),
|
||||||
|
vec2(-1.0, -1.0),
|
||||||
|
vec2( 1.0, -1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
vec2 uvs[6] = vec2[](
|
||||||
|
vec2(1.0, 0.0),
|
||||||
|
vec2(0.0, 0.0),
|
||||||
|
vec2(0.0, 1.0),
|
||||||
|
vec2(1.0, 0.0),
|
||||||
|
vec2(0.0, 1.0),
|
||||||
|
vec2(1.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = constants.model * vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||||
|
fragUV = uvs[gl_VertexIndex];
|
||||||
|
}
|
@ -29,193 +29,212 @@
|
|||||||
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
|
|
||||||
static std::filesystem::path getResourcesPath()
|
static std::filesystem::path getResourcesPath() {
|
||||||
{
|
std::filesystem::path resourcesPath{};
|
||||||
std::filesystem::path resourcesPath{};
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
CHAR exeDirBuf[MAX_PATH + 1];
|
CHAR exeDirBuf[MAX_PATH + 1];
|
||||||
GetModuleFileNameA(NULL, exeDirBuf, WIN_MAX_PATH + 1);
|
GetModuleFileNameA(NULL, exeDirBuf, WIN_MAX_PATH + 1);
|
||||||
std::filesystem::path cwd = std::filesystem::path(exeDirBuf).parent_path();
|
std::filesystem::path cwd = std::filesystem::path(exeDirBuf).parent_path();
|
||||||
(void)_chdir((const char*)std::filesystem::absolute(cwd).c_str());
|
(void)_chdir((const char*)std::filesystem::absolute(cwd).c_str());
|
||||||
#else
|
#else
|
||||||
std::filesystem::path cwd = std::filesystem::current_path();
|
std::filesystem::path cwd = std::filesystem::current_path();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (std::filesystem::is_directory(cwd / "res")) {
|
if (std::filesystem::is_directory(cwd / "res")) {
|
||||||
resourcesPath = cwd / "res";
|
resourcesPath = cwd / "res";
|
||||||
}
|
} else {
|
||||||
else {
|
resourcesPath = cwd.parent_path() / "share" / "sdltest";
|
||||||
resourcesPath = cwd.parent_path() / "share" / "sdltest";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (std::filesystem::is_directory(resourcesPath) == false) {
|
if (std::filesystem::is_directory(resourcesPath) == false) {
|
||||||
resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest";
|
resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::filesystem::is_directory(resourcesPath) == false) {
|
if (std::filesystem::is_directory(resourcesPath) == false) {
|
||||||
throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string());
|
throw std::runtime_error("Unable to determine resources location. CWD: " +
|
||||||
}
|
cwd.string());
|
||||||
|
}
|
||||||
return resourcesPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
Application::Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings)
|
|
||||||
{
|
|
||||||
window_ = std::make_unique<Window>(appName, true, false);
|
|
||||||
input_manager_ = std::make_unique<InputManager>(window_.get());
|
|
||||||
scene_manager_ = std::make_unique<SceneManager>(this);
|
|
||||||
|
|
||||||
// get base path for resources
|
|
||||||
resources_path_ = getResourcesPath();
|
|
||||||
|
|
||||||
// register resource managers
|
|
||||||
RegisterResourceManager<resources::Font>();
|
|
||||||
RegisterResourceManager<resources::Texture>();
|
|
||||||
RegisterResourceManager<resources::Shader>();
|
|
||||||
RegisterResourceManager<resources::Material>();
|
|
||||||
RegisterResourceManager<resources::Mesh>();
|
|
||||||
|
|
||||||
// initialise the render data
|
|
||||||
render_data_.gfxdev = std::make_unique<GFXDevice>(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 resources
|
|
||||||
{
|
|
||||||
auto monoFont = std::make_unique<resources::Font>(
|
|
||||||
GetResourcePath("engine/fonts/mono.ttf")
|
|
||||||
);
|
|
||||||
GetResourceManager<resources::Font>()->AddPersistent("builtin.mono", std::move(monoFont));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
resources::Shader::VertexParams vertParams{};
|
|
||||||
vertParams.has_normal = true;
|
|
||||||
vertParams.has_uv0 = true;
|
|
||||||
auto texturedShader = std::make_unique<resources::Shader>(
|
|
||||||
&render_data_,
|
|
||||||
GetResourcePath("engine/shaders/standard.vert").c_str(),
|
|
||||||
GetResourcePath("engine/shaders/standard.frag").c_str(),
|
|
||||||
vertParams,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
GetResourceManager<resources::Shader>()->AddPersistent("builtin.standard", std::move(texturedShader));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
resources::Shader::VertexParams vertParams{};
|
|
||||||
vertParams.has_normal = true;
|
|
||||||
vertParams.has_uv0 = true;
|
|
||||||
auto skyboxShader = std::make_unique<resources::Shader>(
|
|
||||||
&render_data_,
|
|
||||||
GetResourcePath("engine/shaders/skybox.vert").c_str(),
|
|
||||||
GetResourcePath("engine/shaders/skybox.frag").c_str(),
|
|
||||||
vertParams,
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
GetResourceManager<resources::Shader>()->AddPersistent("builtin.skybox", std::move(skyboxShader));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
|
||||||
&render_data_,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::GameLoop()
|
|
||||||
{
|
|
||||||
LOG_TRACE("Begin game loop...");
|
|
||||||
|
|
||||||
constexpr int FPS_LIMIT = 240;
|
|
||||||
constexpr auto FRAMETIME_LIMIT = std::chrono::nanoseconds(1000000000 / FPS_LIMIT);
|
|
||||||
auto beginFrame = std::chrono::steady_clock::now();
|
|
||||||
auto endFrame = beginFrame + FRAMETIME_LIMIT;
|
|
||||||
|
|
||||||
auto lastTick = window_->GetNanos();
|
|
||||||
|
|
||||||
// single-threaded game loop
|
|
||||||
while (window_->IsRunning()) {
|
|
||||||
|
|
||||||
/* logic */
|
|
||||||
scene_manager_->UpdateActiveScene(window_->dt());
|
|
||||||
|
|
||||||
if(window_->GetKeyPress(inputs::Key::K_F)) [[unlikely]] {
|
|
||||||
window_->InfoBox("fps", std::to_string(window_->GetFPS()) + " fps " + std::to_string(window_->dt() * 1000.0f) + " ms");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t now = window_->GetNanos();
|
|
||||||
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
|
||||||
lastTick = now;
|
|
||||||
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
|
||||||
gfxdev()->LogPerformanceInfo();
|
|
||||||
window_->ResetAvgFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* poll events */
|
|
||||||
window_->GetInputAndEvents();
|
|
||||||
|
|
||||||
/* fps limiter */
|
|
||||||
if (enable_frame_limiter_) {
|
|
||||||
std::this_thread::sleep_until(endFrame);
|
|
||||||
}
|
|
||||||
beginFrame = endFrame;
|
|
||||||
endFrame = beginFrame + FRAMETIME_LIMIT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
gfxdev()->WaitIdle();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return resourcesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Application::Application(const char* appName, const char* appVersion,
|
||||||
|
gfx::GraphicsSettings graphicsSettings) {
|
||||||
|
window_ = std::make_unique<Window>(appName, true, false);
|
||||||
|
input_manager_ = std::make_unique<InputManager>(window_.get());
|
||||||
|
scene_manager_ = std::make_unique<SceneManager>(this);
|
||||||
|
|
||||||
|
// get base path for resources
|
||||||
|
resources_path_ = getResourcesPath();
|
||||||
|
|
||||||
|
// register resource managers
|
||||||
|
RegisterResourceManager<resources::Font>();
|
||||||
|
RegisterResourceManager<resources::Texture>();
|
||||||
|
RegisterResourceManager<resources::Shader>();
|
||||||
|
RegisterResourceManager<resources::Material>();
|
||||||
|
RegisterResourceManager<resources::Mesh>();
|
||||||
|
|
||||||
|
// initialise the render data
|
||||||
|
render_data_.gfxdev = std::make_unique<GFXDevice>(
|
||||||
|
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>(
|
||||||
|
GetResourcePath("engine/fonts/mono.ttf"));
|
||||||
|
GetResourceManager<resources::Font>()->AddPersistent("builtin.mono",
|
||||||
|
std::move(monoFont));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default shaders */
|
||||||
|
{
|
||||||
|
resources::Shader::VertexParams vertParams{};
|
||||||
|
vertParams.has_normal = true;
|
||||||
|
vertParams.has_uv0 = true;
|
||||||
|
auto texturedShader = std::make_unique<resources::Shader>(
|
||||||
|
&render_data_, GetResourcePath("engine/shaders/standard.vert").c_str(),
|
||||||
|
GetResourcePath("engine/shaders/standard.frag").c_str(), vertParams,
|
||||||
|
false, true);
|
||||||
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
|
"builtin.standard", std::move(texturedShader));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
resources::Shader::VertexParams vertParams{};
|
||||||
|
vertParams.has_normal = true;
|
||||||
|
vertParams.has_uv0 = true;
|
||||||
|
auto skyboxShader = std::make_unique<resources::Shader>(
|
||||||
|
&render_data_, GetResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||||
|
GetResourcePath("engine/shaders/skybox.frag").c_str(), vertParams,
|
||||||
|
false, true);
|
||||||
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
|
"builtin.skybox", std::move(skyboxShader));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
resources::Shader::VertexParams vertParams{};
|
||||||
|
vertParams.has_normal = true;
|
||||||
|
vertParams.has_uv0 = true;
|
||||||
|
auto quadShader = std::make_unique<resources::Shader>(
|
||||||
|
&render_data_, GetResourcePath("engine/shaders/quad.vert").c_str(),
|
||||||
|
GetResourcePath("engine/shaders/quad.frag").c_str(), vertParams,
|
||||||
|
true, true);
|
||||||
|
GetResourceManager<resources::Shader>()->AddPersistent(
|
||||||
|
"builtin.quad", std::move(quadShader));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* default textures */
|
||||||
|
{
|
||||||
|
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||||
|
&render_data_, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::GameLoop() {
|
||||||
|
LOG_TRACE("Begin game loop...");
|
||||||
|
|
||||||
|
constexpr int FPS_LIMIT = 240;
|
||||||
|
constexpr auto FRAMETIME_LIMIT =
|
||||||
|
std::chrono::nanoseconds(1000000000 / FPS_LIMIT);
|
||||||
|
auto beginFrame = std::chrono::steady_clock::now();
|
||||||
|
auto endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||||
|
|
||||||
|
auto lastTick = window_->GetNanos();
|
||||||
|
|
||||||
|
// single-threaded game loop
|
||||||
|
while (window_->IsRunning()) {
|
||||||
|
/* logic */
|
||||||
|
scene_manager_->UpdateActiveScene(window_->dt());
|
||||||
|
|
||||||
|
if (window_->GetKeyPress(inputs::Key::K_F)) [[unlikely]] {
|
||||||
|
window_->InfoBox("fps", std::to_string(window_->GetFPS()) + " fps " +
|
||||||
|
std::to_string(window_->dt() * 1000.0f) +
|
||||||
|
" ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t now = window_->GetNanos();
|
||||||
|
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
||||||
|
lastTick = now;
|
||||||
|
LOG_INFO("fps: {}", window_->GetAvgFPS());
|
||||||
|
gfxdev()->LogPerformanceInfo();
|
||||||
|
window_->ResetAvgFPS();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* poll events */
|
||||||
|
window_->GetInputAndEvents();
|
||||||
|
|
||||||
|
/* fps limiter */
|
||||||
|
if (enable_frame_limiter_) {
|
||||||
|
std::this_thread::sleep_until(endFrame);
|
||||||
|
}
|
||||||
|
beginFrame = endFrame;
|
||||||
|
endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxdev()->WaitIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace engine
|
||||||
|
@ -78,6 +78,13 @@ std::unique_ptr<std::vector<uint8_t>> Font::GetTextBitmap(
|
|||||||
auto bitmap =
|
auto bitmap =
|
||||||
std::make_unique<std::vector<uint8_t>>(bitmap_width * bitmap_height * 4);
|
std::make_unique<std::vector<uint8_t>>(bitmap_width * bitmap_height * 4);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < bitmap->size() / 4; i++) {
|
||||||
|
bitmap->at(i * 4 + 0) = 0x00;
|
||||||
|
bitmap->at(i * 4 + 1) = 0x00;
|
||||||
|
bitmap->at(i * 4 + 2) = 0x00;
|
||||||
|
bitmap->at(i * 4 + 3) = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
int top_left_x = 0;
|
int top_left_x = 0;
|
||||||
for (const auto& renderInfo : characterRenderInfos) {
|
for (const auto& renderInfo : characterRenderInfos) {
|
||||||
if (renderInfo.isEmpty == false) {
|
if (renderInfo.isEmpty == false) {
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#include "systems/render2d.h"
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
#include "components/transform.h"
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
Render2DSystem::Render2DSystem(Scene* scene)
|
|
||||||
: System(scene, {typeid(TransformComponent).hash_code()}) {}
|
|
||||||
|
|
||||||
Render2DSystem::~Render2DSystem() {}
|
|
||||||
|
|
||||||
void Render2DSystem::OnUpdate(float ts) { (void)ts; }
|
|
||||||
|
|
||||||
} // namespace engine
|
|
@ -1,21 +0,0 @@
|
|||||||
#include "systems/ui.h"
|
|
||||||
|
|
||||||
#include "components/ui_element.h"
|
|
||||||
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
namespace engine {
|
|
||||||
|
|
||||||
UISystem::UISystem(Scene* scene)
|
|
||||||
: System(scene, { typeid(UIElementComponent).hash_code() })
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void UISystem::OnUpdate(float ts)
|
|
||||||
{
|
|
||||||
(void)ts;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -102,7 +102,7 @@ void PlayGame(GameSettings settings) {
|
|||||||
cube_renderable->material = std::make_shared<engine::resources::Material>(
|
cube_renderable->material = std::make_shared<engine::resources::Material>(
|
||||||
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
app.GetResource<engine::resources::Shader>("builtin.standard"));
|
||||||
cube_renderable->material->texture_ = grass_texture;
|
cube_renderable->material->texture_ = grass_texture;
|
||||||
// app.GetResource<engine::resources::Texture>("builtin.white");
|
// app.GetResource<engine::resources::Texture>("builtin.white");
|
||||||
cube_renderable->mesh = GenCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
|
cube_renderable->mesh = GenCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
|
||||||
auto cube_collider =
|
auto cube_collider =
|
||||||
my_scene->AddComponent<engine::ColliderComponent>(cube);
|
my_scene->AddComponent<engine::ColliderComponent>(cube);
|
||||||
@ -129,8 +129,8 @@ void PlayGame(GameSettings settings) {
|
|||||||
floor_collider->aabb = {{0.0f, 0.0f, 0.0f}, {10000.0f, 1.0f, 10000.0f}};
|
floor_collider->aabb = {{0.0f, 0.0f, 0.0f}, {10000.0f, 1.0f, 10000.0f}};
|
||||||
}
|
}
|
||||||
|
|
||||||
//engine::util::LoadMeshFromFile(
|
// engine::util::LoadMeshFromFile(
|
||||||
// my_scene, app.GetResourcePath("models/astronaut/astronaut.dae"));
|
// my_scene, app.GetResourcePath("models/astronaut/astronaut.dae"));
|
||||||
|
|
||||||
/* skybox */
|
/* skybox */
|
||||||
{
|
{
|
||||||
@ -146,5 +146,24 @@ void PlayGame(GameSettings settings) {
|
|||||||
-5.0f, -5.0f, -5.0f};
|
-5.0f, -5.0f, -5.0f};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* some text */
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
auto bitmap = app.GetResource<engine::resources::Font>("builtin.mono")
|
||||||
|
->GetTextBitmap("The", 768.0f, width, height);
|
||||||
|
|
||||||
|
uint32_t textbox = my_scene->CreateEntity("textbox");
|
||||||
|
auto textbox_renderable =
|
||||||
|
my_scene->AddComponent<engine::RenderableComponent>(textbox);
|
||||||
|
textbox_renderable->material =
|
||||||
|
std::make_unique<engine::resources::Material>(
|
||||||
|
app.GetResource<engine::resources::Shader>("builtin.quad"));
|
||||||
|
textbox_renderable->material->texture_ =
|
||||||
|
std::make_unique<engine::resources::Texture>(
|
||||||
|
&app.render_data_, bitmap->data(), width, height,
|
||||||
|
engine::resources::Texture::Filtering::kOff);
|
||||||
|
textbox_renderable->mesh = GenSphereMesh(app.gfxdev(), 1.0f, 8);
|
||||||
|
}
|
||||||
|
|
||||||
app.GameLoop();
|
app.GameLoop();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user