begin changing style

This commit is contained in:
Bailey Harrison 2023-04-29 15:22:25 +01:00
parent 440ad2de82
commit c5b7a09e63
40 changed files with 1500 additions and 1428 deletions

3
README
View File

@ -1,3 +1,6 @@
a random game engine thing. Now finally with ECS! a random game engine thing. Now finally with ECS!
Use the 'dev' branch for WIP. Use the 'dev' branch for WIP.
Uses the google style guide:
https://google.github.io/styleguide/cppguide.html

View File

@ -1,3 +1,6 @@
#pragma once #ifndef ENGINE_CONFIG_H_
#define ENGINE_CONFIG_H_
#define ENGINE_VERSION "@PROJECT_VERSION@" #define ENGINE_VERSION "@PROJECT_VERSION@"
#endif

View File

@ -1,59 +1,53 @@
#pragma once #ifndef ENGINE_INCLUDE_APPLICATION_H_
#define ENGINE_INCLUDE_APPLICATION_H_
#include "resource_manager.hpp" #include <assert.h>
#include <filesystem>
#include "gfx.hpp" #include <memory>
#include "gfx_device.hpp" #include <string>
#include <unordered_map>
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
#include <memory> #include "gfx.hpp"
#include <string> #include "gfx_device.hpp"
#include <filesystem> #include "input_manager.hpp"
#include <unordered_map> #include "resource_manager.hpp"
#include <assert.h> #include "scene_manager.hpp"
#include "window.hpp"
namespace engine { namespace engine {
class Window; // "window.hpp" struct RenderData {
class GFXDevice; // "gfx_device.hpp"
class InputManager; // "input_manager.hpp"
class SceneManager; // "scene_manager.hpp"
namespace resources {
class Shader;
class Texture;
}
struct RenderData {
std::unique_ptr<GFXDevice> gfxdev; std::unique_ptr<GFXDevice> gfxdev;
gfx::DrawBuffer* drawBuffer = nullptr; gfx::DrawBuffer* draw_buffer = nullptr;
/* uniforms for engine globals */ /* uniforms for engine globals */
const gfx::DescriptorSetLayout* globalSetLayout; const gfx::DescriptorSetLayout* global_set_layout;
const gfx::DescriptorSet* globalSet; const gfx::DescriptorSet* global_set;
struct GlobalSetUniformBuffer { struct GlobalSetUniformBuffer {
glm::mat4 proj; glm::mat4 proj;
}; };
gfx::UniformBuffer* globalSetUniformBuffer; gfx::UniformBuffer* global_set_uniform_buffer;
/* uniforms for per-frame data */ /* uniforms for per-frame data */
const gfx::DescriptorSetLayout* frameSetLayout; const gfx::DescriptorSetLayout* frame_set_layout;
const gfx::DescriptorSet* frameSet; const gfx::DescriptorSet* frame_set;
struct FrameSetUniformBuffer { struct FrameSetUniformBuffer {
glm::mat4 view; glm::mat4 view;
}; };
gfx::UniformBuffer* frameSetUniformBuffer; gfx::UniformBuffer* frame_set_uniform_buffer;
/* this descriptor set is bound per-material */ /* this descriptor set is bound per-material */
const gfx::DescriptorSetLayout* materialSetLayout; const gfx::DescriptorSetLayout* material_set_layout;
std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers{}; std::unordered_map<gfx::SamplerInfo, const gfx::Sampler*> samplers{};
}; };
class Application { class Application {
public: public:
Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings); Application(const char* app_name, const char* app_version,
gfx::GraphicsSettings graphics_settings);
~Application(); ~Application();
Application(const Application&) = delete; Application(const Application&) = delete;
Application& operator=(const Application&) = delete; Application& operator=(const Application&) = delete;
@ -61,69 +55,72 @@ namespace engine {
/* resource stuff */ /* resource stuff */
template <typename T> template <typename T>
void registerResourceManager() void RegisterResourceManager()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_resourceManagers.contains(hash) == false && "Registering resource manager type more than once."); assert(resource_managers_.contains(hash) == false &&
m_resourceManagers.emplace(hash, std::make_unique<ResourceManager<T>>()); "Registering resource manager type more than once.");
resource_managers_.emplace(hash, std::make_unique<ResourceManager<T>>());
} }
template <typename T> template <typename T>
std::shared_ptr<T> addResource(const std::string& name, std::unique_ptr<T>&& resource) std::shared_ptr<T> AddResource(const std::string& name,
std::unique_ptr<T>&& resource)
{ {
auto resourceManager = getResourceManager<T>(); auto resource_manager = GetResourceManager<T>();
return resourceManager->add(name, std::move(resource)); return resource_manager->Add(name, std::move(resource));
} }
template <typename T> template <typename T>
std::shared_ptr<T> getResource(const std::string& name) std::shared_ptr<T> GetResource(const std::string& name)
{ {
auto resourceManager = getResourceManager<T>(); auto resource_manager = GetResourceManager<T>();
return resourceManager->get(name); return resource_manager->Get(name);
} }
/* methods */ /* methods */
void gameLoop(); void GameLoop();
void setFrameLimiter(bool on) { m_enableFrameLimiter = on; } void SetFrameLimiter(bool on) { enable_frame_limiter_ = on; }
/* getters */ /* getters */
Window* window() { return m_window.get(); } Window* window() { return window_.get(); }
GFXDevice* gfx() { return renderData.gfxdev.get(); } GFXDevice* gfxdev() { return render_data_.gfxdev.get(); }
InputManager* inputManager() { return m_inputManager.get(); } InputManager* input_manager() { return input_manager_.get(); }
SceneManager* sceneManager() { return m_sceneManager.get(); } SceneManager* scene_manager() { return scene_manager_.get(); }
std::string getResourcePath(const std::string relativePath) { return (m_resourcesPath / relativePath).string(); } std::string GetResourcePath(const std::string relative_path) {
return (resources_path_ / relative_path).string();
}
RenderData renderData{}; RenderData render_data_{};
private: private:
std::unique_ptr<Window> m_window; std::unique_ptr<Window> window_;
std::unique_ptr<InputManager> m_inputManager; std::unique_ptr<InputManager> input_manager_;
std::unique_ptr<SceneManager> m_sceneManager; std::unique_ptr<SceneManager> scene_manager_;
std::unordered_map<size_t, std::unique_ptr<IResourceManager>>
resource_managers_{};
std::filesystem::path resources_path_;
std::filesystem::path m_resourcesPath; bool enable_frame_limiter_ = true;
bool m_enableFrameLimiter = true;
/* resource stuff */
std::unordered_map<size_t, std::unique_ptr<IResourceManager>> m_resourceManagers{};
template <typename T> template <typename T>
ResourceManager<T>* getResourceManager() ResourceManager<T>* GetResourceManager()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = m_resourceManagers.find(hash); auto it = resource_managers_.find(hash);
if (it == m_resourceManagers.end()) { if (it == resource_managers_.end()) {
throw std::runtime_error("Cannot find resource manager."); throw std::runtime_error("Cannot find resource manager.");
} }
auto ptr = it->second.get(); auto ptr = it->second.get();
auto castedPtr = dynamic_cast<ResourceManager<T>*>(ptr); auto casted_ptr = dynamic_cast<ResourceManager<T>*>(ptr);
assert(castedPtr != nullptr); assert(casted_ptr != nullptr);
return castedPtr; return casted_ptr;
} }
}; };
} }
#endif

View File

@ -1,73 +1,76 @@
#pragma once #ifndef ENGINE_INCLUDE_ECS_SYSTEM_H_
#define ENGINE_INCLUDE_ECS_SYSTEM_H_
#include <set>
#include <vector>
#include <map>
#include <string>
#include <bitset> #include <bitset>
#include <cassert>
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <assert.h> #include <map>
#include <set>
#include <typeinfo>
namespace engine { namespace engine {
class Scene; class Scene;
constexpr size_t MAX_COMPONENTS = 64; constexpr size_t kMaxComponents = 64;
class IComponentArray { class IComponentArray {
public: public:
virtual ~IComponentArray() = default; virtual ~IComponentArray() = default;
}; };
template<typename T> template<typename T>
class ComponentArray : public IComponentArray { class ComponentArray : public IComponentArray {
public: public:
void insertData(uint32_t entity, T component) void InsertData(uint32_t entity, T component)
{ {
assert(m_componentArray.find(entity) == m_componentArray.end() && "Adding component which already exists to entity"); assert(component_array_.find(entity) == component_array_.end() &&
m_componentArray.emplace(entity, component); "Adding component which already exists to entity");
component_array_.emplace(entity, component);
} }
void deleteData(uint32_t entity) void DeleteData(uint32_t entity)
{ {
m_componentArray.erase(entity); component_array_.erase(entity);
} }
T* getData(uint32_t entity) T* GetData(uint32_t entity)
{ {
if (m_componentArray.contains(entity)) { if (component_array_.contains(entity)) {
return &(m_componentArray.at(entity)); return &(component_array_.at(entity));
} else { } else {
return nullptr; return nullptr;
} }
} }
private: private:
std::map<uint32_t, T> m_componentArray{}; std::map<uint32_t, T> component_array_{};
}; };
class System { class System {
public: public:
System(Scene* scene, std::set<size_t> requiredComponentHashes); System(Scene* scene, std::set<size_t> required_component_hashes);
virtual ~System() {} virtual ~System() {}
System(const System&) = delete; System(const System&) = delete;
System& operator=(const System&) = delete; System& operator=(const System&) = delete;
virtual void onUpdate(float ts) = 0; virtual void OnUpdate(float ts) = 0;
virtual void onComponentInsert(uint32_t) {} virtual void OnComponentInsert(uint32_t) {}
virtual void onComponentRemove(uint32_t) {} virtual void OnComponentRemove(uint32_t) {}
Scene* const m_scene; Scene* const scene_;
std::bitset<MAX_COMPONENTS> m_signature; std::bitset<kMaxComponents> signature_;
std::set<uint32_t> m_entities{}; // entities that contain the required components
}; // entities that contain the needed components
std::set<uint32_t> entities_{};
} };
} // namespace engine
#endif

View File

@ -1,4 +1,5 @@
#pragma once #ifndef ENGINE_INCLUDE_ENGINE_API_H_
#define ENGINE_INCLUDE_ENGINE_API_H_
/* /*
#ifndef ENGINE_API #ifndef ENGINE_API
@ -15,3 +16,5 @@
*/ */
#define ENGINE_API #define ENGINE_API
#endif

View File

@ -1,65 +1,68 @@
#pragma once #ifndef ENGINE_INCLUDE_EVENT_SYSTEM_H_
#define ENGINE_INCLUDE_EVENT_SYSTEM_H_
#include <cstddef>
#include <cstdint>
#include <memory>
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
#include <memory>
#include <cstdlib>
#include <cassert>
#include <typeinfo>
namespace engine { namespace engine {
enum class EventSubscriberKind { enum class EventSubscriberKind {
ENTITY, kEntity,
}; };
// Event handler base-class // Event handler base-class
template <typename T> template <typename T>
class EventHandler { class EventHandler {
public: public:
virtual void onEvent(T data) = 0; virtual void OnEvent(T data) = 0;
}; };
// Event queue interface to allow for different type queues to be in the map // Event queue interface to allow for different type queues to be in the map
class IEventQueue { class IEventQueue {
public: public:
virtual ~IEventQueue() {} virtual ~IEventQueue() {}
virtual void dispatchEvents() = 0; virtual void DespatchEvents() = 0;
}; };
template <typename T> template <typename T>
class EventQueue : public IEventQueue { class EventQueue : public IEventQueue {
// holds events of type T and subscribers to those events // holds events of type T and subscribers to those events
public: public:
void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler) void Subscribe(EventSubscriberKind kind, uint32_t id,
EventHandler<T>* handler)
{ {
// For the time being, ignore kind (TODO) // For the time being, ignore kind (TODO)
(void)kind; (void)kind;
assert(m_subscribers.contains(id) == false && "subscribing to an event with ID that's already in use!"); assert(subscribers_.contains(id) == false &&
m_subscribers.emplace(id, handler); "subscribing to an event with ID that's already in use!");
subscribers_.emplace(id, handler);
} }
void queueEvent(EventSubscriberKind kind, uint32_t id, T event) void QueueEvent(EventSubscriberKind kind, uint32_t id, T event)
{ {
// For the time being, ignore kind (TODO) // For the time being, ignore kind (TODO)
(void)kind; (void)kind;
assert(m_subscribers.contains(id) && "Attempt to submit event to non-existing subscriber!"); assert(subscribers_.contains(id) &&
EventHandler<T>* handler = m_subscribers.at(id); "Attempt to submit event to non-existing subscriber!");
m_eventQueue.emplace(handler, event); EventHandler<T>* handler = subscribers_.at(id);
event_queue_.emplace(handler, event);
} }
void dispatchEvents() override void DespatchEvents() override
{ {
while (m_eventQueue.empty() == false) { while (event_queue_.empty() == false) {
auto [handler, event] = m_eventQueue.front(); auto [handler, event] = event_queue_.front();
handler->onEvent(event); handler->OnEvent(event);
m_eventQueue.pop(); event_queue_.pop();
} }
} }
private: private:
std::unordered_map<uint32_t, EventHandler<T>*> m_subscribers; std::unordered_map<uint32_t, EventHandler<T>*> subscribers_;
struct QueuedEvent { struct QueuedEvent {
@ -70,56 +73,64 @@ namespace engine {
EventHandler<T>* handler; EventHandler<T>* handler;
T event; T event;
}; };
std::queue<QueuedEvent> m_eventQueue{}; std::queue<QueuedEvent> event_queue_{};
}; };
class EventSystem { class EventSystem {
public: public:
EventSystem() {} EventSystem() {}
EventSystem(const EventSystem&) = delete; EventSystem(const EventSystem&) = delete;
EventSystem& operator=(const EventSystem&) = delete; EventSystem& operator=(const EventSystem&) = delete;
~EventSystem() {} ~EventSystem() {}
template <typename T> template <typename T>
void registerEventType() void RegisterEventType()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_eventQueues.contains(hash) == false && "Registering an event queue more than once!"); assert(event_queues_.contains(hash) == false &&
m_eventQueues.emplace(hash, std::make_unique<EventQueue<T>>()); "Registering an event queue more than once!");
event_queues_.emplace(hash, std::make_unique<EventQueue<T>>());
} }
template <typename T> template <typename T>
void subscribeToEventType(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler) void SubscribeToEventType(EventSubscriberKind kind, uint32_t id,
EventHandler<T>* handler)
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_eventQueues.contains(hash) && "Subscribing to event type that isn't registered!"); assert(event_queues_.contains(hash) &&
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_eventQueues.at(hash).get()); "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(
event_queues_.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot"); assert(queue != nullptr && "This cast should work?!! wot");
queue->subscribe(kind, id, handler); queue->Subscribe(kind, id, handler);
} }
template <typename T> template <typename T>
void queueEvent(EventSubscriberKind kind, uint32_t subscriberID, T event) void QueueEvent(EventSubscriberKind kind, uint32_t subscriber_id, T event)
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_eventQueues.contains(hash) && "Subscribing to event type that isn't registered!"); assert(event_queues_.contains(hash) &&
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_eventQueues.at(hash).get()); "Subscribing to event type that isn't registered!");
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(
event_queues_.at(hash).get());
assert(queue != nullptr && "This cast should work?!! wot"); assert(queue != nullptr && "This cast should work?!! wot");
queue->queueEvent(kind, subscriberID, event); queue->QueueEvent(kind, subscriber_id, event);
} }
void dispatchEvents() void DespatchEvents()
{ {
for (auto& [hash, queue] : m_eventQueues) { for (auto& [hash, queue] : event_queues_) {
queue->dispatchEvents(); queue->DespatchEvents();
} }
} }
private: private:
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> m_eventQueues{}; std::unordered_map<size_t, std::unique_ptr<IEventQueue>> event_queues_{};
}; };
} } // namespace engine
#endif

View File

@ -1,138 +1,144 @@
#pragma once #ifndef ENGINE_INCLUDE_GFX_H_
#define ENGINE_INCLUDE_GFX_H_
#include <cstdint> #include <cstdint>
#include <vector>
#include <type_traits>
#include <functional> #include <functional>
#include <type_traits>
#include <vector>
// Enums and structs for the graphics abstraction // Enums and structs for the graphics abstraction
namespace engine::gfx { namespace engine {
namespace gfx {
// handles (incomplete types) // handles (incomplete types)
struct Pipeline; struct Pipeline;
struct UniformBuffer; struct UniformBuffer;
struct Buffer; struct Buffer;
struct DrawBuffer; struct DrawBuffer;
struct DescriptorSetLayout; struct DescriptorSetLayout;
struct DescriptorSet; struct DescriptorSet;
struct Image; struct Image;
struct Sampler; struct Sampler;
enum class MSAALevel { enum class MSAALevel {
MSAA_OFF, kOff,
MSAA_2X, k2X,
MSAA_4X, k4X,
MSAA_8X, k8X,
MSAA_16X, k16X,
}; };
struct GraphicsSettings { struct GraphicsSettings {
GraphicsSettings() GraphicsSettings()
{ {
// sane defaults // sane defaults
enableValidation = true; enable_validation = true;
vsync = true; vsync = true;
waitForPresent = true; // not all GPUs/drivers support immediate present with V-sync enabled // not all GPUs/drivers support immediate present with V-sync enabled
msaaLevel = MSAALevel::MSAA_OFF; wait_for_present = true;
msaa_level = MSAALevel::kOff;
} }
bool enableValidation; bool enable_validation;
bool vsync; bool vsync;
// idle CPU after render until the frame has been presented (no affect with V-sync disabled) // idle CPU after render until the frame has been presented
bool waitForPresent; // (no affect with V-sync disabled)
MSAALevel msaaLevel; bool wait_for_present;
MSAALevel msaa_level;
}; };
enum class ShaderType { enum class ShaderType {
VERTEX, kVertex,
FRAGMENT, kFragment,
}; };
enum class BufferType { enum class BufferType {
VERTEX, kVertex,
INDEX, kIndex,
UNIFORM, kUniform,
}; };
enum class Primitive { enum class Primitive {
POINTS, kPoints,
LINES, kLines,
LINE_STRIP, kLineStrip,
TRIANGLES, kTriangles,
TRIANGLE_STRIP, kTriangleStrip,
}; };
enum class VertexAttribFormat { enum class VertexAttribFormat {
FLOAT2, kFloat2,
FLOAT3, kFloat3,
FLOAT4 kFloat4
}; };
enum class Filter : int { enum class Filter : int {
LINEAR, kLinear,
NEAREST, kNearest,
}; };
enum class DescriptorType { enum class DescriptorType {
UNIFORM_BUFFER, kUniformBuffer,
COMBINED_IMAGE_SAMPLER, kCombinedImageSampler,
}; };
namespace ShaderStageFlags { namespace ShaderStageFlags {
enum Bits : uint32_t { enum Bits : uint32_t {
VERTEX = 1 << 0, kVertex = 1 << 0,
FRAGMENT = 1 << 1, kFragment = 1 << 1,
}; };
typedef std::underlying_type<Bits>::type Flags; typedef std::underlying_type<Bits>::type Flags;
} }
struct VertexAttribDescription { struct VertexAttribDescription {
VertexAttribDescription(uint32_t location, VertexAttribFormat format, uint32_t offset) : VertexAttribDescription(uint32_t location, VertexAttribFormat format,
uint32_t offset) :
location(location), location(location),
format(format), format(format),
offset(offset) {} offset(offset) {}
uint32_t location; // the index to use in the shader uint32_t location; // the index to use in the shader
VertexAttribFormat format; VertexAttribFormat format;
uint32_t offset; uint32_t offset;
}; };
struct VertexFormat { struct VertexFormat {
uint32_t stride; uint32_t stride;
std::vector<VertexAttribDescription> attributeDescriptions; std::vector<VertexAttribDescription> attribute_descriptions;
}; };
struct PipelineInfo { struct PipelineInfo {
const char* vertShaderPath; const char* vert_shader_path;
const char* fragShaderPath; const char* frag_shader_path;
VertexFormat vertexFormat; VertexFormat vertex_format;
bool alphaBlending; bool alpha_blending;
bool backfaceCulling; bool backface_culling;
std::vector<const DescriptorSetLayout*> descriptorSetLayouts; std::vector<const DescriptorSetLayout*> descriptor_set_layouts;
}; };
struct DescriptorSetLayoutBinding { struct DescriptorSetLayoutBinding {
DescriptorType descriptorType = DescriptorType::UNIFORM_BUFFER; DescriptorType descriptor_type = DescriptorType::kUniformBuffer;
ShaderStageFlags::Flags stageFlags = 0; ShaderStageFlags::Flags stage_flags = 0;
}; };
struct SamplerInfo { struct SamplerInfo {
Filter minify; Filter minify;
Filter magnify; Filter magnify;
Filter mipmap; Filter mipmap;
bool anisotropicFiltering; bool anisotropic_filtering;
bool operator==(const SamplerInfo&) const = default; bool operator==(const SamplerInfo&) const = default;
}; };
} } // namespace gfx
} // namespace engine
namespace std { namespace std {
template<> template<>
struct std::hash<engine::gfx::SamplerInfo> struct std::hash<engine::gfx::SamplerInfo>
{ {
std::size_t operator()(const engine::gfx::SamplerInfo& k) const std::size_t operator()(const engine::gfx::SamplerInfo& k) const
{ {
using std::hash; using std::hash;
@ -140,13 +146,15 @@ namespace std {
size_t h1 = hash<int>()(static_cast<int>(k.minify)); size_t h1 = hash<int>()(static_cast<int>(k.minify));
size_t h2 = hash<int>()(static_cast<int>(k.magnify)); size_t h2 = hash<int>()(static_cast<int>(k.magnify));
size_t h3 = hash<int>()(static_cast<int>(k.mipmap)); size_t h3 = hash<int>()(static_cast<int>(k.mipmap));
size_t h4 = hash<bool>()(k.anisotropicFiltering); size_t h4 = hash<bool>()(k.anisotropic_filtering);
return ((h1 & 0xFF) << 24) | return ((h1 & 0xFF) << 24) |
((h2 & 0xFF) << 16) | ((h2 & 0xFF) << 16) |
((h3 & 0xFF) << 8) | ((h3 & 0xFF) << 8) |
((h4 & 0xFF) << 0); ((h4 & 0xFF) << 0);
} }
}; };
} } // namespace std
#endif

View File

@ -1,71 +1,108 @@
#pragma once #ifndef ENGINE_INCLUDE_GFX_DEVICE_H_
#define ENGINE_INCLUDE_GFX_DEVICE_H_
#include "gfx.hpp"
#include <memory> #include <memory>
#include "gfx.hpp"
struct SDL_Window; // <SDL_video.h> struct SDL_Window; // <SDL_video.h>
namespace engine { namespace engine {
class GFXDevice { class GFXDevice {
public: public:
GFXDevice(const char* appName, const char* appVersion, SDL_Window* window, gfx::GraphicsSettings settings); GFXDevice(const char* app_name, const char* app_version, SDL_Window* window,
gfx::GraphicsSettings settings);
GFXDevice(const GFXDevice&) = delete; GFXDevice(const GFXDevice&) = delete;
GFXDevice& operator=(const GFXDevice&) = delete; GFXDevice& operator=(const GFXDevice&) = delete;
~GFXDevice(); ~GFXDevice();
void getViewportSize(uint32_t *w, uint32_t *h); void GetViewportSize(uint32_t* w, uint32_t* h);
gfx::DrawBuffer* beginRender(); gfx::DrawBuffer* BeginRender();
void finishRender(gfx::DrawBuffer* drawBuffer);
void cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline); void FinishRender(gfx::DrawBuffer* draw_buffer);
void cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer);
void cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer);
void cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
void cmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data);
void cmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber);
gfx::Pipeline* createPipeline(const gfx::PipelineInfo& info); void CmdBindPipeline(gfx::DrawBuffer* draw_buffer,
void destroyPipeline(const gfx::Pipeline* pipeline); const gfx::Pipeline* pipeline);
gfx::DescriptorSetLayout* createDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings); void CmdBindVertexBuffer(gfx::DrawBuffer* draw_buffer, uint32_t binding,
void destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout); const gfx::Buffer* buffer);
gfx::DescriptorSet* allocateDescriptorSet(const gfx::DescriptorSetLayout* layout); void CmdBindIndexBuffer(gfx::DrawBuffer* draw_buffer,
// This updates all copies of the descriptor. This cannot be used after any frames have been renderered const gfx::Buffer* buffer);
void updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range);
void updateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler);
gfx::UniformBuffer* createUniformBuffer(uint64_t size, const void* initialData); void CmdDrawIndexed(gfx::DrawBuffer* draw_buffer, uint32_t index_count,
void destroyUniformBuffer(const gfx::UniformBuffer* descriptorBuffer); uint32_t instance_count, uint32_t first_index,
int32_t vertex_offset, uint32_t first_instance);
void writeUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data); void CmdPushConstants(gfx::DrawBuffer* draw_buffer,
const gfx::Pipeline* pipeline, uint32_t offset,
uint32_t size, const void* data);
void CmdBindDescriptorSet(gfx::DrawBuffer* draw_buffer,
const gfx::Pipeline* pipeline,
const gfx::DescriptorSet* set, uint32_t set_number);
gfx::Pipeline* CreatePipeline(const gfx::PipelineInfo& info);
void DestroyPipeline(const gfx::Pipeline* pipeline);
gfx::DescriptorSetLayout* CreateDescriptorSetLayout(
const std::vector<gfx::DescriptorSetLayoutBinding>& bindings);
void DestroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout);
gfx::DescriptorSet* AllocateDescriptorSet(
const gfx::DescriptorSetLayout* layout);
// This updates all copies of the descriptor.
// This cannot be used after any frames have been renderered
void UpdateDescriptorUniformBuffer(const gfx::DescriptorSet* set,
uint32_t binding,
const gfx::UniformBuffer* buffer,
size_t offset, size_t range);
void UpdateDescriptorCombinedImageSampler(const gfx::DescriptorSet* set,
uint32_t binding,
const gfx::Image* image,
const gfx::Sampler* sampler);
gfx::UniformBuffer* CreateUniformBuffer(uint64_t size,
const void* initial_data);
void DestroyUniformBuffer(const gfx::UniformBuffer* descriptor_buffer);
void WriteUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset,
uint64_t size, const void* data);
// Loads data into staging buffer and copies that into a single GPU buffer. // Loads data into staging buffer and copies that into a single GPU buffer.
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data); gfx::Buffer* CreateBuffer(gfx::BufferType type, uint64_t size,
void destroyBuffer(const gfx::Buffer* buffer); const void* data);
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData); void DestroyBuffer(const gfx::Buffer* buffer);
void destroyImage(const gfx::Image* image);
const gfx::Sampler* createSampler(const gfx::SamplerInfo& info); gfx::Image* CreateImage(uint32_t w, uint32_t h, const void* image_data);
void destroySampler(const gfx::Sampler* sampler);
uint64_t getFrameCount(); void DestroyImage(const gfx::Image* image);
void logPerformanceInfo(); const gfx::Sampler* CreateSampler(const gfx::SamplerInfo& info);
void DestroySampler(const gfx::Sampler* sampler);
uint64_t GetFrameCount();
void LogPerformanceInfo();
// wait until all the active GPU queues have finished working // wait until all the active GPU queues have finished working
void waitIdle(); void WaitIdle();
private: private:
struct Impl; struct Impl;
std::unique_ptr<Impl> pimpl; std::unique_ptr<Impl> pimpl;
};
}; } // namespace engine
} #endif

View File

@ -1,57 +1,95 @@
#pragma once #ifndef ENGINE_INCLUDE_INPUT_MANAGER_H_
#define ENGINE_INCLUDE_INPUT_MANAGER_H_
#include "engine_api.h" #include <array>
#include <string>
#include <vector>
#include "window.hpp"
#include "inputs/mouse.hpp" #include "inputs/mouse.hpp"
#include "inputs/keyboard.hpp" #include "inputs/keyboard.hpp"
#include <vector>
#include <array>
#include <string>
namespace engine { namespace engine {
class Window; // "window.hpp" enum class InputDevice : int {
kMouse,
kKeyboard,
kController,
kSize
};
enum class InputDevice : int { // This class should be used to get platform/input-device independent input
MOUSE, class InputManager {
KEYBOARD,
CONTROLLER,
SIZE
};
// This class should be used to get platform/input-device independent input public:
class ENGINE_API InputManager {
public: /* The Window object here is stored for the duration of the InputManager.
* 'win' must point to a valid Window object. */
// requires a window reference to get input from InputManager(const Window* win) : win_(win) {
InputManager(const Window* win); assert(win != nullptr);
enabled_devices_.fill(true);
}
InputManager(const InputManager&) = delete; InputManager(const InputManager&) = delete;
InputManager& operator=(const InputManager&) = delete; InputManager& operator=(const InputManager&) = delete;
~InputManager();
// Add a mouse input ~InputManager() {}
void addInputButton(const std::string& name, inputs::MouseButton button);
void addInputAxis(const std::string& name, inputs::MouseAxis axis);
void addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low);
// Add a keyboard input
void addInputButton(const std::string& name, inputs::Key button);
void addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low);
void delInputButton(int index); void AddInputButton(const std::string& name, inputs::MouseButton button) {
void delInputAxis(int index); AddInputDeviceButton(name, InputDevice::kMouse,
static_cast<int>(button));
}
void setDeviceActive(enum InputDevice device, bool active); void AddInputButton(const std::string& name, inputs::Key button) {
bool getDeviceActive(enum InputDevice device) const; AddInputDeviceButton(name, InputDevice::kKeyboard,
static_cast<int>(button));
}
float getAxis(const std::string& axisName) const; void AddInputAxis(const std::string& name, inputs::MouseAxis axis) {
bool getButton(const std::string& buttonName) const; AddInputDeviceAxis(name, InputDevice::kMouse, static_cast<int>(axis));
bool getButtonPress(const std::string& buttonName) const; }
bool getButtonRelease(const std::string& buttonName) const;
void AddInputButtonAsAxis(const std::string& name, inputs::MouseButton high,
inputs::MouseButton low) {
AddInputDeviceButtonAsAxis(name, InputDevice::kMouse,
static_cast<int>(high), static_cast<int>(low));
}
private: void AddInputButtonAsAxis(const std::string& name, inputs::Key high,
inputs::Key low) {
AddInputDeviceButtonAsAxis(name, InputDevice::kKeyboard,
static_cast<int>(high), static_cast<int>(low));
}
void DelInputButton(int index) {
std::vector<struct ButtonEntry>::iterator it = button_entries_.begin();
std::advance(it, index);
button_entries_.erase(it);
}
void DelInputAxis(int index) {
std::vector<struct AxisEntry>::iterator it = axis_entries_.begin();
std::advance(it, index);
axis_entries_.erase(it);
}
void SetDeviceActive(enum InputDevice device, bool active) {
enabled_devices_[static_cast<int>(device)] = active;
}
bool GetDeviceActive(enum InputDevice device) const {
return enabled_devices_[static_cast<int>(device)];
}
float GetAxis(const std::string& axis_name) const;
bool GetButton(const std::string& button_name) const;
bool GetButtonPress(const std::string& button_name) const;
bool GetButtonRelease(const std::string& button_name) const;
private:
struct ButtonEntry { struct ButtonEntry {
std::string name; std::string name;
@ -63,31 +101,54 @@ namespace engine {
std::string name; std::string name;
enum InputDevice device; enum InputDevice device;
int axis; int axis;
bool isButtonAxis; bool is_button_axis;
int high; int high;
int low; int low;
}; };
const Window* const m_win; const Window* win_;
std::vector<struct ButtonEntry> m_buttonEntries; std::vector<struct ButtonEntry> button_entries_;
std::vector<struct AxisEntry> m_axisEntries; std::vector<struct AxisEntry> axis_entries_;
std::array<bool, static_cast<int>(InputDevice::SIZE)> m_enabledDevices; std::array<bool, static_cast<int>(InputDevice::kSize)> enabled_devices_;
// private methods // private methods
float getDeviceAxis(enum InputDevice device, int axis) const; float GetDeviceAxis(enum InputDevice device, int axis) const;
bool getDeviceButton(enum InputDevice device, int button) const;
bool GetDeviceButton(enum InputDevice device, int button) const;
bool getDeviceButtonDown(enum InputDevice device, int button) const; bool getDeviceButtonDown(enum InputDevice device, int button) const;
bool getDeviceButtonUp(enum InputDevice device, int button) const;
float getButtonAxis(enum InputDevice device, int high, int low) const; bool GetDeviceButtonUp(enum InputDevice device, int button) const;
void addInputButton(const std::string& name, InputDevice device, int button); float GetButtonAxis(enum InputDevice device, int high, int low) const {
void addInputAxis(const std::string& name, InputDevice device, int axis); float value = 0.0f;
void addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low); if (GetDeviceButton(device, high)) value += 1.0f;
if (low != 0) {
if (GetDeviceButton(device, low)) value += -1.0f;
}
return value;
}
}; void AddInputDeviceButton(const std::string& name, InputDevice device,
int button) {
button_entries_.push_back({ name, device, button });
}
} void AddInputDeviceAxis(const std::string& name, InputDevice device,
int axis) {
axis_entries_.push_back({ name, device, axis, false, 0, 0 });
}
void AddInputDeviceButtonAsAxis(const std::string& name, InputDevice device,
int high, int low) {
axis_entries_.push_back({ name, device, 0, true, high, low });
}
};
} // namespace engine
#endif

View File

@ -1,4 +1,5 @@
#pragma once #ifndef ENGINE_INCLUDE_LOG_H_
#define ENGINE_INCLUDE_LOG_H_
#ifdef NDEBUG #ifdef NDEBUG
#define SPDLOG_ACTIVE_LEVEL 2 // info #define SPDLOG_ACTIVE_LEVEL 2 // info
@ -14,3 +15,5 @@
#define LOG_WARN SPDLOG_WARN #define LOG_WARN SPDLOG_WARN
#define LOG_ERROR SPDLOG_ERROR #define LOG_ERROR SPDLOG_ERROR
#define LOG_CRITICAL SPDLOG_CRITICAL #define LOG_CRITICAL SPDLOG_CRITICAL
#endif

View File

@ -1,4 +1,5 @@
#pragma once #ifndef ENGINE_INCLUDE_LOGGER_H_
#define ENGINE_INCLUDE_LOGGER_H_
#include "log.hpp" #include "log.hpp"
@ -10,15 +11,15 @@
namespace engine { namespace engine {
// To be executed in the target application, NOT engine.dll // To be executed in the target application, NOT engine.dll
void setupLog(const char* appName) void SetupLog(const char* appName) {
{
const std::string LOG_FILENAME{ std::string(appName) + ".log"}; const std::string LOG_FILENAME{ std::string(appName) + ".log"};
#ifdef NDEBUG #ifdef NDEBUG
// RELEASE // RELEASE
const std::filesystem::path log_path{ std::filesystem::temp_directory_path() / LOG_FILENAME }; const std::filesystem::path log_path{
std::filesystem::temp_directory_path() / LOG_FILENAME};
#else #else
// DEBUG // DEBUG
const std::filesystem::path log_path{ LOG_FILENAME }; const std::filesystem::path log_path{ LOG_FILENAME };
@ -26,15 +27,18 @@ namespace engine {
std::vector<spdlog::sink_ptr> sinks; std::vector<spdlog::sink_ptr> sinks;
sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(log_path.string(), true)); sinks.emplace_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(
log_path.string(), true));
sinks.back()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v"); sinks.back()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%l] %v");
sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()); sinks.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
sinks.back()->set_pattern("[%H:%M:%S.%e] [%l] %v"); sinks.back()->set_pattern("[%H:%M:%S.%e] [%l] %v");
auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(), sinks.end()); auto logger = std::make_shared<spdlog::logger>(appName, sinks.begin(),
sinks.end());
logger->set_level(spdlog::level::trace); // Logs below INFO are ignored through macros in release (see log.hpp) // Logs below INFO are ignored through macros in release (see log.hpp)
logger->set_level(spdlog::level::trace);
spdlog::register_logger(logger); spdlog::register_logger(logger);
spdlog::set_default_logger(logger); spdlog::set_default_logger(logger);
@ -42,6 +46,8 @@ namespace engine {
LOG_INFO("Created log with path: {}", log_path.string()); LOG_INFO("Created log with path: {}", log_path.string());
}
} }
} // namespace engine
#endif

View File

@ -1,47 +1,48 @@
#pragma once #ifndef ENGINE_INCLUDE_RESOURCE_MANAGER_H_
#define ENGINE_INCLUDE_RESOURCE_MANAGER_H_
#include <unordered_map>
#include <vector>
#include <string>
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>
namespace engine { namespace engine {
class IResourceManager { class IResourceManager {
public: public:
virtual ~IResourceManager() = default; virtual ~IResourceManager() = default;
}; };
template <class T> template <class T>
class ResourceManager : public IResourceManager { class ResourceManager : public IResourceManager {
public: public:
std::shared_ptr<T> add(const std::string& name, std::unique_ptr<T>&& resource) std::shared_ptr<T> Add(const std::string& name, std::unique_ptr<T>&& resource)
{ {
if (m_resources.contains(name) == false) { if (resources_.contains(name) == false) {
std::shared_ptr<T> resourceSharedPtr(std::move(resource)); std::shared_ptr<T> resource_shared(std::move(resource));
m_resources.emplace(name, resourceSharedPtr); resources_.emplace(name, resource_shared);
return resourceSharedPtr; return resource_shared;
} }
else { else {
throw std::runtime_error("Cannot add a resource which already exists"); throw std::runtime_error("Cannot add a resource which already exists");
} }
} }
void addPersistent(const std::string& name, std::unique_ptr<T>&& resource) void AddPersistent(const std::string& name, std::unique_ptr<T>&& resource)
{ {
m_persistentResources.push_back(add(name, std::move(resource))); persistent_resources_.push_back(Add(name, std::move(resource)));
} }
std::shared_ptr<T> get(const std::string& name) std::shared_ptr<T> Get(const std::string& name)
{ {
if (m_resources.contains(name)) { if (resources_.contains(name)) {
std::weak_ptr<T> ptr = m_resources.at(name); std::weak_ptr<T> ptr = resources_.at(name);
if (ptr.expired() == false) { if (ptr.expired() == false) {
return ptr.lock(); return ptr.lock();
} else { } else {
m_resources.erase(name); resources_.erase(name);
} }
} }
// resource doesn't exist: // resource doesn't exist:
@ -49,10 +50,13 @@ namespace engine {
return {}; return {};
} }
private: private:
std::unordered_map<std::string, std::weak_ptr<T>> m_resources{}; std::unordered_map<std::string, std::weak_ptr<T>> resources_{};
std::vector<std::shared_ptr<T>> m_persistentResources{}; // This array owns persistent resources // This array owns persistent resources
std::vector<std::shared_ptr<T>> persistent_resources_{};
}; };
} } // namespace engine
#endif

View File

@ -1,140 +1,145 @@
#pragma once #ifndef ENGINE_INCLUDE_SCENE_H_
#define ENGINE_INCLUDE_SCENE_H_
#include "log.hpp" #include <cassert>
#include <cstdint>
#include <map>
#include <typeinfo>
#include "ecs_system.hpp" #include "ecs_system.hpp"
#include "event_system.hpp" #include "event_system.hpp"
#include <map>
#include <cstdint>
#include <typeinfo>
#include <assert.h>
namespace engine { namespace engine {
class Application; class Application;
class Scene { class Scene {
public: public:
Scene(Application* app); Scene(Application* app);
Scene(const Scene&) = delete; Scene(const Scene&) = delete;
Scene& operator=(const Scene&) = delete; Scene& operator=(const Scene&) = delete;
~Scene(); ~Scene();
void update(float ts); void Update(float ts);
Application* app() { return m_app; } Application* app() { return app_; }
EventSystem* events() { return m_eventSystem.get(); } EventSystem* event_system() { return event_system_.get(); }
/* ecs stuff */ /* ecs stuff */
uint32_t createEntity(const std::string& tag, uint32_t parent = 0); uint32_t CreateEntity(const std::string& tag, uint32_t parent = 0);
uint32_t getEntity(const std::string& tag, uint32_t parent = 0); uint32_t getEntity(const std::string& tag, uint32_t parent = 0);
size_t getComponentSignaturePosition(size_t hash); size_t GetComponentSignaturePosition(size_t hash);
template <typename T> template <typename T>
void registerComponent() void registerComponent()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_componentArrays.contains(hash) == false && "Registering component type more than once."); assert(component_arrays_.contains(hash) == false &&
m_componentArrays.emplace(hash, std::make_unique<ComponentArray<T>>()); "Registering component type more than once.");
component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>());
size_t componentSignaturePosition = m_nextSignaturePosition++; size_t signature_position = next_signature_position_;
assert(componentSignaturePosition < MAX_COMPONENTS && "Registering too many components!"); ++next_signature_position_;
assert(m_componentSignaturePositions.contains(hash) == false); assert(signature_position < kMaxComponents &&
m_componentSignaturePositions.emplace(hash, componentSignaturePosition); "Registering too many components!");
assert(component_signature_positions_.contains(hash) == false);
component_signature_positions_.emplace(hash, signature_position);
} }
template <typename T> template <typename T>
T* getComponent(uint32_t entity) T* GetComponent(uint32_t entity)
{ {
auto array = getComponentArray<T>(); auto array = GetComponentArray<T>();
return array->getData(entity); return array->GetData(entity);
} }
template <typename T> template <typename T>
T* addComponent(uint32_t entity) T* AddComponent(uint32_t entity)
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto array = getComponentArray<T>(); auto array = GetComponentArray<T>();
array->insertData(entity, T{}); // errors if entity already exists in array array->InsertData(entity, T{}); // errors if entity already exists in array
// set the component bit for this entity // set the component bit for this entity
size_t componentSignaturePosition = m_componentSignaturePositions.at(hash); size_t signature_position = component_signature_positions_.at(hash);
auto& signatureRef = m_signatures.at(entity); auto& signature_ref = signatures_.at(entity);
signatureRef.set(componentSignaturePosition); signature_ref.set(signature_position);
for (auto& [systemName, system] : m_systems) for (auto& [system_name, system] : systems_)
{ {
if (system->m_entities.contains(entity)) continue; if (system->entities_.contains(entity)) continue;
if ((system->m_signature & signatureRef) == system->m_signature) { if ((system->signature_ & signature_ref) == system->signature_) {
system->m_entities.insert(entity); system->entities_.insert(entity);
system->onComponentInsert(entity); system->OnComponentInsert(entity);
} }
} }
return array->getData(entity); return array->GetData(entity);
} }
template <typename T> template <typename T>
void registerSystem() void RegisterSystem()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(m_systems.find(hash) == m_systems.end() && "Registering system more than once."); assert(systems_.find(hash) == systems_.end() &&
m_systems.emplace(hash, std::make_unique<T>(this)); "Registering system more than once.");
systems_.emplace(hash, std::make_unique<T>(this));
} }
template <typename T> template <typename T>
T* getSystem() T* GetSystem()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = m_systems.find(hash); auto it = systems_.find(hash);
if (it == m_systems.end()) { if (it == systems_.end()) {
throw std::runtime_error("Cannot find ecs system."); throw std::runtime_error("Cannot find ecs system.");
} }
auto ptr = it->second.get(); auto ptr = it->second.get();
auto castedPtr = dynamic_cast<T*>(ptr); auto casted_ptr = dynamic_cast<T*>(ptr);
assert(castedPtr != nullptr); assert(casted_ptr != nullptr);
return castedPtr; return casted_ptr;
} }
private: private:
Application* const m_app; Application* const app_;
uint32_t m_nextEntityID = 1000; uint32_t next_entity_id_ = 1000;
/* ecs stuff */ /* ecs stuff */
size_t m_nextSignaturePosition = 0; size_t next_signature_position_ = 0;
// maps component hashes to signature positions // maps component hashes to signature positions
std::map<size_t, size_t> m_componentSignaturePositions{}; std::map<size_t, size_t> component_signature_positions_{};
// maps entity ids to their signatures // maps entity ids to their signatures
std::map<uint32_t, std::bitset<MAX_COMPONENTS>> m_signatures{}; std::map<uint32_t, std::bitset<kMaxComponents>> signatures_{};
// maps component hashes to their arrays // maps component hashes to their arrays
std::map<size_t, std::unique_ptr<IComponentArray>> m_componentArrays{}; std::map<size_t, std::unique_ptr<IComponentArray>> component_arrays_{};
// maps system hashes to their class instantiations // maps system hashes to their class instantiations
std::map<size_t, std::unique_ptr<System>> m_systems{}; std::map<size_t, std::unique_ptr<System>> systems_{};
template <typename T> template <typename T>
ComponentArray<T>* getComponentArray() ComponentArray<T>* GetComponentArray()
{ {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
auto it = m_componentArrays.find(hash); auto it = component_arrays_.find(hash);
if (it == m_componentArrays.end()) { if (it == component_arrays_.end()) {
throw std::runtime_error("Cannot find component array."); throw std::runtime_error("Cannot find component array.");
} }
auto ptr = it->second.get(); auto ptr = it->second.get();
auto castedPtr = dynamic_cast<ComponentArray<T>*>(ptr); auto casted_ptr = dynamic_cast<ComponentArray<T>*>(ptr);
assert(castedPtr != nullptr); assert(casted_ptr != nullptr);
return castedPtr; return casted_ptr;
} }
std::unique_ptr<EventSystem> m_eventSystem{}; std::unique_ptr<EventSystem> event_system_{};
}; };
} } // namespace engine
#endif

View File

@ -1,34 +1,37 @@
#pragma once #ifndef ENGINE_INCLUDE_SCENE_MANAGER_H_
#define ENGINE_INCLUDE_SCENE_MANAGER_H_
#include "resource_manager.hpp"
#include <vector>
#include <memory> #include <memory>
#include <vector>
#include "scene.hpp"
#include "resource_manager.hpp"
namespace engine { namespace engine {
class Application; class Application;
class Scene; // "scene.hpp"
class SceneManager { class SceneManager {
public: public:
SceneManager(Application* app); SceneManager(Application* app);
~SceneManager(); ~SceneManager();
SceneManager(const SceneManager&) = delete; SceneManager(const SceneManager&) = delete;
SceneManager& operator=(const SceneManager&) = delete; SceneManager& operator=(const SceneManager&) = delete;
// creates an empty scene and sets it as active // creates an empty scene and sets it as active
Scene* createEmptyScene(); Scene* CreateEmptyScene();
void updateActiveScene(float ts); void UpdateActiveScene(float ts);
private: private:
Application* const m_app; Application* const app_;
std::vector<std::unique_ptr<Scene>> m_scenes; std::vector<std::unique_ptr<Scene>> scenes_;
int m_activeSceneIndex = -1; int active_scene_index_ = -1;
}; };
} } // namespace engine
#endif

View File

@ -1,11 +1,13 @@
#pragma once #pragma once
#include "ecs_system.hpp" #include <cstdint>
#include <vector>
#include "components/collider.hpp"
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
#include "components/collider.hpp"
#include "ecs_system.hpp"
namespace engine { namespace engine {
class PhysicsSystem : public System { class PhysicsSystem : public System {
@ -13,9 +15,9 @@ namespace engine {
public: public:
PhysicsSystem(Scene* scene); PhysicsSystem(Scene* scene);
void onUpdate(float ts) override; void OnUpdate(float ts) override;
void onComponentInsert(uint32_t entity) override; void OnComponentInsert(uint32_t entity) override;
struct CollisionEvent { struct CollisionEvent {
bool isCollisionEnter; // false == collision exit bool isCollisionEnter; // false == collision exit

View File

@ -18,7 +18,7 @@ namespace engine {
RenderSystem(Scene* scene); RenderSystem(Scene* scene);
~RenderSystem(); ~RenderSystem();
void onUpdate(float ts) override; void OnUpdate(float ts) override;
void setCameraEntity(uint32_t entity); void setCameraEntity(uint32_t entity);

View File

@ -10,7 +10,7 @@ namespace engine {
Render2DSystem(Scene* scene); Render2DSystem(Scene* scene);
~Render2DSystem(); ~Render2DSystem();
void onUpdate(float ts) override; void OnUpdate(float ts) override;
private: private:

View File

@ -9,7 +9,7 @@ namespace engine {
public: public:
TransformSystem(Scene* scene); TransformSystem(Scene* scene);
void onUpdate(float ts) override; void OnUpdate(float ts) override;
uint32_t getChildEntity(uint32_t parent, const std::string& tag); uint32_t getChildEntity(uint32_t parent, const std::string& tag);

View File

@ -9,7 +9,7 @@ namespace engine {
public: public:
UISystem(Scene* scene); UISystem(Scene* scene);
void onUpdate(float ts) override; void OnUpdate(float ts) override;
private: private:

View File

@ -1,18 +1,22 @@
#pragma once #ifndef ENGINE_INCLUDE_UTIL_H_
#define ENGINE_INCLUDE_UTIL_H_
#include <cstdio> #include <cstdio>
namespace engine { namespace engine {
inline bool versionFromCharArray(const char* version, int* major, int* minor, int* patch) inline bool versionFromCharArray(const char* version, int* major, int* minor,
{ int* patch) {
if (sscanf(version, "%d.%d.%d", major, minor, patch) != 3) { if (sscanf(version, "%d.%d.%d", major, minor, patch) != 3) {
*major = 0; *major = 0;
*minor = 0; *minor = 0;
*patch = 0; *patch = 0;
return false; return false;
} } else {
return true; return true;
} }
} }
} // namespace engine
#endif

View File

@ -1,23 +1,22 @@
#pragma once #ifndef ENGINE_INCLUDE_WINDOW_H_
#define ENGINE_INCLUDE_WINDOW_H_
#include "engine_api.h"
#include "inputs/keyboard.hpp"
#include "inputs/mouse.hpp"
#include <SDL.h>
#include <glm/vec2.hpp>
#include <array> #include <array>
#include <string> #include <string>
#include <glm/vec2.hpp>
#include <SDL.h>
#include "inputs/keyboard.hpp"
#include "inputs/mouse.hpp"
namespace engine { namespace engine {
class ENGINE_API Window { class Window {
public: public:
Window(const std::string& title, bool resizable = true, bool fullscreen = true); Window(const std::string& title, bool resizable = true,
bool fullscreen = true);
Window(const Window&) = delete; Window(const Window&) = delete;
Window& operator=(const Window&) = delete; Window& operator=(const Window&) = delete;
~Window(); ~Window();
@ -52,7 +51,8 @@ namespace engine {
bool isFullscreen() const; bool isFullscreen() const;
// Relative mouse mode captures the cursor for FPS style use. Returns false if unsupported. // Relative mouse mode captures the cursor for FPS style use.
// Returns false if unsupported.
bool setRelativeMouseMode(bool enabled); bool setRelativeMouseMode(bool enabled);
// returns true if relative mouse mode is enabled // returns true if relative mouse mode is enabled
@ -123,7 +123,7 @@ namespace engine {
/* STATIC METHODS */ /* STATIC METHODS */
static void errorBox(const std::string& message); static void errorBox(const std::string& message);
private: private:
SDL_Window* m_handle; SDL_Window* m_handle;
@ -193,6 +193,8 @@ namespace engine {
void onMouseButtonEvent(SDL_MouseButtonEvent& e); void onMouseButtonEvent(SDL_MouseButtonEvent& e);
void onMouseMotionEvent(SDL_MouseMotionEvent& e); void onMouseMotionEvent(SDL_MouseMotionEvent& e);
void onMouseWheelEvent(SDL_MouseWheelEvent& e); void onMouseWheelEvent(SDL_MouseWheelEvent& e);
}; };
} }
#endif

View File

@ -1,28 +1,29 @@
#include "application.hpp" #include "application.hpp"
#include "log.hpp" #include <filesystem>
#include <memory>
#include "window.hpp" #include <stdexcept>
#include "gfx_device.hpp" #include <string>
#include "input_manager.hpp" #include <thread>
#include "scene_manager.hpp"
#include "scene.hpp"
#include "resources/mesh.hpp"
#include "resources/material.hpp"
#include "resources/shader.hpp"
#include "resources/texture.hpp"
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
// To allow the FPS-limiter to put the thread to sleep #include "gfx.hpp"
#include <thread> #include "gfx_device.hpp"
#include "input_manager.hpp"
#include "log.hpp"
#include "resources/material.hpp"
#include "resources/mesh.hpp"
#include "resources/shader.hpp"
#include "resources/texture.hpp"
#include "scene.hpp"
#include "scene_manager.hpp"
#include "window.hpp"
#ifdef _MSC_VER #ifdef _MSC_VER
#include <windows.h> #include <windows.h>
#include <direct.h> #include <direct.h>
#define MAX_PATH 260 #define WIN_MAX_PATH 260
#endif #endif
namespace engine { namespace engine {
@ -33,7 +34,7 @@ namespace engine {
#ifdef _MSC_VER #ifdef _MSC_VER
CHAR exeDirBuf[MAX_PATH + 1]; CHAR exeDirBuf[MAX_PATH + 1];
GetModuleFileNameA(NULL, exeDirBuf, 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
@ -60,57 +61,57 @@ namespace engine {
Application::Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings) Application::Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings)
{ {
m_window = std::make_unique<Window>(appName, true, false); window_ = std::make_unique<Window>(appName, true, false);
m_inputManager = std::make_unique<InputManager>(window()); input_manager_ = std::make_unique<InputManager>(window_.get());
m_sceneManager = std::make_unique<SceneManager>(this); scene_manager_ = std::make_unique<SceneManager>(this);
// get base path for resources // get base path for resources
m_resourcesPath = getResourcesPath(); resources_path_ = getResourcesPath();
// register resource managers // register resource managers
registerResourceManager<resources::Texture>(); RegisterResourceManager<resources::Texture>();
registerResourceManager<resources::Shader>(); RegisterResourceManager<resources::Shader>();
registerResourceManager<resources::Material>(); RegisterResourceManager<resources::Material>();
registerResourceManager<resources::Mesh>(); RegisterResourceManager<resources::Mesh>();
// initialise the render data // initialise the render data
renderData.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, m_window->getHandle(), graphicsSettings); render_data_.gfxdev = std::make_unique<GFXDevice>(appName, appVersion, window_->getHandle(), graphicsSettings);
std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings; std::vector<gfx::DescriptorSetLayoutBinding> globalSetBindings;
{ {
auto& binding0 = globalSetBindings.emplace_back(); auto& binding0 = globalSetBindings.emplace_back();
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER; binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX; binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
} }
renderData.globalSetLayout = gfx()->createDescriptorSetLayout(globalSetBindings); render_data_.global_set_layout = gfxdev()->CreateDescriptorSetLayout(globalSetBindings);
renderData.globalSet = gfx()->allocateDescriptorSet(renderData.globalSetLayout); render_data_.global_set = gfxdev()->AllocateDescriptorSet(render_data_.global_set_layout);
RenderData::GlobalSetUniformBuffer globalSetUniformBufferData{ RenderData::GlobalSetUniformBuffer globalSetUniformBufferData{
.proj = glm::mat4{ 1.0f }, .proj = glm::mat4{ 1.0f },
}; };
renderData.globalSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData); render_data_.global_set_uniform_buffer = gfxdev()->CreateUniformBuffer(sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData);
gfx()->updateDescriptorUniformBuffer(renderData.globalSet, 0, renderData.globalSetUniformBuffer, 0, sizeof(RenderData::GlobalSetUniformBuffer)); gfxdev()->UpdateDescriptorUniformBuffer(render_data_.global_set, 0, render_data_.global_set_uniform_buffer, 0, sizeof(RenderData::GlobalSetUniformBuffer));
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings; std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
{ {
auto& binding0 = frameSetBindings.emplace_back(); auto& binding0 = frameSetBindings.emplace_back();
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER; binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX; binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
} }
renderData.frameSetLayout = gfx()->createDescriptorSetLayout(frameSetBindings); render_data_.frame_set_layout = gfxdev()->CreateDescriptorSetLayout(frameSetBindings);
renderData.frameSet = gfx()->allocateDescriptorSet(renderData.frameSetLayout); render_data_.frame_set = gfxdev()->AllocateDescriptorSet(render_data_.frame_set_layout);
RenderData::FrameSetUniformBuffer initialSetOneData{ RenderData::FrameSetUniformBuffer initialSetOneData{
.view = glm::mat4{ 1.0f }, .view = glm::mat4{ 1.0f },
}; };
renderData.frameSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData); render_data_.frame_set_uniform_buffer = gfxdev()->CreateUniformBuffer(sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData);
gfx()->updateDescriptorUniformBuffer(renderData.frameSet, 0, renderData.frameSetUniformBuffer, 0, sizeof(RenderData::FrameSetUniformBuffer)); gfxdev()->UpdateDescriptorUniformBuffer(render_data_.frame_set, 0, render_data_.frame_set_uniform_buffer, 0, sizeof(RenderData::FrameSetUniformBuffer));
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings; std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
{ {
auto& binding0 = materialSetBindings.emplace_back(); auto& binding0 = materialSetBindings.emplace_back();
binding0.descriptorType = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER; binding0.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
binding0.stageFlags = gfx::ShaderStageFlags::FRAGMENT; binding0.stage_flags = gfx::ShaderStageFlags::kFragment;
} }
renderData.materialSetLayout = gfx()->createDescriptorSetLayout(materialSetBindings); render_data_.material_set_layout = gfxdev()->CreateDescriptorSetLayout(materialSetBindings);
// default resources // default resources
{ {
@ -118,54 +119,54 @@ namespace engine {
vertParams.hasNormal = true; vertParams.hasNormal = true;
vertParams.hasUV0 = true; vertParams.hasUV0 = true;
auto texturedShader = std::make_unique<resources::Shader>( auto texturedShader = std::make_unique<resources::Shader>(
&renderData, &render_data_,
getResourcePath("engine/shaders/standard.vert").c_str(), GetResourcePath("engine/shaders/standard.vert").c_str(),
getResourcePath("engine/shaders/standard.frag").c_str(), GetResourcePath("engine/shaders/standard.frag").c_str(),
vertParams, vertParams,
false, false,
true true
); );
getResourceManager<resources::Shader>()->addPersistent("builtin.standard", std::move(texturedShader)); GetResourceManager<resources::Shader>()->AddPersistent("builtin.standard", std::move(texturedShader));
} }
{ {
resources::Shader::VertexParams vertParams{}; resources::Shader::VertexParams vertParams{};
vertParams.hasNormal = true; vertParams.hasNormal = true;
vertParams.hasUV0 = true; vertParams.hasUV0 = true;
auto skyboxShader = std::make_unique<resources::Shader>( auto skyboxShader = std::make_unique<resources::Shader>(
&renderData, &render_data_,
getResourcePath("engine/shaders/skybox.vert").c_str(), GetResourcePath("engine/shaders/skybox.vert").c_str(),
getResourcePath("engine/shaders/skybox.frag").c_str(), GetResourcePath("engine/shaders/skybox.frag").c_str(),
vertParams, vertParams,
false, false,
true true
); );
getResourceManager<resources::Shader>()->addPersistent("builtin.skybox", std::move(skyboxShader)); GetResourceManager<resources::Shader>()->AddPersistent("builtin.skybox", std::move(skyboxShader));
} }
{ {
auto whiteTexture = std::make_unique<resources::Texture>( auto whiteTexture = std::make_unique<resources::Texture>(
&renderData, &render_data_,
getResourcePath("engine/textures/white.png"), GetResourcePath("engine/textures/white.png"),
resources::Texture::Filtering::OFF resources::Texture::Filtering::OFF
); );
getResourceManager<resources::Texture>()->addPersistent("builtin.white", std::move(whiteTexture)); GetResourceManager<resources::Texture>()->AddPersistent("builtin.white", std::move(whiteTexture));
} }
} }
Application::~Application() Application::~Application()
{ {
for (const auto& [info, sampler] : renderData.samplers) { for (const auto& [info, sampler] : render_data_.samplers) {
gfx()->destroySampler(sampler); gfxdev()->DestroySampler(sampler);
} }
gfx()->destroyDescriptorSetLayout(renderData.materialSetLayout); gfxdev()->DestroyDescriptorSetLayout(render_data_.material_set_layout);
gfx()->destroyUniformBuffer(renderData.frameSetUniformBuffer); gfxdev()->DestroyUniformBuffer(render_data_.frame_set_uniform_buffer);
gfx()->destroyDescriptorSetLayout(renderData.frameSetLayout); gfxdev()->DestroyDescriptorSetLayout(render_data_.frame_set_layout);
gfx()->destroyUniformBuffer(renderData.globalSetUniformBuffer); gfxdev()->DestroyUniformBuffer(render_data_.global_set_uniform_buffer);
gfx()->destroyDescriptorSetLayout(renderData.globalSetLayout); gfxdev()->DestroyDescriptorSetLayout(render_data_.global_set_layout);
} }
void Application::gameLoop() void Application::GameLoop()
{ {
LOG_TRACE("Begin game loop..."); LOG_TRACE("Begin game loop...");
@ -174,31 +175,31 @@ namespace engine {
auto beginFrame = std::chrono::steady_clock::now(); auto beginFrame = std::chrono::steady_clock::now();
auto endFrame = beginFrame + FRAMETIME_LIMIT; auto endFrame = beginFrame + FRAMETIME_LIMIT;
auto lastTick = m_window->getNanos(); auto lastTick = window_->getNanos();
// single-threaded game loop // single-threaded game loop
while (m_window->isRunning()) { while (window_->isRunning()) {
/* logic */ /* logic */
m_sceneManager->updateActiveScene(m_window->dt()); scene_manager_->UpdateActiveScene(window_->dt());
if(m_window->getKeyPress(inputs::Key::K_F)) [[unlikely]] { if(window_->getKeyPress(inputs::Key::K_F)) [[unlikely]] {
m_window->infoBox("fps", std::to_string(m_window->getFPS()) + " fps " + std::to_string(m_window->dt() * 1000.0f) + " ms"); window_->infoBox("fps", std::to_string(window_->getFPS()) + " fps " + std::to_string(window_->dt() * 1000.0f) + " ms");
} }
uint64_t now = m_window->getNanos(); uint64_t now = window_->getNanos();
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] { if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
lastTick = now; lastTick = now;
LOG_INFO("fps: {}", m_window->getAvgFPS()); LOG_INFO("fps: {}", window_->getAvgFPS());
gfx()->logPerformanceInfo(); gfxdev()->LogPerformanceInfo();
m_window->resetAvgFPS(); window_->resetAvgFPS();
} }
/* poll events */ /* poll events */
m_window->getInputAndEvents(); window_->getInputAndEvents();
/* fps limiter */ /* fps limiter */
if (m_enableFrameLimiter) { if (enable_frame_limiter_) {
std::this_thread::sleep_until(endFrame); std::this_thread::sleep_until(endFrame);
} }
beginFrame = endFrame; beginFrame = endFrame;
@ -206,7 +207,7 @@ namespace engine {
} }
gfx()->waitIdle(); gfxdev()->WaitIdle();
} }
} }

View File

@ -5,11 +5,11 @@
namespace engine { namespace engine {
System::System(Scene* scene, std::set<size_t> requiredComponentHashes) System::System(Scene* scene, std::set<size_t> requiredComponentHashes)
: m_scene(scene) : scene_(scene)
{ {
for (size_t componentHash : requiredComponentHashes) { for (size_t componentHash : requiredComponentHashes) {
size_t componentSignaturePosition = m_scene->getComponentSignaturePosition(componentHash); size_t componentSignaturePosition = scene_->GetComponentSignaturePosition(componentHash);
m_signature.set(componentSignaturePosition); signature_.set(componentSignaturePosition);
} }
} }

View File

@ -130,11 +130,11 @@ namespace engine {
static VkFormat getVertexAttribFormat(gfx::VertexAttribFormat fmt) static VkFormat getVertexAttribFormat(gfx::VertexAttribFormat fmt)
{ {
switch (fmt) { switch (fmt) {
case gfx::VertexAttribFormat::FLOAT2: case gfx::VertexAttribFormat::kFloat2:
return VK_FORMAT_R32G32_SFLOAT; return VK_FORMAT_R32G32_SFLOAT;
case gfx::VertexAttribFormat::FLOAT3: case gfx::VertexAttribFormat::kFloat3:
return VK_FORMAT_R32G32B32_SFLOAT; return VK_FORMAT_R32G32B32_SFLOAT;
case gfx::VertexAttribFormat::FLOAT4: case gfx::VertexAttribFormat::kFloat4:
return VK_FORMAT_R32G32B32A32_SFLOAT; return VK_FORMAT_R32G32B32A32_SFLOAT;
} }
throw std::runtime_error("Unknown vertex attribute format"); throw std::runtime_error("Unknown vertex attribute format");
@ -143,11 +143,11 @@ namespace engine {
static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type) static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
{ {
switch (type) { switch (type) {
case gfx::BufferType::VERTEX: case gfx::BufferType::kVertex:
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
case gfx::BufferType::INDEX: case gfx::BufferType::kIndex:
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
case gfx::BufferType::UNIFORM: case gfx::BufferType::kUniform:
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
default: default:
throw std::runtime_error("This buffer type does not have usage bits"); throw std::runtime_error("This buffer type does not have usage bits");
@ -157,9 +157,9 @@ namespace engine {
[[maybe_unused]] static VkFilter getFilter(gfx::Filter filter) [[maybe_unused]] static VkFilter getFilter(gfx::Filter filter)
{ {
switch (filter) { switch (filter) {
case gfx::Filter::LINEAR: case gfx::Filter::kLinear:
return VK_FILTER_LINEAR; return VK_FILTER_LINEAR;
case gfx::Filter::NEAREST: case gfx::Filter::kNearest:
return VK_FILTER_NEAREST; return VK_FILTER_NEAREST;
} }
throw std::runtime_error("Unknown filter"); throw std::runtime_error("Unknown filter");
@ -168,9 +168,9 @@ namespace engine {
[[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter) [[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter)
{ {
switch (filter) { switch (filter) {
case gfx::Filter::LINEAR: case gfx::Filter::kLinear:
return VK_SAMPLER_MIPMAP_MODE_LINEAR; return VK_SAMPLER_MIPMAP_MODE_LINEAR;
case gfx::Filter::NEAREST: case gfx::Filter::kNearest:
return VK_SAMPLER_MIPMAP_MODE_NEAREST; return VK_SAMPLER_MIPMAP_MODE_NEAREST;
} }
throw std::runtime_error("Unknown filter"); throw std::runtime_error("Unknown filter");
@ -179,15 +179,15 @@ namespace engine {
[[maybe_unused]] static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level) [[maybe_unused]] static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level)
{ {
switch (level) { switch (level) {
case gfx::MSAALevel::MSAA_OFF: case gfx::MSAALevel::kOff:
return VK_SAMPLE_COUNT_1_BIT; return VK_SAMPLE_COUNT_1_BIT;
case gfx::MSAALevel::MSAA_2X: case gfx::MSAALevel::k2X:
return VK_SAMPLE_COUNT_2_BIT; return VK_SAMPLE_COUNT_2_BIT;
case gfx::MSAALevel::MSAA_4X: case gfx::MSAALevel::k4X:
return VK_SAMPLE_COUNT_4_BIT; return VK_SAMPLE_COUNT_4_BIT;
case gfx::MSAALevel::MSAA_8X: case gfx::MSAALevel::k8X:
return VK_SAMPLE_COUNT_8_BIT; return VK_SAMPLE_COUNT_8_BIT;
case gfx::MSAALevel::MSAA_16X: case gfx::MSAALevel::k16X:
return VK_SAMPLE_COUNT_16_BIT; return VK_SAMPLE_COUNT_16_BIT;
default: default:
throw std::runtime_error("Unknown MSAA level"); throw std::runtime_error("Unknown MSAA level");
@ -197,9 +197,9 @@ namespace engine {
static VkDescriptorType getDescriptorType(gfx::DescriptorType type) static VkDescriptorType getDescriptorType(gfx::DescriptorType type)
{ {
switch (type) { switch (type) {
case gfx::DescriptorType::UNIFORM_BUFFER: case gfx::DescriptorType::kUniformBuffer:
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case gfx::DescriptorType::COMBINED_IMAGE_SAMPLER: case gfx::DescriptorType::kCombinedImageSampler:
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
default: default:
throw std::runtime_error("Unknown descriptor type"); throw std::runtime_error("Unknown descriptor type");
@ -209,8 +209,8 @@ namespace engine {
static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags) static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags)
{ {
VkShaderStageFlags out = 0; VkShaderStageFlags out = 0;
if (flags & gfx::ShaderStageFlags::VERTEX) out |= VK_SHADER_STAGE_VERTEX_BIT; if (flags & gfx::ShaderStageFlags::kVertex) out |= VK_SHADER_STAGE_VERTEX_BIT;
if (flags & gfx::ShaderStageFlags::FRAGMENT) out |= VK_SHADER_STAGE_FRAGMENT_BIT; if (flags & gfx::ShaderStageFlags::kFragment) out |= VK_SHADER_STAGE_FRAGMENT_BIT;
return out; return out;
} }
@ -365,7 +365,7 @@ namespace engine {
throw std::runtime_error("The loaded Vulkan version must be at least 1.3"); throw std::runtime_error("The loaded Vulkan version must be at least 1.3");
} }
pimpl->instance = createVulkanInstance(pimpl->window, appName, appVersion, pimpl->graphicsSettings.enableValidation, MessageSeverity::SEV_WARNING); pimpl->instance = createVulkanInstance(pimpl->window, appName, appVersion, pimpl->graphicsSettings.enable_validation, MessageSeverity::SEV_WARNING);
if (SDL_Vulkan_CreateSurface(pimpl->window, pimpl->instance.instance, &pimpl->surface) == false) { if (SDL_Vulkan_CreateSurface(pimpl->window, pimpl->instance.instance, &pimpl->surface) == false) {
throw std::runtime_error("Unable to create window surface"); throw std::runtime_error("Unable to create window surface");
@ -440,7 +440,7 @@ namespace engine {
pimpl->swapchainInfo.surface = pimpl->surface; pimpl->swapchainInfo.surface = pimpl->surface;
pimpl->swapchainInfo.window = pimpl->window; pimpl->swapchainInfo.window = pimpl->window;
pimpl->swapchainInfo.vsync = pimpl->graphicsSettings.vsync; pimpl->swapchainInfo.vsync = pimpl->graphicsSettings.vsync;
pimpl->swapchainInfo.waitForPresent = pimpl->graphicsSettings.waitForPresent; pimpl->swapchainInfo.waitForPresent = pimpl->graphicsSettings.wait_for_present;
createSwapchain(&pimpl->swapchain, pimpl->swapchainInfo); createSwapchain(&pimpl->swapchain, pimpl->swapchainInfo);
/* make synchronisation primitives for rendering and allocate command buffers */ /* make synchronisation primitives for rendering and allocate command buffers */
@ -541,7 +541,7 @@ namespace engine {
destroyVulkanInstance(pimpl->instance); destroyVulkanInstance(pimpl->instance);
} }
void GFXDevice::getViewportSize(uint32_t* w, uint32_t* h) void GFXDevice::GetViewportSize(uint32_t* w, uint32_t* h)
{ {
int width, height; int width, height;
SDL_Vulkan_GetDrawableSize(pimpl->window, &width, &height); SDL_Vulkan_GetDrawableSize(pimpl->window, &width, &height);
@ -555,7 +555,7 @@ namespace engine {
} }
} }
gfx::DrawBuffer* GFXDevice::beginRender() gfx::DrawBuffer* GFXDevice::BeginRender()
{ {
VkResult res; VkResult res;
@ -724,7 +724,7 @@ namespace engine {
} }
void GFXDevice::finishRender(gfx::DrawBuffer* drawBuffer) void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
@ -785,68 +785,68 @@ namespace engine {
delete drawBuffer; delete drawBuffer;
} }
void GFXDevice::cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline) void GFXDevice::CmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
vkCmdBindPipeline(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle); vkCmdBindPipeline(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
} }
void GFXDevice::cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer) void GFXDevice::CmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
assert(buffer != nullptr); assert(buffer != nullptr);
assert(buffer->type == gfx::BufferType::VERTEX); assert(buffer->type == gfx::BufferType::kVertex);
const VkDeviceSize offset = 0; const VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(drawBuffer->frameData.drawBuf, binding, 1, &buffer->buffer, &offset); vkCmdBindVertexBuffers(drawBuffer->frameData.drawBuf, binding, 1, &buffer->buffer, &offset);
} }
void GFXDevice::cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer) void GFXDevice::CmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
assert(buffer != nullptr); assert(buffer != nullptr);
assert(buffer->type == gfx::BufferType::INDEX); assert(buffer->type == gfx::BufferType::kIndex);
vkCmdBindIndexBuffer(drawBuffer->frameData.drawBuf, buffer->buffer, 0, INDEX_TYPE); vkCmdBindIndexBuffer(drawBuffer->frameData.drawBuf, buffer->buffer, 0, INDEX_TYPE);
} }
void GFXDevice::cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) void GFXDevice::CmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
vkCmdDrawIndexed(drawBuffer->frameData.drawBuf, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); vkCmdDrawIndexed(drawBuffer->frameData.drawBuf, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
} }
void GFXDevice::cmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data) void GFXDevice::CmdPushConstants(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, uint32_t offset, uint32_t size, const void* data)
{ {
assert(drawBuffer != nullptr); assert(drawBuffer != nullptr);
vkCmdPushConstants(drawBuffer->frameData.drawBuf, pipeline->layout, VK_SHADER_STAGE_VERTEX_BIT, offset, size, data); vkCmdPushConstants(drawBuffer->frameData.drawBuf, pipeline->layout, VK_SHADER_STAGE_VERTEX_BIT, offset, size, data);
} }
void GFXDevice::cmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber) void GFXDevice::CmdBindDescriptorSet(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline, const gfx::DescriptorSet* set, uint32_t setNumber)
{ {
vkCmdBindDescriptorSets(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, setNumber, 1, &set->sets[drawBuffer->currentFrameIndex], 0, nullptr); vkCmdBindDescriptorSets(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, setNumber, 1, &set->sets[drawBuffer->currentFrameIndex], 0, nullptr);
} }
gfx::Pipeline* GFXDevice::createPipeline(const gfx::PipelineInfo& info) gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
{ {
[[maybe_unused]] VkResult res; [[maybe_unused]] VkResult res;
gfx::Pipeline* pipeline = new gfx::Pipeline; gfx::Pipeline* pipeline = new gfx::Pipeline;
auto vertShaderCode = util::readTextFile(info.vertShaderPath); auto vertShaderCode = util::readTextFile(info.vert_shader_path);
auto fragShaderCode = util::readTextFile(info.fragShaderPath); auto fragShaderCode = util::readTextFile(info.frag_shader_path);
VkShaderModule vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), info.vertShaderPath); VkShaderModule vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), info.vert_shader_path);
VkShaderModule fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), info.fragShaderPath); VkShaderModule fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), info.frag_shader_path);
// get vertex attrib layout: // get vertex attrib layout:
VkVertexInputBindingDescription bindingDescription{ }; VkVertexInputBindingDescription bindingDescription{ };
bindingDescription.binding = 0; bindingDescription.binding = 0;
bindingDescription.stride = info.vertexFormat.stride; bindingDescription.stride = info.vertex_format.stride;
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
std::vector<VkVertexInputAttributeDescription> attribDescs{}; std::vector<VkVertexInputAttributeDescription> attribDescs{};
attribDescs.reserve(info.vertexFormat.attributeDescriptions.size()); attribDescs.reserve(info.vertex_format.attribute_descriptions.size());
for (const auto& desc : info.vertexFormat.attributeDescriptions) { for (const auto& desc : info.vertex_format.attribute_descriptions) {
VkVertexInputAttributeDescription vulkanAttribDesc{}; VkVertexInputAttributeDescription vulkanAttribDesc{};
vulkanAttribDesc.location = desc.location; vulkanAttribDesc.location = desc.location;
vulkanAttribDesc.binding = 0; vulkanAttribDesc.binding = 0;
@ -920,7 +920,7 @@ namespace engine {
rasterizer.rasterizerDiscardEnable = VK_FALSE; // enabling this will not run the fragment shaders at all rasterizer.rasterizerDiscardEnable = VK_FALSE; // enabling this will not run the fragment shaders at all
rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
rasterizer.lineWidth = 1.0f; rasterizer.lineWidth = 1.0f;
if (info.backfaceCulling == true) { if (info.backface_culling == true) {
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
} }
else { else {
@ -947,7 +947,7 @@ namespace engine {
VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT; VK_COLOR_COMPONENT_A_BIT;
if (info.alphaBlending) { if (info.alpha_blending) {
colorBlendAttachment.blendEnable = VK_TRUE; colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
@ -988,9 +988,9 @@ namespace engine {
pushConstantRange.size = PUSH_CONSTANT_MAX_SIZE; pushConstantRange.size = PUSH_CONSTANT_MAX_SIZE;
pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
std::vector<VkDescriptorSetLayout> descriptorSetLayouts(info.descriptorSetLayouts.size()); std::vector<VkDescriptorSetLayout> descriptorSetLayouts(info.descriptor_set_layouts.size());
for (size_t i = 0; i < descriptorSetLayouts.size(); i++) { for (size_t i = 0; i < descriptorSetLayouts.size(); i++) {
descriptorSetLayouts[i] = info.descriptorSetLayouts[i]->layout; descriptorSetLayouts[i] = info.descriptor_set_layouts[i]->layout;
} }
VkPipelineLayoutCreateInfo layoutInfo{}; VkPipelineLayoutCreateInfo layoutInfo{};
@ -1031,7 +1031,7 @@ namespace engine {
} }
void GFXDevice::destroyPipeline(const gfx::Pipeline* pipeline) void GFXDevice::DestroyPipeline(const gfx::Pipeline* pipeline)
{ {
vkDestroyPipeline(pimpl->device.device, pipeline->handle, nullptr); vkDestroyPipeline(pimpl->device.device, pipeline->handle, nullptr);
vkDestroyPipelineLayout(pimpl->device.device, pipeline->layout, nullptr); vkDestroyPipelineLayout(pimpl->device.device, pipeline->layout, nullptr);
@ -1039,7 +1039,7 @@ namespace engine {
delete pipeline; delete pipeline;
} }
gfx::DescriptorSetLayout* GFXDevice::createDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings) gfx::DescriptorSetLayout* GFXDevice::CreateDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings)
{ {
gfx::DescriptorSetLayout* out = new gfx::DescriptorSetLayout{}; gfx::DescriptorSetLayout* out = new gfx::DescriptorSetLayout{};
@ -1048,9 +1048,9 @@ namespace engine {
for (const auto& binding : bindings) { for (const auto& binding : bindings) {
auto& vulkanBinding = vulkanBindings.emplace_back(); auto& vulkanBinding = vulkanBindings.emplace_back();
vulkanBinding.binding = i; // This should be as low as possible to avoid wasting memory vulkanBinding.binding = i; // This should be as low as possible to avoid wasting memory
vulkanBinding.descriptorType = converters::getDescriptorType(binding.descriptorType); vulkanBinding.descriptorType = converters::getDescriptorType(binding.descriptor_type);
vulkanBinding.descriptorCount = 1; // if > 1, accessible as an array in the shader vulkanBinding.descriptorCount = 1; // if > 1, accessible as an array in the shader
vulkanBinding.stageFlags = converters::getShaderStageFlags(binding.stageFlags); vulkanBinding.stageFlags = converters::getShaderStageFlags(binding.stage_flags);
++i; ++i;
} }
@ -1066,13 +1066,13 @@ namespace engine {
return out; return out;
} }
void GFXDevice::destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout) void GFXDevice::DestroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
{ {
vkDestroyDescriptorSetLayout(pimpl->device.device, layout->layout, nullptr); vkDestroyDescriptorSetLayout(pimpl->device.device, layout->layout, nullptr);
delete layout; delete layout;
} }
gfx::DescriptorSet* GFXDevice::allocateDescriptorSet(const gfx::DescriptorSetLayout* layout) gfx::DescriptorSet* GFXDevice::AllocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
{ {
gfx::DescriptorSet* set = new gfx::DescriptorSet{}; gfx::DescriptorSet* set = new gfx::DescriptorSet{};
@ -1094,7 +1094,7 @@ namespace engine {
return set; return set;
} }
void GFXDevice::updateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range) void GFXDevice::UpdateDescriptorUniformBuffer(const gfx::DescriptorSet* set, uint32_t binding, const gfx::UniformBuffer* buffer, size_t offset, size_t range)
{ {
assert(pimpl->FRAMECOUNT == 0); assert(pimpl->FRAMECOUNT == 0);
@ -1120,7 +1120,7 @@ namespace engine {
} }
} }
void GFXDevice::updateDescriptorCombinedImageSampler(const gfx::DescriptorSet *set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler) void GFXDevice::UpdateDescriptorCombinedImageSampler(const gfx::DescriptorSet *set, uint32_t binding, const gfx::Image* image, const gfx::Sampler* sampler)
{ {
assert(pimpl->FRAMECOUNT == 0); assert(pimpl->FRAMECOUNT == 0);
@ -1146,13 +1146,13 @@ namespace engine {
} }
} }
gfx::UniformBuffer* GFXDevice::createUniformBuffer(uint64_t size, const void* initialData) gfx::UniformBuffer* GFXDevice::CreateUniformBuffer(uint64_t size, const void* initialData)
{ {
gfx::UniformBuffer* out = new gfx::UniformBuffer{}; gfx::UniformBuffer* out = new gfx::UniformBuffer{};
/* first make staging buffer */ /* first make staging buffer */
out->stagingBuffer.size = size; out->stagingBuffer.size = size;
out->stagingBuffer.type = gfx::BufferType::UNIFORM; out->stagingBuffer.type = gfx::BufferType::kUniform;
{ {
VkBufferCreateInfo stagingBufferInfo{}; VkBufferCreateInfo stagingBufferInfo{};
stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -1177,7 +1177,7 @@ namespace engine {
/* create the device-local set of buffers */ /* create the device-local set of buffers */
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) { for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
out->gpuBuffers[i].size = out->stagingBuffer.size; out->gpuBuffers[i].size = out->stagingBuffer.size;
out->gpuBuffers[i].type = gfx::BufferType::UNIFORM; out->gpuBuffers[i].type = gfx::BufferType::kUniform;
VkBufferCreateInfo gpuBufferInfo{}; VkBufferCreateInfo gpuBufferInfo{};
gpuBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; gpuBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -1200,7 +1200,7 @@ namespace engine {
} }
void GFXDevice::destroyUniformBuffer(const gfx::UniformBuffer* uniformBuffer) void GFXDevice::DestroyUniformBuffer(const gfx::UniformBuffer* uniformBuffer)
{ {
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) { for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
vmaDestroyBuffer(pimpl->allocator, uniformBuffer->gpuBuffers[i].buffer, uniformBuffer->gpuBuffers[i].allocation); vmaDestroyBuffer(pimpl->allocator, uniformBuffer->gpuBuffers[i].buffer, uniformBuffer->gpuBuffers[i].allocation);
@ -1211,7 +1211,7 @@ namespace engine {
delete uniformBuffer; delete uniformBuffer;
} }
void GFXDevice::writeUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data) void GFXDevice::WriteUniformBuffer(gfx::UniformBuffer* buffer, uint64_t offset, uint64_t size, const void* data)
{ {
assert(offset + size <= buffer->stagingBuffer.size); assert(offset + size <= buffer->stagingBuffer.size);
@ -1229,7 +1229,7 @@ namespace engine {
} }
gfx::Buffer* GFXDevice::createBuffer(gfx::BufferType type, uint64_t size, const void* data) gfx::Buffer* GFXDevice::CreateBuffer(gfx::BufferType type, uint64_t size, const void* data)
{ {
[[maybe_unused]] VkResult res; [[maybe_unused]] VkResult res;
@ -1287,14 +1287,14 @@ namespace engine {
} }
void GFXDevice::destroyBuffer(const gfx::Buffer* buffer) void GFXDevice::DestroyBuffer(const gfx::Buffer* buffer)
{ {
vmaDestroyBuffer(pimpl->allocator, buffer->buffer, buffer->allocation); vmaDestroyBuffer(pimpl->allocator, buffer->buffer, buffer->allocation);
delete buffer; delete buffer;
} }
// imageData must have pixel format R8G8B8A8_SRGB // imageData must have pixel format R8G8B8A8_SRGB
gfx::Image* GFXDevice::createImage(uint32_t w, uint32_t h, const void* imageData) gfx::Image* GFXDevice::CreateImage(uint32_t w, uint32_t h, const void* imageData)
{ {
assert(imageData != nullptr); assert(imageData != nullptr);
assert(pimpl->FRAMECOUNT == 0); assert(pimpl->FRAMECOUNT == 0);
@ -1541,14 +1541,14 @@ namespace engine {
return out; return out;
} }
void GFXDevice::destroyImage(const gfx::Image *image) void GFXDevice::DestroyImage(const gfx::Image *image)
{ {
vkDestroyImageView(pimpl->device.device, image->view, nullptr); vkDestroyImageView(pimpl->device.device, image->view, nullptr);
vmaDestroyImage(pimpl->allocator, image->image, image->allocation); vmaDestroyImage(pimpl->allocator, image->image, image->allocation);
delete image; delete image;
} }
const gfx::Sampler *GFXDevice::createSampler(const gfx::SamplerInfo& info) const gfx::Sampler *GFXDevice::CreateSampler(const gfx::SamplerInfo& info)
{ {
gfx::Sampler* out = new gfx::Sampler{}; gfx::Sampler* out = new gfx::Sampler{};
@ -1561,7 +1561,7 @@ namespace engine {
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.mipLodBias = 0.0f; samplerInfo.mipLodBias = 0.0f;
samplerInfo.anisotropyEnable = info.anisotropicFiltering ? VK_TRUE : VK_FALSE; samplerInfo.anisotropyEnable = info.anisotropic_filtering ? VK_TRUE : VK_FALSE;
samplerInfo.maxAnisotropy = pimpl->device.properties.limits.maxSamplerAnisotropy; samplerInfo.maxAnisotropy = pimpl->device.properties.limits.maxSamplerAnisotropy;
samplerInfo.minLod = 0.0f; samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = VK_LOD_CLAMP_NONE; samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
@ -1571,13 +1571,13 @@ namespace engine {
return out; return out;
} }
void GFXDevice::destroySampler(const gfx::Sampler *sampler) void GFXDevice::DestroySampler(const gfx::Sampler *sampler)
{ {
vkDestroySampler(pimpl->device.device, sampler->sampler, nullptr); vkDestroySampler(pimpl->device.device, sampler->sampler, nullptr);
delete sampler; delete sampler;
} }
void GFXDevice::logPerformanceInfo() void GFXDevice::LogPerformanceInfo()
{ {
VmaTotalStatistics pStats{}; VmaTotalStatistics pStats{};
vmaCalculateStatistics(pimpl->allocator, &pStats); vmaCalculateStatistics(pimpl->allocator, &pStats);
@ -1601,12 +1601,12 @@ namespace engine {
} }
} }
uint64_t GFXDevice::getFrameCount() uint64_t GFXDevice::GetFrameCount()
{ {
return pimpl->FRAMECOUNT; return pimpl->FRAMECOUNT;
} }
void GFXDevice::waitIdle() void GFXDevice::WaitIdle()
{ {
vkDeviceWaitIdle(pimpl->device.device); vkDeviceWaitIdle(pimpl->device.device);
} }

View File

@ -7,185 +7,31 @@
namespace engine { namespace engine {
InputManager::InputManager(const Window* win) : m_win(win) float InputManager::GetAxis(const std::string& axis_name) const
{ {
m_enabledDevices.fill(true); for (const AxisEntry& e : axis_entries_) {
} if (e.name == axis_name) {
if (enabled_devices_[static_cast<int>(e.device)]) {
InputManager::~InputManager() {} if (e.is_button_axis) {
return GetButtonAxis(e.device, e.high, e.low);
/* private methods */
float InputManager::getDeviceAxis(enum InputDevice device, int axis) const
{
switch (device) {
case InputDevice::MOUSE:
switch (static_cast<inputs::MouseAxis>(axis)) {
case inputs::MouseAxis::X:
return static_cast<float>(m_win->getMouseDX());
case inputs::MouseAxis::Y:
return static_cast<float>(m_win->getMouseDY());
case inputs::MouseAxis::X_SCR:
return m_win->getMouseScrollX();
case inputs::MouseAxis::Y_SCR:
return m_win->getMouseScrollY();
default: break;
}
break;
case InputDevice::KEYBOARD:
break;
case InputDevice::CONTROLLER:
break;
default: break;
}
throw std::runtime_error("Error getting device axis");
}
bool InputManager::getDeviceButton(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::MOUSE:
return m_win->getButton(static_cast<inputs::MouseButton>(button));
case InputDevice::KEYBOARD:
return m_win->getKey(static_cast<inputs::Key>(button));
case InputDevice::CONTROLLER:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
bool InputManager::getDeviceButtonDown(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::MOUSE:
return m_win->getButtonPress(static_cast<enum inputs::MouseButton>(button));
case InputDevice::KEYBOARD:
return m_win->getKeyPress(static_cast<enum inputs::Key>(button));
case InputDevice::CONTROLLER:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
bool InputManager::getDeviceButtonUp(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::MOUSE:
return m_win->getButtonRelease(static_cast<enum inputs::MouseButton>(button));
case InputDevice::KEYBOARD:
return m_win->getKeyRelease(static_cast<enum inputs::Key>(button));
case InputDevice::CONTROLLER:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
float InputManager::getButtonAxis(enum InputDevice device, int high, int low) const
{
float value = 0.0f;
if (getDeviceButton(device, high)) value += 1.0f;
if (low != 0) {
if (getDeviceButton(device, low)) value += -1.0f;
}
return value;
}
// public methods
void InputManager::addInputButton(const std::string& name, InputDevice device, int button)
{
m_buttonEntries.push_back({ name, device, button });
}
void InputManager::addInputAxis(const std::string& name, InputDevice device, int axis)
{
m_axisEntries.push_back({ name, device, axis, false, 0, 0 });
}
void InputManager::addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low)
{
m_axisEntries.push_back({ name, device, 0, true, high, low });
}
// OVERLOADS:
void InputManager::addInputButton(const std::string& name, inputs::MouseButton button)
{
addInputButton(name, InputDevice::MOUSE, static_cast<int>(button));
}
void InputManager::addInputAxis(const std::string& name, inputs::MouseAxis axis)
{
addInputAxis(name, InputDevice::MOUSE, static_cast<int>(axis));
}
void InputManager::addInputButtonAsAxis(const std::string& name, inputs::MouseButton high, inputs::MouseButton low)
{
addInputButtonAsAxis(name, InputDevice::MOUSE, static_cast<int>(high), static_cast<int>(low));
}
void InputManager::addInputButton(const std::string& name, inputs::Key button)
{
addInputButton(name, InputDevice::KEYBOARD, static_cast<int>(button));
}
void InputManager::addInputButtonAsAxis(const std::string& name, inputs::Key high, inputs::Key low)
{
addInputButtonAsAxis(name, InputDevice::KEYBOARD, static_cast<int>(high), static_cast<int>(low));
}
void InputManager::delInputButton(int index)
{
std::vector<struct ButtonEntry>::iterator it = m_buttonEntries.begin();
std::advance(it, index);
m_buttonEntries.erase(it);
}
void InputManager::delInputAxis(int index)
{
std::vector<struct AxisEntry>::iterator it = m_axisEntries.begin();
std::advance(it, index);
m_axisEntries.erase(it);
}
void InputManager::setDeviceActive(enum InputDevice device, bool active)
{
m_enabledDevices[static_cast<int>(device)] = active;
}
bool InputManager::getDeviceActive(enum InputDevice device) const
{
return m_enabledDevices[static_cast<int>(device)];
}
float InputManager::getAxis(const std::string& axisName) const
{
for (const AxisEntry& e : m_axisEntries) {
if (e.name == axisName) {
if (m_enabledDevices[static_cast<int>(e.device)]) {
if (e.isButtonAxis) {
return getButtonAxis(e.device, e.high, e.low);
} }
else { else {
return getDeviceAxis(e.device, e.axis); return GetDeviceAxis(e.device, e.axis);
} }
} }
} }
} }
return 0.0f; // instead of throwing an exception, just return nothing return 0.0f; // instead of throwing an exception, just return nothing
} }
bool InputManager::getButton(const std::string& buttonName) const bool InputManager::GetButton(const std::string& buttonName) const
{ {
bool isDown = false; bool isDown = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : button_entries_) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (enabled_devices_[static_cast<int>(e.device)]) {
if (getDeviceButton(e.device, e.button) == true) { if (GetDeviceButton(e.device, e.button) == true) {
isDown = true; isDown = true;
break; break;
} }
@ -193,15 +39,15 @@ namespace engine {
} }
} }
return isDown; return isDown;
} }
bool InputManager::getButtonPress(const std::string& buttonName) const bool InputManager::GetButtonPress(const std::string& buttonName) const
{ {
bool isPressed = false; bool isPressed = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : button_entries_) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (enabled_devices_[static_cast<int>(e.device)]) {
if (getDeviceButtonDown(e.device, e.button) == true) { if (getDeviceButtonDown(e.device, e.button) == true) {
isPressed = true; isPressed = true;
break; break;
@ -210,16 +56,16 @@ namespace engine {
} }
} }
return isPressed; return isPressed;
} }
bool InputManager::getButtonRelease(const std::string& buttonName) const bool InputManager::GetButtonRelease(const std::string& buttonName) const
{ {
bool isReleased = false; bool isReleased = false;
for (const ButtonEntry& e : m_buttonEntries) { for (const ButtonEntry& e : button_entries_) {
if (e.name == buttonName) { if (e.name == buttonName) {
if (m_enabledDevices[static_cast<int>(e.device)]) { if (enabled_devices_[static_cast<int>(e.device)]) {
if (getDeviceButtonUp(e.device, e.button) == true) { if (GetDeviceButtonUp(e.device, e.button) == true) {
isReleased = true; isReleased = true;
break; break;
} }
@ -227,6 +73,74 @@ namespace engine {
} }
} }
return isReleased; return isReleased;
}
float InputManager::GetDeviceAxis(enum InputDevice device, int axis) const
{
switch (device) {
case InputDevice::kMouse:
switch (static_cast<inputs::MouseAxis>(axis)) {
case inputs::MouseAxis::X:
return static_cast<float>(win_->getMouseDX());
case inputs::MouseAxis::Y:
return static_cast<float>(win_->getMouseDY());
case inputs::MouseAxis::X_SCR:
return win_->getMouseScrollX();
case inputs::MouseAxis::Y_SCR:
return win_->getMouseScrollY();
default: break;
} }
break;
case InputDevice::kKeyboard:
break;
case InputDevice::kController:
break;
default: break;
}
throw std::runtime_error("Error getting device axis");
}
bool InputManager::GetDeviceButton(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::kMouse:
return win_->getButton(static_cast<inputs::MouseButton>(button));
case InputDevice::kKeyboard:
return win_->getKey(static_cast<inputs::Key>(button));
case InputDevice::kController:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
bool InputManager::getDeviceButtonDown(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::kMouse:
return win_->getButtonPress(static_cast<enum inputs::MouseButton>(button));
case InputDevice::kKeyboard:
return win_->getKeyPress(static_cast<enum inputs::Key>(button));
case InputDevice::kController:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
bool InputManager::GetDeviceButtonUp(enum InputDevice device, int button) const
{
switch (device) {
case InputDevice::kMouse:
return win_->getButtonRelease(static_cast<enum inputs::MouseButton>(button));
case InputDevice::kKeyboard:
return win_->getKeyRelease(static_cast<enum inputs::Key>(button));
case InputDevice::kController:
break;
default: break;
}
throw std::runtime_error("Error getting device button");
}
} }

View File

@ -17,8 +17,8 @@ namespace engine::resources {
Mesh::~Mesh() Mesh::~Mesh()
{ {
m_gfx->destroyBuffer(m_ib); m_gfx->DestroyBuffer(m_ib);
m_gfx->destroyBuffer(m_vb); m_gfx->DestroyBuffer(m_vb);
} }
const gfx::Buffer* Mesh::getVB() const gfx::Buffer* Mesh::getVB()
@ -38,8 +38,8 @@ namespace engine::resources {
void Mesh::initMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices) void Mesh::initMesh(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices)
{ {
m_vb = m_gfx->createBuffer(gfx::BufferType::VERTEX, vertices.size() * sizeof(Vertex), vertices.data()); m_vb = m_gfx->CreateBuffer(gfx::BufferType::kVertex, vertices.size() * sizeof(Vertex), vertices.data());
m_ib = m_gfx->createBuffer(gfx::BufferType::INDEX, indices.size() * sizeof(uint32_t), indices.data()); m_ib = m_gfx->CreateBuffer(gfx::BufferType::kIndex, indices.size() * sizeof(uint32_t), indices.data());
m_count = (uint32_t)indices.size(); m_count = (uint32_t)indices.size();
LOG_INFO("Loaded mesh, vertices: {}, indices: {}", vertices.size(), indices.size()); LOG_INFO("Loaded mesh, vertices: {}, indices: {}", vertices.size(), indices.size());
} }

View File

@ -17,46 +17,46 @@ namespace engine::resources {
uint32_t stride = 0; uint32_t stride = 0;
gfx::VertexFormat vertFormat{}; gfx::VertexFormat vertFormat{};
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::FLOAT3, stride); vertFormat.attribute_descriptions.emplace_back(index++, gfx::VertexAttribFormat::kFloat3, stride);
stride += 3 * sizeof(float); stride += 3 * sizeof(float);
if (vertexParams.hasNormal) { if (vertexParams.hasNormal) {
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::FLOAT3, stride); vertFormat.attribute_descriptions.emplace_back(index++, gfx::VertexAttribFormat::kFloat3, stride);
stride += 3 * sizeof(float); stride += 3 * sizeof(float);
} }
if (vertexParams.hasTangent) { if (vertexParams.hasTangent) {
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::FLOAT4, stride); vertFormat.attribute_descriptions.emplace_back(index++, gfx::VertexAttribFormat::kFloat4, stride);
stride += 4 * sizeof(float); stride += 4 * sizeof(float);
} }
if (vertexParams.hasColor) { if (vertexParams.hasColor) {
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::FLOAT4, stride); vertFormat.attribute_descriptions.emplace_back(index++, gfx::VertexAttribFormat::kFloat4, stride);
stride += 4 * sizeof(float); stride += 4 * sizeof(float);
} }
if (vertexParams.hasUV0) { if (vertexParams.hasUV0) {
vertFormat.attributeDescriptions.emplace_back(index++, gfx::VertexAttribFormat::FLOAT2, stride); vertFormat.attribute_descriptions.emplace_back(index++, gfx::VertexAttribFormat::kFloat2, stride);
stride += 2 * sizeof(float); stride += 2 * sizeof(float);
} }
vertFormat.stride = stride; vertFormat.stride = stride;
gfx::PipelineInfo info{}; gfx::PipelineInfo info{};
info.vertShaderPath = vertPath; info.vert_shader_path = vertPath;
info.fragShaderPath = fragPath; info.frag_shader_path = fragPath;
info.vertexFormat = vertFormat; info.vertex_format = vertFormat;
info.alphaBlending = alphaBlending; info.alpha_blending = alphaBlending;
info.backfaceCulling = cullBackFace; info.backface_culling = cullBackFace;
info.descriptorSetLayouts.push_back(renderData->globalSetLayout); info.descriptor_set_layouts.push_back(renderData->global_set_layout);
info.descriptorSetLayouts.push_back(renderData->frameSetLayout); info.descriptor_set_layouts.push_back(renderData->frame_set_layout);
info.descriptorSetLayouts.push_back(renderData->materialSetLayout); info.descriptor_set_layouts.push_back(renderData->material_set_layout);
m_pipeline = m_gfx->createPipeline(info); m_pipeline = m_gfx->CreatePipeline(info);
LOG_INFO("Loaded shader: {}, vertex attribs: {}", vertPath, vertFormat.attributeDescriptions.size()); LOG_INFO("Loaded shader: {}, vertex attribs: {}", vertPath, vertFormat.attribute_descriptions.size());
} }
Shader::~Shader() Shader::~Shader()
{ {
m_gfx->destroyPipeline(m_pipeline); m_gfx->DestroyPipeline(m_pipeline);
} }
const gfx::Pipeline* Shader::getPipeline() const gfx::Pipeline* Shader::getPipeline()

View File

@ -17,37 +17,37 @@ Texture::Texture(RenderData* renderData, const std::string& path, Filtering filt
gfx::SamplerInfo samplerInfo{}; gfx::SamplerInfo samplerInfo{};
samplerInfo.magnify = gfx::Filter::LINEAR; samplerInfo.magnify = gfx::Filter::kLinear;
switch (filtering) { switch (filtering) {
case Filtering::OFF: case Filtering::OFF:
samplerInfo.minify = gfx::Filter::NEAREST; samplerInfo.minify = gfx::Filter::kNearest;
samplerInfo.mipmap = gfx::Filter::NEAREST; samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.anisotropicFiltering = false; samplerInfo.anisotropic_filtering = false;
break; break;
case Filtering::BILINEAR: case Filtering::BILINEAR:
samplerInfo.minify = gfx::Filter::LINEAR; samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::NEAREST; samplerInfo.mipmap = gfx::Filter::kNearest;
samplerInfo.anisotropicFiltering = false; samplerInfo.anisotropic_filtering = false;
break; break;
case Filtering::TRILINEAR: case Filtering::TRILINEAR:
samplerInfo.minify = gfx::Filter::LINEAR; samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::LINEAR; samplerInfo.mipmap = gfx::Filter::kLinear;
samplerInfo.anisotropicFiltering = false; samplerInfo.anisotropic_filtering = false;
break; break;
case Filtering::ANISOTROPIC: case Filtering::ANISOTROPIC:
samplerInfo.minify = gfx::Filter::LINEAR; samplerInfo.minify = gfx::Filter::kLinear;
samplerInfo.mipmap = gfx::Filter::LINEAR; samplerInfo.mipmap = gfx::Filter::kLinear;
samplerInfo.anisotropicFiltering = true; samplerInfo.anisotropic_filtering = true;
} }
if (renderData->samplers.contains(samplerInfo) == false) { if (renderData->samplers.contains(samplerInfo) == false) {
renderData->samplers.insert(std::make_pair(samplerInfo, m_gfxDevice->createSampler(samplerInfo))); renderData->samplers.insert(std::make_pair(samplerInfo, m_gfxDevice->CreateSampler(samplerInfo)));
} }
m_image = m_gfxDevice->createImage(width, height, texbuf->data()); m_image = m_gfxDevice->CreateImage(width, height, texbuf->data());
m_descriptorSet = m_gfxDevice->allocateDescriptorSet(renderData->materialSetLayout); m_descriptorSet = m_gfxDevice->AllocateDescriptorSet(renderData->material_set_layout);
m_gfxDevice->updateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, renderData->samplers.at(samplerInfo)); m_gfxDevice->UpdateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, renderData->samplers.at(samplerInfo));
LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height); LOG_INFO("Loaded texture: {}, width: {} height: {}", path, width, height);
@ -55,7 +55,7 @@ Texture::Texture(RenderData* renderData, const std::string& path, Filtering filt
Texture::~Texture() Texture::~Texture()
{ {
m_gfxDevice->destroyImage(m_image); m_gfxDevice->DestroyImage(m_image);
} }
} }

View File

@ -10,10 +10,10 @@
namespace engine { namespace engine {
Scene::Scene(Application* app) Scene::Scene(Application* app)
: m_app(app) : app_(app)
{ {
// event system // event system
m_eventSystem = std::make_unique<EventSystem>(); event_system_ = std::make_unique<EventSystem>();
// ecs configuration: // ecs configuration:
@ -22,22 +22,22 @@ namespace engine {
registerComponent<ColliderComponent>(); registerComponent<ColliderComponent>();
// Order here matters: // Order here matters:
registerSystem<TransformSystem>(); RegisterSystem<TransformSystem>();
registerSystem<PhysicsSystem>(); RegisterSystem<PhysicsSystem>();
registerSystem<RenderSystem>(); RegisterSystem<RenderSystem>();
} }
Scene::~Scene() Scene::~Scene()
{ {
} }
uint32_t Scene::createEntity(const std::string& tag, uint32_t parent) uint32_t Scene::CreateEntity(const std::string& tag, uint32_t parent)
{ {
uint32_t id = m_nextEntityID++; uint32_t id = next_entity_id_++;
m_signatures.emplace(id, std::bitset<MAX_COMPONENTS>{}); signatures_.emplace(id, std::bitset<kMaxComponents>{});
auto t = addComponent<TransformComponent>(id); auto t = AddComponent<TransformComponent>(id);
t->position = {0.0f, 0.0f, 0.0f}; t->position = {0.0f, 0.0f, 0.0f};
t->rotation = {}; t->rotation = {};
@ -51,21 +51,21 @@ namespace engine {
uint32_t Scene::getEntity(const std::string& tag, uint32_t parent) uint32_t Scene::getEntity(const std::string& tag, uint32_t parent)
{ {
return getSystem<TransformSystem>()->getChildEntity(parent, tag); return GetSystem<TransformSystem>()->getChildEntity(parent, tag);
} }
size_t Scene::getComponentSignaturePosition(size_t hash) size_t Scene::GetComponentSignaturePosition(size_t hash)
{ {
return m_componentSignaturePositions.at(hash); return component_signature_positions_.at(hash);
} }
void Scene::update(float ts) void Scene::Update(float ts)
{ {
for (auto& [name, system] : m_systems) { for (auto& [name, system] : systems_) {
system->onUpdate(ts); system->OnUpdate(ts);
} }
m_eventSystem->dispatchEvents(); // clears event queue event_system_->DespatchEvents(); // clears event queue
} }
} }

View File

@ -8,25 +8,25 @@
namespace engine { namespace engine {
SceneManager::SceneManager(Application* app) SceneManager::SceneManager(Application* app)
: m_app(app) : app_(app)
{ {
} }
SceneManager::~SceneManager() {} SceneManager::~SceneManager() {}
Scene* SceneManager::createEmptyScene() Scene* SceneManager::CreateEmptyScene()
{ {
auto scene = std::make_unique<Scene>(m_app); auto scene = std::make_unique<Scene>(app_);
m_scenes.emplace_back(std::move(scene)); scenes_.emplace_back(std::move(scene));
m_activeSceneIndex = (int)m_scenes.size() - 1; active_scene_index_ = (int)scenes_.size() - 1;
return m_scenes.back().get(); return scenes_.back().get();
} }
void SceneManager::updateActiveScene(float ts) void SceneManager::UpdateActiveScene(float ts)
{ {
if (m_activeSceneIndex >= 0) [[likely]] { if (active_scene_index_ >= 0) [[likely]] {
assert((size_t)m_activeSceneIndex < m_scenes.size()); assert((size_t)active_scene_index_ < scenes_.size());
m_scenes[m_activeSceneIndex]->update(ts); scenes_[active_scene_index_]->Update(ts);
} }
} }

View File

@ -68,13 +68,13 @@ namespace engine {
PhysicsSystem::PhysicsSystem(Scene* scene) PhysicsSystem::PhysicsSystem(Scene* scene)
: System(scene, { typeid(TransformComponent).hash_code(), typeid(ColliderComponent).hash_code() }) : System(scene, { typeid(TransformComponent).hash_code(), typeid(ColliderComponent).hash_code() })
{ {
m_scene->events()->registerEventType<CollisionEvent>(); scene_->event_system()->RegisterEventType<CollisionEvent>();
} }
void PhysicsSystem::onComponentInsert(uint32_t entity) void PhysicsSystem::OnComponentInsert(uint32_t entity)
{ {
(void)entity; (void)entity;
const size_t size = m_entities.size(); const size_t size = entities_.size();
m_staticAABBs.reserve(size); m_staticAABBs.reserve(size);
m_dynamicAABBs.reserve(size); m_dynamicAABBs.reserve(size);
m_possibleCollisions.reserve(size); m_possibleCollisions.reserve(size);
@ -82,7 +82,7 @@ namespace engine {
LOG_TRACE("added entity {} to collider system", entity); LOG_TRACE("added entity {} to collider system", entity);
} }
void PhysicsSystem::onUpdate(float ts) void PhysicsSystem::OnUpdate(float ts)
{ {
(void)ts; (void)ts;
@ -91,9 +91,9 @@ namespace engine {
m_possibleCollisions.clear(); m_possibleCollisions.clear();
m_collisionInfos.clear(); m_collisionInfos.clear();
for (uint32_t entity : m_entities) { for (uint32_t entity : entities_) {
const auto t = m_scene->getComponent<TransformComponent>(entity); const auto t = scene_->GetComponent<TransformComponent>(entity);
const auto c = m_scene->getComponent<ColliderComponent>(entity); const auto c = scene_->GetComponent<ColliderComponent>(entity);
const glm::vec3 globalPosition = t->worldMatrix[3]; const glm::vec3 globalPosition = t->worldMatrix[3];
const AABB localBoundingBox = c->aabb; const AABB localBoundingBox = c->aabb;
@ -157,7 +157,7 @@ namespace engine {
} }
for (const auto& [entity, info] : m_collisionInfos) { for (const auto& [entity, info] : m_collisionInfos) {
m_scene->events()->queueEvent<CollisionEvent>(EventSubscriberKind::ENTITY, entity, info); scene_->event_system()->QueueEvent<CollisionEvent>(EventSubscriberKind::kEntity, entity, info);
} }
} }

View File

@ -16,7 +16,7 @@ namespace engine {
RenderSystem::RenderSystem(Scene* scene) RenderSystem::RenderSystem(Scene* scene)
: System(scene, { typeid(TransformComponent).hash_code(), typeid(RenderableComponent).hash_code() }), : System(scene, { typeid(TransformComponent).hash_code(), typeid(RenderableComponent).hash_code() }),
m_gfx(m_scene->app()->gfx()) m_gfx(scene_->app()->gfxdev())
{ {
} }
@ -24,23 +24,23 @@ namespace engine {
{ {
} }
void RenderSystem::onUpdate(float ts) void RenderSystem::OnUpdate(float ts)
{ {
(void)ts; (void)ts;
RenderData& renderData = m_scene->app()->renderData; RenderData& renderData = scene_->app()->render_data_;
/* camera stuff */ /* camera stuff */
const auto cameraTransform = m_scene->getComponent<TransformComponent>(m_camera.camEntity); const auto cameraTransform = scene_->GetComponent<TransformComponent>(m_camera.camEntity);
// do not render if camera is not set // do not render if camera is not set
if (cameraTransform == nullptr) return; if (cameraTransform == nullptr) return;
glm::mat4 viewMatrix = glm::inverse(cameraTransform->worldMatrix); glm::mat4 viewMatrix = glm::inverse(cameraTransform->worldMatrix);
if (m_scene->app()->window()->getWindowResized()) { if (scene_->app()->window()->getWindowResized()) {
uint32_t w, h; uint32_t w, h;
m_gfx->getViewportSize(&w, &h); m_gfx->GetViewportSize(&w, &h);
m_viewportAspectRatio = (float)w / (float)h; m_viewportAspectRatio = (float)w / (float)h;
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees); const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar); const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
@ -48,13 +48,13 @@ namespace engine {
RenderData::GlobalSetUniformBuffer globalSetUniformBuffer{ RenderData::GlobalSetUniformBuffer globalSetUniformBuffer{
.proj = projMatrix .proj = projMatrix
}; };
m_gfx->writeUniformBuffer(renderData.globalSetUniformBuffer, 0, sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBuffer); m_gfx->WriteUniformBuffer(renderData.global_set_uniform_buffer, 0, sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBuffer);
} }
RenderData::FrameSetUniformBuffer frameSetUniformBuffer{ RenderData::FrameSetUniformBuffer frameSetUniformBuffer{
.view = viewMatrix .view = viewMatrix
}; };
m_gfx->writeUniformBuffer(renderData.frameSetUniformBuffer, 0, sizeof(RenderData::FrameSetUniformBuffer), &frameSetUniformBuffer); m_gfx->WriteUniformBuffer(renderData.frame_set_uniform_buffer, 0, sizeof(RenderData::FrameSetUniformBuffer), &frameSetUniformBuffer);
/* render all renderable entities */ /* render all renderable entities */
@ -71,16 +71,16 @@ namespace engine {
}; };
std::unordered_map <const gfx::Pipeline*, std::vector<DrawCallData>> pipelineDrawCalls{}; std::unordered_map <const gfx::Pipeline*, std::vector<DrawCallData>> pipelineDrawCalls{};
for (uint32_t entity : m_entities) { for (uint32_t entity : entities_) {
auto r = m_scene->getComponent<RenderableComponent>(entity); auto r = scene_->GetComponent<RenderableComponent>(entity);
assert(r != nullptr); assert(r != nullptr);
assert(r->material != nullptr); assert(r->material != nullptr);
assert(r->material->m_texture != nullptr); assert(r->material->m_texture != nullptr);
assert(r->mesh != nullptr); assert(r->mesh != nullptr);
if (r->shown == false) continue; if (r->shown == false) continue;
auto t = m_scene->getComponent<TransformComponent>(entity); auto t = scene_->GetComponent<TransformComponent>(entity);
assert(t != nullptr); assert(t != nullptr);
const gfx::Pipeline* pipeline = r->material->getShader()->getPipeline(); const gfx::Pipeline* pipeline = r->material->getShader()->getPipeline();
@ -96,26 +96,26 @@ namespace engine {
} }
/* begin rendering */ /* begin rendering */
renderData.drawBuffer = m_gfx->beginRender(); renderData.draw_buffer = m_gfx->BeginRender();
/* these descriptor set bindings should persist across pipeline changes */ /* these descriptor set bindings should persist across pipeline changes */
const gfx::Pipeline* firstPipeline = pipelineDrawCalls.begin()->first; const gfx::Pipeline* firstPipeline = pipelineDrawCalls.begin()->first;
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.globalSet, 0); m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, firstPipeline, renderData.global_set, 0);
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.frameSet, 1); m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, firstPipeline, renderData.frame_set, 1);
for (const auto& [pipeline, drawCalls] : pipelineDrawCalls) { for (const auto& [pipeline, drawCalls] : pipelineDrawCalls) {
m_gfx->cmdBindPipeline(renderData.drawBuffer, pipeline); m_gfx->CmdBindPipeline(renderData.draw_buffer, pipeline);
for (const auto& drawCall : drawCalls) { for (const auto& drawCall : drawCalls) {
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, pipeline, drawCall.materialSet, 2); m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, pipeline, drawCall.materialSet, 2);
m_gfx->cmdPushConstants(renderData.drawBuffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts); m_gfx->CmdPushConstants(renderData.draw_buffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts);
m_gfx->cmdBindVertexBuffer(renderData.drawBuffer, 0, drawCall.vb); m_gfx->CmdBindVertexBuffer(renderData.draw_buffer, 0, drawCall.vb);
m_gfx->cmdBindIndexBuffer(renderData.drawBuffer, drawCall.ib); m_gfx->CmdBindIndexBuffer(renderData.draw_buffer, drawCall.ib);
m_gfx->cmdDrawIndexed(renderData.drawBuffer, drawCall.indexCount, 1, 0, 0, 0); m_gfx->CmdDrawIndexed(renderData.draw_buffer, drawCall.indexCount, 1, 0, 0, 0);
} }
} }
/* draw */ /* draw */
m_gfx->finishRender(renderData.drawBuffer); m_gfx->FinishRender(renderData.draw_buffer);
} }

View File

@ -1,5 +1,7 @@
#include "systems/render2d.hpp" #include "systems/render2d.hpp"
#include <typeinfo>
#include "components/transform.hpp" #include "components/transform.hpp"
namespace engine { namespace engine {
@ -13,7 +15,7 @@ namespace engine {
{ {
} }
void Render2DSystem::onUpdate(float ts) void Render2DSystem::OnUpdate(float ts)
{ {
(void)ts; (void)ts;
} }

View File

@ -12,13 +12,13 @@ namespace engine {
{ {
} }
void TransformSystem::onUpdate(float ts) void TransformSystem::OnUpdate(float ts)
{ {
(void)ts; (void)ts;
for (uint32_t entity : m_entities) { for (uint32_t entity : entities_) {
auto t = m_scene->getComponent<TransformComponent>(entity); auto t = scene_->GetComponent<TransformComponent>(entity);
glm::mat4 transform; glm::mat4 transform;
@ -30,7 +30,7 @@ namespace engine {
transform = glm::scale(transform, t->scale); transform = glm::scale(transform, t->scale);
if (t->parent != 0) { if (t->parent != 0) {
transform = m_scene->getComponent<TransformComponent>(t->parent)->worldMatrix * transform; transform = scene_->GetComponent<TransformComponent>(t->parent)->worldMatrix * transform;
} }
t->worldMatrix = transform; t->worldMatrix = transform;
@ -39,8 +39,8 @@ namespace engine {
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 : m_entities) { for (uint32_t entity : entities_) {
auto t = m_scene->getComponent<TransformComponent>(entity); auto t = scene_->GetComponent<TransformComponent>(entity);
if (t->parent == parent) { if (t->parent == parent) {
if (t->tag == tag) { if (t->tag == tag) {
return entity; return entity;

View File

@ -12,7 +12,7 @@ namespace engine {
} }
void UISystem::onUpdate(float ts) void UISystem::OnUpdate(float ts)
{ {
(void)ts; (void)ts;

View File

@ -67,21 +67,21 @@ namespace engine::util {
glm::quat rotation = glm::quat_cast(transform); glm::quat rotation = glm::quat_cast(transform);
// update position, scale, rotation // update position, scale, rotation
auto parentTransform = scene->getComponent<TransformComponent>(parentObj); auto parentTransform = scene->GetComponent<TransformComponent>(parentObj);
parentTransform->position = position; parentTransform->position = position;
parentTransform->scale = scale; parentTransform->scale = scale;
parentTransform->rotation = rotation; parentTransform->rotation = rotation;
for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) { for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) {
// create child node for each mesh // create child node for each mesh
auto child = scene->createEntity("_mesh" + std::to_string(i), parentObj); auto child = scene->CreateEntity("_mesh" + std::to_string(i), parentObj);
auto childRenderer = scene->addComponent<RenderableComponent>(child); auto childRenderer = scene->AddComponent<RenderableComponent>(child);
childRenderer->mesh = meshes[parentNode->mMeshes[i]]; childRenderer->mesh = meshes[parentNode->mMeshes[i]];
childRenderer->material = std::make_shared<resources::Material>(scene->app()->getResource<resources::Shader>("builtin.standard")); childRenderer->material = std::make_shared<resources::Material>(scene->app()->GetResource<resources::Shader>("builtin.standard"));
if (textures.contains(meshTextureIndices[parentNode->mMeshes[i]])) { if (textures.contains(meshTextureIndices[parentNode->mMeshes[i]])) {
childRenderer->material->m_texture = textures.at(meshTextureIndices[parentNode->mMeshes[i]]); childRenderer->material->m_texture = textures.at(meshTextureIndices[parentNode->mMeshes[i]]);
} else { } else {
childRenderer->material->m_texture = scene->app()->getResource<resources::Texture>("builtin.white"); childRenderer->material->m_texture = scene->app()->GetResource<resources::Texture>("builtin.white");
} }
} }
@ -92,7 +92,7 @@ namespace engine::util {
meshTextureIndices, meshTextureIndices,
parentNode->mChildren[i], parentNode->mChildren[i],
scene, scene,
scene->createEntity("child" + std::to_string(i), parentObj) scene->CreateEntity("child" + std::to_string(i), parentObj)
); );
} }
} }
@ -182,10 +182,10 @@ 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()->renderData, absPath.string(), &parent->app()->render_data_, absPath.string(),
resources::Texture::Filtering::TRILINEAR); resources::Texture::Filtering::TRILINEAR);
} 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,10 +223,10 @@ 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()->gfx(), vertices, indices)); meshes.push_back(std::make_shared<resources::Mesh>(parent->app()->gfxdev(), vertices, indices));
} }
uint32_t obj = parent->createEntity(scene->GetShortFilename(path.c_str())); uint32_t obj = parent->CreateEntity(scene->GetShortFilename(path.c_str()));
buildGraph(textures, meshes, meshMaterialIndices, scene->mRootNode, parent, obj); buildGraph(textures, meshes, meshMaterialIndices, scene->mRootNode, parent, obj);

View File

@ -21,14 +21,14 @@ CameraControllerSystem::CameraControllerSystem(engine::Scene* scene)
{ {
} }
void CameraControllerSystem::onUpdate(float ts) void CameraControllerSystem::OnUpdate(float ts)
{ {
if (t == nullptr || c == nullptr || col == nullptr) { if (t == nullptr || c == nullptr || col == nullptr) {
for (uint32_t entity : m_entities) { for (uint32_t entity : entities_) {
t = m_scene->getComponent<engine::TransformComponent>(entity); t = scene_->GetComponent<engine::TransformComponent>(entity);
col = m_scene->getComponent<engine::ColliderComponent>(entity); col = scene_->GetComponent<engine::ColliderComponent>(entity);
c = m_scene->getComponent<CameraControllerComponent>(entity); c = scene_->GetComponent<CameraControllerComponent>(entity);
break; break;
} }
if (t == nullptr) return; if (t == nullptr) return;
@ -78,32 +78,32 @@ void CameraControllerSystem::onUpdate(float ts)
// jumping // jumping
constexpr float JUMPVEL = (float)2.82231110971133017648; //std::sqrt(2 * G * JUMPHEIGHT); constexpr float JUMPVEL = (float)2.82231110971133017648; //std::sqrt(2 * G * JUMPHEIGHT);
if (m_scene->app()->inputManager()->getButton("jump") && c->isGrounded == true) { if (scene_->app()->input_manager()->GetButton("jump") && c->isGrounded == true) {
c->dy = JUMPVEL; c->dy = JUMPVEL;
} }
if (m_scene->app()->window()->getButton(engine::inputs::MouseButton::M_LEFT)) { if (scene_->app()->window()->getButton(engine::inputs::MouseButton::M_LEFT)) {
c->dy += dt * c->thrust; c->dy += dt * c->thrust;
} }
// in metres per second // in metres per second
float SPEED = c->walk_speed; float SPEED = c->walk_speed;
if (m_scene->app()->inputManager()->getButton("sprint")) SPEED *= 10.0f; if (scene_->app()->input_manager()->GetButton("sprint")) SPEED *= 10.0f;
float dx = m_scene->app()->inputManager()->getAxis("movex"); float dx = scene_->app()->input_manager()->GetAxis("movex");
float dz = (-m_scene->app()->inputManager()->getAxis("movey")); float dz = (-scene_->app()->input_manager()->GetAxis("movey"));
// calculate new pitch and yaw // calculate new pitch and yaw
constexpr float MAX_PITCH = glm::half_pi<float>(); constexpr float MAX_PITCH = glm::half_pi<float>();
constexpr float MIN_PITCH = -MAX_PITCH; constexpr float MIN_PITCH = -MAX_PITCH;
float dPitch = m_scene->app()->inputManager()->getAxis("looky") * -1.0f * c->m_cameraSensitivity; float dPitch = scene_->app()->input_manager()->GetAxis("looky") * -1.0f * c->m_cameraSensitivity;
c->m_pitch += dPitch; c->m_pitch += dPitch;
if (c->m_pitch <= MIN_PITCH || c->m_pitch >= MAX_PITCH) { if (c->m_pitch <= MIN_PITCH || c->m_pitch >= MAX_PITCH) {
c->m_pitch -= dPitch; c->m_pitch -= dPitch;
} }
c->m_yaw += m_scene->app()->inputManager()->getAxis("lookx") * -1.0f * c->m_cameraSensitivity; c->m_yaw += scene_->app()->input_manager()->GetAxis("lookx") * -1.0f * c->m_cameraSensitivity;
// update position relative to camera direction in xz plane // update position relative to camera direction in xz plane
const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw); const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw);
@ -148,27 +148,27 @@ void CameraControllerSystem::onUpdate(float ts)
/* user interface inputs */ /* user interface inputs */
if (m_scene->app()->window()->getKeyPress(engine::inputs::Key::K_P)) { if (scene_->app()->window()->getKeyPress(engine::inputs::Key::K_P)) {
std::string pos_string{ std::string pos_string{
"x: " + std::to_string(t->position.x) + "x: " + std::to_string(t->position.x) +
" y: " + std::to_string(t->position.y) + " y: " + std::to_string(t->position.y) +
" z: " + std::to_string(t->position.z) " z: " + std::to_string(t->position.z)
}; };
//m_scene->app()->window()->infoBox("POSITION", pos_string); //scene_->app()->window()->infoBox("POSITION", pos_string);
LOG_INFO("position: " + pos_string); LOG_INFO("position: " + pos_string);
} }
if (m_scene->app()->window()->getKeyPress(engine::inputs::Key::K_R)) { if (scene_->app()->window()->getKeyPress(engine::inputs::Key::K_R)) {
t->position = { 0.0f, 5.0f, 0.0f }; t->position = { 0.0f, 5.0f, 0.0f };
c->dy = 0.0f; c->dy = 0.0f;
} }
if (m_scene->app()->inputManager()->getButtonPress("fullscreen")) { if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) {
m_scene->app()->window()->toggleFullscreen(); scene_->app()->window()->toggleFullscreen();
} }
if (m_scene->app()->inputManager()->getButtonPress("exit")) { if (scene_->app()->input_manager()->GetButtonPress("exit")) {
m_scene->app()->window()->setCloseFlag(); scene_->app()->window()->setCloseFlag();
} }
c->justCollided = false; c->justCollided = false;
@ -176,7 +176,7 @@ void CameraControllerSystem::onUpdate(float ts)
} }
// called once per frame // called once per frame
void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info) void CameraControllerSystem::OnEvent(engine::PhysicsSystem::CollisionEvent info)
{ {
c->justCollided = info.isCollisionEnter; c->justCollided = info.isCollisionEnter;
c->lastCollisionNormal = info.normal; c->lastCollisionNormal = info.normal;

View File

@ -30,10 +30,10 @@ public:
CameraControllerSystem(engine::Scene* scene); CameraControllerSystem(engine::Scene* scene);
// engine::System overrides // engine::System overrides
void onUpdate(float ts) override; void OnUpdate(float ts) override;
// engine::EventHandler overrides // engine::EventHandler overrides
void onEvent(engine::PhysicsSystem::CollisionEvent info) override; void OnEvent(engine::PhysicsSystem::CollisionEvent info) override;
engine::TransformComponent* t = nullptr; engine::TransformComponent* t = nullptr;
engine::ColliderComponent* col = nullptr; engine::ColliderComponent* col = nullptr;

View File

@ -26,19 +26,19 @@
static void configureInputs(engine::InputManager* inputManager) static void configureInputs(engine::InputManager* inputManager)
{ {
// user interface mappings // user interface mappings
inputManager->addInputButton("fullscreen", engine::inputs::Key::K_F11); inputManager->AddInputButton("fullscreen", engine::inputs::Key::K_F11);
inputManager->addInputButton("exit", engine::inputs::Key::K_ESCAPE); inputManager->AddInputButton("exit", engine::inputs::Key::K_ESCAPE);
// game buttons // game buttons
inputManager->addInputButton("fire", engine::inputs::MouseButton::M_LEFT); inputManager->AddInputButton("fire", engine::inputs::MouseButton::M_LEFT);
inputManager->addInputButton("aim", engine::inputs::MouseButton::M_RIGHT); inputManager->AddInputButton("aim", engine::inputs::MouseButton::M_RIGHT);
inputManager->addInputButton("jump", engine::inputs::Key::K_SPACE); inputManager->AddInputButton("jump", engine::inputs::Key::K_SPACE);
inputManager->addInputButton("sprint", engine::inputs::Key::K_LSHIFT); inputManager->AddInputButton("sprint", engine::inputs::Key::K_LSHIFT);
// game movement // game movement
inputManager->addInputButtonAsAxis("movex", engine::inputs::Key::K_D, engine::inputs::Key::K_A); inputManager->AddInputButtonAsAxis("movex", engine::inputs::Key::K_D, engine::inputs::Key::K_A);
inputManager->addInputButtonAsAxis("movey", engine::inputs::Key::K_W, engine::inputs::Key::K_S); inputManager->AddInputButtonAsAxis("movey", engine::inputs::Key::K_W, engine::inputs::Key::K_S);
// looking around // looking around
inputManager->addInputAxis("lookx", engine::inputs::MouseAxis::X); inputManager->AddInputAxis("lookx", engine::inputs::MouseAxis::X);
inputManager->addInputAxis("looky", engine::inputs::MouseAxis::Y); inputManager->AddInputAxis("looky", engine::inputs::MouseAxis::Y);
} }
void playGame(GameSettings settings) void playGame(GameSettings settings)
@ -47,92 +47,92 @@ void playGame(GameSettings settings)
LOG_INFO("Graphics Validation: {}", settings.enableValidation ? "ON" : "OFF"); LOG_INFO("Graphics Validation: {}", settings.enableValidation ? "ON" : "OFF");
engine::gfx::GraphicsSettings graphicsSettings{}; engine::gfx::GraphicsSettings graphicsSettings{};
graphicsSettings.enableValidation = settings.enableValidation; graphicsSettings.enable_validation = settings.enableValidation;
graphicsSettings.vsync = true; graphicsSettings.vsync = true;
graphicsSettings.waitForPresent = false; graphicsSettings.wait_for_present = false;
graphicsSettings.msaaLevel = engine::gfx::MSAALevel::MSAA_OFF; graphicsSettings.msaa_level = engine::gfx::MSAALevel::kOff;
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings); engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings);
app.setFrameLimiter(settings.enableFrameLimiter); app.SetFrameLimiter(settings.enableFrameLimiter);
// configure window // configure window
app.window()->setRelativeMouseMode(true); app.window()->setRelativeMouseMode(true);
configureInputs(app.inputManager()); configureInputs(app.input_manager());
auto myScene = app.sceneManager()->createEmptyScene(); auto myScene = app.scene_manager()->CreateEmptyScene();
/* create camera */ /* create camera */
{ {
myScene->registerComponent<CameraControllerComponent>(); myScene->registerComponent<CameraControllerComponent>();
myScene->registerSystem<CameraControllerSystem>(); myScene->RegisterSystem<CameraControllerSystem>();
auto camera = myScene->createEntity("camera"); auto camera = myScene->CreateEntity("camera");
myScene->getComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f }; myScene->GetComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f };
auto cameraCollider = myScene->addComponent<engine::ColliderComponent>(camera); auto cameraCollider = myScene->AddComponent<engine::ColliderComponent>(camera);
cameraCollider->isStatic = false; cameraCollider->isStatic = false;
cameraCollider->isTrigger = true; cameraCollider->isTrigger = true;
cameraCollider->aabb = { { -0.2f, -1.5f, -0.2f }, { 0.2f, 0.2f, 0.2f} }; // Origin is at eye level cameraCollider->aabb = { { -0.2f, -1.5f, -0.2f }, { 0.2f, 0.2f, 0.2f} }; // Origin is at eye level
myScene->addComponent<CameraControllerComponent>(camera); myScene->AddComponent<CameraControllerComponent>(camera);
myScene->events()->subscribeToEventType<engine::PhysicsSystem::CollisionEvent>( myScene->event_system()->SubscribeToEventType<engine::PhysicsSystem::CollisionEvent>(
engine::EventSubscriberKind::ENTITY, camera, myScene->getSystem<CameraControllerSystem>() engine::EventSubscriberKind::kEntity, camera, myScene->GetSystem<CameraControllerSystem>()
); );
auto renderSystem = myScene->getSystem<engine::RenderSystem>(); auto renderSystem = myScene->GetSystem<engine::RenderSystem>();
renderSystem->setCameraEntity(camera); renderSystem->setCameraEntity(camera);
} }
/* shared resources */ /* shared resources */
auto grassTexture = std::make_shared<engine::resources::Texture>( auto grassTexture = std::make_shared<engine::resources::Texture>(
&app.renderData, &app.render_data_,
app.getResourcePath("textures/grass.jpg"), app.GetResourcePath("textures/grass.jpg"),
engine::resources::Texture::Filtering::ANISOTROPIC engine::resources::Texture::Filtering::ANISOTROPIC
); );
auto spaceTexture = std::make_shared<engine::resources::Texture>( auto spaceTexture = std::make_shared<engine::resources::Texture>(
&app.renderData, &app.render_data_,
app.getResourcePath("textures/space2.png"), app.GetResourcePath("textures/space2.png"),
engine::resources::Texture::Filtering::ANISOTROPIC engine::resources::Texture::Filtering::ANISOTROPIC
); );
/* cube */ /* cube */
{ {
uint32_t cube = myScene->createEntity("cube"); uint32_t cube = myScene->CreateEntity("cube");
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f }; myScene->GetComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f };
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube); auto cubeRenderable = myScene->AddComponent<engine::RenderableComponent>(cube);
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard")); cubeRenderable->material = std::make_shared<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.standard"));
cubeRenderable->material->m_texture = app.getResource<engine::resources::Texture>("builtin.white"); cubeRenderable->material->m_texture = app.GetResource<engine::resources::Texture>("builtin.white");
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1); cubeRenderable->mesh = genCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
auto cubeCollider = myScene->addComponent<engine::ColliderComponent>(cube); auto cubeCollider = myScene->AddComponent<engine::ColliderComponent>(cube);
cubeCollider->isStatic = true; cubeCollider->isStatic = true;
cubeCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } }; cubeCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } };
} }
/* floor */ /* floor */
{ {
uint32_t floor = myScene->createEntity("floor"); uint32_t floor = myScene->CreateEntity("floor");
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f}; myScene->GetComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f};
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor); auto floorRenderable = myScene->AddComponent<engine::RenderableComponent>(floor);
floorRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard")); floorRenderable->material = std::make_shared<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.standard"));
floorRenderable->material->m_texture = grassTexture; floorRenderable->material->m_texture = grassTexture;
floorRenderable->mesh = genCuboidMesh(app.gfx(), 10000.0f, 1.0f, 10000.0f, 5000.0f); floorRenderable->mesh = genCuboidMesh(app.gfxdev(), 10000.0f, 1.0f, 10000.0f, 5000.0f);
floorRenderable->shown = true; floorRenderable->shown = true;
auto floorCollider = myScene->addComponent<engine::ColliderComponent>(floor); auto floorCollider = myScene->AddComponent<engine::ColliderComponent>(floor);
floorCollider->isStatic = true; floorCollider->isStatic = true;
floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10000.0f, 1.0f, 10000.0f } }; floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10000.0f, 1.0f, 10000.0f } };
} }
//engine::util::loadMeshFromFile(myScene, app.getResourcePath("models/astronaut/astronaut.dae")); //engine::util::loadMeshFromFile(myScene, app.GetResourcePath("models/astronaut/astronaut.dae"));
/* skybox */ /* skybox */
{ {
uint32_t skybox = myScene->createEntity("skybox"); uint32_t skybox = myScene->CreateEntity("skybox");
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox); auto skyboxRenderable = myScene->AddComponent<engine::RenderableComponent>(skybox);
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox")); skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.skybox"));
skyboxRenderable->material->m_texture = spaceTexture; skyboxRenderable->material->m_texture = spaceTexture;
skyboxRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f, 1.0f, true); skyboxRenderable->mesh = genCuboidMesh(app.gfxdev(), 10.0f, 10.0f, 10.0f, 1.0f, true);
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f }; myScene->GetComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f };
} }
app.gameLoop(); app.GameLoop();
} }

View File

@ -25,7 +25,7 @@ int main(int argc, char* argv[])
if (args.contains("gpuvalidation")) settings.enableValidation = true; if (args.contains("gpuvalidation")) settings.enableValidation = true;
} }
engine::setupLog(PROJECT_NAME); engine::SetupLog(PROJECT_NAME);
LOG_INFO("{} v{}", PROJECT_NAME, PROJECT_VERSION); LOG_INFO("{} v{}", PROJECT_NAME, PROJECT_VERSION);