mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
begin changing style
This commit is contained in:
parent
440ad2de82
commit
c5b7a09e63
3
README
3
README
@ -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
|
@ -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
|
@ -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"
|
|
||||||
class GFXDevice; // "gfx_device.hpp"
|
|
||||||
class InputManager; // "input_manager.hpp"
|
|
||||||
class SceneManager; // "scene_manager.hpp"
|
|
||||||
|
|
||||||
namespace resources {
|
|
||||||
class Shader;
|
|
||||||
class Texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderData {
|
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
|
@ -1,20 +1,18 @@
|
|||||||
#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:
|
||||||
@ -25,49 +23,54 @@ namespace engine {
|
|||||||
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
|
@ -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
|
@ -1,30 +1,30 @@
|
|||||||
#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>
|
||||||
@ -32,34 +32,37 @@ namespace engine {
|
|||||||
// 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,7 +73,7 @@ namespace engine {
|
|||||||
EventHandler<T>* handler;
|
EventHandler<T>* handler;
|
||||||
T event;
|
T event;
|
||||||
};
|
};
|
||||||
std::queue<QueuedEvent> m_eventQueue{};
|
std::queue<QueuedEvent> event_queue_{};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,43 +86,51 @@ namespace engine {
|
|||||||
~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
|
106
include/gfx.hpp
106
include/gfx.hpp
@ -1,13 +1,15 @@
|
|||||||
#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;
|
||||||
@ -20,11 +22,11 @@ namespace engine::gfx {
|
|||||||
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 {
|
||||||
@ -32,65 +34,68 @@ namespace engine::gfx {
|
|||||||
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) {}
|
||||||
@ -101,33 +106,34 @@ namespace engine::gfx {
|
|||||||
|
|
||||||
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<>
|
||||||
@ -140,7 +146,7 @@ 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) |
|
||||||
@ -149,4 +155,6 @@ namespace std {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace std
|
||||||
|
|
||||||
|
#endif
|
@ -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
|
||||||
|
@ -1,55 +1,93 @@
|
|||||||
#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 {
|
enum class InputDevice : int {
|
||||||
MOUSE,
|
kMouse,
|
||||||
KEYBOARD,
|
kKeyboard,
|
||||||
CONTROLLER,
|
kController,
|
||||||
SIZE
|
kSize
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class should be used to get platform/input-device independent input
|
// This class should be used to get platform/input-device independent input
|
||||||
class ENGINE_API InputManager {
|
class InputManager {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// requires a window reference to get input from
|
/* The Window object here is stored for the duration of the InputManager.
|
||||||
InputManager(const Window* win);
|
* 'win' must point to a valid Window object. */
|
||||||
|
InputManager(const Window* win) : win_(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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
private:
|
||||||
|
|
||||||
@ -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
|
@ -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
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#ifndef ENGINE_INCLUDE_LOGGER_H_
|
||||||
|
#define ENGINE_INCLUDE_LOGGER_H_
|
||||||
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
|
|
||||||
@ -11,14 +12,14 @@
|
|||||||
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);
|
||||||
@ -44,4 +48,6 @@ namespace engine {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace engine
|
||||||
|
|
||||||
|
#endif
|
@ -1,10 +1,11 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@ -17,31 +18,31 @@ namespace engine {
|
|||||||
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:
|
||||||
@ -50,9 +51,12 @@ namespace engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
@ -1,15 +1,14 @@
|
|||||||
#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;
|
||||||
@ -22,119 +21,125 @@ namespace engine {
|
|||||||
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
|
@ -1,14 +1,15 @@
|
|||||||
#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 {
|
||||||
|
|
||||||
@ -19,16 +20,18 @@ namespace engine {
|
|||||||
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
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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
|
@ -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
|
||||||
@ -196,3 +196,5 @@ namespace engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -7,170 +7,16 @@
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,14 +24,14 @@ namespace engine {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -195,13 +41,13 @@ 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;
|
||||||
@ -212,14 +58,14 @@ 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;
|
||||||
}
|
}
|
||||||
@ -229,4 +75,72 @@ 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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -12,7 +12,7 @@ namespace engine {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UISystem::onUpdate(float ts)
|
void UISystem::OnUpdate(float ts)
|
||||||
{
|
{
|
||||||
(void)ts;
|
(void)ts;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user