diff --git a/include/components/camera.hpp b/include/components/camera.hpp index dc6e91f..4e6db0d 100644 --- a/include/components/camera.hpp +++ b/include/components/camera.hpp @@ -11,7 +11,7 @@ #include #include -namespace components { +namespace engine::components { class ENGINE_API Camera : public Component { diff --git a/include/components/component.hpp b/include/components/component.hpp index 3c0af10..5781db1 100644 --- a/include/components/component.hpp +++ b/include/components/component.hpp @@ -5,42 +5,43 @@ namespace engine { class Window; class Input; -} -class Object; -class ResourceManager; + class Object; + class ResourceManager; -class ENGINE_API Component { + class ENGINE_API Component { -public: + public: + + enum class TypeEnum { + TRANSFORM, + CAMERA, + RENDERER, + UI, + CUSTOM, + }; + + Component(Object* parent, TypeEnum type); + Component(const Component&) = delete; + Component& operator=(const Component&) = delete; + virtual ~Component() = 0; + + int getID(); + TypeEnum getType(); + + Object& parent; + + protected: + engine::Window& win; + engine::Input& inp; + ResourceManager& res; + + private: + static int s_next_component_id; + + int m_id = s_next_component_id; + TypeEnum m_type; - enum class TypeEnum { - TRANSFORM, - CAMERA, - RENDERER, - UI, - CUSTOM, }; - Component(Object* parent, TypeEnum type); - Component(const Component&) = delete; - Component& operator=(const Component&) = delete; - virtual ~Component() = 0; - - int getID(); - TypeEnum getType(); - - Object& parent; - -protected: - engine::Window& win; - engine::Input& inp; - ResourceManager& res; - -private: - static int s_next_component_id; - - int m_id = s_next_component_id; - TypeEnum m_type; - -}; +} \ No newline at end of file diff --git a/include/components/custom.hpp b/include/components/custom.hpp index 96b8434..b258b6d 100644 --- a/include/components/custom.hpp +++ b/include/components/custom.hpp @@ -6,7 +6,7 @@ #include -namespace components { +namespace engine::components { class ENGINE_API CustomComponent : public Component { diff --git a/include/components/mesh_renderer.hpp b/include/components/mesh_renderer.hpp index bd68556..43a468f 100644 --- a/include/components/mesh_renderer.hpp +++ b/include/components/mesh_renderer.hpp @@ -12,7 +12,7 @@ #include #include -namespace components { +namespace engine::components { class ENGINE_API Renderer : public Component { diff --git a/include/components/text_ui_renderer.hpp b/include/components/text_ui_renderer.hpp index 7a82b0e..333649b 100644 --- a/include/components/text_ui_renderer.hpp +++ b/include/components/text_ui_renderer.hpp @@ -9,7 +9,7 @@ #include -namespace components { +namespace engine::components { class ENGINE_API UI : public Component { diff --git a/include/gfx.hpp b/include/gfx.hpp index 6210e26..cee3b3e 100644 --- a/include/gfx.hpp +++ b/include/gfx.hpp @@ -3,7 +3,7 @@ #include #include -namespace gfx { +namespace engine { enum class ShaderType { VERTEX, diff --git a/include/inputs/keyboard.hpp b/include/inputs/keyboard.hpp index a8a6e66..491bf18 100644 --- a/include/inputs/keyboard.hpp +++ b/include/inputs/keyboard.hpp @@ -2,7 +2,7 @@ // Keyboard scancodes, taken from SDL_scancode.h -namespace inputs { +namespace engine::inputs { enum class Key : int { UNKNOWN = 0, diff --git a/include/inputs/mouse.hpp b/include/inputs/mouse.hpp index 0715f25..712455c 100644 --- a/include/inputs/mouse.hpp +++ b/include/inputs/mouse.hpp @@ -1,6 +1,6 @@ #pragma once -namespace inputs { +namespace engine::inputs { enum class MouseButton : int { M_LEFT, diff --git a/include/object.hpp b/include/object.hpp index e835738..06ecc0a 100644 --- a/include/object.hpp +++ b/include/object.hpp @@ -15,128 +15,130 @@ namespace engine { class Window; class Input; -} -class ResourceManager; -class SceneRoot; -class Component; + class ResourceManager; -namespace components { - class Transform; - class Camera; - class Renderer; - class UI; - class CustomComponent; -} + class SceneRoot; + class Component; -struct GameIO { - engine::Window * const win; - engine::Input * const input; - ResourceManager * const resMan; -}; + namespace components { + class Transform; + class Camera; + class Renderer; + class UI; + class CustomComponent; + } -// This object lives until it is deleted by its parent(s) or finally when the "Scene" is destroyed. -// Therefore it is safe to return raw pointers -class ENGINE_API Object { - -public: - Object(std::string name, Object* parent, SceneRoot& root, struct GameIO things); - Object(const Object&) = delete; - Object& operator=(const Object&) = delete; - ~Object(); - - engine::Window& win; - engine::Input& inp; - ResourceManager& res; - - SceneRoot& root; - - std::string getName(); - - Object* getParent(); - - Object* getChild(std::string name); - std::vector getChildren(); - - Object* createChild(std::string name); - void deleteChild(std::string name); - - void printTree(int level = 0); - - // Returns the component of type T - // Returns nullptr if the component is not found. - template T* getComponent(); - - // returns the component added - template T* createComponent(); - - template void deleteComponent(); - - struct CompList { - std::vector> cameras; - std::vector> renderers; - std::vector> uis; - std::vector> customs; + struct GameIO { + engine::Window* const win; + engine::Input* const input; + ResourceManager* const resMan; }; - - // Adds to the provided vector all components of this object and of its children recursively. - // Ignores 'Transform' - void getAllSubComponents(struct CompList& compList, glm::mat4 t); - Transform transform; + // This object lives until it is deleted by its parent(s) or finally when the "Scene" is destroyed. + // Therefore it is safe to return raw pointers + class ENGINE_API Object { -private: - static int s_object_count; - int m_id = s_object_count; - std::string m_name; + public: + Object(std::string name, Object* parent, SceneRoot& root, struct GameIO things); + Object(const Object&) = delete; + Object& operator=(const Object&) = delete; + ~Object(); - std::list> m_children{}; - std::list> m_components{}; + engine::Window& win; + engine::Input& inp; + ResourceManager& res; - // If nullptr, this is the root object - Object* const m_parent; - struct GameIO m_gameIO; + SceneRoot& root; -}; + std::string getName(); -// implementation of template functions + Object* getParent(); -template T* Object::getComponent() -{ - if (std::is_base_of::value == false) { - throw std::runtime_error("getComponent() error: specified type is not a subclass of 'Component'"); - } - for (const auto& component : m_components) { - T* derived = dynamic_cast(component.get()); - if (derived != nullptr) { - return derived; + Object* getChild(std::string name); + std::vector getChildren(); + + Object* createChild(std::string name); + void deleteChild(std::string name); + + void printTree(int level = 0); + + // Returns the component of type T + // Returns nullptr if the component is not found. + template T* getComponent(); + + // returns the component added + template T* createComponent(); + + template void deleteComponent(); + + struct CompList { + std::vector> cameras; + std::vector> renderers; + std::vector> uis; + std::vector> customs; + }; + + // Adds to the provided vector all components of this object and of its children recursively. + // Ignores 'Transform' + void getAllSubComponents(struct CompList& compList, glm::mat4 t); + + Transform transform; + + private: + static int s_object_count; + int m_id = s_object_count; + std::string m_name; + + std::list> m_children{}; + std::list> m_components{}; + + // If nullptr, this is the root object + Object* const m_parent; + struct GameIO m_gameIO; + + }; + + // implementation of template functions + + template T* Object::getComponent() + { + if (std::is_base_of::value == false) { + throw std::runtime_error("getComponent() error: specified type is not a subclass of 'Component'"); } - } - return nullptr; -} - -template T* Object::createComponent() -{ - if (std::is_base_of::value == false) { - throw std::runtime_error("addComponent() error: specified type is not a subclass of 'Component'"); - } - if (getComponent() != nullptr) { - throw std::runtime_error("addComponent() error: attempt to add component of a type already present"); - } - m_components.emplace_back(std::make_unique(this)); - return dynamic_cast(m_components.back().get()); -} - -template void Object::deleteComponent() -{ - if (std::is_base_of::value == false) { - throw std::runtime_error("deleteComponent() error: specified type is not a subclass of 'Component'"); - } - for (auto itr = m_components.begin(); itr != m_components.end(); ++itr) { - if (dynamic_cast((*itr).get()) != nullptr) { - m_components.erase(itr); - return; + for (const auto& component : m_components) { + T* derived = dynamic_cast(component.get()); + if (derived != nullptr) { + return derived; + } } + return nullptr; } - throw std::runtime_error("deleteComponent() error: attempt to delete component that is not present."); -} + + template T* Object::createComponent() + { + if (std::is_base_of::value == false) { + throw std::runtime_error("addComponent() error: specified type is not a subclass of 'Component'"); + } + if (getComponent() != nullptr) { + throw std::runtime_error("addComponent() error: attempt to add component of a type already present"); + } + m_components.emplace_back(std::make_unique(this)); + return dynamic_cast(m_components.back().get()); + } + + template void Object::deleteComponent() + { + if (std::is_base_of::value == false) { + throw std::runtime_error("deleteComponent() error: specified type is not a subclass of 'Component'"); + } + for (auto itr = m_components.begin(); itr != m_components.end(); ++itr) { + if (dynamic_cast((*itr).get()) != nullptr) { + m_components.erase(itr); + return; + } + } + throw std::runtime_error("deleteComponent() error: attempt to delete component that is not present."); + } + +} \ No newline at end of file diff --git a/include/resource_manager.hpp b/include/resource_manager.hpp index 5077098..923e7b1 100644 --- a/include/resource_manager.hpp +++ b/include/resource_manager.hpp @@ -9,73 +9,77 @@ // Doesn't own resources, only holds weak_ptrs -class ENGINE_API ResourceManager { +namespace engine { -public: - ResourceManager(); - ResourceManager(const ResourceManager&) = delete; - ResourceManager& operator=(const ResourceManager&) = delete; - ~ResourceManager() = default; + class ENGINE_API ResourceManager { + + public: + ResourceManager(); + ResourceManager(const ResourceManager&) = delete; + ResourceManager& operator=(const ResourceManager&) = delete; + ~ResourceManager() = default; + + template + std::shared_ptr create(const std::string& name); + + // creates the resource if it is not in the map or the weak_ptr has expired + template + std::shared_ptr get(const std::string& name); + + std::unique_ptr getResourcesListString(); + + std::vector> getAllResourcesOfType(const std::string& type); + + std::filesystem::path getFilePath(const std::string& name); + + private: + std::filesystem::path m_resourcesPath; + std::unordered_map> m_resources; + + }; template - std::shared_ptr create(const std::string& name); + std::shared_ptr ResourceManager::create(const std::string& name) + { + if (std::is_base_of::value == false) { + throw std::runtime_error("ResourceManager::create() error: specified type is not a subclass of 'Resource'"); + } + auto resource = std::make_shared(getFilePath(name)); + m_resources.emplace(name, std::dynamic_pointer_cast(resource)); + return resource; + } - // creates the resource if it is not in the map or the weak_ptr has expired template - std::shared_ptr get(const std::string& name); + std::shared_ptr ResourceManager::get(const std::string& name) + { - std::unique_ptr getResourcesListString(); + if (std::is_base_of::value == false) { + throw std::runtime_error("ResourceManager::get() error: specified type is not a subclass of 'Resource'"); + } - std::vector> getAllResourcesOfType(const std::string& type); + if (m_resources.contains(name)) { - std::filesystem::path getFilePath(const std::string& name); + std::weak_ptr res = m_resources.at(name); -private: - std::filesystem::path m_resourcesPath; - std::unordered_map> m_resources; - -}; - -template -std::shared_ptr ResourceManager::create(const std::string& name) -{ - if (std::is_base_of::value == false) { - throw std::runtime_error("ResourceManager::create() error: specified type is not a subclass of 'Resource'"); - } - auto resource = std::make_shared(getFilePath(name)); - m_resources.emplace(name, std::dynamic_pointer_cast(resource)); - return resource; -} - -template -std::shared_ptr ResourceManager::get(const std::string& name) -{ - - if (std::is_base_of::value == false) { - throw std::runtime_error("ResourceManager::get() error: specified type is not a subclass of 'Resource'"); - } - - if (m_resources.contains(name)) { - - std::weak_ptr res = m_resources.at(name); - - if (res.expired() == false) { - // resource definitely exists - auto castedSharedPtr = std::dynamic_pointer_cast(res.lock()); - if (castedSharedPtr == nullptr) { - throw std::runtime_error("error: attempt to get Resource which already exists as another type"); + if (res.expired() == false) { + // resource definitely exists + auto castedSharedPtr = std::dynamic_pointer_cast(res.lock()); + if (castedSharedPtr == nullptr) { + throw std::runtime_error("error: attempt to get Resource which already exists as another type"); + } + else { + return castedSharedPtr; + } } else { - return castedSharedPtr; + // Resource in map but no longer exists. Delete it. + m_resources.erase(name); } + } - else { - // Resource in map but no longer exists. Delete it. - m_resources.erase(name); - } + + return create(name); } - - return create(name); -} +} \ No newline at end of file diff --git a/include/resources/font.hpp b/include/resources/font.hpp index b284bfd..1e868c3 100644 --- a/include/resources/font.hpp +++ b/include/resources/font.hpp @@ -10,7 +10,7 @@ #include -namespace resources { +namespace engine::resources { class ENGINE_API Font : public Resource { diff --git a/include/resources/mesh.hpp b/include/resources/mesh.hpp index 4eb5349..b270cb0 100644 --- a/include/resources/mesh.hpp +++ b/include/resources/mesh.hpp @@ -20,7 +20,7 @@ struct Vertex { glm::vec2 uv; }; -namespace resources { +namespace engine::resources { class ENGINE_API Mesh : public Resource { diff --git a/include/resources/resource.hpp b/include/resources/resource.hpp index f18ae00..50bc78d 100644 --- a/include/resources/resource.hpp +++ b/include/resources/resource.hpp @@ -5,20 +5,24 @@ #include #include -class ENGINE_API Resource { +namespace engine { -public: - Resource(const std::filesystem::path& resPath, const std::string& type); - Resource(const Resource&) = delete; - Resource& operator=(const Resource&) = delete; - virtual ~Resource() = 0; + class ENGINE_API Resource { - std::string getType(); + public: + Resource(const std::filesystem::path& resPath, const std::string& type); + Resource(const Resource&) = delete; + Resource& operator=(const Resource&) = delete; + virtual ~Resource() = 0; -protected: - std::filesystem::path m_resourcePath; + std::string getType(); -private: - const std::string m_type; + protected: + std::filesystem::path m_resourcePath; -}; + private: + const std::string m_type; + + }; + +} \ No newline at end of file diff --git a/include/resources/shader.hpp b/include/resources/shader.hpp index 60ed5bf..839e00b 100644 --- a/include/resources/shader.hpp +++ b/include/resources/shader.hpp @@ -11,7 +11,7 @@ #include #include -namespace resources { +namespace engine::resources { class ENGINE_API Shader : public Resource { @@ -40,7 +40,7 @@ public: static void invalidate() { - s_activeProgram = -1; + s_activeProgram = std::numeric_limits::max(); } private: diff --git a/include/resources/texture.hpp b/include/resources/texture.hpp index 2c6e334..cdfc9a5 100644 --- a/include/resources/texture.hpp +++ b/include/resources/texture.hpp @@ -6,7 +6,7 @@ #include -namespace resources { +namespace engine::resources { class ENGINE_API Texture : public Resource { diff --git a/include/sceneroot.hpp b/include/sceneroot.hpp index 5096b50..a3bc312 100644 --- a/include/sceneroot.hpp +++ b/include/sceneroot.hpp @@ -6,24 +6,28 @@ #include -// Holds everything you would expect to find in a game scene -class ENGINE_API SceneRoot : public Object { +namespace engine { -public: - // create a new empty scene - SceneRoot(struct GameIO things); - SceneRoot(const std::filesystem::path& file, struct GameIO things); + // Holds everything you would expect to find in a game scene + class ENGINE_API SceneRoot : public Object { - SceneRoot(const SceneRoot&) = delete; - SceneRoot& operator=(const SceneRoot&) = delete; - ~SceneRoot(); + public: + // create a new empty scene + SceneRoot(struct GameIO things); + SceneRoot(const std::filesystem::path& file, struct GameIO things); - void updateStuff(); + SceneRoot(const SceneRoot&) = delete; + SceneRoot& operator=(const SceneRoot&) = delete; + ~SceneRoot(); - void activateCam(int id); - void deactivateCam(int id); + void updateStuff(); -private: - std::vector m_activeCameras{}; + void activateCam(int id); + void deactivateCam(int id); -}; + private: + std::vector m_activeCameras{}; + + }; + +} \ No newline at end of file diff --git a/include/transform.hpp b/include/transform.hpp index dbb3122..938a6ff 100644 --- a/include/transform.hpp +++ b/include/transform.hpp @@ -6,12 +6,16 @@ #include #include -struct ENGINE_API Transform { +namespace engine { -// Scale, rotate (XYZ), translate + struct ENGINE_API Transform { - glm::vec3 position{0.0f}; - glm::quat rotation{}; - glm::vec3 scale{1.0f}; + // Scale, rotate (XYZ), translate -}; \ No newline at end of file + glm::vec3 position{ 0.0f }; + glm::quat rotation{}; + glm::vec3 scale{ 1.0f }; + + }; + +} \ No newline at end of file diff --git a/include/window.hpp b/include/window.hpp index 7686f1c..544a458 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -22,7 +22,7 @@ namespace engine { class ENGINE_API Window { public: - Window(const std::string& title); + Window(const std::string& title, bool resizable = true); Window(const Window&) = delete; Window& operator=(const Window&) = delete; ~Window(); @@ -52,7 +52,7 @@ namespace engine { // Returns true if the window should remain open bool isRunning() const; - void setFullscreen(bool fullscreen, bool exclusive = true); + void setFullscreen(bool fullscreen, bool exclusive = false); void toggleFullscreen(); bool isFullscreen() const; @@ -139,6 +139,8 @@ namespace engine { std::string m_title; + bool m_resizable; + bool m_fullscreen = false; bool m_justResized = false; bool m_keyboardFocus = true; diff --git a/src/components/camera.cpp b/src/components/camera.cpp index 3c83fdc..e7222b2 100644 --- a/src/components/camera.cpp +++ b/src/components/camera.cpp @@ -13,7 +13,7 @@ static const std::string VIEW_MAT_UNIFORM = "viewMat"; static const std::string PROJ_MAT_UNIFORM = "projMat"; static const std::string WINDOW_SIZE_UNIFORM = "windowSize"; -namespace components { +namespace engine::components { glm::vec4 Camera::s_clearColor{-999.0f, -999.0f, -999.0f, -999.0f}; diff --git a/src/components/component.cpp b/src/components/component.cpp index 9bc9f45..ca91f33 100644 --- a/src/components/component.cpp +++ b/src/components/component.cpp @@ -4,27 +4,31 @@ #include -int Component::s_next_component_id = 0; +namespace engine { -Component::Component(Object* parent, TypeEnum type) : - m_type(type), parent(*parent), - win(parent->win), - inp(parent->inp), - res(parent->res) -{ - s_next_component_id++; -} + int Component::s_next_component_id = 0; -Component::~Component() -{ -} + Component::Component(Object* parent, TypeEnum type) : + m_type(type), parent(*parent), + win(parent->win), + inp(parent->inp), + res(parent->res) + { + s_next_component_id++; + } -int Component::getID() -{ - return m_id; -} + Component::~Component() + { + } -Component::TypeEnum Component::getType() -{ - return m_type; -} + int Component::getID() + { + return m_id; + } + + Component::TypeEnum Component::getType() + { + return m_type; + } + +} \ No newline at end of file diff --git a/src/components/custom.cpp b/src/components/custom.cpp index a1feee8..931b59b 100644 --- a/src/components/custom.cpp +++ b/src/components/custom.cpp @@ -1,6 +1,6 @@ #include "components/custom.hpp" -namespace components { +namespace engine::components { CustomComponent::CustomComponent(Object* parent) : Component(parent, TypeEnum::CUSTOM) { diff --git a/src/components/mesh_renderer.cpp b/src/components/mesh_renderer.cpp index 189fdc2..8c98701 100644 --- a/src/components/mesh_renderer.cpp +++ b/src/components/mesh_renderer.cpp @@ -6,7 +6,7 @@ #include -namespace components { +namespace engine::components { Renderer::Renderer(Object* parent) : Component(parent, TypeEnum::RENDERER) { diff --git a/src/components/text_ui_renderer.cpp b/src/components/text_ui_renderer.cpp index 5a26fff..a7011bb 100644 --- a/src/components/text_ui_renderer.cpp +++ b/src/components/text_ui_renderer.cpp @@ -4,7 +4,7 @@ #include "resource_manager.hpp" #include "resources/texture.hpp" -namespace components { +namespace engine::components { UI::UI(Object* parent) : Component(parent, TypeEnum::UI) { diff --git a/src/engine.cpp b/src/engine.cpp index fade760..44b4112 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -7,7 +7,7 @@ namespace engine { Application::Application(const char* appName, const char* appVersion) { - m_win = std::make_unique(appName); + m_win = std::make_unique(appName, true); m_gfx = std::make_unique(appName, appVersion, m_win->getHandle()); } @@ -34,12 +34,7 @@ namespace engine { } if (m_win->getKeyPress(inputs::Key::F11)) { - if (m_win->isFullscreen()) { - m_win->setFullscreen(false); - } - else { - m_win->setFullscreen(true, false); // borderless window - } + m_win->toggleFullscreen(); } if (m_win->getKeyPress(inputs::Key::ESCAPE)) { m_win->setCloseFlag(); diff --git a/src/object.cpp b/src/object.cpp index f81c599..11d74d3 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -7,127 +7,132 @@ #include -int Object::s_object_count = 0; +namespace engine { -Object::Object(std::string name, Object* parent, SceneRoot& root, struct GameIO things) - : m_name(name), m_parent(parent), root(root), - m_gameIO(things), - win(*things.win), - inp(*things.input), - res(*things.resMan) -{ - s_object_count++; -} + int Object::s_object_count = 0; -Object::~Object() -{ -} + Object::Object(std::string name, Object* parent, SceneRoot& root, struct GameIO things) + : m_name(name), m_parent(parent), root(root), + m_gameIO(things), + win(*things.win), + inp(*things.input), + res(*things.resMan) + { + s_object_count++; + } -std::string Object::getName() -{ - return m_name; -} + Object::~Object() + { + } -Object* Object::getParent() -{ - return m_parent; -} + std::string Object::getName() + { + return m_name; + } -Object* Object::getChild(std::string name) -{ - for (const auto& child : m_children) { - if (name == child->getName()) { - return child.get(); + Object* Object::getParent() + { + return m_parent; + } + + Object* Object::getChild(std::string name) + { + for (const auto& child : m_children) { + if (name == child->getName()) { + return child.get(); + } + } + return nullptr; + } + + std::vector Object::getChildren() + { + std::vector newVector{}; + for (const auto& child : m_children) { + newVector.push_back(child.get()); + } + return newVector; + } + + Object* Object::createChild(std::string name) + { + if (getChild(name) != nullptr) { + throw std::runtime_error("Attempt to create child object with existing name"); + } + m_children.emplace_back(std::make_unique(name, this, root, m_gameIO)); + return m_children.back().get(); + } + + void Object::deleteChild(std::string name) + { + for (auto itr = m_children.begin(); itr != m_children.end(); ++itr) { + if ((*itr)->getName() == name) { + m_children.erase(itr); + return; + } + } + throw std::runtime_error("Unable to delete child '" + name + "' as it does not exist"); + } + + void Object::printTree(int level) + { + std::string buf; + for (int i = 0; i < level; i++) { + if (i + 1 == level) { + buf += "\\_______"; + } + else { + buf += " "; + } + } + buf += m_name; + INFO(buf); + for (const auto& child : this->getChildren()) { + child->printTree(level + 1); } } - return nullptr; -} -std::vector Object::getChildren() -{ - std::vector newVector{}; - for (const auto& child : m_children) { - newVector.push_back(child.get()); - } - return newVector; -} + void Object::getAllSubComponents(struct CompList& compList, glm::mat4 parentTransform) + { + using namespace components; -Object* Object::createChild(std::string name) -{ - if (getChild(name) != nullptr) { - throw std::runtime_error("Attempt to create child object with existing name"); - } - m_children.emplace_back(std::make_unique(name, this, root, m_gameIO)); - return m_children.back().get(); -} + glm::mat4 objTransform{ 1.0f }; -void Object::deleteChild(std::string name) -{ - for (auto itr = m_children.begin(); itr != m_children.end(); ++itr) { - if ((*itr)->getName() == name) { - m_children.erase(itr); - return; + auto t = transform; + + // rotation + objTransform = glm::mat4_cast(t.rotation); + + // position + reinterpret_cast(objTransform[3]) = t.position; + + // scale (effectively applied first + objTransform = glm::scale(objTransform, t.scale); + + const glm::mat4 newTransform = parentTransform * objTransform; + + for (const auto& compUnq : m_components) { + const auto comp = compUnq.get(); + switch (comp->getType()) { + case Component::TypeEnum::CAMERA: + compList.cameras.emplace_back(dynamic_cast(comp), newTransform); + break; + case Component::TypeEnum::RENDERER: + compList.renderers.emplace_back(dynamic_cast(comp), newTransform); + break; + case Component::TypeEnum::UI: + compList.uis.emplace_back(dynamic_cast(comp), newTransform); + break; + case Component::TypeEnum::CUSTOM: + compList.customs.emplace_back(dynamic_cast(comp), newTransform); + break; + default: + break; + } + } + for (const auto& child : m_children) { + child->getAllSubComponents(compList, newTransform); } } - throw std::runtime_error("Unable to delete child '" + name + "' as it does not exist"); -} -void Object::printTree(int level) -{ - std::string buf; - for (int i = 0; i < level; i++) { - if (i+1 == level) { - buf += "\\_______"; - } else { - buf += " "; - } - } - buf += m_name; - INFO(buf); - for (const auto& child : this->getChildren()) { - child->printTree(level+1); - } -} - -void Object::getAllSubComponents(struct CompList& compList, glm::mat4 parentTransform) -{ - using namespace components; - - glm::mat4 objTransform{1.0f}; - - auto t = transform; - - // rotation - objTransform = glm::mat4_cast(t.rotation); - - // position - reinterpret_cast(objTransform[3]) = t.position; - - // scale (effectively applied first - objTransform = glm::scale(objTransform, t.scale); - - const glm::mat4 newTransform = parentTransform * objTransform; - - for (const auto& compUnq : m_components) { - const auto comp = compUnq.get(); - switch (comp->getType()) { - case Component::TypeEnum::CAMERA: - compList.cameras.emplace_back(dynamic_cast(comp), newTransform); - break; - case Component::TypeEnum::RENDERER: - compList.renderers.emplace_back(dynamic_cast(comp), newTransform); - break; - case Component::TypeEnum::UI: - compList.uis.emplace_back(dynamic_cast(comp), newTransform); - break; - case Component::TypeEnum::CUSTOM: - compList.customs.emplace_back(dynamic_cast(comp), newTransform); - break; - default: - break; - } - } - for (const auto& child : m_children) { - child->getAllSubComponents(compList, newTransform); - } -} +} \ No newline at end of file diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index 6a2da36..dfef6da 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -8,68 +8,73 @@ #include "log.hpp" -ResourceManager::ResourceManager() -{ +namespace engine { + + ResourceManager::ResourceManager() + { #ifdef _MSC_VER - CHAR exeDirBuf[MAX_PATH + 1]; - GetModuleFileNameA(NULL, exeDirBuf, MAX_PATH + 1); - std::filesystem::path cwd = std::filesystem::path(exeDirBuf).parent_path(); - (void)_chdir((const char*)std::filesystem::absolute(cwd).c_str()); + CHAR exeDirBuf[MAX_PATH + 1]; + GetModuleFileNameA(NULL, exeDirBuf, MAX_PATH + 1); + std::filesystem::path cwd = std::filesystem::path(exeDirBuf).parent_path(); + (void)_chdir((const char*)std::filesystem::absolute(cwd).c_str()); #else - std::filesystem::path cwd = std::filesystem::current_path(); + std::filesystem::path cwd = std::filesystem::current_path(); #endif - if (std::filesystem::is_directory(cwd / "res")) { - m_resourcesPath = cwd / "res"; - } else { - m_resourcesPath = cwd.parent_path() / "share" / "sdltest"; - } - - if (std::filesystem::is_directory(m_resourcesPath) == false) { - m_resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest"; - } - - if (std::filesystem::is_directory(m_resourcesPath) == false) { - throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string()); - } -} - -std::unique_ptr ResourceManager::getResourcesListString() -{ - auto bufPtr = std::make_unique(); - std::string& buf = *bufPtr; - int maxLength = 0; - for (const auto& [name, ptr] : m_resources) { - if (name.length() > maxLength) - maxLength = name.length(); - } - for (const auto& [name, ptr] : m_resources) { - buf += name; - for (int i = 0; i < (maxLength - name.length() + 4); i++) { - buf += " "; + if (std::filesystem::is_directory(cwd / "res")) { + m_resourcesPath = cwd / "res"; + } + else { + m_resourcesPath = cwd.parent_path() / "share" / "sdltest"; + } + + if (std::filesystem::is_directory(m_resourcesPath) == false) { + m_resourcesPath = cwd.root_path() / "usr" / "local" / "share" / "sdltest"; + } + + if (std::filesystem::is_directory(m_resourcesPath) == false) { + throw std::runtime_error("Unable to determine resources location. CWD: " + cwd.string()); } - buf += std::to_string(ptr.use_count()) + "\n"; } - return bufPtr; -} + + std::unique_ptr ResourceManager::getResourcesListString() + { + auto bufPtr = std::make_unique(); + std::string& buf = *bufPtr; + int maxLength = 0; + for (const auto& [name, ptr] : m_resources) { + if (name.length() > maxLength) + maxLength = name.length(); + } + for (const auto& [name, ptr] : m_resources) { + buf += name; + for (int i = 0; i < (maxLength - name.length() + 4); i++) { + buf += " "; + } + buf += std::to_string(ptr.use_count()) + "\n"; + } + return bufPtr; + } -std::vector> ResourceManager::getAllResourcesOfType(const std::string& type) -{ - std::vector> resources; - for (const auto& [name, ptr] : m_resources) { - if (ptr.expired() == false) { - if (ptr.lock()->getType() == type) { - resources.push_back(ptr); + std::vector> ResourceManager::getAllResourcesOfType(const std::string& type) + { + std::vector> resources; + for (const auto& [name, ptr] : m_resources) { + if (ptr.expired() == false) { + if (ptr.lock()->getType() == type) { + resources.push_back(ptr); + } } } + return resources; } - return resources; -} -// private + // private -std::filesystem::path ResourceManager::getFilePath(const std::string& name) -{ - return m_resourcesPath / name; -} + std::filesystem::path ResourceManager::getFilePath(const std::string& name) + { + return m_resourcesPath / name; + } + +} \ No newline at end of file diff --git a/src/resources/font.cpp b/src/resources/font.cpp index 41df828..8a505aa 100644 --- a/src/resources/font.cpp +++ b/src/resources/font.cpp @@ -3,7 +3,7 @@ #include #include FT_FREETYPE_H -namespace resources { +namespace engine::resources { Font::Font(const std::filesystem::path& resPath) : Resource(resPath, "font") { diff --git a/src/resources/mesh.cpp b/src/resources/mesh.cpp index c155882..b6092f3 100644 --- a/src/resources/mesh.cpp +++ b/src/resources/mesh.cpp @@ -1,6 +1,6 @@ #include "resources/mesh.hpp" -namespace resources { +namespace engine::resources { struct MeshFileHeader { unsigned int vertex_count; diff --git a/src/resources/resource.cpp b/src/resources/resource.cpp index faa40b7..457ecef 100644 --- a/src/resources/resource.cpp +++ b/src/resources/resource.cpp @@ -2,19 +2,23 @@ #include -Resource::Resource(const std::filesystem::path& resPath, const std::string& type) : m_resourcePath(resPath), m_type(type) -{ - if (m_type != "mesh") - TRACE("Creating {} resource: {}", type, resPath.filename().string()); -} +namespace engine { -Resource::~Resource() -{ - if (m_type != "mesh") - TRACE("Destroyed {} resource: {}", m_type, m_resourcePath.filename().string()); -} + Resource::Resource(const std::filesystem::path& resPath, const std::string& type) : m_resourcePath(resPath), m_type(type) + { + if (m_type != "mesh") + TRACE("Creating {} resource: {}", type, resPath.filename().string()); + } -std::string Resource::getType() -{ - return m_type; -} + Resource::~Resource() + { + if (m_type != "mesh") + TRACE("Destroyed {} resource: {}", m_type, m_resourcePath.filename().string()); + } + + std::string Resource::getType() + { + return m_type; + } + +} \ No newline at end of file diff --git a/src/resources/shader.cpp b/src/resources/shader.cpp index 59c1a7f..85dec72 100644 --- a/src/resources/shader.cpp +++ b/src/resources/shader.cpp @@ -50,7 +50,7 @@ static GLuint compile(const char *path, GLenum type) } return handle; } -namespace resources { +namespace engine::resources { // I've got to do this because of GL's stupid state machine GLuint Shader::s_activeProgram = 0; diff --git a/src/resources/texture.cpp b/src/resources/texture.cpp index c46afbf..9bc9119 100644 --- a/src/resources/texture.cpp +++ b/src/resources/texture.cpp @@ -7,7 +7,7 @@ #include -namespace resources { +namespace engine::resources { // -1 means invalid / no bind GLuint Texture::s_binded_texture = -1; @@ -28,7 +28,7 @@ static bool readPNG(const std::string& path, std::vector& texbuf, int * return false; } - const size_t size = x * y * n; + const size_t size = (size_t)x * (size_t)y * (size_t)n; texbuf.resize(size); memcpy(texbuf.data(), data, size); diff --git a/src/sceneroot.cpp b/src/sceneroot.cpp index 3ceba42..9d952b7 100644 --- a/src/sceneroot.cpp +++ b/src/sceneroot.cpp @@ -14,77 +14,81 @@ #include "log.hpp" -SceneRoot::SceneRoot(struct GameIO things) : Object("root", nullptr, *this, things) -{ -} +namespace engine { -SceneRoot::SceneRoot(const std::filesystem::path& file, struct GameIO things) : SceneRoot(things) -{ - // TODO: make this a resource - //loadFromSceneFile(file); -} - -SceneRoot::~SceneRoot() -{ -} - -// private methods - -// public methods - -void SceneRoot::updateStuff() -{ - - using namespace components; - using namespace glm; - - struct CompList compList{}; - - getAllSubComponents(compList, glm::mat4{1.0f}); - - // update - - for (const auto& [c, t] : compList.customs) { - c->onUpdate(t); + SceneRoot::SceneRoot(struct GameIO things) : Object("root", nullptr, *this, things) + { } - // render + SceneRoot::SceneRoot(const std::filesystem::path& file, struct GameIO things) : SceneRoot(things) + { + // TODO: make this a resource + //loadFromSceneFile(file); + } - for (const auto& [c, t] : compList.cameras) { - for (int id : m_activeCameras) { - if (c->getID() == id) { - c->updateCam(t); - for (const auto& [c, t] : compList.renderers) { - c->render(t); + SceneRoot::~SceneRoot() + { + } + + // private methods + + // public methods + + void SceneRoot::updateStuff() + { + + using namespace components; + using namespace glm; + + struct CompList compList {}; + + getAllSubComponents(compList, glm::mat4{ 1.0f }); + + // update + + for (const auto& [c, t] : compList.customs) { + c->onUpdate(t); + } + + // render + + for (const auto& [c, t] : compList.cameras) { + for (int id : m_activeCameras) { + if (c->getID() == id) { + c->updateCam(t); + for (const auto& [c, t] : compList.renderers) { + c->render(t); + } + + break; } + } + } - break; + for (const auto& [c, t] : compList.uis) { + c->render(t); + } + + } + + void SceneRoot::activateCam(int id) + { + auto& v = m_activeCameras; + + if (std::find(v.begin(), v.end(), id) == v.end()) { + v.push_back(id); + } + } + + void SceneRoot::deactivateCam(int id) + { + auto& v = m_activeCameras; + + for (auto it = v.begin(); it != v.end(); it++) { + if (*it == id) { + v.erase(it); } } } - for (const auto& [c, t] : compList.uis) { - c->render(t); - } - -} - -void SceneRoot::activateCam(int id) -{ - auto& v = m_activeCameras; - - if (std::find(v.begin(), v.end(), id) == v.end()) { - v.push_back(id); - } -} - -void SceneRoot::deactivateCam(int id) -{ - auto& v = m_activeCameras; - - for (auto it = v.begin(); it != v.end(); it++) { - if (*it == id) { - v.erase(it); - } - } -} +} \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp index 552240b..0e694be 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -9,7 +9,7 @@ const uint64_t BILLION = 1000000000; namespace engine { - Window::Window(const std::string& title) : m_title(title) + Window::Window(const std::string& title, bool resizable) : m_title(title), m_resizable(resizable) { // init SDL @@ -26,13 +26,23 @@ namespace engine { m_lastFrameStamp = m_startTime - 1; m_avgFpsStart = m_startTime; + Uint32 windowFlags = SDL_WINDOW_SHOWN; + +#ifdef ENGINE_BUILD_VULKAN + windowFlags |= SDL_WINDOW_VULKAN; +#endif + + if (m_resizable) { + windowFlags |= SDL_WINDOW_RESIZABLE; + } + // create the window m_handle = SDL_CreateWindow( m_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, static_cast(m_winSize.x), static_cast(m_winSize.y), - SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN); + windowFlags); if (m_handle == NULL) { SDL_Quit(); throw std::runtime_error("Unable to create window: " + std::string(SDL_GetError())); @@ -278,14 +288,16 @@ namespace engine { void Window::setFullscreen(bool fullscreen, bool exclusive) { - if (SDL_SetWindowFullscreen(m_handle, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) { - throw std::runtime_error("Unable to set window to fullscreen/windowed"); - } - m_fullscreen = fullscreen; - if (fullscreen) { - int width, height; - SDL_GetWindowSize(m_handle, &width, &height); - onResize(width, height); + if (m_resizable) { + if (SDL_SetWindowFullscreen(m_handle, fullscreen ? (exclusive ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP) : 0) != 0) { + throw std::runtime_error("Unable to set window to fullscreen/windowed"); + } + m_fullscreen = fullscreen; + if (fullscreen) { + int width, height; + SDL_GetWindowSize(m_handle, &width, &height); + onResize(width, height); + } } }