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!
|
||||
|
||||
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@"
|
||||
|
||||
#endif
|
@ -1,59 +1,53 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_APPLICATION_H_
|
||||
#define ENGINE_INCLUDE_APPLICATION_H_
|
||||
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_device.hpp"
|
||||
#include <assert.h>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
#include <assert.h>
|
||||
#include "gfx.hpp"
|
||||
#include "gfx_device.hpp"
|
||||
#include "input_manager.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
#include "scene_manager.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
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;
|
||||
gfx::DrawBuffer* drawBuffer = nullptr;
|
||||
gfx::DrawBuffer* draw_buffer = nullptr;
|
||||
|
||||
/* uniforms for engine globals */
|
||||
const gfx::DescriptorSetLayout* globalSetLayout;
|
||||
const gfx::DescriptorSet* globalSet;
|
||||
const gfx::DescriptorSetLayout* global_set_layout;
|
||||
const gfx::DescriptorSet* global_set;
|
||||
struct GlobalSetUniformBuffer {
|
||||
glm::mat4 proj;
|
||||
};
|
||||
gfx::UniformBuffer* globalSetUniformBuffer;
|
||||
gfx::UniformBuffer* global_set_uniform_buffer;
|
||||
|
||||
/* uniforms for per-frame data */
|
||||
const gfx::DescriptorSetLayout* frameSetLayout;
|
||||
const gfx::DescriptorSet* frameSet;
|
||||
const gfx::DescriptorSetLayout* frame_set_layout;
|
||||
const gfx::DescriptorSet* frame_set;
|
||||
struct FrameSetUniformBuffer {
|
||||
glm::mat4 view;
|
||||
};
|
||||
gfx::UniformBuffer* frameSetUniformBuffer;
|
||||
gfx::UniformBuffer* frame_set_uniform_buffer;
|
||||
|
||||
/* 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{};
|
||||
};
|
||||
};
|
||||
|
||||
class Application {
|
||||
class Application {
|
||||
|
||||
public:
|
||||
Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings);
|
||||
public:
|
||||
Application(const char* app_name, const char* app_version,
|
||||
gfx::GraphicsSettings graphics_settings);
|
||||
~Application();
|
||||
Application(const Application&) = delete;
|
||||
Application& operator=(const Application&) = delete;
|
||||
@ -61,69 +55,72 @@ namespace engine {
|
||||
/* resource stuff */
|
||||
|
||||
template <typename T>
|
||||
void registerResourceManager()
|
||||
void RegisterResourceManager()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_resourceManagers.contains(hash) == false && "Registering resource manager type more than once.");
|
||||
m_resourceManagers.emplace(hash, std::make_unique<ResourceManager<T>>());
|
||||
assert(resource_managers_.contains(hash) == false &&
|
||||
"Registering resource manager type more than once.");
|
||||
resource_managers_.emplace(hash, std::make_unique<ResourceManager<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>();
|
||||
return resourceManager->add(name, std::move(resource));
|
||||
auto resource_manager = GetResourceManager<T>();
|
||||
return resource_manager->Add(name, std::move(resource));
|
||||
}
|
||||
|
||||
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>();
|
||||
return resourceManager->get(name);
|
||||
auto resource_manager = GetResourceManager<T>();
|
||||
return resource_manager->Get(name);
|
||||
}
|
||||
|
||||
/* methods */
|
||||
void gameLoop();
|
||||
void GameLoop();
|
||||
|
||||
void setFrameLimiter(bool on) { m_enableFrameLimiter = on; }
|
||||
void SetFrameLimiter(bool on) { enable_frame_limiter_ = on; }
|
||||
|
||||
/* getters */
|
||||
Window* window() { return m_window.get(); }
|
||||
GFXDevice* gfx() { return renderData.gfxdev.get(); }
|
||||
InputManager* inputManager() { return m_inputManager.get(); }
|
||||
SceneManager* sceneManager() { return m_sceneManager.get(); }
|
||||
Window* window() { return window_.get(); }
|
||||
GFXDevice* gfxdev() { return render_data_.gfxdev.get(); }
|
||||
InputManager* input_manager() { return input_manager_.get(); }
|
||||
SceneManager* scene_manager() { return scene_manager_.get(); }
|
||||
|
||||
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:
|
||||
std::unique_ptr<Window> m_window;
|
||||
std::unique_ptr<InputManager> m_inputManager;
|
||||
std::unique_ptr<SceneManager> m_sceneManager;
|
||||
private:
|
||||
std::unique_ptr<Window> window_;
|
||||
std::unique_ptr<InputManager> input_manager_;
|
||||
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 m_enableFrameLimiter = true;
|
||||
|
||||
/* resource stuff */
|
||||
|
||||
std::unordered_map<size_t, std::unique_ptr<IResourceManager>> m_resourceManagers{};
|
||||
bool enable_frame_limiter_ = true;
|
||||
|
||||
template <typename T>
|
||||
ResourceManager<T>* getResourceManager()
|
||||
ResourceManager<T>* GetResourceManager()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
auto it = m_resourceManagers.find(hash);
|
||||
if (it == m_resourceManagers.end()) {
|
||||
auto it = resource_managers_.find(hash);
|
||||
if (it == resource_managers_.end()) {
|
||||
throw std::runtime_error("Cannot find resource manager.");
|
||||
}
|
||||
auto ptr = it->second.get();
|
||||
auto castedPtr = dynamic_cast<ResourceManager<T>*>(ptr);
|
||||
assert(castedPtr != nullptr);
|
||||
return castedPtr;
|
||||
auto casted_ptr = dynamic_cast<ResourceManager<T>*>(ptr);
|
||||
assert(casted_ptr != nullptr);
|
||||
return casted_ptr;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,73 +1,76 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_ECS_SYSTEM_H_
|
||||
#define ENGINE_INCLUDE_ECS_SYSTEM_H_
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
|
||||
#include <typeinfo>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Scene;
|
||||
class Scene;
|
||||
|
||||
constexpr size_t MAX_COMPONENTS = 64;
|
||||
constexpr size_t kMaxComponents = 64;
|
||||
|
||||
class IComponentArray {
|
||||
public:
|
||||
class IComponentArray {
|
||||
public:
|
||||
virtual ~IComponentArray() = default;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ComponentArray : public IComponentArray {
|
||||
template<typename T>
|
||||
class ComponentArray : public IComponentArray {
|
||||
|
||||
public:
|
||||
void insertData(uint32_t entity, T component)
|
||||
public:
|
||||
void InsertData(uint32_t entity, T component)
|
||||
{
|
||||
assert(m_componentArray.find(entity) == m_componentArray.end() && "Adding component which already exists to entity");
|
||||
m_componentArray.emplace(entity, component);
|
||||
assert(component_array_.find(entity) == component_array_.end() &&
|
||||
"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)) {
|
||||
return &(m_componentArray.at(entity));
|
||||
if (component_array_.contains(entity)) {
|
||||
return &(component_array_.at(entity));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<uint32_t, T> m_componentArray{};
|
||||
private:
|
||||
std::map<uint32_t, T> component_array_{};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class System {
|
||||
class System {
|
||||
|
||||
public:
|
||||
System(Scene* scene, std::set<size_t> requiredComponentHashes);
|
||||
public:
|
||||
System(Scene* scene, std::set<size_t> required_component_hashes);
|
||||
virtual ~System() {}
|
||||
System(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 onComponentRemove(uint32_t) {}
|
||||
virtual void OnComponentInsert(uint32_t) {}
|
||||
virtual void OnComponentRemove(uint32_t) {}
|
||||
|
||||
Scene* const m_scene;
|
||||
Scene* const scene_;
|
||||
|
||||
std::bitset<MAX_COMPONENTS> m_signature;
|
||||
std::set<uint32_t> m_entities{}; // entities that contain the required components
|
||||
std::bitset<kMaxComponents> signature_;
|
||||
|
||||
};
|
||||
// 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
|
||||
@ -15,3 +16,5 @@
|
||||
*/
|
||||
|
||||
#define ENGINE_API
|
||||
|
||||
#endif
|
@ -1,65 +1,68 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_EVENT_SYSTEM_H_
|
||||
#define ENGINE_INCLUDE_EVENT_SYSTEM_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace engine {
|
||||
|
||||
enum class EventSubscriberKind {
|
||||
ENTITY,
|
||||
};
|
||||
enum class EventSubscriberKind {
|
||||
kEntity,
|
||||
};
|
||||
|
||||
// Event handler base-class
|
||||
template <typename T>
|
||||
class EventHandler {
|
||||
public:
|
||||
virtual void onEvent(T data) = 0;
|
||||
};
|
||||
// Event handler base-class
|
||||
template <typename T>
|
||||
class EventHandler {
|
||||
public:
|
||||
virtual void OnEvent(T data) = 0;
|
||||
};
|
||||
|
||||
// Event queue interface to allow for different type queues to be in the map
|
||||
class IEventQueue {
|
||||
public:
|
||||
// Event queue interface to allow for different type queues to be in the map
|
||||
class IEventQueue {
|
||||
public:
|
||||
virtual ~IEventQueue() {}
|
||||
virtual void dispatchEvents() = 0;
|
||||
};
|
||||
virtual void DespatchEvents() = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class EventQueue : public IEventQueue {
|
||||
template <typename T>
|
||||
class EventQueue : public IEventQueue {
|
||||
// holds events of type T and subscribers to those events
|
||||
|
||||
public:
|
||||
void subscribe(EventSubscriberKind kind, uint32_t id, EventHandler<T>* handler)
|
||||
public:
|
||||
void Subscribe(EventSubscriberKind kind, uint32_t id,
|
||||
EventHandler<T>* handler)
|
||||
{
|
||||
// For the time being, ignore kind (TODO)
|
||||
(void)kind;
|
||||
assert(m_subscribers.contains(id) == false && "subscribing to an event with ID that's already in use!");
|
||||
m_subscribers.emplace(id, handler);
|
||||
assert(subscribers_.contains(id) == false &&
|
||||
"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)
|
||||
(void)kind;
|
||||
assert(m_subscribers.contains(id) && "Attempt to submit event to non-existing subscriber!");
|
||||
EventHandler<T>* handler = m_subscribers.at(id);
|
||||
m_eventQueue.emplace(handler, event);
|
||||
assert(subscribers_.contains(id) &&
|
||||
"Attempt to submit event to non-existing subscriber!");
|
||||
EventHandler<T>* handler = subscribers_.at(id);
|
||||
event_queue_.emplace(handler, event);
|
||||
}
|
||||
|
||||
void dispatchEvents() override
|
||||
void DespatchEvents() override
|
||||
{
|
||||
while (m_eventQueue.empty() == false) {
|
||||
auto [handler, event] = m_eventQueue.front();
|
||||
handler->onEvent(event);
|
||||
m_eventQueue.pop();
|
||||
while (event_queue_.empty() == false) {
|
||||
auto [handler, event] = event_queue_.front();
|
||||
handler->OnEvent(event);
|
||||
event_queue_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, EventHandler<T>*> m_subscribers;
|
||||
private:
|
||||
std::unordered_map<uint32_t, EventHandler<T>*> subscribers_;
|
||||
|
||||
struct QueuedEvent {
|
||||
|
||||
@ -70,56 +73,64 @@ namespace engine {
|
||||
EventHandler<T>* handler;
|
||||
T event;
|
||||
};
|
||||
std::queue<QueuedEvent> m_eventQueue{};
|
||||
std::queue<QueuedEvent> event_queue_{};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class EventSystem {
|
||||
class EventSystem {
|
||||
|
||||
public:
|
||||
public:
|
||||
EventSystem() {}
|
||||
EventSystem(const EventSystem&) = delete;
|
||||
EventSystem& operator=(const EventSystem&) = delete;
|
||||
~EventSystem() {}
|
||||
|
||||
template <typename T>
|
||||
void registerEventType()
|
||||
void RegisterEventType()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_eventQueues.contains(hash) == false && "Registering an event queue more than once!");
|
||||
m_eventQueues.emplace(hash, std::make_unique<EventQueue<T>>());
|
||||
assert(event_queues_.contains(hash) == false &&
|
||||
"Registering an event queue more than once!");
|
||||
event_queues_.emplace(hash, std::make_unique<EventQueue<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();
|
||||
assert(m_eventQueues.contains(hash) && "Subscribing to event type that isn't registered!");
|
||||
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_eventQueues.at(hash).get());
|
||||
assert(event_queues_.contains(hash) &&
|
||||
"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");
|
||||
queue->subscribe(kind, id, handler);
|
||||
queue->Subscribe(kind, id, handler);
|
||||
}
|
||||
|
||||
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();
|
||||
assert(m_eventQueues.contains(hash) && "Subscribing to event type that isn't registered!");
|
||||
EventQueue<T>* queue = dynamic_cast<EventQueue<T>*>(m_eventQueues.at(hash).get());
|
||||
assert(event_queues_.contains(hash) &&
|
||||
"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");
|
||||
queue->queueEvent(kind, subscriberID, event);
|
||||
queue->QueueEvent(kind, subscriber_id, event);
|
||||
}
|
||||
|
||||
void dispatchEvents()
|
||||
void DespatchEvents()
|
||||
{
|
||||
for (auto& [hash, queue] : m_eventQueues) {
|
||||
queue->dispatchEvents();
|
||||
for (auto& [hash, queue] : event_queues_) {
|
||||
queue->DespatchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> m_eventQueues{};
|
||||
private:
|
||||
std::unordered_map<size_t, std::unique_ptr<IEventQueue>> event_queues_{};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
188
include/gfx.hpp
188
include/gfx.hpp
@ -1,138 +1,144 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_GFX_H_
|
||||
#define ENGINE_INCLUDE_GFX_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
// Enums and structs for the graphics abstraction
|
||||
|
||||
namespace engine::gfx {
|
||||
namespace engine {
|
||||
namespace gfx {
|
||||
|
||||
// handles (incomplete types)
|
||||
struct Pipeline;
|
||||
struct UniformBuffer;
|
||||
struct Buffer;
|
||||
struct DrawBuffer;
|
||||
struct DescriptorSetLayout;
|
||||
struct DescriptorSet;
|
||||
struct Image;
|
||||
struct Sampler;
|
||||
// handles (incomplete types)
|
||||
struct Pipeline;
|
||||
struct UniformBuffer;
|
||||
struct Buffer;
|
||||
struct DrawBuffer;
|
||||
struct DescriptorSetLayout;
|
||||
struct DescriptorSet;
|
||||
struct Image;
|
||||
struct Sampler;
|
||||
|
||||
enum class MSAALevel {
|
||||
MSAA_OFF,
|
||||
MSAA_2X,
|
||||
MSAA_4X,
|
||||
MSAA_8X,
|
||||
MSAA_16X,
|
||||
};
|
||||
enum class MSAALevel {
|
||||
kOff,
|
||||
k2X,
|
||||
k4X,
|
||||
k8X,
|
||||
k16X,
|
||||
};
|
||||
|
||||
struct GraphicsSettings {
|
||||
struct GraphicsSettings {
|
||||
|
||||
GraphicsSettings()
|
||||
{
|
||||
// sane defaults
|
||||
enableValidation = true;
|
||||
enable_validation = true;
|
||||
vsync = true;
|
||||
waitForPresent = true; // not all GPUs/drivers support immediate present with V-sync enabled
|
||||
msaaLevel = MSAALevel::MSAA_OFF;
|
||||
// not all GPUs/drivers support immediate present with V-sync enabled
|
||||
wait_for_present = true;
|
||||
msaa_level = MSAALevel::kOff;
|
||||
}
|
||||
|
||||
bool enableValidation;
|
||||
bool enable_validation;
|
||||
bool vsync;
|
||||
// idle CPU after render until the frame has been presented (no affect with V-sync disabled)
|
||||
bool waitForPresent;
|
||||
MSAALevel msaaLevel;
|
||||
// idle CPU after render until the frame has been presented
|
||||
// (no affect with V-sync disabled)
|
||||
bool wait_for_present;
|
||||
MSAALevel msaa_level;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
enum class ShaderType {
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
};
|
||||
enum class ShaderType {
|
||||
kVertex,
|
||||
kFragment,
|
||||
};
|
||||
|
||||
enum class BufferType {
|
||||
VERTEX,
|
||||
INDEX,
|
||||
UNIFORM,
|
||||
};
|
||||
enum class BufferType {
|
||||
kVertex,
|
||||
kIndex,
|
||||
kUniform,
|
||||
};
|
||||
|
||||
enum class Primitive {
|
||||
POINTS,
|
||||
LINES,
|
||||
LINE_STRIP,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
};
|
||||
enum class Primitive {
|
||||
kPoints,
|
||||
kLines,
|
||||
kLineStrip,
|
||||
kTriangles,
|
||||
kTriangleStrip,
|
||||
};
|
||||
|
||||
enum class VertexAttribFormat {
|
||||
FLOAT2,
|
||||
FLOAT3,
|
||||
FLOAT4
|
||||
};
|
||||
enum class VertexAttribFormat {
|
||||
kFloat2,
|
||||
kFloat3,
|
||||
kFloat4
|
||||
};
|
||||
|
||||
enum class Filter : int {
|
||||
LINEAR,
|
||||
NEAREST,
|
||||
};
|
||||
enum class Filter : int {
|
||||
kLinear,
|
||||
kNearest,
|
||||
};
|
||||
|
||||
enum class DescriptorType {
|
||||
UNIFORM_BUFFER,
|
||||
COMBINED_IMAGE_SAMPLER,
|
||||
};
|
||||
enum class DescriptorType {
|
||||
kUniformBuffer,
|
||||
kCombinedImageSampler,
|
||||
};
|
||||
|
||||
namespace ShaderStageFlags {
|
||||
namespace ShaderStageFlags {
|
||||
enum Bits : uint32_t {
|
||||
VERTEX = 1 << 0,
|
||||
FRAGMENT = 1 << 1,
|
||||
kVertex = 1 << 0,
|
||||
kFragment = 1 << 1,
|
||||
};
|
||||
typedef std::underlying_type<Bits>::type Flags;
|
||||
}
|
||||
}
|
||||
|
||||
struct VertexAttribDescription {
|
||||
VertexAttribDescription(uint32_t location, VertexAttribFormat format, uint32_t offset) :
|
||||
struct VertexAttribDescription {
|
||||
VertexAttribDescription(uint32_t location, VertexAttribFormat format,
|
||||
uint32_t offset) :
|
||||
location(location),
|
||||
format(format),
|
||||
offset(offset) {}
|
||||
uint32_t location; // the index to use in the shader
|
||||
VertexAttribFormat format;
|
||||
uint32_t offset;
|
||||
};
|
||||
};
|
||||
|
||||
struct VertexFormat {
|
||||
struct VertexFormat {
|
||||
uint32_t stride;
|
||||
std::vector<VertexAttribDescription> attributeDescriptions;
|
||||
};
|
||||
std::vector<VertexAttribDescription> attribute_descriptions;
|
||||
};
|
||||
|
||||
struct PipelineInfo {
|
||||
const char* vertShaderPath;
|
||||
const char* fragShaderPath;
|
||||
VertexFormat vertexFormat;
|
||||
bool alphaBlending;
|
||||
bool backfaceCulling;
|
||||
std::vector<const DescriptorSetLayout*> descriptorSetLayouts;
|
||||
};
|
||||
struct PipelineInfo {
|
||||
const char* vert_shader_path;
|
||||
const char* frag_shader_path;
|
||||
VertexFormat vertex_format;
|
||||
bool alpha_blending;
|
||||
bool backface_culling;
|
||||
std::vector<const DescriptorSetLayout*> descriptor_set_layouts;
|
||||
};
|
||||
|
||||
struct DescriptorSetLayoutBinding {
|
||||
DescriptorType descriptorType = DescriptorType::UNIFORM_BUFFER;
|
||||
ShaderStageFlags::Flags stageFlags = 0;
|
||||
};
|
||||
struct DescriptorSetLayoutBinding {
|
||||
DescriptorType descriptor_type = DescriptorType::kUniformBuffer;
|
||||
ShaderStageFlags::Flags stage_flags = 0;
|
||||
};
|
||||
|
||||
struct SamplerInfo {
|
||||
struct SamplerInfo {
|
||||
Filter minify;
|
||||
Filter magnify;
|
||||
Filter mipmap;
|
||||
bool anisotropicFiltering;
|
||||
bool anisotropic_filtering;
|
||||
|
||||
bool operator==(const SamplerInfo&) const = default;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace gfx
|
||||
} // namespace engine
|
||||
|
||||
namespace std {
|
||||
template<>
|
||||
struct std::hash<engine::gfx::SamplerInfo>
|
||||
{
|
||||
template<>
|
||||
struct std::hash<engine::gfx::SamplerInfo>
|
||||
{
|
||||
std::size_t operator()(const engine::gfx::SamplerInfo& k) const
|
||||
{
|
||||
using std::hash;
|
||||
@ -140,13 +146,15 @@ namespace std {
|
||||
size_t h1 = hash<int>()(static_cast<int>(k.minify));
|
||||
size_t h2 = hash<int>()(static_cast<int>(k.magnify));
|
||||
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) |
|
||||
((h2 & 0xFF) << 16) |
|
||||
((h3 & 0xFF) << 8) |
|
||||
((h4 & 0xFF) << 0);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif
|
@ -1,71 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include "gfx.hpp"
|
||||
#ifndef ENGINE_INCLUDE_GFX_DEVICE_H_
|
||||
#define ENGINE_INCLUDE_GFX_DEVICE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "gfx.hpp"
|
||||
|
||||
struct SDL_Window; // <SDL_video.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class GFXDevice {
|
||||
|
||||
class GFXDevice {
|
||||
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& operator=(const GFXDevice&) = delete;
|
||||
~GFXDevice();
|
||||
|
||||
void getViewportSize(uint32_t *w, uint32_t *h);
|
||||
void GetViewportSize(uint32_t* w, uint32_t* h);
|
||||
|
||||
gfx::DrawBuffer* beginRender();
|
||||
void finishRender(gfx::DrawBuffer* drawBuffer);
|
||||
gfx::DrawBuffer* BeginRender();
|
||||
|
||||
void cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline);
|
||||
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);
|
||||
void FinishRender(gfx::DrawBuffer* draw_buffer);
|
||||
|
||||
gfx::Pipeline* createPipeline(const gfx::PipelineInfo& info);
|
||||
void destroyPipeline(const gfx::Pipeline* pipeline);
|
||||
void CmdBindPipeline(gfx::DrawBuffer* draw_buffer,
|
||||
const gfx::Pipeline* pipeline);
|
||||
|
||||
gfx::DescriptorSetLayout* createDescriptorSetLayout(const std::vector<gfx::DescriptorSetLayoutBinding>& bindings);
|
||||
void destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout);
|
||||
void CmdBindVertexBuffer(gfx::DrawBuffer* draw_buffer, uint32_t binding,
|
||||
const gfx::Buffer* buffer);
|
||||
|
||||
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);
|
||||
void CmdBindIndexBuffer(gfx::DrawBuffer* draw_buffer,
|
||||
const gfx::Buffer* buffer);
|
||||
|
||||
gfx::UniformBuffer* createUniformBuffer(uint64_t size, const void* initialData);
|
||||
void destroyUniformBuffer(const gfx::UniformBuffer* descriptorBuffer);
|
||||
void CmdDrawIndexed(gfx::DrawBuffer* draw_buffer, uint32_t index_count,
|
||||
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.
|
||||
gfx::Buffer* createBuffer(gfx::BufferType type, uint64_t size, const void* data);
|
||||
void destroyBuffer(const gfx::Buffer* buffer);
|
||||
gfx::Buffer* CreateBuffer(gfx::BufferType type, uint64_t size,
|
||||
const void* data);
|
||||
|
||||
gfx::Image* createImage(uint32_t w, uint32_t h, const void* imageData);
|
||||
void destroyImage(const gfx::Image* image);
|
||||
void DestroyBuffer(const gfx::Buffer* buffer);
|
||||
|
||||
const gfx::Sampler* createSampler(const gfx::SamplerInfo& info);
|
||||
void destroySampler(const gfx::Sampler* sampler);
|
||||
gfx::Image* CreateImage(uint32_t w, uint32_t h, const void* image_data);
|
||||
|
||||
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
|
||||
void waitIdle();
|
||||
void WaitIdle();
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> pimpl;
|
||||
};
|
||||
|
||||
};
|
||||
} // namespace engine
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -1,57 +1,95 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_INPUT_MANAGER_H_
|
||||
#define ENGINE_INCLUDE_INPUT_MANAGER_H_
|
||||
|
||||
#include "engine_api.h"
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "window.hpp"
|
||||
#include "inputs/mouse.hpp"
|
||||
#include "inputs/keyboard.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Window; // "window.hpp"
|
||||
enum class InputDevice : int {
|
||||
kMouse,
|
||||
kKeyboard,
|
||||
kController,
|
||||
kSize
|
||||
};
|
||||
|
||||
enum class InputDevice : int {
|
||||
MOUSE,
|
||||
KEYBOARD,
|
||||
CONTROLLER,
|
||||
SIZE
|
||||
};
|
||||
// This class should be used to get platform/input-device independent input
|
||||
class InputManager {
|
||||
|
||||
// This class should be used to get platform/input-device independent input
|
||||
class ENGINE_API InputManager {
|
||||
public:
|
||||
|
||||
public:
|
||||
|
||||
// requires a window reference to get input from
|
||||
InputManager(const Window* win);
|
||||
/* The Window object here is stored for the duration of the InputManager.
|
||||
* '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& operator=(const InputManager&) = delete;
|
||||
~InputManager();
|
||||
|
||||
// Add a mouse input
|
||||
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);
|
||||
~InputManager() {}
|
||||
|
||||
void delInputButton(int index);
|
||||
void delInputAxis(int index);
|
||||
void AddInputButton(const std::string& name, inputs::MouseButton button) {
|
||||
AddInputDeviceButton(name, InputDevice::kMouse,
|
||||
static_cast<int>(button));
|
||||
}
|
||||
|
||||
void setDeviceActive(enum InputDevice device, bool active);
|
||||
bool getDeviceActive(enum InputDevice device) const;
|
||||
void AddInputButton(const std::string& name, inputs::Key button) {
|
||||
AddInputDeviceButton(name, InputDevice::kKeyboard,
|
||||
static_cast<int>(button));
|
||||
}
|
||||
|
||||
float getAxis(const std::string& axisName) const;
|
||||
bool getButton(const std::string& buttonName) const;
|
||||
bool getButtonPress(const std::string& buttonName) const;
|
||||
bool getButtonRelease(const std::string& buttonName) const;
|
||||
void AddInputAxis(const std::string& name, inputs::MouseAxis axis) {
|
||||
AddInputDeviceAxis(name, InputDevice::kMouse, static_cast<int>(axis));
|
||||
}
|
||||
|
||||
void AddInputButtonAsAxis(const std::string& name, inputs::MouseButton high,
|
||||
inputs::MouseButton low) {
|
||||
AddInputDeviceButtonAsAxis(name, InputDevice::kMouse,
|
||||
static_cast<int>(high), static_cast<int>(low));
|
||||
}
|
||||
|
||||
private:
|
||||
void AddInputButtonAsAxis(const std::string& name, inputs::Key high,
|
||||
inputs::Key low) {
|
||||
AddInputDeviceButtonAsAxis(name, InputDevice::kKeyboard,
|
||||
static_cast<int>(high), static_cast<int>(low));
|
||||
}
|
||||
|
||||
void DelInputButton(int index) {
|
||||
std::vector<struct ButtonEntry>::iterator it = button_entries_.begin();
|
||||
std::advance(it, index);
|
||||
button_entries_.erase(it);
|
||||
}
|
||||
|
||||
void DelInputAxis(int index) {
|
||||
std::vector<struct AxisEntry>::iterator it = axis_entries_.begin();
|
||||
std::advance(it, index);
|
||||
axis_entries_.erase(it);
|
||||
}
|
||||
|
||||
void SetDeviceActive(enum InputDevice device, bool active) {
|
||||
enabled_devices_[static_cast<int>(device)] = active;
|
||||
}
|
||||
|
||||
bool GetDeviceActive(enum InputDevice device) const {
|
||||
return enabled_devices_[static_cast<int>(device)];
|
||||
}
|
||||
|
||||
float GetAxis(const std::string& axis_name) const;
|
||||
|
||||
bool GetButton(const std::string& button_name) const;
|
||||
|
||||
bool GetButtonPress(const std::string& button_name) const;
|
||||
|
||||
bool GetButtonRelease(const std::string& button_name) const;
|
||||
|
||||
private:
|
||||
|
||||
struct ButtonEntry {
|
||||
std::string name;
|
||||
@ -63,31 +101,54 @@ namespace engine {
|
||||
std::string name;
|
||||
enum InputDevice device;
|
||||
int axis;
|
||||
bool isButtonAxis;
|
||||
bool is_button_axis;
|
||||
int high;
|
||||
int low;
|
||||
};
|
||||
|
||||
const Window* const m_win;
|
||||
const Window* win_;
|
||||
|
||||
std::vector<struct ButtonEntry> m_buttonEntries;
|
||||
std::vector<struct AxisEntry> m_axisEntries;
|
||||
std::vector<struct ButtonEntry> button_entries_;
|
||||
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
|
||||
|
||||
float getDeviceAxis(enum InputDevice device, int axis) const;
|
||||
bool getDeviceButton(enum InputDevice device, int button) const;
|
||||
float GetDeviceAxis(enum InputDevice device, int axis) const;
|
||||
|
||||
bool GetDeviceButton(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);
|
||||
void addInputAxis(const std::string& name, InputDevice device, int axis);
|
||||
void addInputButtonAsAxis(const std::string& name, InputDevice device, int high, int low);
|
||||
float 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;
|
||||
}
|
||||
|
||||
};
|
||||
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
|
||||
#define SPDLOG_ACTIVE_LEVEL 2 // info
|
||||
@ -14,3 +15,5 @@
|
||||
#define LOG_WARN SPDLOG_WARN
|
||||
#define LOG_ERROR SPDLOG_ERROR
|
||||
#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"
|
||||
|
||||
@ -10,15 +11,15 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
// To be executed in the target application, NOT engine.dll
|
||||
void setupLog(const char* appName)
|
||||
{
|
||||
// To be executed in the target application, NOT engine.dll
|
||||
void SetupLog(const char* appName) {
|
||||
|
||||
const std::string LOG_FILENAME{ std::string(appName) + ".log"};
|
||||
|
||||
#ifdef NDEBUG
|
||||
// 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
|
||||
// DEBUG
|
||||
const std::filesystem::path log_path{ LOG_FILENAME };
|
||||
@ -26,15 +27,18 @@ namespace engine {
|
||||
|
||||
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.emplace_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
|
||||
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::set_default_logger(logger);
|
||||
@ -42,6 +46,8 @@ namespace engine {
|
||||
|
||||
LOG_INFO("Created log with path: {}", log_path.string());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -1,47 +1,48 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_RESOURCE_MANAGER_H_
|
||||
#define ENGINE_INCLUDE_RESOURCE_MANAGER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class IResourceManager {
|
||||
public:
|
||||
class IResourceManager {
|
||||
public:
|
||||
virtual ~IResourceManager() = default;
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ResourceManager : public IResourceManager {
|
||||
template <class T>
|
||||
class ResourceManager : public IResourceManager {
|
||||
|
||||
public:
|
||||
std::shared_ptr<T> add(const std::string& name, std::unique_ptr<T>&& resource)
|
||||
public:
|
||||
std::shared_ptr<T> Add(const std::string& name, std::unique_ptr<T>&& resource)
|
||||
{
|
||||
if (m_resources.contains(name) == false) {
|
||||
std::shared_ptr<T> resourceSharedPtr(std::move(resource));
|
||||
m_resources.emplace(name, resourceSharedPtr);
|
||||
return resourceSharedPtr;
|
||||
if (resources_.contains(name) == false) {
|
||||
std::shared_ptr<T> resource_shared(std::move(resource));
|
||||
resources_.emplace(name, resource_shared);
|
||||
return resource_shared;
|
||||
}
|
||||
else {
|
||||
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)) {
|
||||
std::weak_ptr<T> ptr = m_resources.at(name);
|
||||
if (resources_.contains(name)) {
|
||||
std::weak_ptr<T> ptr = resources_.at(name);
|
||||
if (ptr.expired() == false) {
|
||||
return ptr.lock();
|
||||
} else {
|
||||
m_resources.erase(name);
|
||||
resources_.erase(name);
|
||||
}
|
||||
}
|
||||
// resource doesn't exist:
|
||||
@ -49,10 +50,13 @@ namespace engine {
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::weak_ptr<T>> m_resources{};
|
||||
std::vector<std::shared_ptr<T>> m_persistentResources{}; // This array owns persistent resources
|
||||
private:
|
||||
std::unordered_map<std::string, std::weak_ptr<T>> resources_{};
|
||||
// This array owns persistent resources
|
||||
std::vector<std::shared_ptr<T>> persistent_resources_{};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -1,140 +1,145 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_SCENE_H_
|
||||
#define ENGINE_INCLUDE_SCENE_H_
|
||||
|
||||
#include "log.hpp"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
#include "event_system.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <typeinfo>
|
||||
#include <assert.h>
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Application;
|
||||
class Application;
|
||||
|
||||
class Scene {
|
||||
class Scene {
|
||||
|
||||
public:
|
||||
public:
|
||||
Scene(Application* app);
|
||||
Scene(const Scene&) = delete;
|
||||
Scene& operator=(const Scene&) = delete;
|
||||
~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 */
|
||||
|
||||
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);
|
||||
|
||||
size_t getComponentSignaturePosition(size_t hash);
|
||||
size_t GetComponentSignaturePosition(size_t hash);
|
||||
|
||||
template <typename T>
|
||||
void registerComponent()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_componentArrays.contains(hash) == false && "Registering component type more than once.");
|
||||
m_componentArrays.emplace(hash, std::make_unique<ComponentArray<T>>());
|
||||
assert(component_arrays_.contains(hash) == false &&
|
||||
"Registering component type more than once.");
|
||||
component_arrays_.emplace(hash, std::make_unique<ComponentArray<T>>());
|
||||
|
||||
size_t componentSignaturePosition = m_nextSignaturePosition++;
|
||||
assert(componentSignaturePosition < MAX_COMPONENTS && "Registering too many components!");
|
||||
assert(m_componentSignaturePositions.contains(hash) == false);
|
||||
m_componentSignaturePositions.emplace(hash, componentSignaturePosition);
|
||||
size_t signature_position = next_signature_position_;
|
||||
++next_signature_position_;
|
||||
assert(signature_position < kMaxComponents &&
|
||||
"Registering too many components!");
|
||||
assert(component_signature_positions_.contains(hash) == false);
|
||||
component_signature_positions_.emplace(hash, signature_position);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* getComponent(uint32_t entity)
|
||||
T* GetComponent(uint32_t entity)
|
||||
{
|
||||
auto array = getComponentArray<T>();
|
||||
return array->getData(entity);
|
||||
auto array = GetComponentArray<T>();
|
||||
return array->GetData(entity);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* addComponent(uint32_t entity)
|
||||
T* AddComponent(uint32_t entity)
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
|
||||
auto array = getComponentArray<T>();
|
||||
array->insertData(entity, T{}); // errors if entity already exists in array
|
||||
auto array = GetComponentArray<T>();
|
||||
array->InsertData(entity, T{}); // errors if entity already exists in array
|
||||
|
||||
// set the component bit for this entity
|
||||
size_t componentSignaturePosition = m_componentSignaturePositions.at(hash);
|
||||
auto& signatureRef = m_signatures.at(entity);
|
||||
signatureRef.set(componentSignaturePosition);
|
||||
size_t signature_position = component_signature_positions_.at(hash);
|
||||
auto& signature_ref = signatures_.at(entity);
|
||||
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->m_signature & signatureRef) == system->m_signature) {
|
||||
system->m_entities.insert(entity);
|
||||
system->onComponentInsert(entity);
|
||||
if (system->entities_.contains(entity)) continue;
|
||||
if ((system->signature_ & signature_ref) == system->signature_) {
|
||||
system->entities_.insert(entity);
|
||||
system->OnComponentInsert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return array->getData(entity);
|
||||
return array->GetData(entity);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void registerSystem()
|
||||
void RegisterSystem()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
assert(m_systems.find(hash) == m_systems.end() && "Registering system more than once.");
|
||||
m_systems.emplace(hash, std::make_unique<T>(this));
|
||||
assert(systems_.find(hash) == systems_.end() &&
|
||||
"Registering system more than once.");
|
||||
systems_.emplace(hash, std::make_unique<T>(this));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* getSystem()
|
||||
T* GetSystem()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
auto it = m_systems.find(hash);
|
||||
if (it == m_systems.end()) {
|
||||
auto it = systems_.find(hash);
|
||||
if (it == systems_.end()) {
|
||||
throw std::runtime_error("Cannot find ecs system.");
|
||||
}
|
||||
auto ptr = it->second.get();
|
||||
auto castedPtr = dynamic_cast<T*>(ptr);
|
||||
assert(castedPtr != nullptr);
|
||||
return castedPtr;
|
||||
auto casted_ptr = dynamic_cast<T*>(ptr);
|
||||
assert(casted_ptr != nullptr);
|
||||
return casted_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Application* const m_app;
|
||||
uint32_t m_nextEntityID = 1000;
|
||||
private:
|
||||
Application* const app_;
|
||||
uint32_t next_entity_id_ = 1000;
|
||||
|
||||
/* ecs stuff */
|
||||
|
||||
size_t m_nextSignaturePosition = 0;
|
||||
size_t next_signature_position_ = 0;
|
||||
// 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
|
||||
std::map<uint32_t, std::bitset<MAX_COMPONENTS>> m_signatures{};
|
||||
std::map<uint32_t, std::bitset<kMaxComponents>> signatures_{};
|
||||
// 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
|
||||
std::map<size_t, std::unique_ptr<System>> m_systems{};
|
||||
std::map<size_t, std::unique_ptr<System>> systems_{};
|
||||
|
||||
template <typename T>
|
||||
ComponentArray<T>* getComponentArray()
|
||||
ComponentArray<T>* GetComponentArray()
|
||||
{
|
||||
size_t hash = typeid(T).hash_code();
|
||||
auto it = m_componentArrays.find(hash);
|
||||
if (it == m_componentArrays.end()) {
|
||||
auto it = component_arrays_.find(hash);
|
||||
if (it == component_arrays_.end()) {
|
||||
throw std::runtime_error("Cannot find component array.");
|
||||
}
|
||||
auto ptr = it->second.get();
|
||||
auto castedPtr = dynamic_cast<ComponentArray<T>*>(ptr);
|
||||
assert(castedPtr != nullptr);
|
||||
return castedPtr;
|
||||
auto casted_ptr = dynamic_cast<ComponentArray<T>*>(ptr);
|
||||
assert(casted_ptr != nullptr);
|
||||
return casted_ptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<EventSystem> m_eventSystem{};
|
||||
std::unique_ptr<EventSystem> event_system_{};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -1,34 +1,37 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_SCENE_MANAGER_H_
|
||||
#define ENGINE_INCLUDE_SCENE_MANAGER_H_
|
||||
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "scene.hpp"
|
||||
#include "resource_manager.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class Application;
|
||||
class Scene; // "scene.hpp"
|
||||
class Application;
|
||||
|
||||
class SceneManager {
|
||||
class SceneManager {
|
||||
|
||||
public:
|
||||
public:
|
||||
SceneManager(Application* app);
|
||||
~SceneManager();
|
||||
SceneManager(const SceneManager&) = delete;
|
||||
SceneManager& operator=(const SceneManager&) = delete;
|
||||
|
||||
// creates an empty scene and sets it as active
|
||||
Scene* createEmptyScene();
|
||||
Scene* CreateEmptyScene();
|
||||
|
||||
void updateActiveScene(float ts);
|
||||
void UpdateActiveScene(float ts);
|
||||
|
||||
private:
|
||||
Application* const m_app;
|
||||
private:
|
||||
Application* const app_;
|
||||
|
||||
std::vector<std::unique_ptr<Scene>> m_scenes;
|
||||
int m_activeSceneIndex = -1;
|
||||
std::vector<std::unique_ptr<Scene>> scenes_;
|
||||
int active_scene_index_ = -1;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
#include "components/collider.hpp"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
#include "components/collider.hpp"
|
||||
#include "ecs_system.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class PhysicsSystem : public System {
|
||||
@ -13,9 +15,9 @@ namespace engine {
|
||||
public:
|
||||
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 {
|
||||
bool isCollisionEnter; // false == collision exit
|
||||
|
@ -18,7 +18,7 @@ namespace engine {
|
||||
RenderSystem(Scene* scene);
|
||||
~RenderSystem();
|
||||
|
||||
void onUpdate(float ts) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
void setCameraEntity(uint32_t entity);
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace engine {
|
||||
Render2DSystem(Scene* scene);
|
||||
~Render2DSystem();
|
||||
|
||||
void onUpdate(float ts) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace engine {
|
||||
public:
|
||||
TransformSystem(Scene* scene);
|
||||
|
||||
void onUpdate(float ts) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
uint32_t getChildEntity(uint32_t parent, const std::string& tag);
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace engine {
|
||||
public:
|
||||
UISystem(Scene* scene);
|
||||
|
||||
void onUpdate(float ts) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -1,18 +1,22 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_INCLUDE_UTIL_H_
|
||||
#define ENGINE_INCLUDE_UTIL_H_
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
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) {
|
||||
*major = 0;
|
||||
*minor = 0;
|
||||
*patch = 0;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace engine
|
||||
|
||||
#endif
|
@ -1,23 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include "engine_api.h"
|
||||
|
||||
#include "inputs/keyboard.hpp"
|
||||
#include "inputs/mouse.hpp"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#ifndef ENGINE_INCLUDE_WINDOW_H_
|
||||
#define ENGINE_INCLUDE_WINDOW_H_
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "inputs/keyboard.hpp"
|
||||
#include "inputs/mouse.hpp"
|
||||
|
||||
namespace engine {
|
||||
|
||||
class ENGINE_API Window {
|
||||
class Window {
|
||||
|
||||
public:
|
||||
Window(const std::string& title, bool resizable = true, bool fullscreen = true);
|
||||
public:
|
||||
Window(const std::string& title, bool resizable = true,
|
||||
bool fullscreen = true);
|
||||
Window(const Window&) = delete;
|
||||
Window& operator=(const Window&) = delete;
|
||||
~Window();
|
||||
@ -52,7 +51,8 @@ namespace engine {
|
||||
|
||||
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);
|
||||
|
||||
// returns true if relative mouse mode is enabled
|
||||
@ -123,7 +123,7 @@ namespace engine {
|
||||
/* STATIC METHODS */
|
||||
static void errorBox(const std::string& message);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
SDL_Window* m_handle;
|
||||
|
||||
@ -193,6 +193,8 @@ namespace engine {
|
||||
void onMouseButtonEvent(SDL_MouseButtonEvent& e);
|
||||
void onMouseMotionEvent(SDL_MouseMotionEvent& e);
|
||||
void onMouseWheelEvent(SDL_MouseWheelEvent& e);
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,28 +1,29 @@
|
||||
#include "application.hpp"
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include "window.hpp"
|
||||
#include "gfx_device.hpp"
|
||||
#include "input_manager.hpp"
|
||||
#include "scene_manager.hpp"
|
||||
|
||||
#include "scene.hpp"
|
||||
|
||||
#include "resources/mesh.hpp"
|
||||
#include "resources/material.hpp"
|
||||
#include "resources/shader.hpp"
|
||||
#include "resources/texture.hpp"
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <glm/mat4x4.hpp>
|
||||
|
||||
// To allow the FPS-limiter to put the thread to sleep
|
||||
#include <thread>
|
||||
#include "gfx.hpp"
|
||||
#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
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#define MAX_PATH 260
|
||||
#define WIN_MAX_PATH 260
|
||||
#endif
|
||||
|
||||
namespace engine {
|
||||
@ -33,7 +34,7 @@ namespace engine {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
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();
|
||||
(void)_chdir((const char*)std::filesystem::absolute(cwd).c_str());
|
||||
#else
|
||||
@ -60,57 +61,57 @@ namespace engine {
|
||||
|
||||
Application::Application(const char* appName, const char* appVersion, gfx::GraphicsSettings graphicsSettings)
|
||||
{
|
||||
m_window = std::make_unique<Window>(appName, true, false);
|
||||
m_inputManager = std::make_unique<InputManager>(window());
|
||||
m_sceneManager = std::make_unique<SceneManager>(this);
|
||||
window_ = std::make_unique<Window>(appName, true, false);
|
||||
input_manager_ = std::make_unique<InputManager>(window_.get());
|
||||
scene_manager_ = std::make_unique<SceneManager>(this);
|
||||
|
||||
// get base path for resources
|
||||
m_resourcesPath = getResourcesPath();
|
||||
resources_path_ = getResourcesPath();
|
||||
|
||||
// register resource managers
|
||||
registerResourceManager<resources::Texture>();
|
||||
registerResourceManager<resources::Shader>();
|
||||
registerResourceManager<resources::Material>();
|
||||
registerResourceManager<resources::Mesh>();
|
||||
RegisterResourceManager<resources::Texture>();
|
||||
RegisterResourceManager<resources::Shader>();
|
||||
RegisterResourceManager<resources::Material>();
|
||||
RegisterResourceManager<resources::Mesh>();
|
||||
|
||||
// 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;
|
||||
{
|
||||
auto& binding0 = globalSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
renderData.globalSetLayout = gfx()->createDescriptorSetLayout(globalSetBindings);
|
||||
renderData.globalSet = gfx()->allocateDescriptorSet(renderData.globalSetLayout);
|
||||
render_data_.global_set_layout = gfxdev()->CreateDescriptorSetLayout(globalSetBindings);
|
||||
render_data_.global_set = gfxdev()->AllocateDescriptorSet(render_data_.global_set_layout);
|
||||
RenderData::GlobalSetUniformBuffer globalSetUniformBufferData{
|
||||
.proj = glm::mat4{ 1.0f },
|
||||
};
|
||||
renderData.globalSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.globalSet, 0, renderData.globalSetUniformBuffer, 0, sizeof(RenderData::GlobalSetUniformBuffer));
|
||||
render_data_.global_set_uniform_buffer = gfxdev()->CreateUniformBuffer(sizeof(RenderData::GlobalSetUniformBuffer), &globalSetUniformBufferData);
|
||||
gfxdev()->UpdateDescriptorUniformBuffer(render_data_.global_set, 0, render_data_.global_set_uniform_buffer, 0, sizeof(RenderData::GlobalSetUniformBuffer));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> frameSetBindings;
|
||||
{
|
||||
auto& binding0 = frameSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::UNIFORM_BUFFER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::VERTEX;
|
||||
binding0.descriptor_type = gfx::DescriptorType::kUniformBuffer;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kVertex;
|
||||
}
|
||||
renderData.frameSetLayout = gfx()->createDescriptorSetLayout(frameSetBindings);
|
||||
renderData.frameSet = gfx()->allocateDescriptorSet(renderData.frameSetLayout);
|
||||
render_data_.frame_set_layout = gfxdev()->CreateDescriptorSetLayout(frameSetBindings);
|
||||
render_data_.frame_set = gfxdev()->AllocateDescriptorSet(render_data_.frame_set_layout);
|
||||
RenderData::FrameSetUniformBuffer initialSetOneData{
|
||||
.view = glm::mat4{ 1.0f },
|
||||
};
|
||||
renderData.frameSetUniformBuffer = gfx()->createUniformBuffer(sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData);
|
||||
gfx()->updateDescriptorUniformBuffer(renderData.frameSet, 0, renderData.frameSetUniformBuffer, 0, sizeof(RenderData::FrameSetUniformBuffer));
|
||||
render_data_.frame_set_uniform_buffer = gfxdev()->CreateUniformBuffer(sizeof(RenderData::FrameSetUniformBuffer), &initialSetOneData);
|
||||
gfxdev()->UpdateDescriptorUniformBuffer(render_data_.frame_set, 0, render_data_.frame_set_uniform_buffer, 0, sizeof(RenderData::FrameSetUniformBuffer));
|
||||
|
||||
std::vector<gfx::DescriptorSetLayoutBinding> materialSetBindings;
|
||||
{
|
||||
auto& binding0 = materialSetBindings.emplace_back();
|
||||
binding0.descriptorType = gfx::DescriptorType::COMBINED_IMAGE_SAMPLER;
|
||||
binding0.stageFlags = gfx::ShaderStageFlags::FRAGMENT;
|
||||
binding0.descriptor_type = gfx::DescriptorType::kCombinedImageSampler;
|
||||
binding0.stage_flags = gfx::ShaderStageFlags::kFragment;
|
||||
}
|
||||
renderData.materialSetLayout = gfx()->createDescriptorSetLayout(materialSetBindings);
|
||||
render_data_.material_set_layout = gfxdev()->CreateDescriptorSetLayout(materialSetBindings);
|
||||
|
||||
// default resources
|
||||
{
|
||||
@ -118,54 +119,54 @@ namespace engine {
|
||||
vertParams.hasNormal = true;
|
||||
vertParams.hasUV0 = true;
|
||||
auto texturedShader = std::make_unique<resources::Shader>(
|
||||
&renderData,
|
||||
getResourcePath("engine/shaders/standard.vert").c_str(),
|
||||
getResourcePath("engine/shaders/standard.frag").c_str(),
|
||||
&render_data_,
|
||||
GetResourcePath("engine/shaders/standard.vert").c_str(),
|
||||
GetResourcePath("engine/shaders/standard.frag").c_str(),
|
||||
vertParams,
|
||||
false,
|
||||
true
|
||||
);
|
||||
getResourceManager<resources::Shader>()->addPersistent("builtin.standard", std::move(texturedShader));
|
||||
GetResourceManager<resources::Shader>()->AddPersistent("builtin.standard", std::move(texturedShader));
|
||||
}
|
||||
{
|
||||
resources::Shader::VertexParams vertParams{};
|
||||
vertParams.hasNormal = true;
|
||||
vertParams.hasUV0 = true;
|
||||
auto skyboxShader = std::make_unique<resources::Shader>(
|
||||
&renderData,
|
||||
getResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||
getResourcePath("engine/shaders/skybox.frag").c_str(),
|
||||
&render_data_,
|
||||
GetResourcePath("engine/shaders/skybox.vert").c_str(),
|
||||
GetResourcePath("engine/shaders/skybox.frag").c_str(),
|
||||
vertParams,
|
||||
false,
|
||||
true
|
||||
);
|
||||
getResourceManager<resources::Shader>()->addPersistent("builtin.skybox", std::move(skyboxShader));
|
||||
GetResourceManager<resources::Shader>()->AddPersistent("builtin.skybox", std::move(skyboxShader));
|
||||
}
|
||||
{
|
||||
auto whiteTexture = std::make_unique<resources::Texture>(
|
||||
&renderData,
|
||||
getResourcePath("engine/textures/white.png"),
|
||||
&render_data_,
|
||||
GetResourcePath("engine/textures/white.png"),
|
||||
resources::Texture::Filtering::OFF
|
||||
);
|
||||
getResourceManager<resources::Texture>()->addPersistent("builtin.white", std::move(whiteTexture));
|
||||
GetResourceManager<resources::Texture>()->AddPersistent("builtin.white", std::move(whiteTexture));
|
||||
}
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
for (const auto& [info, sampler] : renderData.samplers) {
|
||||
gfx()->destroySampler(sampler);
|
||||
for (const auto& [info, sampler] : render_data_.samplers) {
|
||||
gfxdev()->DestroySampler(sampler);
|
||||
}
|
||||
gfx()->destroyDescriptorSetLayout(renderData.materialSetLayout);
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.material_set_layout);
|
||||
|
||||
gfx()->destroyUniformBuffer(renderData.frameSetUniformBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.frameSetLayout);
|
||||
gfxdev()->DestroyUniformBuffer(render_data_.frame_set_uniform_buffer);
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.frame_set_layout);
|
||||
|
||||
gfx()->destroyUniformBuffer(renderData.globalSetUniformBuffer);
|
||||
gfx()->destroyDescriptorSetLayout(renderData.globalSetLayout);
|
||||
gfxdev()->DestroyUniformBuffer(render_data_.global_set_uniform_buffer);
|
||||
gfxdev()->DestroyDescriptorSetLayout(render_data_.global_set_layout);
|
||||
}
|
||||
|
||||
void Application::gameLoop()
|
||||
void Application::GameLoop()
|
||||
{
|
||||
LOG_TRACE("Begin game loop...");
|
||||
|
||||
@ -174,31 +175,31 @@ namespace engine {
|
||||
auto beginFrame = std::chrono::steady_clock::now();
|
||||
auto endFrame = beginFrame + FRAMETIME_LIMIT;
|
||||
|
||||
auto lastTick = m_window->getNanos();
|
||||
auto lastTick = window_->getNanos();
|
||||
|
||||
// single-threaded game loop
|
||||
while (m_window->isRunning()) {
|
||||
while (window_->isRunning()) {
|
||||
|
||||
/* logic */
|
||||
m_sceneManager->updateActiveScene(m_window->dt());
|
||||
scene_manager_->UpdateActiveScene(window_->dt());
|
||||
|
||||
if(m_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");
|
||||
if(window_->getKeyPress(inputs::Key::K_F)) [[unlikely]] {
|
||||
window_->infoBox("fps", std::to_string(window_->getFPS()) + " fps " + std::to_string(window_->dt() * 1000.0f) + " ms");
|
||||
}
|
||||
|
||||
uint64_t now = m_window->getNanos();
|
||||
uint64_t now = window_->getNanos();
|
||||
if (now - lastTick >= 1000000000LL * 5LL) [[unlikely]] {
|
||||
lastTick = now;
|
||||
LOG_INFO("fps: {}", m_window->getAvgFPS());
|
||||
gfx()->logPerformanceInfo();
|
||||
m_window->resetAvgFPS();
|
||||
LOG_INFO("fps: {}", window_->getAvgFPS());
|
||||
gfxdev()->LogPerformanceInfo();
|
||||
window_->resetAvgFPS();
|
||||
}
|
||||
|
||||
/* poll events */
|
||||
m_window->getInputAndEvents();
|
||||
window_->getInputAndEvents();
|
||||
|
||||
/* fps limiter */
|
||||
if (m_enableFrameLimiter) {
|
||||
if (enable_frame_limiter_) {
|
||||
std::this_thread::sleep_until(endFrame);
|
||||
}
|
||||
beginFrame = endFrame;
|
||||
@ -206,7 +207,7 @@ namespace engine {
|
||||
|
||||
}
|
||||
|
||||
gfx()->waitIdle();
|
||||
gfxdev()->WaitIdle();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,11 +5,11 @@
|
||||
namespace engine {
|
||||
|
||||
System::System(Scene* scene, std::set<size_t> requiredComponentHashes)
|
||||
: m_scene(scene)
|
||||
: scene_(scene)
|
||||
{
|
||||
for (size_t componentHash : requiredComponentHashes) {
|
||||
size_t componentSignaturePosition = m_scene->getComponentSignaturePosition(componentHash);
|
||||
m_signature.set(componentSignaturePosition);
|
||||
size_t componentSignaturePosition = scene_->GetComponentSignaturePosition(componentHash);
|
||||
signature_.set(componentSignaturePosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,11 +130,11 @@ namespace engine {
|
||||
static VkFormat getVertexAttribFormat(gfx::VertexAttribFormat fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
case gfx::VertexAttribFormat::FLOAT2:
|
||||
case gfx::VertexAttribFormat::kFloat2:
|
||||
return VK_FORMAT_R32G32_SFLOAT;
|
||||
case gfx::VertexAttribFormat::FLOAT3:
|
||||
case gfx::VertexAttribFormat::kFloat3:
|
||||
return VK_FORMAT_R32G32B32_SFLOAT;
|
||||
case gfx::VertexAttribFormat::FLOAT4:
|
||||
case gfx::VertexAttribFormat::kFloat4:
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
}
|
||||
throw std::runtime_error("Unknown vertex attribute format");
|
||||
@ -143,11 +143,11 @@ namespace engine {
|
||||
static VkBufferUsageFlagBits getBufferUsageFlag(gfx::BufferType type)
|
||||
{
|
||||
switch (type) {
|
||||
case gfx::BufferType::VERTEX:
|
||||
case gfx::BufferType::kVertex:
|
||||
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||
case gfx::BufferType::INDEX:
|
||||
case gfx::BufferType::kIndex:
|
||||
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||
case gfx::BufferType::UNIFORM:
|
||||
case gfx::BufferType::kUniform:
|
||||
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
switch (filter) {
|
||||
case gfx::Filter::LINEAR:
|
||||
case gfx::Filter::kLinear:
|
||||
return VK_FILTER_LINEAR;
|
||||
case gfx::Filter::NEAREST:
|
||||
case gfx::Filter::kNearest:
|
||||
return VK_FILTER_NEAREST;
|
||||
}
|
||||
throw std::runtime_error("Unknown filter");
|
||||
@ -168,9 +168,9 @@ namespace engine {
|
||||
[[maybe_unused]] static VkSamplerMipmapMode getSamplerMipmapMode(gfx::Filter filter)
|
||||
{
|
||||
switch (filter) {
|
||||
case gfx::Filter::LINEAR:
|
||||
case gfx::Filter::kLinear:
|
||||
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
case gfx::Filter::NEAREST:
|
||||
case gfx::Filter::kNearest:
|
||||
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
}
|
||||
throw std::runtime_error("Unknown filter");
|
||||
@ -179,15 +179,15 @@ namespace engine {
|
||||
[[maybe_unused]] static VkSampleCountFlags getSampleCountFlags(gfx::MSAALevel level)
|
||||
{
|
||||
switch (level) {
|
||||
case gfx::MSAALevel::MSAA_OFF:
|
||||
case gfx::MSAALevel::kOff:
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
case gfx::MSAALevel::MSAA_2X:
|
||||
case gfx::MSAALevel::k2X:
|
||||
return VK_SAMPLE_COUNT_2_BIT;
|
||||
case gfx::MSAALevel::MSAA_4X:
|
||||
case gfx::MSAALevel::k4X:
|
||||
return VK_SAMPLE_COUNT_4_BIT;
|
||||
case gfx::MSAALevel::MSAA_8X:
|
||||
case gfx::MSAALevel::k8X:
|
||||
return VK_SAMPLE_COUNT_8_BIT;
|
||||
case gfx::MSAALevel::MSAA_16X:
|
||||
case gfx::MSAALevel::k16X:
|
||||
return VK_SAMPLE_COUNT_16_BIT;
|
||||
default:
|
||||
throw std::runtime_error("Unknown MSAA level");
|
||||
@ -197,9 +197,9 @@ namespace engine {
|
||||
static VkDescriptorType getDescriptorType(gfx::DescriptorType type)
|
||||
{
|
||||
switch (type) {
|
||||
case gfx::DescriptorType::UNIFORM_BUFFER:
|
||||
case gfx::DescriptorType::kUniformBuffer:
|
||||
return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
case gfx::DescriptorType::COMBINED_IMAGE_SAMPLER:
|
||||
case gfx::DescriptorType::kCombinedImageSampler:
|
||||
return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
default:
|
||||
throw std::runtime_error("Unknown descriptor type");
|
||||
@ -209,8 +209,8 @@ namespace engine {
|
||||
static VkShaderStageFlags getShaderStageFlags(gfx::ShaderStageFlags::Flags flags)
|
||||
{
|
||||
VkShaderStageFlags out = 0;
|
||||
if (flags & gfx::ShaderStageFlags::VERTEX) out |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (flags & gfx::ShaderStageFlags::FRAGMENT) out |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
if (flags & gfx::ShaderStageFlags::kVertex) out |= VK_SHADER_STAGE_VERTEX_BIT;
|
||||
if (flags & gfx::ShaderStageFlags::kFragment) out |= VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ namespace engine {
|
||||
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) {
|
||||
throw std::runtime_error("Unable to create window surface");
|
||||
@ -440,7 +440,7 @@ namespace engine {
|
||||
pimpl->swapchainInfo.surface = pimpl->surface;
|
||||
pimpl->swapchainInfo.window = pimpl->window;
|
||||
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);
|
||||
|
||||
/* make synchronisation primitives for rendering and allocate command buffers */
|
||||
@ -541,7 +541,7 @@ namespace engine {
|
||||
destroyVulkanInstance(pimpl->instance);
|
||||
}
|
||||
|
||||
void GFXDevice::getViewportSize(uint32_t* w, uint32_t* h)
|
||||
void GFXDevice::GetViewportSize(uint32_t* w, uint32_t* h)
|
||||
{
|
||||
int 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;
|
||||
|
||||
@ -724,7 +724,7 @@ namespace engine {
|
||||
|
||||
}
|
||||
|
||||
void GFXDevice::finishRender(gfx::DrawBuffer* drawBuffer)
|
||||
void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
|
||||
{
|
||||
assert(drawBuffer != nullptr);
|
||||
|
||||
@ -785,68 +785,68 @@ namespace engine {
|
||||
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);
|
||||
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(buffer != nullptr);
|
||||
assert(buffer->type == gfx::BufferType::VERTEX);
|
||||
assert(buffer->type == gfx::BufferType::kVertex);
|
||||
const VkDeviceSize offset = 0;
|
||||
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(buffer != nullptr);
|
||||
assert(buffer->type == gfx::BufferType::INDEX);
|
||||
assert(buffer->type == gfx::BufferType::kIndex);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
gfx::Pipeline* GFXDevice::createPipeline(const gfx::PipelineInfo& info)
|
||||
gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
|
||||
{
|
||||
|
||||
[[maybe_unused]] VkResult res;
|
||||
|
||||
gfx::Pipeline* pipeline = new gfx::Pipeline;
|
||||
|
||||
auto vertShaderCode = util::readTextFile(info.vertShaderPath);
|
||||
auto fragShaderCode = util::readTextFile(info.fragShaderPath);
|
||||
auto vertShaderCode = util::readTextFile(info.vert_shader_path);
|
||||
auto fragShaderCode = util::readTextFile(info.frag_shader_path);
|
||||
|
||||
VkShaderModule vertShaderModule = compileShader(pimpl->device.device, shaderc_vertex_shader, vertShaderCode->data(), info.vertShaderPath);
|
||||
VkShaderModule fragShaderModule = compileShader(pimpl->device.device, shaderc_fragment_shader, fragShaderCode->data(), info.fragShaderPath);
|
||||
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.frag_shader_path);
|
||||
|
||||
// get vertex attrib layout:
|
||||
VkVertexInputBindingDescription bindingDescription{ };
|
||||
bindingDescription.binding = 0;
|
||||
bindingDescription.stride = info.vertexFormat.stride;
|
||||
bindingDescription.stride = info.vertex_format.stride;
|
||||
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
|
||||
std::vector<VkVertexInputAttributeDescription> attribDescs{};
|
||||
attribDescs.reserve(info.vertexFormat.attributeDescriptions.size());
|
||||
for (const auto& desc : info.vertexFormat.attributeDescriptions) {
|
||||
attribDescs.reserve(info.vertex_format.attribute_descriptions.size());
|
||||
for (const auto& desc : info.vertex_format.attribute_descriptions) {
|
||||
VkVertexInputAttributeDescription vulkanAttribDesc{};
|
||||
vulkanAttribDesc.location = desc.location;
|
||||
vulkanAttribDesc.binding = 0;
|
||||
@ -920,7 +920,7 @@ namespace engine {
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE; // enabling this will not run the fragment shaders at all
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
if (info.backfaceCulling == true) {
|
||||
if (info.backface_culling == true) {
|
||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
}
|
||||
else {
|
||||
@ -947,7 +947,7 @@ namespace engine {
|
||||
VK_COLOR_COMPONENT_G_BIT |
|
||||
VK_COLOR_COMPONENT_B_BIT |
|
||||
VK_COLOR_COMPONENT_A_BIT;
|
||||
if (info.alphaBlending) {
|
||||
if (info.alpha_blending) {
|
||||
colorBlendAttachment.blendEnable = VK_TRUE;
|
||||
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
@ -988,9 +988,9 @@ namespace engine {
|
||||
pushConstantRange.size = PUSH_CONSTANT_MAX_SIZE;
|
||||
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++) {
|
||||
descriptorSetLayouts[i] = info.descriptorSetLayouts[i]->layout;
|
||||
descriptorSetLayouts[i] = info.descriptor_set_layouts[i]->layout;
|
||||
}
|
||||
|
||||
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);
|
||||
vkDestroyPipelineLayout(pimpl->device.device, pipeline->layout, nullptr);
|
||||
@ -1039,7 +1039,7 @@ namespace engine {
|
||||
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{};
|
||||
|
||||
@ -1048,9 +1048,9 @@ namespace engine {
|
||||
for (const auto& binding : bindings) {
|
||||
auto& vulkanBinding = vulkanBindings.emplace_back();
|
||||
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.stageFlags = converters::getShaderStageFlags(binding.stageFlags);
|
||||
vulkanBinding.stageFlags = converters::getShaderStageFlags(binding.stage_flags);
|
||||
|
||||
++i;
|
||||
}
|
||||
@ -1066,13 +1066,13 @@ namespace engine {
|
||||
return out;
|
||||
}
|
||||
|
||||
void GFXDevice::destroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
|
||||
void GFXDevice::DestroyDescriptorSetLayout(const gfx::DescriptorSetLayout* layout)
|
||||
{
|
||||
vkDestroyDescriptorSetLayout(pimpl->device.device, layout->layout, nullptr);
|
||||
delete layout;
|
||||
}
|
||||
|
||||
gfx::DescriptorSet* GFXDevice::allocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
|
||||
gfx::DescriptorSet* GFXDevice::AllocateDescriptorSet(const gfx::DescriptorSetLayout* layout)
|
||||
{
|
||||
gfx::DescriptorSet* set = new gfx::DescriptorSet{};
|
||||
|
||||
@ -1094,7 +1094,7 @@ namespace engine {
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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{};
|
||||
|
||||
/* first make staging buffer */
|
||||
out->stagingBuffer.size = size;
|
||||
out->stagingBuffer.type = gfx::BufferType::UNIFORM;
|
||||
out->stagingBuffer.type = gfx::BufferType::kUniform;
|
||||
{
|
||||
VkBufferCreateInfo stagingBufferInfo{};
|
||||
stagingBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
@ -1177,7 +1177,7 @@ namespace engine {
|
||||
/* create the device-local set of buffers */
|
||||
for (uint32_t i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
out->gpuBuffers[i].size = out->stagingBuffer.size;
|
||||
out->gpuBuffers[i].type = gfx::BufferType::UNIFORM;
|
||||
out->gpuBuffers[i].type = gfx::BufferType::kUniform;
|
||||
|
||||
VkBufferCreateInfo gpuBufferInfo{};
|
||||
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++) {
|
||||
vmaDestroyBuffer(pimpl->allocator, uniformBuffer->gpuBuffers[i].buffer, uniformBuffer->gpuBuffers[i].allocation);
|
||||
@ -1211,7 +1211,7 @@ namespace engine {
|
||||
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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
// 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(pimpl->FRAMECOUNT == 0);
|
||||
@ -1541,14 +1541,14 @@ namespace engine {
|
||||
return out;
|
||||
}
|
||||
|
||||
void GFXDevice::destroyImage(const gfx::Image *image)
|
||||
void GFXDevice::DestroyImage(const gfx::Image *image)
|
||||
{
|
||||
vkDestroyImageView(pimpl->device.device, image->view, nullptr);
|
||||
vmaDestroyImage(pimpl->allocator, image->image, image->allocation);
|
||||
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{};
|
||||
|
||||
@ -1561,7 +1561,7 @@ namespace engine {
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
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.minLod = 0.0f;
|
||||
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
|
||||
@ -1571,13 +1571,13 @@ namespace engine {
|
||||
return out;
|
||||
}
|
||||
|
||||
void GFXDevice::destroySampler(const gfx::Sampler *sampler)
|
||||
void GFXDevice::DestroySampler(const gfx::Sampler *sampler)
|
||||
{
|
||||
vkDestroySampler(pimpl->device.device, sampler->sampler, nullptr);
|
||||
delete sampler;
|
||||
}
|
||||
|
||||
void GFXDevice::logPerformanceInfo()
|
||||
void GFXDevice::LogPerformanceInfo()
|
||||
{
|
||||
VmaTotalStatistics pStats{};
|
||||
vmaCalculateStatistics(pimpl->allocator, &pStats);
|
||||
@ -1601,12 +1601,12 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t GFXDevice::getFrameCount()
|
||||
uint64_t GFXDevice::GetFrameCount()
|
||||
{
|
||||
return pimpl->FRAMECOUNT;
|
||||
}
|
||||
|
||||
void GFXDevice::waitIdle()
|
||||
void GFXDevice::WaitIdle()
|
||||
{
|
||||
vkDeviceWaitIdle(pimpl->device.device);
|
||||
}
|
||||
|
@ -7,185 +7,31 @@
|
||||
|
||||
namespace engine {
|
||||
|
||||
InputManager::InputManager(const Window* win) : m_win(win)
|
||||
{
|
||||
m_enabledDevices.fill(true);
|
||||
}
|
||||
|
||||
InputManager::~InputManager() {}
|
||||
|
||||
/* 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);
|
||||
float InputManager::GetAxis(const std::string& axis_name) const
|
||||
{
|
||||
for (const AxisEntry& e : axis_entries_) {
|
||||
if (e.name == axis_name) {
|
||||
if (enabled_devices_[static_cast<int>(e.device)]) {
|
||||
if (e.is_button_axis) {
|
||||
return GetButtonAxis(e.device, e.high, e.low);
|
||||
}
|
||||
else {
|
||||
return getDeviceAxis(e.device, e.axis);
|
||||
return GetDeviceAxis(e.device, e.axis);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
for (const ButtonEntry& e : m_buttonEntries) {
|
||||
for (const ButtonEntry& e : button_entries_) {
|
||||
if (e.name == buttonName) {
|
||||
if (m_enabledDevices[static_cast<int>(e.device)]) {
|
||||
if (getDeviceButton(e.device, e.button) == true) {
|
||||
if (enabled_devices_[static_cast<int>(e.device)]) {
|
||||
if (GetDeviceButton(e.device, e.button) == true) {
|
||||
isDown = true;
|
||||
break;
|
||||
}
|
||||
@ -193,15 +39,15 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
return isDown;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputManager::getButtonPress(const std::string& buttonName) const
|
||||
{
|
||||
bool InputManager::GetButtonPress(const std::string& buttonName) const
|
||||
{
|
||||
bool isPressed = false;
|
||||
|
||||
for (const ButtonEntry& e : m_buttonEntries) {
|
||||
for (const ButtonEntry& e : button_entries_) {
|
||||
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) {
|
||||
isPressed = true;
|
||||
break;
|
||||
@ -210,16 +56,16 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
return isPressed;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputManager::getButtonRelease(const std::string& buttonName) const
|
||||
{
|
||||
bool InputManager::GetButtonRelease(const std::string& buttonName) const
|
||||
{
|
||||
bool isReleased = false;
|
||||
|
||||
for (const ButtonEntry& e : m_buttonEntries) {
|
||||
for (const ButtonEntry& e : button_entries_) {
|
||||
if (e.name == buttonName) {
|
||||
if (m_enabledDevices[static_cast<int>(e.device)]) {
|
||||
if (getDeviceButtonUp(e.device, e.button) == true) {
|
||||
if (enabled_devices_[static_cast<int>(e.device)]) {
|
||||
if (GetDeviceButtonUp(e.device, e.button) == true) {
|
||||
isReleased = true;
|
||||
break;
|
||||
}
|
||||
@ -227,6 +73,74 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
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()
|
||||
{
|
||||
m_gfx->destroyBuffer(m_ib);
|
||||
m_gfx->destroyBuffer(m_vb);
|
||||
m_gfx->DestroyBuffer(m_ib);
|
||||
m_gfx->DestroyBuffer(m_vb);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_vb = m_gfx->createBuffer(gfx::BufferType::VERTEX, vertices.size() * sizeof(Vertex), vertices.data());
|
||||
m_ib = m_gfx->createBuffer(gfx::BufferType::INDEX, indices.size() * sizeof(uint32_t), indices.data());
|
||||
m_vb = m_gfx->CreateBuffer(gfx::BufferType::kVertex, vertices.size() * sizeof(Vertex), vertices.data());
|
||||
m_ib = m_gfx->CreateBuffer(gfx::BufferType::kIndex, indices.size() * sizeof(uint32_t), indices.data());
|
||||
m_count = (uint32_t)indices.size();
|
||||
LOG_INFO("Loaded mesh, vertices: {}, indices: {}", vertices.size(), indices.size());
|
||||
}
|
||||
|
@ -17,46 +17,46 @@ namespace engine::resources {
|
||||
uint32_t stride = 0;
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
vertFormat.stride = stride;
|
||||
|
||||
gfx::PipelineInfo info{};
|
||||
info.vertShaderPath = vertPath;
|
||||
info.fragShaderPath = fragPath;
|
||||
info.vertexFormat = vertFormat;
|
||||
info.alphaBlending = alphaBlending;
|
||||
info.backfaceCulling = cullBackFace;
|
||||
info.descriptorSetLayouts.push_back(renderData->globalSetLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->frameSetLayout);
|
||||
info.descriptorSetLayouts.push_back(renderData->materialSetLayout);
|
||||
info.vert_shader_path = vertPath;
|
||||
info.frag_shader_path = fragPath;
|
||||
info.vertex_format = vertFormat;
|
||||
info.alpha_blending = alphaBlending;
|
||||
info.backface_culling = cullBackFace;
|
||||
info.descriptor_set_layouts.push_back(renderData->global_set_layout);
|
||||
info.descriptor_set_layouts.push_back(renderData->frame_set_layout);
|
||||
info.descriptor_set_layouts.push_back(renderData->material_set_layout);
|
||||
|
||||
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()
|
||||
{
|
||||
m_gfx->destroyPipeline(m_pipeline);
|
||||
m_gfx->DestroyPipeline(m_pipeline);
|
||||
}
|
||||
|
||||
const gfx::Pipeline* Shader::getPipeline()
|
||||
|
@ -17,37 +17,37 @@ Texture::Texture(RenderData* renderData, const std::string& path, Filtering filt
|
||||
|
||||
gfx::SamplerInfo samplerInfo{};
|
||||
|
||||
samplerInfo.magnify = gfx::Filter::LINEAR;
|
||||
samplerInfo.magnify = gfx::Filter::kLinear;
|
||||
|
||||
switch (filtering) {
|
||||
case Filtering::OFF:
|
||||
samplerInfo.minify = gfx::Filter::NEAREST;
|
||||
samplerInfo.mipmap = gfx::Filter::NEAREST;
|
||||
samplerInfo.anisotropicFiltering = false;
|
||||
samplerInfo.minify = gfx::Filter::kNearest;
|
||||
samplerInfo.mipmap = gfx::Filter::kNearest;
|
||||
samplerInfo.anisotropic_filtering = false;
|
||||
break;
|
||||
case Filtering::BILINEAR:
|
||||
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||
samplerInfo.mipmap = gfx::Filter::NEAREST;
|
||||
samplerInfo.anisotropicFiltering = false;
|
||||
samplerInfo.minify = gfx::Filter::kLinear;
|
||||
samplerInfo.mipmap = gfx::Filter::kNearest;
|
||||
samplerInfo.anisotropic_filtering = false;
|
||||
break;
|
||||
case Filtering::TRILINEAR:
|
||||
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||
samplerInfo.mipmap = gfx::Filter::LINEAR;
|
||||
samplerInfo.anisotropicFiltering = false;
|
||||
samplerInfo.minify = gfx::Filter::kLinear;
|
||||
samplerInfo.mipmap = gfx::Filter::kLinear;
|
||||
samplerInfo.anisotropic_filtering = false;
|
||||
break;
|
||||
case Filtering::ANISOTROPIC:
|
||||
samplerInfo.minify = gfx::Filter::LINEAR;
|
||||
samplerInfo.mipmap = gfx::Filter::LINEAR;
|
||||
samplerInfo.anisotropicFiltering = true;
|
||||
samplerInfo.minify = gfx::Filter::kLinear;
|
||||
samplerInfo.mipmap = gfx::Filter::kLinear;
|
||||
samplerInfo.anisotropic_filtering = true;
|
||||
}
|
||||
|
||||
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_descriptorSet = m_gfxDevice->allocateDescriptorSet(renderData->materialSetLayout);
|
||||
m_gfxDevice->updateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, renderData->samplers.at(samplerInfo));
|
||||
m_image = m_gfxDevice->CreateImage(width, height, texbuf->data());
|
||||
m_descriptorSet = m_gfxDevice->AllocateDescriptorSet(renderData->material_set_layout);
|
||||
m_gfxDevice->UpdateDescriptorCombinedImageSampler(m_descriptorSet, 0, m_image, renderData->samplers.at(samplerInfo));
|
||||
|
||||
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()
|
||||
{
|
||||
m_gfxDevice->destroyImage(m_image);
|
||||
m_gfxDevice->DestroyImage(m_image);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,10 +10,10 @@
|
||||
namespace engine {
|
||||
|
||||
Scene::Scene(Application* app)
|
||||
: m_app(app)
|
||||
: app_(app)
|
||||
{
|
||||
// event system
|
||||
m_eventSystem = std::make_unique<EventSystem>();
|
||||
event_system_ = std::make_unique<EventSystem>();
|
||||
|
||||
// ecs configuration:
|
||||
|
||||
@ -22,22 +22,22 @@ namespace engine {
|
||||
registerComponent<ColliderComponent>();
|
||||
|
||||
// Order here matters:
|
||||
registerSystem<TransformSystem>();
|
||||
registerSystem<PhysicsSystem>();
|
||||
registerSystem<RenderSystem>();
|
||||
RegisterSystem<TransformSystem>();
|
||||
RegisterSystem<PhysicsSystem>();
|
||||
RegisterSystem<RenderSystem>();
|
||||
}
|
||||
|
||||
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->rotation = {};
|
||||
@ -51,21 +51,21 @@ namespace engine {
|
||||
|
||||
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) {
|
||||
system->onUpdate(ts);
|
||||
for (auto& [name, system] : systems_) {
|
||||
system->OnUpdate(ts);
|
||||
}
|
||||
|
||||
m_eventSystem->dispatchEvents(); // clears event queue
|
||||
event_system_->DespatchEvents(); // clears event queue
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,25 +8,25 @@
|
||||
namespace engine {
|
||||
|
||||
SceneManager::SceneManager(Application* app)
|
||||
: m_app(app)
|
||||
: app_(app)
|
||||
{
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager() {}
|
||||
|
||||
Scene* SceneManager::createEmptyScene()
|
||||
Scene* SceneManager::CreateEmptyScene()
|
||||
{
|
||||
auto scene = std::make_unique<Scene>(m_app);
|
||||
m_scenes.emplace_back(std::move(scene));
|
||||
m_activeSceneIndex = (int)m_scenes.size() - 1;
|
||||
return m_scenes.back().get();
|
||||
auto scene = std::make_unique<Scene>(app_);
|
||||
scenes_.emplace_back(std::move(scene));
|
||||
active_scene_index_ = (int)scenes_.size() - 1;
|
||||
return scenes_.back().get();
|
||||
}
|
||||
|
||||
void SceneManager::updateActiveScene(float ts)
|
||||
void SceneManager::UpdateActiveScene(float ts)
|
||||
{
|
||||
if (m_activeSceneIndex >= 0) [[likely]] {
|
||||
assert((size_t)m_activeSceneIndex < m_scenes.size());
|
||||
m_scenes[m_activeSceneIndex]->update(ts);
|
||||
if (active_scene_index_ >= 0) [[likely]] {
|
||||
assert((size_t)active_scene_index_ < scenes_.size());
|
||||
scenes_[active_scene_index_]->Update(ts);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,13 +68,13 @@ namespace engine {
|
||||
PhysicsSystem::PhysicsSystem(Scene* scene)
|
||||
: 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;
|
||||
const size_t size = m_entities.size();
|
||||
const size_t size = entities_.size();
|
||||
m_staticAABBs.reserve(size);
|
||||
m_dynamicAABBs.reserve(size);
|
||||
m_possibleCollisions.reserve(size);
|
||||
@ -82,7 +82,7 @@ namespace engine {
|
||||
LOG_TRACE("added entity {} to collider system", entity);
|
||||
}
|
||||
|
||||
void PhysicsSystem::onUpdate(float ts)
|
||||
void PhysicsSystem::OnUpdate(float ts)
|
||||
{
|
||||
(void)ts;
|
||||
|
||||
@ -91,9 +91,9 @@ namespace engine {
|
||||
m_possibleCollisions.clear();
|
||||
m_collisionInfos.clear();
|
||||
|
||||
for (uint32_t entity : m_entities) {
|
||||
const auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
const auto c = m_scene->getComponent<ColliderComponent>(entity);
|
||||
for (uint32_t entity : entities_) {
|
||||
const auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
const auto c = scene_->GetComponent<ColliderComponent>(entity);
|
||||
|
||||
const glm::vec3 globalPosition = t->worldMatrix[3];
|
||||
const AABB localBoundingBox = c->aabb;
|
||||
@ -157,7 +157,7 @@ namespace engine {
|
||||
}
|
||||
|
||||
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)
|
||||
: 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;
|
||||
|
||||
RenderData& renderData = m_scene->app()->renderData;
|
||||
RenderData& renderData = scene_->app()->render_data_;
|
||||
|
||||
/* 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
|
||||
if (cameraTransform == nullptr) return;
|
||||
|
||||
glm::mat4 viewMatrix = glm::inverse(cameraTransform->worldMatrix);
|
||||
|
||||
if (m_scene->app()->window()->getWindowResized()) {
|
||||
if (scene_->app()->window()->getWindowResized()) {
|
||||
uint32_t w, h;
|
||||
m_gfx->getViewportSize(&w, &h);
|
||||
m_gfx->GetViewportSize(&w, &h);
|
||||
m_viewportAspectRatio = (float)w / (float)h;
|
||||
const float verticalFovRadians = glm::radians(m_camera.verticalFovDegrees);
|
||||
const glm::mat4 projMatrix = glm::perspectiveZO(verticalFovRadians, m_viewportAspectRatio, m_camera.clipNear, m_camera.clipFar);
|
||||
@ -48,13 +48,13 @@ namespace engine {
|
||||
RenderData::GlobalSetUniformBuffer globalSetUniformBuffer{
|
||||
.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{
|
||||
.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 */
|
||||
|
||||
@ -71,16 +71,16 @@ namespace engine {
|
||||
};
|
||||
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->material != nullptr);
|
||||
assert(r->material->m_texture != nullptr);
|
||||
assert(r->mesh != nullptr);
|
||||
if (r->shown == false) continue;
|
||||
|
||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
assert(t != nullptr);
|
||||
|
||||
const gfx::Pipeline* pipeline = r->material->getShader()->getPipeline();
|
||||
@ -96,26 +96,26 @@ namespace engine {
|
||||
}
|
||||
|
||||
/* begin rendering */
|
||||
renderData.drawBuffer = m_gfx->beginRender();
|
||||
renderData.draw_buffer = m_gfx->BeginRender();
|
||||
|
||||
/* these descriptor set bindings should persist across pipeline changes */
|
||||
const gfx::Pipeline* firstPipeline = pipelineDrawCalls.begin()->first;
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.globalSet, 0);
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, firstPipeline, renderData.frameSet, 1);
|
||||
m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, firstPipeline, renderData.global_set, 0);
|
||||
m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, firstPipeline, renderData.frame_set, 1);
|
||||
|
||||
for (const auto& [pipeline, drawCalls] : pipelineDrawCalls) {
|
||||
m_gfx->cmdBindPipeline(renderData.drawBuffer, pipeline);
|
||||
m_gfx->CmdBindPipeline(renderData.draw_buffer, pipeline);
|
||||
for (const auto& drawCall : drawCalls) {
|
||||
m_gfx->cmdBindDescriptorSet(renderData.drawBuffer, pipeline, drawCall.materialSet, 2);
|
||||
m_gfx->cmdPushConstants(renderData.drawBuffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts);
|
||||
m_gfx->cmdBindVertexBuffer(renderData.drawBuffer, 0, drawCall.vb);
|
||||
m_gfx->cmdBindIndexBuffer(renderData.drawBuffer, drawCall.ib);
|
||||
m_gfx->cmdDrawIndexed(renderData.drawBuffer, drawCall.indexCount, 1, 0, 0, 0);
|
||||
m_gfx->CmdBindDescriptorSet(renderData.draw_buffer, pipeline, drawCall.materialSet, 2);
|
||||
m_gfx->CmdPushConstants(renderData.draw_buffer, pipeline, 0, sizeof(PushConstants), &drawCall.pushConsts);
|
||||
m_gfx->CmdBindVertexBuffer(renderData.draw_buffer, 0, drawCall.vb);
|
||||
m_gfx->CmdBindIndexBuffer(renderData.draw_buffer, drawCall.ib);
|
||||
m_gfx->CmdDrawIndexed(renderData.draw_buffer, drawCall.indexCount, 1, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw */
|
||||
m_gfx->finishRender(renderData.drawBuffer);
|
||||
m_gfx->FinishRender(renderData.draw_buffer);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "systems/render2d.hpp"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include "components/transform.hpp"
|
||||
|
||||
namespace engine {
|
||||
@ -13,7 +15,7 @@ namespace engine {
|
||||
{
|
||||
}
|
||||
|
||||
void Render2DSystem::onUpdate(float ts)
|
||||
void Render2DSystem::OnUpdate(float ts)
|
||||
{
|
||||
(void)ts;
|
||||
}
|
||||
|
@ -12,13 +12,13 @@ namespace engine {
|
||||
{
|
||||
}
|
||||
|
||||
void TransformSystem::onUpdate(float ts)
|
||||
void TransformSystem::OnUpdate(float 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;
|
||||
|
||||
@ -30,7 +30,7 @@ namespace engine {
|
||||
transform = glm::scale(transform, t->scale);
|
||||
|
||||
if (t->parent != 0) {
|
||||
transform = m_scene->getComponent<TransformComponent>(t->parent)->worldMatrix * transform;
|
||||
transform = scene_->GetComponent<TransformComponent>(t->parent)->worldMatrix * transform;
|
||||
}
|
||||
|
||||
t->worldMatrix = transform;
|
||||
@ -39,8 +39,8 @@ namespace engine {
|
||||
|
||||
uint32_t TransformSystem::getChildEntity(uint32_t parent, const std::string& tag)
|
||||
{
|
||||
for (uint32_t entity : m_entities) {
|
||||
auto t = m_scene->getComponent<TransformComponent>(entity);
|
||||
for (uint32_t entity : entities_) {
|
||||
auto t = scene_->GetComponent<TransformComponent>(entity);
|
||||
if (t->parent == parent) {
|
||||
if (t->tag == tag) {
|
||||
return entity;
|
||||
|
@ -12,7 +12,7 @@ namespace engine {
|
||||
|
||||
}
|
||||
|
||||
void UISystem::onUpdate(float ts)
|
||||
void UISystem::OnUpdate(float ts)
|
||||
{
|
||||
(void)ts;
|
||||
|
||||
|
@ -67,21 +67,21 @@ namespace engine::util {
|
||||
glm::quat rotation = glm::quat_cast(transform);
|
||||
|
||||
// update position, scale, rotation
|
||||
auto parentTransform = scene->getComponent<TransformComponent>(parentObj);
|
||||
auto parentTransform = scene->GetComponent<TransformComponent>(parentObj);
|
||||
parentTransform->position = position;
|
||||
parentTransform->scale = scale;
|
||||
parentTransform->rotation = rotation;
|
||||
|
||||
for (uint32_t i = 0; i < parentNode->mNumMeshes; i++) {
|
||||
// create child node for each mesh
|
||||
auto child = scene->createEntity("_mesh" + std::to_string(i), parentObj);
|
||||
auto childRenderer = scene->addComponent<RenderableComponent>(child);
|
||||
auto child = scene->CreateEntity("_mesh" + std::to_string(i), parentObj);
|
||||
auto childRenderer = scene->AddComponent<RenderableComponent>(child);
|
||||
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]])) {
|
||||
childRenderer->material->m_texture = textures.at(meshTextureIndices[parentNode->mMeshes[i]]);
|
||||
} 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,
|
||||
parentNode->mChildren[i],
|
||||
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();
|
||||
try {
|
||||
textures[i] = std::make_shared<resources::Texture>(
|
||||
&parent->app()->renderData, absPath.string(),
|
||||
&parent->app()->render_data_, absPath.string(),
|
||||
resources::Texture::Filtering::TRILINEAR);
|
||||
} 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 + 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);
|
||||
|
||||
|
@ -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) {
|
||||
for (uint32_t entity : m_entities) {
|
||||
t = m_scene->getComponent<engine::TransformComponent>(entity);
|
||||
col = m_scene->getComponent<engine::ColliderComponent>(entity);
|
||||
c = m_scene->getComponent<CameraControllerComponent>(entity);
|
||||
for (uint32_t entity : entities_) {
|
||||
t = scene_->GetComponent<engine::TransformComponent>(entity);
|
||||
col = scene_->GetComponent<engine::ColliderComponent>(entity);
|
||||
c = scene_->GetComponent<CameraControllerComponent>(entity);
|
||||
break;
|
||||
}
|
||||
if (t == nullptr) return;
|
||||
@ -78,32 +78,32 @@ void CameraControllerSystem::onUpdate(float ts)
|
||||
|
||||
// jumping
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// in metres per second
|
||||
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 dz = (-m_scene->app()->inputManager()->getAxis("movey"));
|
||||
float dx = scene_->app()->input_manager()->GetAxis("movex");
|
||||
float dz = (-scene_->app()->input_manager()->GetAxis("movey"));
|
||||
|
||||
// calculate new pitch and yaw
|
||||
|
||||
constexpr float MAX_PITCH = glm::half_pi<float>();
|
||||
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;
|
||||
if (c->m_pitch <= MIN_PITCH || c->m_pitch >= MAX_PITCH) {
|
||||
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
|
||||
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 */
|
||||
|
||||
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{
|
||||
"x: " + std::to_string(t->position.x) +
|
||||
" y: " + std::to_string(t->position.y) +
|
||||
" 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);
|
||||
}
|
||||
|
||||
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 };
|
||||
c->dy = 0.0f;
|
||||
}
|
||||
|
||||
if (m_scene->app()->inputManager()->getButtonPress("fullscreen")) {
|
||||
m_scene->app()->window()->toggleFullscreen();
|
||||
if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) {
|
||||
scene_->app()->window()->toggleFullscreen();
|
||||
}
|
||||
|
||||
if (m_scene->app()->inputManager()->getButtonPress("exit")) {
|
||||
m_scene->app()->window()->setCloseFlag();
|
||||
if (scene_->app()->input_manager()->GetButtonPress("exit")) {
|
||||
scene_->app()->window()->setCloseFlag();
|
||||
}
|
||||
|
||||
c->justCollided = false;
|
||||
@ -176,7 +176,7 @@ void CameraControllerSystem::onUpdate(float ts)
|
||||
}
|
||||
|
||||
// called once per frame
|
||||
void CameraControllerSystem::onEvent(engine::PhysicsSystem::CollisionEvent info)
|
||||
void CameraControllerSystem::OnEvent(engine::PhysicsSystem::CollisionEvent info)
|
||||
{
|
||||
c->justCollided = info.isCollisionEnter;
|
||||
c->lastCollisionNormal = info.normal;
|
||||
|
@ -30,10 +30,10 @@ public:
|
||||
CameraControllerSystem(engine::Scene* scene);
|
||||
|
||||
// engine::System overrides
|
||||
void onUpdate(float ts) override;
|
||||
void OnUpdate(float ts) override;
|
||||
|
||||
// engine::EventHandler overrides
|
||||
void onEvent(engine::PhysicsSystem::CollisionEvent info) override;
|
||||
void OnEvent(engine::PhysicsSystem::CollisionEvent info) override;
|
||||
|
||||
engine::TransformComponent* t = nullptr;
|
||||
engine::ColliderComponent* col = nullptr;
|
||||
|
@ -26,19 +26,19 @@
|
||||
static void configureInputs(engine::InputManager* inputManager)
|
||||
{
|
||||
// user interface mappings
|
||||
inputManager->addInputButton("fullscreen", engine::inputs::Key::K_F11);
|
||||
inputManager->addInputButton("exit", engine::inputs::Key::K_ESCAPE);
|
||||
inputManager->AddInputButton("fullscreen", engine::inputs::Key::K_F11);
|
||||
inputManager->AddInputButton("exit", engine::inputs::Key::K_ESCAPE);
|
||||
// game buttons
|
||||
inputManager->addInputButton("fire", engine::inputs::MouseButton::M_LEFT);
|
||||
inputManager->addInputButton("aim", engine::inputs::MouseButton::M_RIGHT);
|
||||
inputManager->addInputButton("jump", engine::inputs::Key::K_SPACE);
|
||||
inputManager->addInputButton("sprint", engine::inputs::Key::K_LSHIFT);
|
||||
inputManager->AddInputButton("fire", engine::inputs::MouseButton::M_LEFT);
|
||||
inputManager->AddInputButton("aim", engine::inputs::MouseButton::M_RIGHT);
|
||||
inputManager->AddInputButton("jump", engine::inputs::Key::K_SPACE);
|
||||
inputManager->AddInputButton("sprint", engine::inputs::Key::K_LSHIFT);
|
||||
// game movement
|
||||
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("movex", engine::inputs::Key::K_D, engine::inputs::Key::K_A);
|
||||
inputManager->AddInputButtonAsAxis("movey", engine::inputs::Key::K_W, engine::inputs::Key::K_S);
|
||||
// looking around
|
||||
inputManager->addInputAxis("lookx", engine::inputs::MouseAxis::X);
|
||||
inputManager->addInputAxis("looky", engine::inputs::MouseAxis::Y);
|
||||
inputManager->AddInputAxis("lookx", engine::inputs::MouseAxis::X);
|
||||
inputManager->AddInputAxis("looky", engine::inputs::MouseAxis::Y);
|
||||
}
|
||||
|
||||
void playGame(GameSettings settings)
|
||||
@ -47,92 +47,92 @@ void playGame(GameSettings settings)
|
||||
LOG_INFO("Graphics Validation: {}", settings.enableValidation ? "ON" : "OFF");
|
||||
|
||||
engine::gfx::GraphicsSettings graphicsSettings{};
|
||||
graphicsSettings.enableValidation = settings.enableValidation;
|
||||
graphicsSettings.enable_validation = settings.enableValidation;
|
||||
graphicsSettings.vsync = true;
|
||||
graphicsSettings.waitForPresent = false;
|
||||
graphicsSettings.msaaLevel = engine::gfx::MSAALevel::MSAA_OFF;
|
||||
graphicsSettings.wait_for_present = false;
|
||||
graphicsSettings.msaa_level = engine::gfx::MSAALevel::kOff;
|
||||
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings);
|
||||
|
||||
app.setFrameLimiter(settings.enableFrameLimiter);
|
||||
app.SetFrameLimiter(settings.enableFrameLimiter);
|
||||
|
||||
// configure window
|
||||
app.window()->setRelativeMouseMode(true);
|
||||
|
||||
configureInputs(app.inputManager());
|
||||
configureInputs(app.input_manager());
|
||||
|
||||
auto myScene = app.sceneManager()->createEmptyScene();
|
||||
auto myScene = app.scene_manager()->CreateEmptyScene();
|
||||
|
||||
/* create camera */
|
||||
{
|
||||
myScene->registerComponent<CameraControllerComponent>();
|
||||
myScene->registerSystem<CameraControllerSystem>();
|
||||
myScene->RegisterSystem<CameraControllerSystem>();
|
||||
|
||||
auto camera = myScene->createEntity("camera");
|
||||
myScene->getComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f };
|
||||
auto cameraCollider = myScene->addComponent<engine::ColliderComponent>(camera);
|
||||
auto camera = myScene->CreateEntity("camera");
|
||||
myScene->GetComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f };
|
||||
auto cameraCollider = myScene->AddComponent<engine::ColliderComponent>(camera);
|
||||
cameraCollider->isStatic = false;
|
||||
cameraCollider->isTrigger = true;
|
||||
cameraCollider->aabb = { { -0.2f, -1.5f, -0.2f }, { 0.2f, 0.2f, 0.2f} }; // Origin is at eye level
|
||||
myScene->addComponent<CameraControllerComponent>(camera);
|
||||
myScene->events()->subscribeToEventType<engine::PhysicsSystem::CollisionEvent>(
|
||||
engine::EventSubscriberKind::ENTITY, camera, myScene->getSystem<CameraControllerSystem>()
|
||||
myScene->AddComponent<CameraControllerComponent>(camera);
|
||||
myScene->event_system()->SubscribeToEventType<engine::PhysicsSystem::CollisionEvent>(
|
||||
engine::EventSubscriberKind::kEntity, camera, myScene->GetSystem<CameraControllerSystem>()
|
||||
);
|
||||
|
||||
auto renderSystem = myScene->getSystem<engine::RenderSystem>();
|
||||
auto renderSystem = myScene->GetSystem<engine::RenderSystem>();
|
||||
renderSystem->setCameraEntity(camera);
|
||||
}
|
||||
|
||||
/* shared resources */
|
||||
auto grassTexture = std::make_shared<engine::resources::Texture>(
|
||||
&app.renderData,
|
||||
app.getResourcePath("textures/grass.jpg"),
|
||||
&app.render_data_,
|
||||
app.GetResourcePath("textures/grass.jpg"),
|
||||
engine::resources::Texture::Filtering::ANISOTROPIC
|
||||
);
|
||||
auto spaceTexture = std::make_shared<engine::resources::Texture>(
|
||||
&app.renderData,
|
||||
app.getResourcePath("textures/space2.png"),
|
||||
&app.render_data_,
|
||||
app.GetResourcePath("textures/space2.png"),
|
||||
engine::resources::Texture::Filtering::ANISOTROPIC
|
||||
);
|
||||
|
||||
/* 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 };
|
||||
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
||||
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->mesh = genCuboidMesh(app.gfx(), 1.0f, 1.0f, 1.0f, 1);
|
||||
auto cubeCollider = myScene->addComponent<engine::ColliderComponent>(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 };
|
||||
auto cubeRenderable = myScene->AddComponent<engine::RenderableComponent>(cube);
|
||||
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->mesh = genCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
|
||||
auto cubeCollider = myScene->AddComponent<engine::ColliderComponent>(cube);
|
||||
cubeCollider->isStatic = true;
|
||||
cubeCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } };
|
||||
}
|
||||
|
||||
/* floor */
|
||||
{
|
||||
uint32_t floor = myScene->createEntity("floor");
|
||||
myScene->getComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f};
|
||||
auto floorRenderable = myScene->addComponent<engine::RenderableComponent>(floor);
|
||||
floorRenderable->material = std::make_shared<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.standard"));
|
||||
uint32_t floor = myScene->CreateEntity("floor");
|
||||
myScene->GetComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f};
|
||||
auto floorRenderable = myScene->AddComponent<engine::RenderableComponent>(floor);
|
||||
floorRenderable->material = std::make_shared<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.standard"));
|
||||
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;
|
||||
auto floorCollider = myScene->addComponent<engine::ColliderComponent>(floor);
|
||||
auto floorCollider = myScene->AddComponent<engine::ColliderComponent>(floor);
|
||||
floorCollider->isStatic = true;
|
||||
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 */
|
||||
{
|
||||
uint32_t skybox = myScene->createEntity("skybox");
|
||||
auto skyboxRenderable = myScene->addComponent<engine::RenderableComponent>(skybox);
|
||||
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.getResource<engine::resources::Shader>("builtin.skybox"));
|
||||
uint32_t skybox = myScene->CreateEntity("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->m_texture = spaceTexture;
|
||||
skyboxRenderable->mesh = genCuboidMesh(app.gfx(), 10.0f, 10.0f, 10.0f, 1.0f, true);
|
||||
myScene->getComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f };
|
||||
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 };
|
||||
}
|
||||
|
||||
app.gameLoop();
|
||||
app.GameLoop();
|
||||
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char* argv[])
|
||||
if (args.contains("gpuvalidation")) settings.enableValidation = true;
|
||||
}
|
||||
|
||||
engine::setupLog(PROJECT_NAME);
|
||||
engine::SetupLog(PROJECT_NAME);
|
||||
|
||||
LOG_INFO("{} v{}", PROJECT_NAME, PROJECT_VERSION);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user