├── .github ├── image │ ├── cardia-logo.png │ ├── cardiator.png │ └── scripting.png └── workflows │ └── windows-latest.yml ├── .gitignore ├── Cardia ├── include │ ├── Cardia.hpp │ ├── Cardia │ │ ├── Application.hpp │ │ ├── Asset │ │ │ ├── Asset.hpp │ │ │ ├── AssetsManager.hpp │ │ │ └── AssetsManager.inl │ │ ├── Core │ │ │ ├── Concepts.hpp │ │ │ ├── Core.hpp │ │ │ ├── Event.hpp │ │ │ ├── Input.hpp │ │ │ ├── KeyCodes.hpp │ │ │ ├── Log.hpp │ │ │ ├── Time.hpp │ │ │ ├── UUID.hpp │ │ │ ├── Window.hpp │ │ │ └── Windows │ │ │ │ └── WindowsWin.hpp │ │ ├── DataStructure │ │ │ ├── Mesh.hpp │ │ │ ├── Model.hpp │ │ │ └── Vertex.hpp │ │ ├── ECS │ │ │ ├── Component │ │ │ │ ├── Camera.hpp │ │ │ │ ├── Id.hpp │ │ │ │ ├── Label.hpp │ │ │ │ ├── Light.hpp │ │ │ │ ├── ModelRenderer.hpp │ │ │ │ ├── Relationship.hpp │ │ │ │ ├── Script.hpp │ │ │ │ ├── SpriteRenderer.hpp │ │ │ │ └── Transform.hpp │ │ │ ├── Components.hpp │ │ │ ├── Entity.hpp │ │ │ ├── Scene.hpp │ │ │ └── SceneCamera.hpp │ │ ├── EntryPoint.hpp │ │ ├── ImGui │ │ │ ├── ImGuiLayer.hpp │ │ │ └── imgui_impl_vulkan.h │ │ ├── Math │ │ │ ├── Angle.hpp │ │ │ ├── Angle.inl │ │ │ ├── Matrix4.hpp │ │ │ ├── Matrix4.inl │ │ │ ├── Quaternion.hpp │ │ │ ├── Quaternion.inl │ │ │ ├── Vector2.hpp │ │ │ ├── Vector2.inl │ │ │ ├── Vector3.hpp │ │ │ ├── Vector3.inl │ │ │ ├── Vector4.hpp │ │ │ └── Vector4.inl │ │ ├── Project │ │ │ └── Project.hpp │ │ ├── Renderer │ │ │ ├── Batch.hpp │ │ │ ├── Buffer.hpp │ │ │ ├── Camera.hpp │ │ │ ├── Descriptors.hpp │ │ │ ├── Device.hpp │ │ │ ├── Framebuffer.hpp │ │ │ ├── Material.hpp │ │ │ ├── MeshRenderer.hpp │ │ │ ├── Pipeline.hpp │ │ │ ├── RenderPass.hpp │ │ │ ├── Renderer.hpp │ │ │ ├── Renderer2D.hpp │ │ │ ├── Shader.hpp │ │ │ ├── Skybox.hpp │ │ │ ├── SubMeshRenderer │ │ │ ├── SwapChain.hpp │ │ │ └── Texture.hpp │ │ ├── Scripting │ │ │ ├── EmbeddedPythonModule.hpp │ │ │ ├── EntityBehavior.hpp │ │ │ ├── ScriptClass.hpp │ │ │ ├── ScriptEngine.hpp │ │ │ ├── ScriptField.hpp │ │ │ ├── ScriptFile.hpp │ │ │ ├── ScriptInstance.hpp │ │ │ └── ScriptUtils.hpp │ │ └── Serialization │ │ │ ├── Serializable.hpp │ │ │ └── Serializer.hpp │ └── cdpch.hpp ├── src │ └── Cardia │ │ ├── Application.cpp │ │ ├── Asset │ │ └── AssetsManager.cpp │ │ ├── Core │ │ ├── Input.cpp │ │ ├── Log.cpp │ │ ├── Time.cpp │ │ ├── UUID.cpp │ │ └── Windows │ │ │ └── WindowsWin.cpp │ │ ├── DataStructure │ │ ├── Model.cpp │ │ └── Vertex.cpp │ │ ├── ECS │ │ ├── Component │ │ │ ├── Camera.cpp │ │ │ ├── Id.cpp │ │ │ ├── Label.cpp │ │ │ ├── Light.cpp │ │ │ ├── ModelRenderer.cpp │ │ │ ├── Script.cpp │ │ │ ├── SpriteRenderer.cpp │ │ │ └── Transform.cpp │ │ ├── Entity.cpp │ │ ├── Scene.cpp │ │ └── SceneCamera.cpp │ │ ├── ImGui │ │ ├── ImGuiLayer.cpp │ │ └── imgui_impl_vulkan.cpp │ │ ├── Project │ │ └── Project.cpp │ │ ├── Renderer │ │ ├── Batch.cpp │ │ ├── Buffer.cpp │ │ ├── Camera.cpp │ │ ├── Descriptors.cpp │ │ ├── Device.cpp │ │ ├── Framebuffer.cpp │ │ ├── Material.cpp │ │ ├── MeshRenderer.cpp │ │ ├── Pipeline.cpp │ │ ├── RenderPass.cpp │ │ ├── Renderer.cpp │ │ ├── Renderer2D.cpp │ │ ├── Shader.cpp │ │ ├── Skybox.cpp │ │ ├── SubMeshRenderer.cpp │ │ ├── SwapChain.cpp │ │ └── Texture.cpp │ │ └── Scripting │ │ ├── EntityBehavior.cpp │ │ ├── ScriptClass.cpp │ │ ├── ScriptEngine.cpp │ │ ├── ScriptField.cpp │ │ ├── ScriptFile.cpp │ │ └── ScriptInstance.cpp └── vendor │ ├── stb_image │ └── stb_image.h │ └── uuid.h ├── CardiaTor ├── include │ ├── CardiaTor.hpp │ ├── Command │ │ └── Commands.hpp │ ├── EditorCamera.hpp │ ├── EditorUI │ │ ├── DragData.hpp │ │ └── Theme.hpp │ └── Panels │ │ ├── ConsolePanel.hpp │ │ ├── DebugPanel.hpp │ │ ├── FileHierarchyPanel.hpp │ │ ├── IPanel.hpp │ │ ├── InspectorPanel.hpp │ │ ├── PanelManager.hpp │ │ └── SceneHierarchyPanel.hpp ├── resources │ ├── editorconfig.ini │ ├── editorconfig.ini.imp │ ├── fonts.imp │ ├── fonts │ │ ├── opensans.imp │ │ └── opensans │ │ │ ├── LICENSE.txt │ │ │ ├── LICENSE.txt.imp │ │ │ ├── OpenSans-Bold.ttf │ │ │ ├── OpenSans-Bold.ttf.imp │ │ │ ├── OpenSans-BoldItalic.ttf │ │ │ ├── OpenSans-BoldItalic.ttf.imp │ │ │ ├── OpenSans-ExtraBold.ttf │ │ │ ├── OpenSans-ExtraBold.ttf.imp │ │ │ ├── OpenSans-ExtraBoldItalic.ttf │ │ │ ├── OpenSans-ExtraBoldItalic.ttf.imp │ │ │ ├── OpenSans-Italic.ttf │ │ │ ├── OpenSans-Italic.ttf.imp │ │ │ ├── OpenSans-Light.ttf │ │ │ ├── OpenSans-Light.ttf.imp │ │ │ ├── OpenSans-LightItalic.ttf │ │ │ ├── OpenSans-LightItalic.ttf.imp │ │ │ ├── OpenSans-Medium.ttf │ │ │ ├── OpenSans-Medium.ttf.imp │ │ │ ├── OpenSans-MediumItalic.ttf │ │ │ ├── OpenSans-MediumItalic.ttf.imp │ │ │ ├── OpenSans-Regular.ttf │ │ │ ├── OpenSans-Regular.ttf.imp │ │ │ ├── OpenSans-SemiBold.ttf │ │ │ ├── OpenSans-SemiBold.ttf.imp │ │ │ ├── OpenSans-SemiBoldItalic.ttf │ │ │ └── OpenSans-SemiBoldItalic.ttf.imp │ ├── icons.imp │ ├── icons │ │ ├── file.png │ │ ├── file.png.imp │ │ ├── folder.png │ │ ├── folder.png.imp │ │ ├── pause.png │ │ ├── pause.png.imp │ │ ├── play.png │ │ └── play.png.imp │ ├── logo.imp │ ├── logo │ │ ├── logo.ico │ │ ├── logo.ico.imp │ │ ├── logo.png │ │ ├── logo.png.imp │ │ ├── resource.rc │ │ └── resource.rc.imp │ ├── shaders.imp │ ├── shaders │ │ ├── simple.frag │ │ ├── simple.frag.imp │ │ ├── simple.vert │ │ ├── simple.vert.imp │ │ ├── skybox.frag │ │ ├── skybox.frag.imp │ │ ├── skybox.vert │ │ └── skybox.vert.imp │ ├── textures.imp │ └── textures │ │ ├── normal.jpg │ │ ├── normal.jpg.imp │ │ ├── skybox.imp │ │ ├── skybox │ │ ├── lilienstein_skybox.tga │ │ └── lilienstein_skybox.tga.imp │ │ ├── white.jpg │ │ └── white.jpg.imp └── src │ ├── CardiaTor.cpp │ ├── CardiaTorApp.cpp │ ├── Command │ └── Commands.cpp │ ├── EditorCamera.cpp │ ├── EditorUI │ └── DragData.cpp │ └── Panels │ ├── ConsolePanel.cpp │ ├── DebugPanel.cpp │ ├── FileHierarchyPanel.cpp │ ├── InspectorPanel.cpp │ ├── PanelManager.cpp │ └── SceneHierarchyPanel.cpp ├── LICENSE ├── README.md ├── Samples └── HelloCardia │ ├── Assets │ ├── HelloCardia.cardia │ ├── Moving.py │ └── cube.obj │ └── HelloCardia.cdproj ├── SandBox ├── include │ └── RuntimeApp.hpp ├── resources │ ├── container.jpg │ ├── shaders │ │ ├── basic.frag │ │ └── basic.vert │ └── square.jpg └── src │ ├── RuntimeApp.cpp │ └── SandBoxApp.cpp ├── Tests └── Cardia │ └── src │ └── Math │ ├── Angle.cpp │ ├── Matrix.cpp │ ├── Quaternion.cpp │ └── Vector.cpp ├── cardia.py ├── .gitignore ├── README.md ├── pyproject.toml ├── setup.py └── src │ ├── LICENSE │ └── cardia │ ├── __init__.py │ ├── component │ ├── __init__.py │ ├── behavior.py │ ├── camera.py │ ├── lights.py │ └── transform.py │ ├── core │ ├── __init__.py │ └── entity.py │ ├── coroutines │ ├── __init__.py │ └── event_loop.py │ ├── editor │ ├── __init__.py │ └── inspector.py │ ├── event │ ├── __init__.py │ ├── event_decorator.py │ ├── input.py │ └── keycode.py │ ├── log │ └── __init__.py │ ├── math │ ├── __init__.py │ └── vector.py │ └── time │ ├── __init__.py │ └── time.py ├── scripts ├── BuildSimpleShader.bat ├── GenerateVSSolution.bat └── cpAssetsCLionDebug.bat └── xmake.lua /.github/image/cardia-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TNtube/Cardia/6fbde85b58bac3921ed7d12624e896750686b2db/.github/image/cardia-logo.png -------------------------------------------------------------------------------- /.github/image/cardiator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TNtube/Cardia/6fbde85b58bac3921ed7d12624e896750686b2db/.github/image/cardiator.png -------------------------------------------------------------------------------- /.github/image/scripting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TNtube/Cardia/6fbde85b58bac3921ed7d12624e896750686b2db/.github/image/scripting.png -------------------------------------------------------------------------------- /.github/workflows/windows-latest.yml: -------------------------------------------------------------------------------- 1 | name: Cardia for Windows 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | name: Checkout 16 | 17 | - uses: xmake-io/github-action-setup-xmake@v1 18 | with: 19 | xmake-version: latest 20 | name: Install xmake 21 | 22 | - name: Build debug 23 | run: | 24 | xmake f -m debug -y -v 25 | xmake -v 26 | 27 | - name: Build release 28 | run: | 29 | xmake f -m release -y 30 | xmake 31 | 32 | - name: Prepare artifacts 33 | run: | 34 | mkdir debug-artifact 35 | move build/debug-windows-x64/SandBox/bin/SandBox.exe debug-artifact/ 36 | move build/debug-windows-x64/SandBox/bin/SandBox.pdb debug-artifact/ 37 | 38 | mkdir release-artifact 39 | move build/release-windows-x64/SandBox/bin/SandBox.exe release-artifact/ 40 | 41 | - uses: actions/upload-artifact@v2 42 | with: 43 | name: cardia-windows-debug-${{ github.run_id }} 44 | path: debug-artifact/ 45 | name: Upload debug artifact 46 | 47 | - uses: actions/upload-artifact@v2 48 | with: 49 | name: cardia-windows-release-${{ github.run_id }} 50 | path: release-artifact/ 51 | name: Upload release artifact 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Directories 2 | 3 | .vs/ 4 | bin/ 5 | bin-int/ 6 | 7 | # Files 8 | CMakeLists.txt 9 | *.user 10 | 11 | # xmake 12 | .xmake/ 13 | build/ 14 | vsxmake2019/ 15 | vs2022/ 16 | 17 | # CLion 18 | .idea/ 19 | cmake-build-debug/ 20 | cmake-build-release/ 21 | /vsxmake2022/ 22 | -------------------------------------------------------------------------------- /Cardia/include/Cardia.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Unique for Cardia App 4 | 5 | #include "Cardia/Application.hpp" 6 | #include "Cardia/Core/Log.hpp" 7 | #include "Cardia/Core/Time.hpp" 8 | 9 | #include "Cardia/ImGui/ImGuiLayer.hpp" 10 | 11 | #include "Cardia/Core/Input.hpp" 12 | #include "Cardia/Core/KeyCodes.hpp" 13 | 14 | // ----- Entity Component System --------- 15 | 16 | #include "Cardia/ECS/Scene.hpp" 17 | #include "Cardia/ECS/Entity.hpp" 18 | #include "Cardia/ECS/Components.hpp" 19 | 20 | // ----- Renderer ------------------------ 21 | 22 | #include "Cardia/Renderer/Renderer2D.hpp" 23 | 24 | #include "Cardia/Renderer/Buffer.hpp" 25 | #include "Cardia/Renderer/Texture.hpp" 26 | #include "Cardia/Renderer/Framebuffer.hpp" 27 | 28 | #include "Cardia/Renderer/Camera.hpp" 29 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Application.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "Cardia/Core/Core.hpp" 5 | #include "Cardia/Core/Time.hpp" 6 | #include "Cardia/Core/Window.hpp" 7 | #include "Cardia/ImGui/ImGuiLayer.hpp" 8 | #include "Cardia/Scripting/ScriptEngine.hpp" 9 | #include "Renderer/Renderer.hpp" 10 | #include "Cardia/Asset/AssetsManager.hpp" 11 | 12 | 13 | namespace Cardia 14 | { 15 | class Application 16 | { 17 | public: 18 | Application(); 19 | virtual ~Application(); 20 | 21 | void Run(); 22 | virtual void OnEvent(Event& e) = 0; 23 | virtual void OnUpdate() = 0; 24 | virtual void OnRender() = 0; 25 | virtual Scene* GetCurrentScene() = 0; 26 | bool OnWinClose(WindowCloseEvent& e); 27 | 28 | inline static Application& Get() { return *s_Instance; } 29 | inline Window& GetWindow() const { return *m_Window; } 30 | inline void Close() { m_Running = false; } 31 | inline Renderer& GetRenderer() { return m_Renderer; } 32 | inline AssetsManager& GetAssetsManager() { return m_AssetsManager; } 33 | 34 | private: 35 | std::unique_ptr m_Window = Window::Create(); 36 | 37 | protected: 38 | Renderer m_Renderer {*m_Window}; 39 | AssetsManager m_AssetsManager {m_Renderer}; 40 | private: 41 | ScriptEngine m_ScriptEngine; 42 | bool m_Running = true; 43 | static Application* s_Instance; 44 | }; 45 | 46 | std::unique_ptr CreateApplication(); 47 | } 48 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Asset/Asset.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "Cardia/Core/UUID.hpp" 5 | 6 | 7 | namespace Cardia 8 | { 9 | struct AssetHandle 10 | { 11 | UUID ID; 12 | 13 | static AssetHandle Invalid() { return { UUID::Default() }; } 14 | 15 | bool IsValid() const { return ID.IsValid(); } 16 | 17 | bool operator==(const AssetHandle& other) const { return ID == other.ID; } 18 | 19 | Json::Value Serialize() const { 20 | Json::Value value; 21 | value["ID"] = ID.ToString(); 22 | 23 | return value; 24 | } 25 | static std::optional Deserialize(const Json::Value& value) { 26 | if (value["ID"].isNull()) 27 | return {}; 28 | return AssetHandle{UUID::FromString(value["ID"].asString())}; 29 | } 30 | 31 | }; 32 | 33 | class Asset 34 | { 35 | public: 36 | explicit Asset(AssetHandle assetHandle) : m_Handle(std::move(assetHandle)) {}; 37 | Asset() = default; 38 | virtual ~Asset() = default; 39 | 40 | const AssetHandle& GetHandle() const { return m_Handle; } 41 | 42 | virtual void Reload() = 0; 43 | virtual bool CheckForDirtyInDependencies() = 0; // return false if any asset dependency is invalid 44 | 45 | protected: 46 | AssetHandle m_Handle; 47 | }; 48 | } 49 | 50 | namespace std { 51 | template<> 52 | struct hash { 53 | auto operator()(const Cardia::AssetHandle& handle) const noexcept -> ::size_t { 54 | return handle.ID.Hash(); 55 | } 56 | }; 57 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/Asset/AssetsManager.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Cardia/Serialization/Serializer.hpp" 9 | #include "Cardia/Project/Project.hpp" 10 | #include "Cardia/Renderer/Material.hpp" 11 | #include "Cardia/Renderer/Texture.hpp" 12 | 13 | namespace Cardia { 14 | struct AssetRefCounter 15 | { 16 | AssetRefCounter() = default; 17 | explicit AssetRefCounter(std::shared_ptr resource) : Resource(std::move(resource)) {} 18 | std::shared_ptr Resource; 19 | bool Dirty = false; 20 | uint32_t UnusedCounter = 0; 21 | }; 22 | } 23 | 24 | namespace Cardia 25 | { 26 | template concept AssetType = std::is_base_of_v; 27 | 28 | class AssetsManager 29 | { 30 | public: 31 | explicit AssetsManager(const Renderer& renderer); 32 | 33 | template std::shared_ptr Load(const std::filesystem::path& path); 34 | template std::shared_ptr Load(const AssetHandle& handle); 35 | 36 | AssetHandle GetHandleFromRelative(const std::filesystem::path& relativePath); 37 | AssetHandle GetHandleFromAbsolute(const std::filesystem::path& absolutePath); 38 | AssetHandle GetHandleFromAsset(const std::filesystem::path& relativeToAssetsPath); 39 | AssetHandle AddPathEntry(const std::filesystem::path& absolutePath); 40 | void AddAssetEntry(const std::shared_ptr& asset); 41 | 42 | void SetDirty(const AssetHandle& handle); 43 | bool IsDirty(const AssetHandle& handle) const; 44 | void ReloadAllDirty(); 45 | 46 | void PopulateHandleFromProject(const Project& project); 47 | void PopulateHandleFromResource(); 48 | 49 | void ReloadAssetFromHandle(const AssetHandle& handle); 50 | 51 | std::filesystem::path RelativePathFromHandle(const AssetHandle& handle) const; 52 | std::filesystem::path AbsolutePathFromHandle(const AssetHandle& handle) const; 53 | 54 | void Update(); 55 | 56 | private: 57 | void PopulateHandleFromPath(const std::filesystem::path& abs); 58 | bool LoadHandleFromPath(const std::filesystem::path& abs); 59 | void RegisterNewHandle(const std::filesystem::path& abs); 60 | 61 | void RemovePathForHandle(const AssetHandle& handle); 62 | 63 | void CollectUnusedAssets(bool force = false); 64 | 65 | const Renderer& m_Renderer; 66 | 67 | Project m_Project; 68 | 69 | std::unordered_map m_Assets; 70 | std::unordered_map m_AssetPaths; 71 | 72 | 73 | // file watcher 74 | struct FileUpdateInfo { 75 | std::filesystem::path OldPath; 76 | std::filesystem::path NewPath; 77 | efsw::Action Action; 78 | }; 79 | 80 | class AssetsListener : public efsw::FileWatchListener 81 | { 82 | public: 83 | explicit AssetsListener(AssetsManager& assetsManager) : m_AssetsManager(assetsManager) {} 84 | void handleFileAction(efsw::WatchID watchId, const std::string& dir, const std::string& filename, 85 | efsw::Action action, std::string oldFilename) override; 86 | 87 | void WatcherRoutine(); 88 | private: 89 | void OnFileAdded(const std::filesystem::path& newPath) const; 90 | void OnFileRemoved(const std::filesystem::path& newPath) const; 91 | void OnFileUpdate(const std::filesystem::path& newPath) const; 92 | void OnFileRename(const std::filesystem::path& oldPath, const std::filesystem::path& newPath) const; 93 | 94 | void ComputeFileInfo(const FileUpdateInfo& updateInfo) const; 95 | 96 | AssetsManager& m_AssetsManager; 97 | std::queue m_Queue; 98 | std::mutex m_WatcherMutex; 99 | }; 100 | 101 | AssetsListener m_AssetsListener; 102 | 103 | efsw::FileWatcher m_FileWatcher; 104 | efsw::WatchID m_WatchID = 0; 105 | }; 106 | } 107 | 108 | #include "Cardia/Asset/AssetsManager.inl" 109 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Asset/AssetsManager.inl: -------------------------------------------------------------------------------- 1 | #include "Cardia/Renderer/Renderer.hpp" 2 | 3 | namespace Cardia 4 | { 5 | template 6 | inline std::shared_ptr AssetsManager::Load(const std::filesystem::path& path) 7 | { 8 | return Load(GetHandleFromAsset(path)); 9 | } 10 | 11 | template 12 | inline std::shared_ptr AssetsManager::Load(const AssetHandle& handle) 13 | { 14 | CdCoreAssert(false, "Asset type not supported"); 15 | } 16 | 17 | template<> 18 | inline std::shared_ptr AssetsManager::Load(const AssetHandle& handle) 19 | { 20 | if (m_Assets.contains(handle)) { 21 | return std::static_pointer_cast(m_Assets.at(handle).Resource); 22 | } 23 | auto path = AbsolutePathFromHandle(handle); 24 | std::shared_ptr texture = Texture::Builder(m_Renderer.GetDevice()) 25 | .SetAssetHandle(handle) 26 | .Build(); 27 | 28 | m_Assets[handle] = AssetRefCounter(texture); 29 | 30 | return texture; 31 | } 32 | 33 | template<> 34 | inline std::shared_ptr AssetsManager::Load(const AssetHandle& handle) 35 | { 36 | if (m_Assets.contains(handle)) { 37 | return std::static_pointer_cast(m_Assets.at(handle).Resource); 38 | } 39 | auto path = AbsolutePathFromHandle(handle); 40 | auto materialData = Serializer::Deserialize(path); 41 | if (!materialData) { 42 | return nullptr; 43 | } 44 | 45 | auto material = std::make_shared(m_Renderer.GetDevice(), *materialData, handle); 46 | m_Assets[handle] = AssetRefCounter(material); 47 | 48 | return material; 49 | } 50 | 51 | template<> 52 | inline std::shared_ptr AssetsManager::Load(const AssetHandle& handle) 53 | { 54 | if (m_Assets.contains(handle)) { 55 | return std::static_pointer_cast(m_Assets.at(handle).Resource); 56 | } 57 | const auto path = AbsolutePathFromHandle(handle); 58 | auto materialData = Model::FromFile(path); 59 | 60 | auto material = std::make_shared(m_Renderer.GetDevice(), handle, materialData); 61 | m_Assets[handle] = AssetRefCounter(material); 62 | 63 | return material; 64 | } 65 | 66 | template<> 67 | inline std::shared_ptr AssetsManager::Load(const AssetHandle& handle) 68 | { 69 | return nullptr; 70 | } 71 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Concepts.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace Cardia 5 | { 6 | template concept arithmetic = std::is_arithmetic_v; 7 | template concept floating_point = std::is_floating_point_v; 8 | } 9 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Core.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #if !defined(_WIN64) && !defined(__linux__) 3 | #error Cardia is only for Windows x64 or Linux ! 4 | #endif 5 | 6 | #include 7 | #include 8 | #include 9 | #include "Log.hpp" 10 | #include 11 | #include "Concepts.hpp" 12 | 13 | 14 | namespace Cardia 15 | { 16 | #define CD_BIND_EVENT_FN(x) [this](auto && PH1) { return (x)(PH1); } 17 | 18 | #if defined(__cpp_consteval) && !defined(NDEBUG) // Trick because CLion can't find std::source_location 19 | template 20 | constexpr void CdAssert(T x, const std::string& message = "invalid", const std::source_location location = std::source_location::current()) 21 | { 22 | if (!x) 23 | Cardia::Log::CoreError("{0} : ({1}:{2}) Assertion failed: {3}", 24 | location.file_name(), location.line(), location.column(), message); 25 | assert(x); 26 | } 27 | template 28 | constexpr void CdCoreAssert(T x, const std::string& message = "invalid", const std::source_location location = std::source_location::current()) 29 | { 30 | if (!x) 31 | Cardia::Log::CoreError("{0} : ({1}:{2}) Assertion failed: {3}", 32 | location.file_name(), location.line(), location.column(), message); 33 | assert(x); 34 | } 35 | #else 36 | template 37 | constexpr void CdAssert(T x, const std::string& message = "invalid") {} 38 | template 39 | constexpr void CdCoreAssert(T x, const std::string& message = "invalid") {}; 40 | #endif 41 | 42 | template 43 | constexpr T Bit(T x) 44 | { 45 | return 1 << x; 46 | } 47 | 48 | template , bool> = true> 49 | constexpr auto enum_as_integer(const Enumeration value) -> std::underlying_type_t 50 | { 51 | return static_cast>(value); 52 | } 53 | 54 | template 55 | constexpr bool IsAlmostEqual(T l, T r) 56 | { 57 | return r == std::nextafter(l, r); 58 | } 59 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Input.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cardia/Math/Vector2.hpp" 4 | 5 | 6 | namespace Cardia 7 | { 8 | class Input 9 | { 10 | public: 11 | static bool IsKeyPressed(int keyCode); 12 | static bool IsMouseButtonPressed(int button); 13 | static Vector2f GetMousePos(); 14 | static float GetMouseX(); 15 | static float GetMouseY(); 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/KeyCodes.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Cardia::Key { 5 | enum Key : uint32_t { 6 | // from GLFW 7 | 8 | // Printable keys 9 | Space = 32, 10 | Apostrophe = 39, 11 | Comma = 44, 12 | Minus = 45, 13 | Period = 46, 14 | Slash = 47, 15 | N0 = 48, 16 | N1 = 49, 17 | N2 = 50, 18 | N3 = 51, 19 | N4 = 52, 20 | N5 = 53, 21 | N6 = 54, 22 | N7 = 55, 23 | N8 = 56, 24 | N9 = 57, 25 | Semicolon = 59, 26 | Equal = 61, 27 | A = 65, 28 | B = 66, 29 | C = 67, 30 | D = 68, 31 | E = 69, 32 | F = 70, 33 | G = 71, 34 | H = 72, 35 | I = 73, 36 | J = 74, 37 | K = 75, 38 | L = 76, 39 | M = 77, 40 | N = 78, 41 | O = 79, 42 | P = 80, 43 | Q = 81, 44 | R = 82, 45 | S = 83, 46 | T = 84, 47 | U = 85, 48 | V = 86, 49 | W = 87, 50 | X = 88, 51 | Y = 89, 52 | Z = 90, 53 | LBracket = 91, 54 | BackSlash = 92, 55 | RBracket = 93, 56 | GraveAccent = 96, 57 | 58 | Right = 262, 59 | Left = 263, 60 | Down = 264, 61 | Up = 265, 62 | 63 | LeftShift = 340, 64 | LeftCtrl = 341, 65 | LeftAlt = 342, 66 | RightShift = 344, 67 | RightCtrl = 345, 68 | RightAlt = 346 69 | 70 | // MISSING A LOT OF KEY CODES 71 | }; 72 | } 73 | 74 | namespace Cardia::Mouse 75 | { 76 | enum Mouse: uint32_t 77 | { 78 | Left = 0, 79 | Right = 1, 80 | Middle = 2 81 | }; 82 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Log.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace Cardia 7 | { 8 | typedef std::function custom_log_callback; 9 | class Logger 10 | { 11 | public: 12 | static void Init(); 13 | static spdlog::logger* GetCoreLogger() { return s_CoreLogger.get(); } 14 | static spdlog::logger* GetEditorLogger() { return s_ClientLogger.get(); } 15 | static void AddCoreCallback(const custom_log_callback& callback); 16 | static void AddEditorCallback(const custom_log_callback& callback); 17 | private: 18 | static std::shared_ptr s_CoreLogger; 19 | static std::shared_ptr s_ClientLogger; 20 | }; 21 | 22 | namespace Log 23 | { 24 | // Core Log 25 | template 26 | constexpr void CoreTrace(Args&&... args) 27 | { 28 | Logger::GetEditorLogger(); 29 | Logger::GetCoreLogger()->trace(std::forward(args)...); 30 | } 31 | 32 | template 33 | constexpr void CoreInfo(Args&&... args) 34 | { 35 | Logger::GetCoreLogger()->info(std::forward(args)...); 36 | } 37 | 38 | template 39 | constexpr void CoreWarn(Args&&... args) 40 | { 41 | Logger::GetCoreLogger()->warn(std::forward(args)...); 42 | } 43 | 44 | template 45 | constexpr void CoreError(Args&&... args) 46 | { 47 | Logger::GetCoreLogger()->error(std::forward(args)...); 48 | } 49 | 50 | // SandBox Log Macros 51 | template 52 | constexpr void Trace(Args&&... args) 53 | { 54 | Logger::GetEditorLogger()->trace(std::forward(args)...); 55 | } 56 | 57 | template 58 | constexpr void Info(Args&&... args) 59 | { 60 | Logger::GetEditorLogger()->info(std::forward(args)...); 61 | } 62 | 63 | template 64 | constexpr void Warn(Args&&... args) 65 | { 66 | Logger::GetEditorLogger()->warn(std::forward(args)...); 67 | } 68 | 69 | template 70 | constexpr void Error(Args&&... args) 71 | { 72 | Logger::GetEditorLogger()->error(std::forward(args)...); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Time.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Cardia { 5 | class DeltaTime { 6 | public: 7 | DeltaTime(float time = 0.0f) 8 | : m_Time(time) {} 9 | 10 | inline float AsSeconds() const { return m_Time; } 11 | 12 | inline float AsMilliseconds() const { return m_Time * 1000.0f; } 13 | 14 | operator float() const { return m_Time; } 15 | 16 | private: 17 | float m_Time; 18 | }; 19 | 20 | class Application; 21 | 22 | class Time { 23 | public: 24 | static DeltaTime GetDeltaTime() { return m_DeltaTime; } 25 | static double GetTime() { return m_LastFrameTime; } 26 | private: 27 | friend Application; 28 | static DeltaTime m_DeltaTime; 29 | static double m_LastFrameTime; 30 | }; 31 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/UUID.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace Cardia { 6 | 7 | class UUID 8 | { 9 | public: 10 | UUID(); 11 | explicit UUID(const uuids::uuid& uuid); 12 | UUID(UUID&& other) noexcept; 13 | UUID& operator=(UUID&& other) noexcept; 14 | UUID(const UUID&) = default; 15 | UUID& operator=(const UUID&) = default; 16 | 17 | static UUID Default() { return UUID(uuids::uuid()); }; 18 | static UUID FromString(const std::string& strUuid); 19 | std::string ToString() const { return uuids::to_string(m_UUID); } 20 | 21 | bool IsValid() const { return !m_UUID.is_nil(); } 22 | 23 | std::size_t Hash() const { return std::hash{}(m_UUID); } 24 | 25 | inline bool operator==(const UUID& rhs) const { return this->m_UUID == rhs.m_UUID; } 26 | private: 27 | uuids::uuid m_UUID; 28 | friend std::hash; 29 | }; 30 | 31 | } 32 | 33 | namespace std { 34 | template<> 35 | struct hash 36 | { 37 | std::size_t operator()(const Cardia::UUID& uuid) const 38 | { 39 | static auto h = std::hash{}; 40 | return h(uuid.m_UUID); 41 | } 42 | }; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Window.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cdpch.hpp" 4 | #include "vulkan/vulkan.h" 5 | #include "Cardia/Core/Core.hpp" 6 | #include "Event.hpp" 7 | #include "Cardia/Math/Vector2.hpp" 8 | 9 | 10 | namespace Cardia 11 | { 12 | struct WinProperties 13 | { 14 | int Width, Height; 15 | std::string Title; 16 | std::filesystem::path IconPath; 17 | 18 | explicit WinProperties(std::string title = "Cardia", 19 | std::filesystem::path iconPath = "resources/logo/logo.png", 20 | int width = 1920, 21 | int height = 1080) 22 | : Width(width), Height(height), Title(std::move(title)), IconPath(std::move(iconPath)) {} 23 | }; 24 | 25 | class Window 26 | { 27 | public: 28 | virtual ~Window() = default; 29 | virtual void OnUpdate() = 0; 30 | 31 | virtual int GetWidth() const = 0; 32 | virtual int GetHeight() const = 0; 33 | virtual Vector2i GetSize() const = 0; 34 | virtual VkExtent2D GetExtent() const = 0; 35 | virtual bool ShouldInvalidateSwapchain() const = 0; 36 | virtual void SwapchainInvalidated() = 0; 37 | 38 | virtual void SetEventCallback(const std::function& callback) = 0; 39 | virtual void SetFullscreen(bool state) = 0; 40 | virtual bool IsFullscreen() const = 0; 41 | virtual bool IsFocused() const = 0; 42 | virtual void UpdateFullscreenMode() = 0; 43 | virtual void SetVSync(bool state) = 0; 44 | virtual bool IsVSync() const = 0; 45 | 46 | virtual void* GetNativeWindow() const = 0; 47 | 48 | static std::unique_ptr Create(const WinProperties& properties = WinProperties()); 49 | 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/Core/Windows/WindowsWin.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cardia/Core/Window.hpp" 4 | #include "Cardia/Renderer/Renderer.hpp" 5 | 6 | #include 7 | 8 | 9 | namespace Cardia 10 | { 11 | struct WinData 12 | { 13 | std::string Title; 14 | int Width, Height; 15 | bool VSync = false; 16 | bool ShouldInvalidateSwapchain = false; 17 | bool ShouldUpdateFullscreenMode = false; 18 | bool IsFullscreen = false; 19 | bool HasFocus = true; 20 | 21 | std::function EventCallback; 22 | }; 23 | 24 | class WindowsWin : public Window 25 | { 26 | public: 27 | explicit WindowsWin(const WinProperties& properties); 28 | ~WindowsWin() override; 29 | 30 | void OnUpdate() override; 31 | inline int GetWidth() const override { return m_Data.Width; } 32 | inline int GetHeight() const override { return m_Data.Height; } 33 | inline Vector2i GetSize() const override { return {m_Data.Width, m_Data.Height}; } 34 | inline VkExtent2D GetExtent() const override { return VkExtent2D {static_cast(m_Data.Width), static_cast(m_Data.Height)}; } 35 | 36 | inline bool ShouldInvalidateSwapchain() const override { return m_Data.ShouldInvalidateSwapchain; } 37 | inline void SwapchainInvalidated() override { m_Data.ShouldInvalidateSwapchain = false; } 38 | 39 | 40 | inline void SetEventCallback(const std::function& callback) override { m_Data.EventCallback = callback; } 41 | 42 | void SetFullscreen(bool state) override; 43 | void UpdateFullscreenMode() override; 44 | bool IsFullscreen() const override; 45 | bool IsFocused() const override; 46 | 47 | void SetVSync(bool state) override; 48 | bool IsVSync() const override; 49 | 50 | inline void* GetNativeWindow() const override { return m_Window; } 51 | 52 | private: 53 | void Init(const WinProperties& properties); 54 | void Quit(); 55 | 56 | static bool s_isGlfwInit; // Can only initialize glfw once. 57 | GLFWwindow* m_Window; 58 | WinData m_Data; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/DataStructure/Mesh.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "Cardia/Math/Vector2.hpp" 8 | #include "Cardia/Math/Vector3.hpp" 9 | #include "Vertex.hpp" 10 | 11 | 12 | namespace Cardia 13 | { 14 | class Mesh 15 | { 16 | public: 17 | Mesh() = default; 18 | std::vector& GetVertices() { return m_Vertices; } 19 | std::vector& GetIndices() { return m_Indices; } 20 | uint32_t GetMaterialIndex() const { return m_MaterialIndex; } 21 | 22 | private: 23 | friend class Model; 24 | uint32_t m_MaterialIndex = 0; 25 | std::vector m_Vertices; 26 | std::vector m_Indices; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/DataStructure/Model.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "Mesh.hpp" 5 | #include "Cardia/Renderer/Texture.hpp" 6 | 7 | namespace Cardia 8 | { 9 | class Model 10 | { 11 | public: 12 | Model() = default; 13 | std::vector& GetMeshes() { return m_Meshes; } 14 | const std::vector& GetMeshes() const { return m_Meshes; } 15 | const std::vector& GetMaterialHandles() const { return m_MaterialHandles; } 16 | std::vector& GetMaterialHandles() { return m_MaterialHandles; } 17 | 18 | static Model FromFile(const std::filesystem::path& absolutePath); 19 | private: 20 | std::vector m_MaterialHandles {}; 21 | std::vector m_Meshes {}; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /Cardia/include/Cardia/DataStructure/Vertex.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include 5 | #include "Cardia/Math/Vector3.hpp" 6 | #include "Cardia/Math/Vector2.hpp" 7 | 8 | namespace Cardia 9 | { 10 | 11 | 12 | struct Vertex 13 | { 14 | Vector3f Position; 15 | Vector3f Normal; 16 | Vector2f TextureCoord; 17 | Vector3f Tangent; 18 | 19 | static std::vector GetBindingDescriptions(); 20 | static std::vector GetAttributeDescriptions(); 21 | }; 22 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/ECS/Component/Camera.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cardia/ECS/SceneCamera.hpp" 4 | #include "Cardia/Renderer/MeshRenderer.hpp" 5 | 6 | namespace Cardia::Component 7 | { 8 | struct Camera 9 | { 10 | SceneCamera CameraData; 11 | bool Primary = true; 12 | Camera() = default; 13 | 14 | inline void Reset() { 15 | CameraData = SceneCamera(); 16 | } 17 | 18 | Json::Value Serialize() const; 19 | static std::optional Deserialize(const Json::Value& root); 20 | }; 21 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/ECS/Component/Id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cardia/Core/UUID.hpp" 4 | #include 5 | 6 | namespace Cardia::Component 7 | { 8 | struct ID 9 | { 10 | ID() : Uuid(UUID()) {} 11 | explicit ID(UUID uuid) 12 | : Uuid(uuid) {} 13 | 14 | UUID Uuid; 15 | 16 | Json::Value Serialize() const; 17 | static std::optional Deserialize(const Json::Value& root); 18 | }; 19 | } -------------------------------------------------------------------------------- /Cardia/include/Cardia/ECS/Component/Label.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Cardia/Math/Vector4.hpp" 4 | 5 | namespace Cardia::Component 6 | { 7 | struct Label 8 | { 9 | Label() = default; 10 | explicit Label(std::string Label) 11 | : Name(std::move(Label)) {} 12 | 13 | std::string Name; 14 | Vector4f Color { 1.0f }; 15 | 16 | inline void Reset() { 17 | Name = "Default"; 18 | Color = Vector4f(1.0f); 19 | } 20 | 21 | Json::Value Serialize() const; 22 | static std::optional