├── .editorconfig ├── .gitignore ├── .gitmodules ├── Dependencies.lua ├── Ghost-Editor ├── Resources │ └── Icons │ │ ├── ContentBrowser │ │ ├── DocumentIcon.png │ │ ├── FileIcon.png │ │ ├── FolderIcon.png │ │ ├── OpenedFolderIcon.png │ │ └── PictureIcon.png │ │ ├── PlayButton.png │ │ └── StopButton.png ├── assets │ ├── Test.txt │ ├── fonts │ │ ├── fontawesome │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-regular-400.ttf │ │ │ └── fa-solid-900.ttf │ │ └── opensans │ │ │ ├── LICENSE.txt │ │ │ ├── OpenSans-Bold.ttf │ │ │ ├── OpenSans-BoldItalic.ttf │ │ │ ├── OpenSans-ExtraBold.ttf │ │ │ ├── OpenSans-ExtraBoldItalic.ttf │ │ │ ├── OpenSans-Italic.ttf │ │ │ ├── OpenSans-Light.ttf │ │ │ ├── OpenSans-LightItalic.ttf │ │ │ ├── OpenSans-Regular.ttf │ │ │ ├── OpenSans-SemiBold.ttf │ │ │ └── OpenSans-SemiBoldItalic.ttf │ ├── scenes │ │ ├── Example.ghost │ │ ├── Orthographic2D.ghost │ │ ├── Perspective2D.ghost │ │ └── Physics2D.ghost │ ├── shaders │ │ ├── FlatColor.glsl │ │ └── Texture.glsl │ └── textures │ │ ├── crate2_diffuse.png │ │ └── test_texture.png ├── imgui.ini ├── premake5.lua └── src │ ├── EditorLayer.cpp │ ├── EditorLayer.h │ ├── GhostEditorApp.cpp │ └── Panels │ ├── ContentBrowserPanel.cpp │ ├── ContentBrowserPanel.h │ ├── SceneHierarchyPanel.cpp │ └── SceneHierarchyPanel.h ├── Ghost ├── premake5.lua ├── src │ ├── Ghost.h │ ├── Ghost │ │ ├── Camera │ │ │ ├── Camera.h │ │ │ ├── Controllers │ │ │ │ ├── OrthographicCameraController.cpp │ │ │ │ └── OrthographicCameraController.h │ │ │ ├── OrthographicCamera.cpp │ │ │ └── OrthographicCamera.h │ │ ├── Core │ │ │ ├── Application.cpp │ │ │ ├── Application.h │ │ │ ├── Assert.h │ │ │ ├── Base.h │ │ │ ├── EntryPoint.h │ │ │ ├── Input.h │ │ │ ├── KeyCodes.h │ │ │ ├── Layer.cpp │ │ │ ├── Layer.h │ │ │ ├── LayerStack.cpp │ │ │ ├── LayerStack.h │ │ │ ├── Log.cpp │ │ │ ├── Log.h │ │ │ ├── MouseCodes.h │ │ │ ├── PlatformDetection.h │ │ │ ├── Timer.h │ │ │ ├── Timestep.h │ │ │ ├── UUID.cpp │ │ │ ├── UUID.h │ │ │ ├── Window.cpp │ │ │ └── Window.h │ │ ├── Debug │ │ │ └── Instrumentor.h │ │ ├── Events │ │ │ ├── ApplicationEvent.h │ │ │ ├── Event.h │ │ │ ├── KeyEvent.h │ │ │ └── MouseEvent.h │ │ ├── Fonts │ │ │ ├── IconsFontAwesome5Pro.h │ │ │ └── LICENSE.txt │ │ ├── ImGui │ │ │ ├── ImGuiBuild.cpp │ │ │ ├── ImGuiLayer.cpp │ │ │ ├── ImGuiLayer.h │ │ │ └── Utilities │ │ │ │ ├── ImGuiAssetBrowser.cpp │ │ │ │ ├── ImGuiAssetBrowser.h │ │ │ │ ├── ImGuiConsole.cpp │ │ │ │ └── ImGuiConsole.h │ │ ├── Math │ │ │ ├── Math.cpp │ │ │ └── Math.h │ │ ├── Renderer │ │ │ ├── Buffer.cpp │ │ │ ├── Buffer.h │ │ │ ├── EditorCamera.cpp │ │ │ ├── EditorCamera.h │ │ │ ├── Framebuffer.cpp │ │ │ ├── Framebuffer.h │ │ │ ├── GraphicsContext.cpp │ │ │ ├── GraphicsContext.h │ │ │ ├── RenderCommand.cpp │ │ │ ├── RenderCommand.h │ │ │ ├── Renderer.cpp │ │ │ ├── Renderer.h │ │ │ ├── Renderer2D.cpp │ │ │ ├── Renderer2D.h │ │ │ ├── RendererAPI.cpp │ │ │ ├── RendererAPI.h │ │ │ ├── Shader.cpp │ │ │ ├── Shader.h │ │ │ ├── SubTexture2D.cpp │ │ │ ├── SubTexture2D.h │ │ │ ├── Texture.cpp │ │ │ ├── Texture.h │ │ │ ├── UniformBuffer.cpp │ │ │ ├── UniformBuffer.h │ │ │ ├── VertexArray.cpp │ │ │ └── VertexArray.h │ │ ├── Scene │ │ │ ├── Components.h │ │ │ ├── Entity.cpp │ │ │ ├── Entity.h │ │ │ ├── Scene.cpp │ │ │ ├── Scene.h │ │ │ ├── SceneCamera.cpp │ │ │ ├── SceneCamera.h │ │ │ ├── SceneSerializer.cpp │ │ │ ├── SceneSerializer.h │ │ │ └── ScriptableEntity.h │ │ └── Utils │ │ │ └── PlatformUtils.h │ ├── Platform │ │ ├── OpenGL │ │ │ ├── OpenGLBuffer.cpp │ │ │ ├── OpenGLBuffer.h │ │ │ ├── OpenGLContext.cpp │ │ │ ├── OpenGLContext.h │ │ │ ├── OpenGLFramebuffer.cpp │ │ │ ├── OpenGLFramebuffer.h │ │ │ ├── OpenGLRendererAPI.cpp │ │ │ ├── OpenGLRendererAPI.h │ │ │ ├── OpenGLShader.cpp │ │ │ ├── OpenGLShader.h │ │ │ ├── OpenGLTexture.cpp │ │ │ ├── OpenGLTexture.h │ │ │ ├── OpenGLUniformBuffer.cpp │ │ │ ├── OpenGLUniformBuffer.h │ │ │ ├── OpenGLVertexArray.cpp │ │ │ └── OpenGLVertexArray.h │ │ └── Windows │ │ │ ├── WindowsInput.cpp │ │ │ ├── WindowsPlatformUtils.cpp │ │ │ ├── WindowsWindow.cpp │ │ │ └── WindowsWindow.h │ ├── gtpch.cpp │ └── gtpch.h └── vendor │ ├── Glad │ ├── Glad.vcxproj │ ├── Glad.vcxproj.filters │ ├── include │ │ ├── KHR │ │ │ └── khrplatform.h │ │ └── glad │ │ │ └── glad.h │ ├── premake5.lua │ └── src │ │ └── glad.c │ ├── entt │ ├── LICENSE.txt │ └── include │ │ └── entt.hpp │ └── stb_image │ ├── stb_image.cpp │ └── stb_image.h ├── Images ├── Screenshot_1.jpg ├── Screenshot_2.png └── Screenshot_3.png ├── LICENSE ├── README.md ├── Sandbox ├── assets │ ├── shaders │ │ ├── FlatColor.glsl │ │ └── Texture.glsl │ └── textures │ │ ├── crate2_diffuse.png │ │ └── test_texture.png ├── premake5.lua └── src │ ├── Sandbox2D.cpp │ ├── Sandbox2D.h │ └── SandboxApp.cpp ├── premake5.lua ├── scripts ├── Setup.bat ├── Setup.py ├── SetupPremake.py ├── SetupPython.py ├── SetupVulkan.py ├── Utils.py └── Win-GenProjects.bat └── vendor └── premake ├── bin ├── LICENSE.txt └── premake5.exe ├── premake5.lua └── premake_customization └── solution_items.lua /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | indent_style = tab -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build & Intermediate Directories 2 | bin/ 3 | !vendor/premake/bin/ 4 | bin-int/ 5 | 6 | # Files 7 | *.user 8 | *.json 9 | *.log 10 | 11 | # Visual Studio files and folder 12 | .vs/ 13 | **.sln 14 | **.vcxproj 15 | **.vcxproj.filters 16 | **.vcxproj.user 17 | 18 | # Directories 19 | Ghost/vendor/VulkanSDK 20 | Ghost-Editor/assets/cache 21 | scripts/__pycache__ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Ghost/vendor/spdlog"] 2 | path = Ghost/vendor/spdlog 3 | url = ../../gabime/spdlog 4 | branch = v1.x 5 | [submodule "Ghost/vendor/GLFW"] 6 | path = Ghost/vendor/GLFW 7 | url = ../../TheCherno/glfw 8 | branch = master 9 | [submodule "Ghost/vendor/imgui"] 10 | path = Ghost/vendor/imgui 11 | url = ../../TheCherno/imgui 12 | branch = docking 13 | [submodule "Ghost/vendor/glm"] 14 | path = Ghost/vendor/glm 15 | url = ../../g-truc/glm 16 | branch = master 17 | [submodule "Ghost/vendor/yaml-cpp"] 18 | path = Ghost/vendor/yaml-cpp 19 | url = https://github.com/thecherno/yaml-cpp 20 | branch = master 21 | [submodule "Ghost/vendor/ImGuizmo"] 22 | path = Ghost/vendor/ImGuizmo 23 | url = https://github.com/thecherno/imguizmo 24 | [submodule "Ghost/vendor/Box2D"] 25 | path = Ghost/vendor/Box2D 26 | url = https://github.com/thecherno/box2d 27 | -------------------------------------------------------------------------------- /Dependencies.lua: -------------------------------------------------------------------------------- 1 | 2 | -- Ghost Dependencies 3 | 4 | VULKAN_SDK = os.getenv("VULKAN_SDK") 5 | 6 | IncludeDir = {} 7 | IncludeDir["stb_image"] = "%{wks.location}/Ghost/vendor/stb_image" 8 | IncludeDir["yaml_cpp"] = "%{wks.location}/Ghost/vendor/yaml-cpp/include" 9 | IncludeDir["Box2D"] = "%{wks.location}/Ghost/vendor/Box2D/include" 10 | IncludeDir["GLFW"] = "%{wks.location}/Ghost/vendor/GLFW/include" 11 | IncludeDir["Glad"] = "%{wks.location}/Ghost/vendor/Glad/include" 12 | IncludeDir["ImGui"] = "%{wks.location}/Ghost/vendor/ImGui" 13 | IncludeDir["ImGuizmo"] = "%{wks.location}/Ghost/vendor/ImGuizmo" 14 | IncludeDir["glm"] = "%{wks.location}/Ghost/vendor/glm" 15 | IncludeDir["entt"] = "%{wks.location}/Ghost/vendor/entt/include" 16 | IncludeDir["shaderc"] = "%{wks.location}/Ghost/vendor/shaderc/include" 17 | IncludeDir["SPIRV_Cross"] = "%{wks.location}/Ghost/vendor/SPIRV_Cross" 18 | IncludeDir["VulkanSDK"] = "%{VULKAN_SDK}/Include" 19 | 20 | LibraryDir = {} 21 | 22 | LibraryDir["VulkanSDK"] = "%{VULKAN_SDK}/Lib" 23 | LibraryDir["VulkanSDK_Debug"] = "%{wks.location}/Ghost/vendor/VulkanSDK/Lib" 24 | LibraryDir["VulkanSDK_DebugDLL"] = "%{wks.location}/Ghost/vendor/VulkanSDK/Bin" 25 | 26 | Library = {} 27 | Library["Vulkan"] = "%{LibraryDir.VulkanSDK}/vulkan-1.lib" 28 | Library["VulkanUtils"] = "%{LibraryDir.VulkanSDK}/VkLayer_utils.lib" 29 | 30 | Library["ShaderC_Debug"] = "%{LibraryDir.VulkanSDK_Debug}/shaderc_sharedd.lib" 31 | Library["SPIRV_Cross_Debug"] = "%{LibraryDir.VulkanSDK_Debug}/spirv-cross-cored.lib" 32 | Library["SPIRV_Cross_GLSL_Debug"] = "%{LibraryDir.VulkanSDK_Debug}/spirv-cross-glsld.lib" 33 | Library["SPIRV_Tools_Debug"] = "%{LibraryDir.VulkanSDK_Debug}/SPIRV-Toolsd.lib" 34 | 35 | Library["ShaderC_Release"] = "%{LibraryDir.VulkanSDK}/shaderc_shared.lib" 36 | Library["SPIRV_Cross_Release"] = "%{LibraryDir.VulkanSDK}/spirv-cross-core.lib" 37 | Library["SPIRV_Cross_GLSL_Release"] = "%{LibraryDir.VulkanSDK}/spirv-cross-glsl.lib" -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/ContentBrowser/DocumentIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/ContentBrowser/DocumentIcon.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/ContentBrowser/FileIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/ContentBrowser/FileIcon.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/ContentBrowser/FolderIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/ContentBrowser/FolderIcon.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/ContentBrowser/OpenedFolderIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/ContentBrowser/OpenedFolderIcon.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/ContentBrowser/PictureIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/ContentBrowser/PictureIcon.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/PlayButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/PlayButton.png -------------------------------------------------------------------------------- /Ghost-Editor/Resources/Icons/StopButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/Resources/Icons/StopButton.png -------------------------------------------------------------------------------- /Ghost-Editor/assets/Test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/Test.txt -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/fontawesome/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/fontawesome/fa-brands-400.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/fontawesome/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/fontawesome/fa-regular-400.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/fontawesome/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/fontawesome/fa-solid-900.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-Bold.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-BoldItalic.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-ExtraBold.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-ExtraBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-ExtraBoldItalic.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-Italic.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-Light.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-LightItalic.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-Regular.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-SemiBold.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/fonts/opensans/OpenSans-SemiBoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/fonts/opensans/OpenSans-SemiBoldItalic.ttf -------------------------------------------------------------------------------- /Ghost-Editor/assets/scenes/Example.ghost: -------------------------------------------------------------------------------- 1 | Scene: Untitled 2 | Entities: 3 | - Entity: 14627957806427910339 4 | TagComponent: 5 | Tag: Camera 6 | TransformComponent: 7 | Translation: [0, 0, 0] 8 | Rotation: [0, 0, 0] 9 | Scale: [1, 1, 1] 10 | CameraComponent: 11 | Camera: 12 | ProjectionType: 1 13 | PerspectiveFOV: 0.785398185 14 | PerspectiveNear: 0.00999999978 15 | PerspectiveFar: 1000 16 | OrthographicSize: 10 17 | OrthographicNear: -1 18 | OrthographicFar: 1 19 | Primary: true 20 | FixedAspectRatio: false 21 | - Entity: 9537582244361184116 22 | TagComponent: 23 | Tag: Cyan Quad 24 | TransformComponent: 25 | Translation: [0, 4, 0] 26 | Rotation: [0, 0, 0] 27 | Scale: [6.5, 1, 1] 28 | SpriteRendererComponent: 29 | Color: [0, 1, 0.918918848, 1] 30 | - Entity: 13374992427181315897 31 | TagComponent: 32 | Tag: Pink Quad 33 | TransformComponent: 34 | Translation: [2.70000005, -2.20000005, 0] 35 | Rotation: [0, 0, 0.167551607] 36 | Scale: [1.20000005, 2.5, 1] 37 | SpriteRendererComponent: 38 | Color: [1, 0.536679506, 0.92307806, 1] 39 | - Entity: 4964002980123589930 40 | TagComponent: 41 | Tag: Orange Quad 42 | TransformComponent: 43 | Translation: [2.79999995, 1.89999998, 0] 44 | Rotation: [0, 0, 0.247836754] 45 | Scale: [3.20000005, 1.39999998, 1] 46 | SpriteRendererComponent: 47 | Color: [1, 0.416666746, 0, 1] 48 | - Entity: 18058190166889354238 49 | TagComponent: 50 | Tag: Yellow Quad 51 | TransformComponent: 52 | Translation: [-4.4000001, 1.79999995, 0] 53 | Rotation: [0, 0, -0.488692194] 54 | Scale: [3.70000005, -3.70000005, 1] 55 | SpriteRendererComponent: 56 | Color: [0.886904597, 1, 0, 1] 57 | - Entity: 10716768924180344089 58 | TagComponent: 59 | Tag: Blue Quad 60 | TransformComponent: 61 | Translation: [0.200000003, 0, 0] 62 | Rotation: [0, 0, 0] 63 | Scale: [6.19999981, 1, 1] 64 | SpriteRendererComponent: 65 | Color: [0, 0.227450982, 1, 0.890196085] 66 | - Entity: 12261979833698486678 67 | TagComponent: 68 | Tag: Green Quad 69 | TransformComponent: 70 | Translation: [0, 0, 0] 71 | Rotation: [0, 0, 0] 72 | Scale: [1, 6, 1] 73 | SpriteRendererComponent: 74 | Color: [0.262548327, 1, 0, 1] 75 | - Entity: 3619380383081114478 76 | TagComponent: 77 | Tag: Red Quad 78 | TransformComponent: 79 | Translation: [-2.79999995, -2.20000005, 0] 80 | Rotation: [0, 0, -0.942477763] 81 | Scale: [3, 1.79999995, 1] 82 | SpriteRendererComponent: 83 | Color: [1, 0, 0, 1] -------------------------------------------------------------------------------- /Ghost-Editor/assets/scenes/Orthographic2D.ghost: -------------------------------------------------------------------------------- 1 | Scene: Untitled 2 | Entities: 3 | - Entity: 10154920668616492112 4 | TagComponent: 5 | Tag: Camera2D 6 | TransformComponent: 7 | Translation: [0, 0, -3] 8 | Rotation: [0, 0, 0] 9 | Scale: [1, 1, 1] 10 | CameraComponent: 11 | Camera: 12 | ProjectionType: 1 13 | PerspectiveFOV: 0.785398185 14 | PerspectiveNear: 0.00999999978 15 | PerspectiveFar: 1000 16 | OrthographicSize: 10 17 | OrthographicNear: -10 18 | OrthographicFar: 10 19 | Primary: true 20 | FixedAspectRatio: false 21 | - Entity: 1951142398601657544 22 | TagComponent: 23 | Tag: Camera 24 | TransformComponent: 25 | Translation: [0, 0, 0] 26 | Rotation: [0, 0, 0] 27 | Scale: [1, 1, 1] 28 | CameraComponent: 29 | Camera: 30 | ProjectionType: 0 31 | PerspectiveFOV: 0.785398185 32 | PerspectiveNear: 0.00999999978 33 | PerspectiveFar: 1000 34 | OrthographicSize: 10 35 | OrthographicNear: -1 36 | OrthographicFar: 1 37 | Primary: false 38 | FixedAspectRatio: false 39 | - Entity: 2309116521414204325 40 | TagComponent: 41 | Tag: YellowQuad 42 | TransformComponent: 43 | Translation: [-1.20000005, 0.5, -3] 44 | Rotation: [0, 0, 0] 45 | Scale: [1, 1, 1] 46 | SpriteRendererComponent: 47 | Color: [0.915057898, 0.849696338, 0, 1] 48 | - Entity: 16528523827001358715 49 | TagComponent: 50 | Tag: GreenQuad 51 | TransformComponent: 52 | Translation: [1.89999998, -1.79999995, -9] 53 | Rotation: [0, 0, 0] 54 | Scale: [1, 1, 1] 55 | SpriteRendererComponent: 56 | Color: [0, 0.876447856, 0.0156507958, 1] -------------------------------------------------------------------------------- /Ghost-Editor/assets/scenes/Perspective2D.ghost: -------------------------------------------------------------------------------- 1 | Scene: Untitled 2 | Entities: 3 | - Entity: 11784898618086241638 4 | TagComponent: 5 | Tag: Green Quad 6 | TransformComponent: 7 | Translation: [-2.07492924, 0, 0.116804004] 8 | Rotation: [0, 0.785398245, 0] 9 | Scale: [3.29999852, 2.79999995, 0.999997616] 10 | SpriteRendererComponent: 11 | Color: [0.101190448, 1, 0, 1] 12 | - Entity: 2211445608767053977 13 | TagComponent: 14 | Tag: Yellow Quad 15 | TransformComponent: 16 | Translation: [2.98023224e-08, 0, -1.32412243] 17 | Rotation: [0, 0, 0] 18 | Scale: [3.45956874, 3.38098192, 1] 19 | SpriteRendererComponent: 20 | Color: [0.863095284, 1, 0, 1] 21 | - Entity: 5144737978958103156 22 | TagComponent: 23 | Tag: Camera 24 | TransformComponent: 25 | Translation: [0, 0, 0] 26 | Rotation: [0, 0, 0] 27 | Scale: [1, 1, 1] 28 | CameraComponent: 29 | Camera: 30 | ProjectionType: 1 31 | PerspectiveFOV: 0.785398185 32 | PerspectiveNear: 0.00999999978 33 | PerspectiveFar: 1000 34 | OrthographicSize: 10 35 | OrthographicNear: -1 36 | OrthographicFar: 1 37 | Primary: true 38 | FixedAspectRatio: false 39 | - Entity: 6216900583927307589 40 | TagComponent: 41 | Tag: Red Quad 42 | TransformComponent: 43 | Translation: [1.99829257, 0, 0.515303612] 44 | Rotation: [0, -0.929071188, 0] 45 | Scale: [2.84675574, 2.45156598, 0.999999881] 46 | SpriteRendererComponent: 47 | Color: [1, 0, 0, 1] 48 | - Entity: 6061070473605388916 49 | TagComponent: 50 | Tag: Blue Quad 51 | TransformComponent: 52 | Translation: [3.21161842, 0, 0.844948649] 53 | Rotation: [0, -0.25463888, 0] 54 | Scale: [3.27451348, 4.1515584, 0.999999046] 55 | SpriteRendererComponent: 56 | Color: [0, 0.154440165, 1, 1] -------------------------------------------------------------------------------- /Ghost-Editor/assets/shaders/FlatColor.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | 6 | uniform mat4 u_ViewProjection; 7 | uniform mat4 u_Transform; 8 | 9 | void main() 10 | { 11 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); 12 | } 13 | 14 | #type fragment 15 | #version 330 core 16 | 17 | layout(location = 0) out vec4 color; 18 | 19 | uniform vec4 u_Color; 20 | 21 | void main() 22 | { 23 | color = u_Color; 24 | } -------------------------------------------------------------------------------- /Ghost-Editor/assets/shaders/Texture.glsl: -------------------------------------------------------------------------------- 1 | // Basic Texture Shader 2 | 3 | #type vertex 4 | #version 450 core 5 | 6 | layout(location = 0) in vec3 a_Position; 7 | layout(location = 1) in vec4 a_Color; 8 | layout(location = 2) in vec2 a_TexCoord; 9 | layout(location = 3) in float a_TexIndex; 10 | layout(location = 4) in float a_TilingFactor; 11 | layout(location = 5) in int a_EntityID; 12 | 13 | layout(std140, binding = 0) uniform Camera 14 | { 15 | mat4 u_ViewProjection; 16 | }; 17 | 18 | struct VertexOutput 19 | { 20 | vec4 Color; 21 | vec2 TexCoord; 22 | float TilingFactor; 23 | }; 24 | 25 | layout (location = 0) out VertexOutput Output; 26 | layout (location = 3) out flat float v_TexIndex; 27 | layout (location = 4) out flat int v_EntityID; 28 | 29 | void main() 30 | { 31 | Output.Color = a_Color; 32 | Output.TexCoord = a_TexCoord; 33 | Output.TilingFactor = a_TilingFactor; 34 | v_TexIndex = a_TexIndex; 35 | v_EntityID = a_EntityID; 36 | 37 | gl_Position = u_ViewProjection * vec4(a_Position, 1.0); 38 | } 39 | 40 | #type fragment 41 | #version 450 core 42 | 43 | layout(location = 0) out vec4 color; 44 | layout(location = 1) out int color2; 45 | 46 | struct VertexOutput 47 | { 48 | vec4 Color; 49 | vec2 TexCoord; 50 | float TilingFactor; 51 | }; 52 | 53 | layout (location = 0) in VertexOutput Input; 54 | layout (location = 3) in flat float v_TexIndex; 55 | layout (location = 4) in flat int v_EntityID; 56 | 57 | layout (binding = 0) uniform sampler2D u_Textures[32]; 58 | 59 | void main() 60 | { 61 | vec4 texColor = Input.Color; 62 | 63 | switch(int(v_TexIndex)) 64 | { 65 | case 0: texColor *= texture(u_Textures[ 0], Input.TexCoord * Input.TilingFactor); break; 66 | case 1: texColor *= texture(u_Textures[ 1], Input.TexCoord * Input.TilingFactor); break; 67 | case 2: texColor *= texture(u_Textures[ 2], Input.TexCoord * Input.TilingFactor); break; 68 | case 3: texColor *= texture(u_Textures[ 3], Input.TexCoord * Input.TilingFactor); break; 69 | case 4: texColor *= texture(u_Textures[ 4], Input.TexCoord * Input.TilingFactor); break; 70 | case 5: texColor *= texture(u_Textures[ 5], Input.TexCoord * Input.TilingFactor); break; 71 | case 6: texColor *= texture(u_Textures[ 6], Input.TexCoord * Input.TilingFactor); break; 72 | case 7: texColor *= texture(u_Textures[ 7], Input.TexCoord * Input.TilingFactor); break; 73 | case 8: texColor *= texture(u_Textures[ 8], Input.TexCoord * Input.TilingFactor); break; 74 | case 9: texColor *= texture(u_Textures[ 9], Input.TexCoord * Input.TilingFactor); break; 75 | case 10: texColor *= texture(u_Textures[10], Input.TexCoord * Input.TilingFactor); break; 76 | case 11: texColor *= texture(u_Textures[11], Input.TexCoord * Input.TilingFactor); break; 77 | case 12: texColor *= texture(u_Textures[12], Input.TexCoord * Input.TilingFactor); break; 78 | case 13: texColor *= texture(u_Textures[13], Input.TexCoord * Input.TilingFactor); break; 79 | case 14: texColor *= texture(u_Textures[14], Input.TexCoord * Input.TilingFactor); break; 80 | case 15: texColor *= texture(u_Textures[15], Input.TexCoord * Input.TilingFactor); break; 81 | case 16: texColor *= texture(u_Textures[16], Input.TexCoord * Input.TilingFactor); break; 82 | case 17: texColor *= texture(u_Textures[17], Input.TexCoord * Input.TilingFactor); break; 83 | case 18: texColor *= texture(u_Textures[18], Input.TexCoord * Input.TilingFactor); break; 84 | case 19: texColor *= texture(u_Textures[19], Input.TexCoord * Input.TilingFactor); break; 85 | case 20: texColor *= texture(u_Textures[20], Input.TexCoord * Input.TilingFactor); break; 86 | case 21: texColor *= texture(u_Textures[21], Input.TexCoord * Input.TilingFactor); break; 87 | case 22: texColor *= texture(u_Textures[22], Input.TexCoord * Input.TilingFactor); break; 88 | case 23: texColor *= texture(u_Textures[23], Input.TexCoord * Input.TilingFactor); break; 89 | case 24: texColor *= texture(u_Textures[24], Input.TexCoord * Input.TilingFactor); break; 90 | case 25: texColor *= texture(u_Textures[25], Input.TexCoord * Input.TilingFactor); break; 91 | case 26: texColor *= texture(u_Textures[26], Input.TexCoord * Input.TilingFactor); break; 92 | case 27: texColor *= texture(u_Textures[27], Input.TexCoord * Input.TilingFactor); break; 93 | case 28: texColor *= texture(u_Textures[28], Input.TexCoord * Input.TilingFactor); break; 94 | case 29: texColor *= texture(u_Textures[29], Input.TexCoord * Input.TilingFactor); break; 95 | case 30: texColor *= texture(u_Textures[30], Input.TexCoord * Input.TilingFactor); break; 96 | case 31: texColor *= texture(u_Textures[31], Input.TexCoord * Input.TilingFactor); break; 97 | } 98 | color = texColor; 99 | 100 | color2 = v_EntityID; 101 | } 102 | -------------------------------------------------------------------------------- /Ghost-Editor/assets/textures/crate2_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/textures/crate2_diffuse.png -------------------------------------------------------------------------------- /Ghost-Editor/assets/textures/test_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Ghost-Editor/assets/textures/test_texture.png -------------------------------------------------------------------------------- /Ghost-Editor/imgui.ini: -------------------------------------------------------------------------------- 1 | [Window][DockSpace] 2 | Pos=0,0 3 | Size=1920,1017 4 | Collapsed=0 5 | 6 | [Window][Debug##Default] 7 | Pos=60,60 8 | Size=400,400 9 | Collapsed=0 10 | 11 | [Window][Viewport] 12 | Pos=372,63 13 | Size=1176,650 14 | Collapsed=0 15 | DockId=0x00000011,0 16 | 17 | [Window][Renderer2D Statistics] 18 | Pos=1550,853 19 | Size=370,164 20 | Collapsed=0 21 | DockId=0x00000004,1 22 | 23 | [Window][Console] 24 | Pos=0,715 25 | Size=370,302 26 | Collapsed=0 27 | DockId=0x00000006,0 28 | 29 | [Window][Properties] 30 | Pos=1550,24 31 | Size=370,827 32 | Collapsed=0 33 | DockId=0x0000000D,0 34 | 35 | [Window][Renderer Info] 36 | Pos=1550,853 37 | Size=370,164 38 | Collapsed=0 39 | DockId=0x00000004,0 40 | 41 | [Window][Dear ImGui Demo] 42 | ViewportPos=229,503 43 | ViewportId=0xE927CF2F 44 | Size=1291,593 45 | Collapsed=0 46 | 47 | [Window][Style Editor] 48 | Pos=86,86 49 | Size=339,856 50 | Collapsed=0 51 | 52 | [Window][Example: Console] 53 | Pos=60,60 54 | Size=520,600 55 | Collapsed=0 56 | 57 | [Window][Menu] 58 | Pos=0,614 59 | Size=1291,50 60 | Collapsed=0 61 | DockId=0x00000008,0 62 | 63 | [Window][Scene Hierarchy] 64 | Pos=0,24 65 | Size=370,689 66 | Collapsed=0 67 | DockId=0x0000000B,0 68 | 69 | [Window][Dear ImGui Metrics] 70 | Pos=60,60 71 | Size=338,239 72 | Collapsed=0 73 | 74 | [Window][Example: Simple layout] 75 | Pos=105,53 76 | Size=500,440 77 | Collapsed=0 78 | 79 | [Window][Example: Property editor] 80 | Pos=60,60 81 | Size=430,450 82 | Collapsed=0 83 | 84 | [Window][Example: Documents] 85 | ViewportPos=365,285 86 | ViewportId=0x1FD64BEB 87 | Size=607,944 88 | Collapsed=0 89 | 90 | [Window][Example: Custom rendering] 91 | Pos=148,142 92 | Size=466,391 93 | Collapsed=0 94 | 95 | [Window][Lettuce] 96 | ViewportPos=365,285 97 | ViewportId=0x1FD64BEB 98 | Pos=8,96 99 | Size=591,840 100 | Collapsed=0 101 | DockId=0xA086D808,0 102 | 103 | [Window][Eggplant] 104 | ViewportPos=365,285 105 | ViewportId=0x1FD64BEB 106 | Pos=8,96 107 | Size=591,840 108 | Collapsed=0 109 | DockId=0xA086D808,1 110 | 111 | [Window][Carrot] 112 | ViewportPos=365,285 113 | ViewportId=0x1FD64BEB 114 | Pos=8,96 115 | Size=591,840 116 | Collapsed=0 117 | DockId=0xA086D808,2 118 | 119 | [Window][Tomato] 120 | ViewportPos=365,285 121 | ViewportId=0x1FD64BEB 122 | Pos=8,96 123 | Size=591,840 124 | Collapsed=0 125 | DockId=0xA086D808,3 126 | 127 | [Window][A Rather Long Title] 128 | ViewportPos=365,285 129 | ViewportId=0x1FD64BEB 130 | Pos=8,96 131 | Size=591,840 132 | Collapsed=0 133 | DockId=0xA086D808,4 134 | 135 | [Window][Some Document] 136 | ViewportPos=365,285 137 | ViewportId=0x1FD64BEB 138 | Pos=8,96 139 | Size=591,840 140 | Collapsed=0 141 | DockId=0xA086D808,5 142 | 143 | [Window][Project] 144 | Pos=372,698 145 | Size=1176,363 146 | Collapsed=0 147 | DockId=0x0000000C,0 148 | 149 | [Window][Content Browser] 150 | Pos=372,715 151 | Size=1176,302 152 | Collapsed=0 153 | DockId=0x0000000A,0 154 | 155 | [Window][##toolbar] 156 | Pos=372,24 157 | Size=1176,37 158 | Collapsed=0 159 | DockId=0x00000010,0 160 | 161 | [Docking][Data] 162 | DockSpace ID=0x09EF459F Window=0x9A404470 Pos=0,47 Size=1920,993 Split=X Selected=0x995B0CF8 163 | DockNode ID=0x00000001 Parent=0x09EF459F SizeRef=1548,993 Split=Y 164 | DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1920,720 Split=Y 165 | DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1281,593 Split=Y Selected=0x995B0CF8 166 | DockNode ID=0x00000009 Parent=0x00000002 SizeRef=1394,44 Split=X Selected=0x995B0CF8 167 | DockNode ID=0x0000000B Parent=0x00000009 SizeRef=370,692 Selected=0x9A68760C 168 | DockNode ID=0x0000000F Parent=0x00000009 SizeRef=1176,692 Split=Y Selected=0x995B0CF8 169 | DockNode ID=0x00000010 Parent=0x0000000F SizeRef=1176,37 HiddenTabBar=1 Selected=0x28257B55 170 | DockNode ID=0x00000011 Parent=0x0000000F SizeRef=1176,681 CentralNode=1 HiddenTabBar=1 Selected=0x995B0CF8 171 | DockNode ID=0x0000000C Parent=0x00000002 SizeRef=1394,991 Selected=0xF9BEF62A 172 | DockNode ID=0x00000008 Parent=0x00000003 SizeRef=1281,286 HiddenTabBar=1 Selected=0xF9BEF62A 173 | DockNode ID=0x00000007 Parent=0x00000001 SizeRef=1920,315 Split=X Selected=0xF9BEF62A 174 | DockNode ID=0x00000006 Parent=0x00000007 SizeRef=370,315 Selected=0xF9BEF62A 175 | DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1176,315 Selected=0x371352B7 176 | DockNode ID=0x00000005 Parent=0x09EF459F SizeRef=370,993 Split=Y Selected=0xC89E3217 177 | DockNode ID=0x0000000D Parent=0x00000005 SizeRef=370,799 Selected=0xC89E3217 178 | DockNode ID=0x00000004 Parent=0x00000005 SizeRef=370,158 Selected=0x343432D5 179 | DockSpace ID=0xA086D808 Pos=373,381 Size=591,840 CentralNode=1 Selected=0x8BB04FA5 180 | 181 | -------------------------------------------------------------------------------- /Ghost-Editor/premake5.lua: -------------------------------------------------------------------------------- 1 | project "Ghost-Editor" 2 | kind "ConsoleApp" 3 | language "C++" 4 | cppdialect "C++17" 5 | staticruntime "off" 6 | 7 | targetdir ("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") 8 | objdir ("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") 9 | 10 | files 11 | { 12 | "src/**.h", 13 | "src/**.cpp", 14 | } 15 | 16 | defines 17 | { 18 | "_CRT_SECURE_NO_WARNINGS", 19 | "GLFW_INCLUDE_NONE" 20 | } 21 | 22 | includedirs 23 | { 24 | "%{wks.location}/Ghost/vendor/spdlog/include", 25 | "%{wks.location}/Ghost/src", 26 | "%{wks.location}/Ghost/vendor", 27 | "%{IncludeDir.glm}", 28 | "%{IncludeDir.entt}", 29 | "%{IncludeDir.ImGuizmo}" 30 | } 31 | 32 | links 33 | { 34 | "Ghost" 35 | } 36 | 37 | filter "system:windows" 38 | systemversion "latest" 39 | 40 | filter "configurations:Debug" 41 | defines "GT_DEBUG" 42 | runtime "Debug" 43 | symbols "on" 44 | 45 | postbuildcommands 46 | { 47 | "{COPY} %{LibraryDir.VulkanSDK_DebugDLL} %{cfg.targetdir}" 48 | } 49 | 50 | filter "configurations:Release" 51 | defines "GT_RELEASE" 52 | runtime "Release" 53 | optimize "on" 54 | 55 | filter "configurations:Dist" 56 | defines "GT_DIST" 57 | runtime "Release" 58 | optimize "on" 59 | -------------------------------------------------------------------------------- /Ghost-Editor/src/EditorLayer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost.h" 4 | #include "Panels/SceneHierarchyPanel.h" 5 | #include "Panels/ContentBrowserPanel.h" 6 | 7 | #include "Ghost/Renderer/EditorCamera.h" 8 | 9 | namespace Ghost 10 | { 11 | class EditorLayer : public Layer { 12 | public: 13 | EditorLayer(); 14 | virtual ~EditorLayer() = default; 15 | 16 | virtual void OnAttach() override; 17 | virtual void OnDetach() override; 18 | 19 | void OnUpdate(Timestep ts) override; 20 | virtual void OnImGuiRender() override; 21 | void OnEvent(Event& e) override; 22 | private: 23 | bool OnKeyPressed(KeyPressedEvent& e); 24 | bool OnMouseButtonPressed(MouseButtonPressedEvent& e); 25 | 26 | void NewScene(); 27 | void OpenScene(); 28 | void OpenScene(const std::filesystem::path& path); 29 | void SaveScene(); 30 | void SaveSceneAs(); 31 | void SerializeScene(Ref scene, const std::filesystem::path& path); 32 | 33 | void OnScenePlay(); 34 | void OnSceneStop(); 35 | 36 | void OnDuplicateEntity(); 37 | 38 | // UI Panels 39 | void UI_Toolbar(); 40 | private: 41 | OrthographicCameraController m_CameraController; 42 | 43 | // Temp 44 | Ref m_SquareVA; 45 | Ref m_FlatColorShader; 46 | Ref m_Framebuffer; 47 | 48 | Ref m_ActiveScene; 49 | Ref m_EditorScene, m_RuntimeScene; 50 | 51 | Entity m_SquareEntity; 52 | Entity m_CameraEntity; 53 | 54 | Entity m_HoveredEntity; 55 | 56 | EditorCamera m_EditorCamera; 57 | 58 | std::filesystem::path m_EditorScenePath; 59 | 60 | bool m_ViewportFocused = false, m_ViewportHovered = false; 61 | glm::vec2 m_ViewportSize = { 0.0f, 0.0f }; 62 | glm::vec2 m_ViewportBounds[2]; 63 | 64 | int m_GizmoType = -1; 65 | 66 | enum class SceneState { 67 | Edit = 0, Play = 1 68 | }; 69 | 70 | // Panels 71 | SceneHierarchyPanel m_SceneHierarchyPanel; 72 | ContentBrowserPanel m_ContentBrowserPanel; 73 | 74 | // Editor resources 75 | Ref m_IconPlay, m_IconStop; 76 | 77 | SceneState m_SceneState = SceneState::Edit; 78 | }; 79 | } 80 | -------------------------------------------------------------------------------- /Ghost-Editor/src/GhostEditorApp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "EditorLayer.h" 5 | 6 | namespace Ghost 7 | { 8 | class GhostEditor : public Application { 9 | public: 10 | GhostEditor(ApplicationCommandLineArgs args) 11 | :Application("Ghost Engine", args) { 12 | PushLayer(new EditorLayer()); 13 | } 14 | 15 | ~GhostEditor() {} 16 | }; 17 | 18 | Application* CreateApplication(ApplicationCommandLineArgs args) { 19 | return new GhostEditor(args); // reference using external in EntryPoint.h 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Ghost-Editor/src/Panels/ContentBrowserPanel.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "ContentBrowserPanel.h" 3 | 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | // Once we have projects, change this 9 | extern const std::filesystem::path g_Assetpath = "assets"; 10 | 11 | ContentBrowserPanel::ContentBrowserPanel() 12 | :m_CurrentDirectory(g_Assetpath) { 13 | m_DirectoryIcon = Texture2D::Create("Resources/Icons/ContentBrowser/FolderIcon.png"); 14 | m_FileIcon = Texture2D::Create("Resources/Icons/ContentBrowser/DocumentIcon.png"); 15 | } 16 | 17 | void ContentBrowserPanel::OnImGuiRender() { 18 | ImGui::Begin("Content Browser"); 19 | 20 | if (m_CurrentDirectory != std::filesystem::path(g_Assetpath)) 21 | { 22 | if (ImGui::Button("<-")) 23 | { 24 | m_CurrentDirectory = m_CurrentDirectory.parent_path(); 25 | } 26 | } 27 | 28 | static float padding = 16.0f; 29 | static float thumbnailSize = 75.0f; 30 | 31 | float cellSize = thumbnailSize + padding; 32 | 33 | float panelWidth = ImGui::GetContentRegionAvail().x; 34 | int columnCount = (int)(panelWidth / cellSize); 35 | 36 | columnCount = columnCount < 1 ? 1 : columnCount; 37 | 38 | ImGui::Columns(columnCount, 0, false); 39 | 40 | for (auto& directoryEntry : std::filesystem::directory_iterator(m_CurrentDirectory)) 41 | { 42 | const auto& path = directoryEntry.path(); 43 | auto relativePath = std::filesystem::relative(path, g_Assetpath); 44 | std::string filenameString = relativePath.filename().string(); 45 | 46 | ImGui::PushID(filenameString.c_str()); 47 | Ref icon = directoryEntry.is_directory() ? m_DirectoryIcon : m_FileIcon; 48 | 49 | ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)); 50 | ImGui::ImageButton((ImTextureID)icon->GetRendererID(), 51 | { thumbnailSize, thumbnailSize }, { 0 , 1 }, { 1, 0 }); 52 | 53 | if (ImGui::BeginDragDropSource()) 54 | { 55 | const wchar_t* itemPath = relativePath.c_str(); 56 | ImGui::SetDragDropPayload("CONTENT_BROWSER_ITEM", itemPath, (wcslen(itemPath) + 1) * sizeof(wchar_t)); 57 | ImGui::EndDragDropSource(); 58 | } 59 | 60 | ImGui::PopStyleColor(); 61 | 62 | if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) 63 | { 64 | if (directoryEntry.is_directory()) 65 | { 66 | m_CurrentDirectory /= path.filename(); 67 | } 68 | } 69 | 70 | float textWidth = ImGui::CalcTextSize(filenameString.c_str()).x; 71 | if (textWidth > thumbnailSize) 72 | { 73 | ImGui::TextWrapped(filenameString.c_str()); 74 | } 75 | else 76 | { 77 | ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ((thumbnailSize - textWidth) / 2) + (padding / 4)); 78 | ImGui::Text(filenameString.c_str()); 79 | } 80 | 81 | ImGui::NextColumn(); 82 | 83 | ImGui::PopID(); 84 | } 85 | 86 | ImGui::Columns(1); 87 | 88 | /*ImGui::SliderFloat("Thumbnail Size", &thumbnailSize, 16, 512); 89 | ImGui::SliderFloat("Padding", &padding, 0, 32);*/ 90 | // TODO: status bar 91 | ImGui::End(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Ghost-Editor/src/Panels/ContentBrowserPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Ghost/Renderer/Texture.h" 6 | 7 | namespace Ghost 8 | { 9 | class ContentBrowserPanel { 10 | public: 11 | ContentBrowserPanel(); 12 | 13 | void OnImGuiRender(); 14 | private: 15 | std::filesystem::path m_CurrentDirectory; 16 | Ref m_DirectoryIcon; 17 | Ref m_FileIcon; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /Ghost-Editor/src/Panels/SceneHierarchyPanel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Log.h" 5 | #include "Ghost/Scene/Scene.h" 6 | #include "Ghost/Scene/Entity.h" 7 | 8 | namespace Ghost 9 | { 10 | class SceneHierarchyPanel { 11 | public: 12 | SceneHierarchyPanel() = default; 13 | SceneHierarchyPanel(const Ref& scene); 14 | 15 | void SetContext(const Ref& scene); 16 | 17 | void OnImGuiRender(); 18 | 19 | Entity GetSelectedEntity() const { return m_SelectionContext; } 20 | void SetSelectedEntity(Entity entity); 21 | private: 22 | template 23 | void DisplayAddComponentEntry(const std::string& entryName); 24 | 25 | void DrawEntityNode(Entity entity); 26 | void DrawComponents(Entity entity); 27 | private: 28 | Ref m_Context; 29 | Entity m_SelectionContext; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /Ghost/premake5.lua: -------------------------------------------------------------------------------- 1 | project "Ghost" 2 | kind "StaticLib" 3 | language "C++" 4 | cppdialect "C++17" 5 | staticruntime "off" 6 | 7 | targetdir ("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") 8 | objdir ("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") 9 | 10 | pchheader "gtpch.h" 11 | pchsource "src/gtpch.cpp" 12 | 13 | files 14 | { 15 | "src/**.h", 16 | "src/**.cpp", 17 | "vendor/stb_image/**.h", 18 | "vendor/stb_image/**.cpp", 19 | "vendor/glm/glm/**.hpp", 20 | "vendor/glm/glm/**.inl", 21 | 22 | "vendor/ImGuizmo/ImGuizmo.h", 23 | "vendor/ImGuizmo/ImGuizmo.cpp" 24 | } 25 | 26 | defines 27 | { 28 | "_CRT_SECURE_NO_WARNINGS", 29 | "GLFW_INCLUDE_NONE" 30 | } 31 | 32 | includedirs 33 | { 34 | "src", 35 | "vendor/spdlog/include", 36 | "%{IncludeDir.Box2D}", 37 | "%{IncludeDir.GLFW}", 38 | "%{IncludeDir.Glad}", 39 | "%{IncludeDir.ImGui}", 40 | "%{IncludeDir.glm}", 41 | "%{IncludeDir.stb_image}", 42 | "%{IncludeDir.entt}", 43 | "%{IncludeDir.yaml_cpp}", 44 | "%{IncludeDir.ImGuizmo}", 45 | "%{IncludeDir.VulkanSDK}" 46 | } 47 | 48 | links 49 | { 50 | "Box2D", 51 | "GLFW", 52 | "Glad", 53 | "ImGui", 54 | "yaml-cpp", 55 | "opengl32.lib" 56 | } 57 | 58 | filter "files:vendor/ImGuizmo/**.cpp" 59 | flags { "NoPCH" } 60 | 61 | filter "system:windows" 62 | systemversion "latest" 63 | 64 | defines 65 | { 66 | } 67 | 68 | filter "configurations:Debug" 69 | defines "GT_DEBUG" 70 | runtime "Debug" 71 | symbols "on" 72 | 73 | links 74 | { 75 | "%{Library.ShaderC_Debug}", 76 | "%{Library.SPIRV_Cross_Debug}", 77 | "%{Library.SPIRV_Cross_GLSL_Debug}" 78 | } 79 | 80 | filter "configurations:Release" 81 | defines "GT_RELEASE" 82 | runtime "Release" 83 | optimize "on" 84 | 85 | links 86 | { 87 | "%{Library.ShaderC_Release}", 88 | "%{Library.SPIRV_Cross_Release}", 89 | "%{Library.SPIRV_Cross_GLSL_Release}" 90 | } 91 | 92 | filter "configurations:Dist" 93 | defines "GT_DIST" 94 | runtime "Release" 95 | optimize "on" 96 | 97 | links 98 | { 99 | "%{Library.ShaderC_Release}", 100 | "%{Library.SPIRV_Cross_Release}", 101 | "%{Library.SPIRV_Cross_GLSL_Release}" 102 | } 103 | -------------------------------------------------------------------------------- /Ghost/src/Ghost.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // For use by Ghost applications 4 | 5 | #include "Ghost/Core/Base.h" 6 | 7 | #include "Ghost/Core/Application.h" 8 | #include "Ghost/Core/Layer.h" 9 | #include "Ghost/Core/Log.h" 10 | #include "Ghost/Core/Assert.h" 11 | 12 | #include "Ghost/Core/Timestep.h" 13 | 14 | #include "Ghost/Core/Input.h" 15 | #include "Ghost/Core/KeyCodes.h" 16 | #include "Ghost/Core/MouseCodes.h" 17 | #include "Ghost/Camera/Controllers/OrthographicCameraController.h" 18 | 19 | #include "Ghost/ImGui/ImGuiLayer.h" 20 | 21 | #include "Ghost/ImGui/Utilities/ImGuiConsole.h" 22 | #include "Ghost/ImGui/Utilities/ImGuiAssetBrowser.h" 23 | 24 | #include "Ghost/Scene/Scene.h" 25 | #include "Ghost/Scene/Entity.h" 26 | #include "Ghost/Scene/ScriptableEntity.h" 27 | #include "Ghost/Scene/Components.h" 28 | 29 | // --Renderer---------------------- 30 | #include "Ghost/Renderer/Renderer.h" 31 | #include "Ghost/Renderer/Renderer2D.h" 32 | #include "Ghost/Renderer/RenderCommand.h" 33 | 34 | #include "Ghost/Renderer/Buffer.h" 35 | #include "Ghost/Renderer/Shader.h" 36 | #include "Ghost/Renderer/Framebuffer.h" 37 | #include "Ghost/Renderer/Texture.h" 38 | #include "Ghost/Renderer/VertexArray.h" 39 | 40 | #include "Ghost/Camera/OrthographicCamera.h" 41 | // -------------------------------- 42 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Camera/Camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Ghost { 6 | class Camera { 7 | public: 8 | Camera() = default; 9 | Camera(const glm::mat4& projection) 10 | : m_Projection(projection) {} 11 | 12 | virtual ~Camera() = default; 13 | 14 | bool Primary = true; // TODO: Think about moving to Scene 15 | 16 | const glm::mat4& GetProjection() const { return m_Projection; } 17 | 18 | protected: 19 | glm::mat4 m_Projection = glm::mat4(1.0f); 20 | }; 21 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Camera/Controllers/OrthographicCameraController.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Camera/Controllers/OrthographicCameraController.h" 3 | 4 | #include "Ghost/Core/Input.h" 5 | #include "Ghost/Core/KeyCodes.h" 6 | 7 | namespace Ghost { 8 | OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool rotation) 9 | :m_AspectRatio(aspectRatio), 10 | m_Camera(-m_AspectRatio * m_ZoomLevel, m_AspectRatio* m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel), 11 | m_Rotation(rotation) 12 | { 13 | } 14 | 15 | void OrthographicCameraController::OnUpdate(Timestep ts) 16 | { 17 | GT_PROFILE_FUNCTION(); 18 | 19 | if (Input::IsKeyPressed(Key::A)) { 20 | m_CameraPosition.x -= cos(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 21 | m_CameraPosition.y -= sin(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 22 | } 23 | else if (Input::IsKeyPressed(Key::D)) { 24 | m_CameraPosition.x += cos(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 25 | m_CameraPosition.y += sin(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 26 | } 27 | 28 | if (Input::IsKeyPressed(Key::W)) { 29 | m_CameraPosition.x += sin(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 30 | m_CameraPosition.y += cos(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 31 | } 32 | else if (Input::IsKeyPressed(Key::S)) { 33 | m_CameraPosition.x -= sin(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 34 | m_CameraPosition.y -= cos(glm::radians(m_CameraRotation)) * m_CameraTranslationSpeed * ts; 35 | } 36 | 37 | if (m_Rotation) { 38 | if (Input::IsKeyPressed(Key::Q)) { 39 | m_CameraRotation += m_CameraRotationSpeed * ts; 40 | } 41 | else if (Input::IsKeyPressed(Key::E)) { 42 | m_CameraRotation -= m_CameraRotationSpeed * ts; 43 | } 44 | 45 | m_CameraRotation <= -180.0f ? m_CameraRotation += 360.0f : m_CameraRotation -= 360.0f; 46 | 47 | m_Camera.SetRotation(m_CameraRotation); 48 | } 49 | 50 | m_Camera.SetPosition(m_CameraPosition); 51 | 52 | m_CameraTranslationSpeed = m_ZoomLevel; 53 | } 54 | 55 | void OrthographicCameraController::OnEvent(Event& e) 56 | { 57 | GT_PROFILE_FUNCTION(); 58 | 59 | EventDispatcher dispatcher(e); 60 | dispatcher.Dispatch(GT_BIND_EVENT_FN(OrthographicCameraController::OnMouseScrolled)); 61 | dispatcher.Dispatch(GT_BIND_EVENT_FN(OrthographicCameraController::OnWindowResized)); 62 | } 63 | 64 | void OrthographicCameraController::OnResize(float width, float height) 65 | { 66 | m_AspectRatio = width / height; 67 | m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel); 68 | } 69 | 70 | bool OrthographicCameraController::OnMouseScrolled(MouseScrolledEvent& e) 71 | { 72 | GT_PROFILE_FUNCTION(); 73 | 74 | m_ZoomLevel -= e.GetYOffset() * 0.25f; 75 | m_ZoomLevel = std::max(m_ZoomLevel, 0.25f); 76 | m_Camera.SetProjection(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel); 77 | return false; 78 | } 79 | 80 | bool OrthographicCameraController::OnWindowResized(WindowResizeEvent& e) 81 | { 82 | GT_PROFILE_FUNCTION(); 83 | 84 | OnResize((float)e.GetWidth(), (float)e.GetHeight()); 85 | return false; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Camera/Controllers/OrthographicCameraController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Timestep.h" 4 | #include "Ghost/Camera/OrthographicCamera.h" 5 | 6 | #include "Ghost/Events/ApplicationEvent.h" 7 | #include "Ghost/Events/MouseEvent.h" 8 | 9 | namespace Ghost { 10 | class OrthographicCameraController { 11 | public: 12 | OrthographicCameraController(float aspectRatio, bool rotation = true); 13 | 14 | void OnUpdate(Timestep ts); 15 | void OnEvent(Event& e); 16 | 17 | void OnResize(float width, float height); 18 | 19 | OrthographicCamera& GetCamera() { return m_Camera; } 20 | const OrthographicCamera& GetCamera() const { return m_Camera; } 21 | 22 | float GetZoomLevel() const { return m_ZoomLevel; } 23 | void SetZoomLevel(float level) { m_ZoomLevel = level; } 24 | private: 25 | bool OnMouseScrolled(MouseScrolledEvent& e); 26 | bool OnWindowResized(WindowResizeEvent& e); 27 | private: 28 | float m_AspectRatio; 29 | float m_ZoomLevel = 1.0f; 30 | OrthographicCamera m_Camera; 31 | 32 | bool m_Rotation; 33 | glm::vec3 m_CameraPosition = { 0.0f, 0.0f, 0.0f }; 34 | float m_CameraRotation = 0; // In degrees, in the anti-clockwise direction 35 | float m_CameraTranslationSpeed = 1.0f, m_CameraRotationSpeed = 180.0f; 36 | }; 37 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Camera/OrthographicCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Camera/OrthographicCamera.h" 3 | 4 | namespace Ghost { 5 | OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top) 6 | :m_ProjectionMatrix(glm::ortho(left, right, bottom, top, -1.0f, 1.0f)), m_ViewMatrix(1.0f) 7 | { 8 | GT_PROFILE_FUNCTION(); 9 | 10 | m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix; 11 | } 12 | 13 | void OrthographicCamera::SetProjection(float left, float right, float bottom, float top) 14 | { 15 | GT_PROFILE_FUNCTION(); 16 | 17 | m_ProjectionMatrix = glm::ortho(left, right, bottom, top, -1.0f, 1.0f); 18 | m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix; 19 | } 20 | 21 | void OrthographicCamera::RecalculateViewMatrix() 22 | { 23 | GT_PROFILE_FUNCTION(); 24 | 25 | // Translation Matrix = Position * Rotation 26 | glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_Position) * 27 | glm::rotate(glm::mat4(1.0f), glm::radians(m_Rotation), glm::vec3(0, 0, 1)); 28 | 29 | m_ViewMatrix = glm::inverse(transform); 30 | m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix; 31 | } 32 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Camera/OrthographicCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Ghost { 7 | class OrthographicCamera { 8 | public: 9 | OrthographicCamera(float left, float right, float bottom, float top); 10 | 11 | void SetProjection(float left, float right, float bottom, float top); 12 | 13 | const glm::vec3& GetPosition() const { return m_Position; } 14 | void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); } 15 | 16 | float GetRotation() const { return m_Rotation; } 17 | void SetRotation(float rotation) { m_Rotation = rotation; RecalculateViewMatrix(); } 18 | 19 | const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; } 20 | const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; } 21 | const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; } 22 | private: 23 | void RecalculateViewMatrix(); 24 | private: 25 | glm::mat4 m_ProjectionMatrix; 26 | glm::mat4 m_ViewMatrix; 27 | glm::mat4 m_ViewProjectionMatrix; 28 | 29 | glm::vec3 m_Position = { 0.0f,0.0f,0.0f }; 30 | float m_Rotation = 0.0f; 31 | }; 32 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Application.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #include "Ghost/Core/Application.h" 4 | #include "Ghost/Core/Input.h" 5 | #include "Ghost/Core/Log.h" 6 | #include "Ghost/Renderer/Renderer.h" 7 | 8 | #include 9 | 10 | namespace Ghost 11 | { 12 | Application* Application::s_Instance = nullptr; 13 | 14 | Application::Application(const std::string& name, ApplicationCommandLineArgs args) 15 | : m_CommandLineArgs(args) { 16 | GT_PROFILE_FUNCTION(); 17 | 18 | GT_CORE_ASSERT(!s_Instance, "Application already exists!"); 19 | s_Instance = this; 20 | 21 | m_Window = Window::Create(WindowProps(name)); 22 | m_Window->SetEventCallback(GT_BIND_EVENT_FN(Application::OnEvent)); 23 | 24 | Renderer::Init(); 25 | 26 | m_ImGuiLayer = new ImGuiLayer(); 27 | PushOverlay(m_ImGuiLayer); 28 | } 29 | 30 | Application::~Application() { 31 | GT_PROFILE_FUNCTION(); 32 | 33 | Renderer::Shutdown(); 34 | } 35 | 36 | void Application::PushLayer(Layer* layer) { 37 | GT_PROFILE_FUNCTION(); 38 | 39 | m_layerStack.PushLayer(layer); 40 | layer->OnAttach(); 41 | } 42 | 43 | void Application::PushOverlay(Layer* overlay) { 44 | GT_PROFILE_FUNCTION(); 45 | 46 | m_layerStack.PushLayerOverlay(overlay); 47 | overlay->OnAttach(); 48 | } 49 | 50 | void Application::Close() { 51 | m_Running = false; 52 | } 53 | 54 | void Application::OnEvent(Event& e) { 55 | GT_PROFILE_FUNCTION(); 56 | 57 | EventDispatcher dispatcher(e); 58 | dispatcher.Dispatch(GT_BIND_EVENT_FN(Application::OnWindowClosed)); 59 | dispatcher.Dispatch(GT_BIND_EVENT_FN(Application::OnWindowResize)); 60 | 61 | for (auto it = m_layerStack.rbegin(); it != m_layerStack.rend(); ++it) 62 | { 63 | if (e.handled) 64 | { 65 | break; 66 | } 67 | (*it)->OnEvent(e); 68 | } 69 | } 70 | 71 | void Application::Run() { 72 | GT_PROFILE_FUNCTION(); 73 | 74 | while (m_Running) 75 | { 76 | GT_PROFILE_SCOPE("RunLoop"); 77 | 78 | float time = (float)glfwGetTime(); // Platform::GetTime() - Platform based implementation and abstraction 79 | Timestep timestep = time - m_LastFrameTime; 80 | m_LastFrameTime = time; 81 | 82 | if (!m_Minimized) 83 | { 84 | { 85 | GT_PROFILE_SCOPE("LayerStack OnUpdate"); 86 | 87 | for (Layer* layer : m_layerStack) 88 | layer->OnUpdate(timestep); 89 | } 90 | 91 | m_ImGuiLayer->Begin(); 92 | { 93 | GT_PROFILE_SCOPE("LayerStack OnImGuiRender"); 94 | 95 | for (Layer* layer : m_layerStack) 96 | layer->OnImGuiRender(); 97 | } 98 | m_ImGuiLayer->End(); 99 | } 100 | 101 | Input::OnUpdate(); 102 | 103 | m_Window->OnUpdate(); 104 | } 105 | } 106 | 107 | bool Application::OnWindowClosed(WindowCloseEvent& e) { 108 | m_Running = false; 109 | return true; 110 | } 111 | 112 | bool Application::OnWindowResize(WindowResizeEvent& e) { 113 | GT_PROFILE_FUNCTION(); 114 | 115 | if (e.GetWidth() == 0 || e.GetHeight() == 0) 116 | { 117 | m_Minimized = true; 118 | return false; 119 | } 120 | 121 | m_Minimized = false; 122 | Renderer::OnWindowResize(e.GetWidth(), e.GetHeight()); 123 | 124 | return false; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Application.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Window.h" 5 | 6 | #include "Ghost/Core/LayerStack.h" 7 | #include "Ghost/Events/Event.h" 8 | #include "Ghost/Events/ApplicationEvent.h" 9 | 10 | #include "Ghost/Core/Timestep.h" 11 | 12 | #include "Ghost/ImGui/ImGuiLayer.h" 13 | 14 | int main(int argc, char** argv); 15 | 16 | namespace Ghost 17 | { 18 | struct ApplicationCommandLineArgs { 19 | int Count = 0; 20 | char** Args = nullptr; 21 | const char* operator[](int index) const { 22 | GT_CORE_ASSERT(index < Count); 23 | return Args[index]; 24 | } 25 | }; 26 | 27 | class Application { 28 | public: 29 | Application(const std::string& name = "Ghost App", ApplicationCommandLineArgs args = 30 | ApplicationCommandLineArgs()); 31 | virtual ~Application(); 32 | 33 | void OnEvent(Event& e); 34 | 35 | void PushLayer(Layer* layer); 36 | void PushOverlay(Layer* overlay); 37 | 38 | Window& GetWindow() { return *m_Window; } 39 | 40 | void Close(); 41 | 42 | ImGuiLayer* GetImGuiLayer() { return m_ImGuiLayer; } 43 | 44 | static Application& Get() { return *s_Instance; } 45 | 46 | ApplicationCommandLineArgs GetCommandLineArgs() const { return m_CommandLineArgs; } 47 | private: 48 | void Run(); 49 | bool OnWindowClosed(WindowCloseEvent& e); 50 | bool OnWindowResize(WindowResizeEvent& e); 51 | 52 | private: 53 | ApplicationCommandLineArgs m_CommandLineArgs; 54 | Scope m_Window; 55 | ImGuiLayer* m_ImGuiLayer; 56 | 57 | bool m_Running = true; 58 | bool m_Minimized = false; 59 | 60 | LayerStack m_layerStack; 61 | 62 | float m_LastFrameTime = 0.0f; 63 | private: 64 | static Application* s_Instance; 65 | friend int ::main(int argc, char** argv); 66 | }; 67 | 68 | // TO BE defined in client 69 | Application* CreateApplication(ApplicationCommandLineArgs args); 70 | } 71 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Assert.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Log.h" 5 | #include 6 | 7 | #ifdef GT_ENABLE_ASSERTS 8 | 9 | // Alteratively we could use the same "default" message for both "WITH_MSG" and "NO_MSG" and 10 | // provide support for custom formatting by concatenating the formatting string instead of having the format inside the default message 11 | #define GT_INTERNAL_ASSERT_IMPL(type, check, msg, ...) { if(!(check)) { GT##type##ERROR(msg, __VA_ARGS__); GT_DEBUGBREAK(); } } 12 | #define GT_INTERNAL_ASSERT_WITH_MSG(type, check, ...) GT_INTERNAL_ASSERT_IMPL(type, check, "Assertion failed: {0}", __VA_ARGS__) 13 | #define GT_INTERNAL_ASSERT_NO_MSG(type, check) GT_INTERNAL_ASSERT_IMPL(type, check, "Assertion '{0}' failed at {1}:{2}", GT_STRINGIFY_MACRO(check), std::filesystem::path(__FILE__).filename().string(), __LINE__) 14 | 15 | #define GT_INTERNAL_ASSERT_GET_MACRO_NAME(arg1, arg2, macro, ...) macro 16 | #define GT_INTERNAL_ASSERT_GET_MACRO(...) GT_EXPAND_MACRO( GT_INTERNAL_ASSERT_GET_MACRO_NAME(__VA_ARGS__, GT_INTERNAL_ASSERT_WITH_MSG, GT_INTERNAL_ASSERT_NO_MSG) ) 17 | 18 | // Currently accepts at least the condition and one additional parameter (the message) being optional 19 | #define GT_ASSERT(...) GT_EXPAND_MACRO( GT_INTERNAL_ASSERT_GET_MACRO(__VA_ARGS__)(_, __VA_ARGS__) ) 20 | #define GT_CORE_ASSERT(...) GT_EXPAND_MACRO( GT_INTERNAL_ASSERT_GET_MACRO(__VA_ARGS__)(_CORE_, __VA_ARGS__) ) 21 | #else 22 | #define GT_ASSERT(...) 23 | #define GT_CORE_ASSERT(...) 24 | #endif 25 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Base.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Ghost/Core/PlatformDetection.h" 6 | 7 | #ifdef GT_DEBUG 8 | #if defined(GT_PLATFORM_WINDOWS) 9 | #define GT_DEBUGBREAK() __debugbreak() 10 | #elif defined(GT_PLATFORM_LINUX) 11 | #include 12 | #define GT_DEBUGBREAK() raise(SIGTRAP) 13 | #endif 14 | #define GT_ENABLE_ASSERTS 15 | #else 16 | #define GT_DEBUGBREAK() 17 | #endif // GT_DEBUG 18 | 19 | #define GT_EXPAND_MACRO(x) x 20 | #define GT_STRINGIFY_MACRO(x) #x 21 | 22 | #define BIT(x) (1 << x) 23 | 24 | #define GT_BIND_EVENT_FN(fn) [this](auto&&... args) -> decltype(auto) { return this->fn(std::forward(args)...);} 25 | 26 | namespace Ghost { 27 | template 28 | using Scope = std::unique_ptr; 29 | 30 | template 31 | constexpr Scope CreateScope(Args&& ... args) { 32 | return std::make_unique(std::forward(args)...); 33 | } 34 | 35 | template 36 | using Ref = std::shared_ptr; 37 | 38 | template 39 | constexpr Ref CreateRef(Args&& ... args) { 40 | return std::make_shared(std::forward(args)...); 41 | } 42 | } 43 | 44 | #include "Ghost/Core/Log.h" 45 | #include "Ghost/Core/Assert.h" 46 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/EntryPoint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Ghost/Core/Base.h" 3 | #include "Ghost/Core/Application.h" 4 | 5 | #ifdef GT_PLATFORM_WINDOWS 6 | 7 | extern Ghost::Application* Ghost::CreateApplication(ApplicationCommandLineArgs args); 8 | 9 | extern "C" { 10 | __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; 11 | } 12 | 13 | int main(int argc, char** argv) { 14 | Ghost::Log::Init(); 15 | 16 | GT_PROFILE_BEGIN_SESSION("Startup", "GhostProfile-Startup.json"); 17 | auto app = Ghost::CreateApplication({ argc, argv }); 18 | GT_PROFILE_END_SESSION(); 19 | 20 | GT_PROFILE_BEGIN_SESSION("Runtime", "GhostProfile-Runtime.json"); 21 | app->Run(); 22 | GT_PROFILE_END_SESSION(); 23 | 24 | GT_PROFILE_BEGIN_SESSION("Shutdown", "GhostProfile-Shutdown.json"); 25 | delete app; 26 | GT_PROFILE_END_SESSION(); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Input.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Ghost/Core/KeyCodes.h" 6 | #include "Ghost/Core/MouseCodes.h" 7 | 8 | namespace Ghost { 9 | class Input { 10 | public: 11 | static bool IsKeyPressed(KeyCode keycode); 12 | static bool IsKeyDown(KeyCode keycode); 13 | static bool IsKeyUp(KeyCode keycode); 14 | 15 | static bool IsMouseButtonPressed(MouseCode button); 16 | static bool IsMouseButtonDown(MouseCode button); 17 | static bool IsMouseButtonUp(MouseCode button); 18 | 19 | static glm::vec2 GetMousePosition(); 20 | static float GetMouseX(); 21 | static float GetMouseY(); 22 | 23 | protected: 24 | static bool GetKey(KeyCode keycode); 25 | static bool GetMouseButton(MouseCode mousecode); 26 | 27 | private: 28 | friend class Application; 29 | 30 | static void OnUpdate(); 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/KeyCodes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Ghost { 4 | using KeyCode = uint16_t; 5 | 6 | namespace Key 7 | { 8 | enum : KeyCode 9 | { 10 | Space = 32, 11 | Apostrophe = 39, /* ' */ 12 | Comma = 44, /* , */ 13 | Minus = 45, /* - */ 14 | Period = 46, /* . */ 15 | Slash = 47, /* / */ 16 | 17 | D0 = 48, /* 0 */ 18 | D1 = 49, /* 1 */ 19 | D2 = 50, /* 2 */ 20 | D3 = 51, /* 3 */ 21 | D4 = 52, /* 4 */ 22 | D5 = 53, /* 5 */ 23 | D6 = 54, /* 6 */ 24 | D7 = 55, /* 7 */ 25 | D8 = 56, /* 8 */ 26 | D9 = 57, /* 9 */ 27 | 28 | Semicolon = 59, /* ; */ 29 | Equal = 61, /* = */ 30 | 31 | A = 65, 32 | B = 66, 33 | C = 67, 34 | D = 68, 35 | E = 69, 36 | F = 70, 37 | G = 71, 38 | H = 72, 39 | I = 73, 40 | J = 74, 41 | K = 75, 42 | L = 76, 43 | M = 77, 44 | N = 78, 45 | O = 79, 46 | P = 80, 47 | Q = 81, 48 | R = 82, 49 | S = 83, 50 | T = 84, 51 | U = 85, 52 | V = 86, 53 | W = 87, 54 | X = 88, 55 | Y = 89, 56 | Z = 90, 57 | 58 | LeftBracket = 91, /* [ */ 59 | Backslash = 92, /* \ */ 60 | RightBracket = 93, /* ] */ 61 | GraveAccent = 96, /* ` */ 62 | 63 | World1 = 161, /* non-US #1 */ 64 | World2 = 162, /* non-US #2 */ 65 | 66 | /* Function keys */ 67 | Escape = 256, 68 | Enter = 257, 69 | Tab = 258, 70 | Backspace = 259, 71 | Insert = 260, 72 | Delete = 261, 73 | Right = 262, 74 | Left = 263, 75 | Down = 264, 76 | Up = 265, 77 | PageUp = 266, 78 | PageDown = 267, 79 | Home = 268, 80 | End = 269, 81 | CapsLock = 280, 82 | ScrollLock = 281, 83 | NumLock = 282, 84 | PrintScreen = 283, 85 | Pause = 284, 86 | F1 = 290, 87 | F2 = 291, 88 | F3 = 292, 89 | F4 = 293, 90 | F5 = 294, 91 | F6 = 295, 92 | F7 = 296, 93 | F8 = 297, 94 | F9 = 298, 95 | F10 = 299, 96 | F11 = 300, 97 | F12 = 301, 98 | F13 = 302, 99 | F14 = 303, 100 | F15 = 304, 101 | F16 = 305, 102 | F17 = 306, 103 | F18 = 307, 104 | F19 = 308, 105 | F20 = 309, 106 | F21 = 310, 107 | F22 = 311, 108 | F23 = 312, 109 | F24 = 313, 110 | F25 = 314, 111 | 112 | /* Keypad */ 113 | KP0 = 320, 114 | KP1 = 321, 115 | KP2 = 322, 116 | KP3 = 323, 117 | KP4 = 324, 118 | KP5 = 325, 119 | KP6 = 326, 120 | KP7 = 327, 121 | KP8 = 328, 122 | KP9 = 329, 123 | KPDecimal = 330, 124 | KPDivide = 331, 125 | KPMultiply = 332, 126 | KPSubtract = 333, 127 | KPAdd = 334, 128 | KPEnter = 335, 129 | KPEqual = 336, 130 | 131 | LeftShift = 340, 132 | LeftControl = 341, 133 | LeftAlt = 342, 134 | LeftSuper = 343, 135 | RightShift = 344, 136 | RightControl = 345, 137 | RightAlt = 346, 138 | RightSuper = 347, 139 | Menu = 348 140 | }; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Layer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Core/Layer.h" 3 | 4 | namespace Ghost { 5 | Layer::Layer(const std::string& debugName) 6 | :m_DebugName(debugName) 7 | { 8 | } 9 | 10 | Layer::~Layer() 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Timestep.h" 5 | #include "Ghost/Events/Event.h" 6 | 7 | namespace Ghost { 8 | class Layer { 9 | public: 10 | Layer(const std::string& name = "Layer"); 11 | virtual ~Layer(); 12 | 13 | virtual void OnAttach() {} 14 | virtual void OnDetach() {} 15 | virtual void OnUpdate(Timestep ts) {} 16 | virtual void OnImGuiRender() {} 17 | virtual void OnEvent(Event& event) {} 18 | 19 | const std::string& GetName() const { return m_DebugName; } 20 | protected: 21 | std::string m_DebugName; 22 | }; 23 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/LayerStack.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Core/LayerStack.h" 3 | 4 | namespace Ghost { 5 | LayerStack::~LayerStack() 6 | { 7 | for (Layer* layer : m_Layers) { 8 | layer->OnDetach(); 9 | delete layer; 10 | } 11 | } 12 | 13 | void LayerStack::PushLayer(Layer* layer) 14 | { 15 | m_Layers.emplace(m_Layers.begin() + m_LayerInsertIndex, layer); 16 | m_LayerInsertIndex++; 17 | } 18 | 19 | void LayerStack::PushLayerOverlay(Layer* overlay) 20 | { 21 | m_Layers.emplace_back(overlay); 22 | } 23 | 24 | void LayerStack::PopLayer(Layer* layer) 25 | { 26 | auto it = std::find(m_Layers.begin(), m_Layers.end(), layer); 27 | if (it != m_Layers.end()) { 28 | m_Layers.erase(it); 29 | m_LayerInsertIndex--; 30 | } 31 | } 32 | 33 | void LayerStack::PopLayerOverlay(Layer* overlay) 34 | { 35 | auto it = std::find(m_Layers.begin(), m_Layers.end(), overlay); 36 | if (it != m_Layers.end()) 37 | m_Layers.erase(it); 38 | } 39 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/LayerStack.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Layer.h" 5 | 6 | #include 7 | 8 | namespace Ghost { 9 | class LayerStack { 10 | public: 11 | LayerStack() = default; 12 | ~LayerStack(); 13 | 14 | void PushLayer(Layer* layer); 15 | void PushLayerOverlay(Layer* overlay); 16 | void PopLayer(Layer* layer); 17 | void PopLayerOverlay(Layer* overlay); 18 | 19 | std::vector::iterator begin() { return m_Layers.begin(); } 20 | std::vector::iterator end() { return m_Layers.end(); } 21 | 22 | std::vector::reverse_iterator rbegin() { return m_Layers.rbegin(); } 23 | std::vector::reverse_iterator rend() { return m_Layers.rend(); } 24 | 25 | std::vector::const_iterator begin() const { return m_Layers.begin(); } 26 | std::vector::const_iterator end() const { return m_Layers.end(); } 27 | 28 | std::vector::const_reverse_iterator rbegin() const { return m_Layers.rbegin(); } 29 | std::vector::const_reverse_iterator rend() const { return m_Layers.rend(); } 30 | 31 | private: 32 | std::vector m_Layers; 33 | unsigned int m_LayerInsertIndex = 0; 34 | }; 35 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Log.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Core/Log.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace Ghost { 8 | Ref Log::s_CoreLogger; 9 | Ref Log::s_ClientLogger; 10 | 11 | void Log::Init() { 12 | std::vector logSinks; 13 | logSinks.emplace_back(std::make_shared()); 14 | logSinks.emplace_back(std::make_shared("Ghost.log", true)); 15 | 16 | logSinks[0]->set_pattern("%^[%T] %n: %v%$"); 17 | logSinks[1]->set_pattern("[%T] [%l] %n: %v"); 18 | 19 | s_CoreLogger = std::make_shared("GHOST", begin(logSinks), end(logSinks)); 20 | spdlog::register_logger(s_CoreLogger); 21 | s_CoreLogger->set_level(spdlog::level::trace); 22 | s_CoreLogger->flush_on(spdlog::level::trace); 23 | 24 | s_ClientLogger = std::make_shared("APP", begin(logSinks), end(logSinks)); 25 | spdlog::register_logger(s_ClientLogger); 26 | s_ClientLogger->set_level(spdlog::level::trace); 27 | s_ClientLogger->flush_on(spdlog::level::trace); 28 | } 29 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | 5 | #define GLM_ENABLE_EXPERIMENTAL 6 | #include "glm/gtx/string_cast.hpp" 7 | 8 | #pragma warning(push, 0) 9 | #include 10 | #include 11 | #pragma warning(pop) 12 | 13 | namespace Ghost 14 | { 15 | class Log { 16 | public: 17 | static void Init(); 18 | 19 | static Ref& GetCoreLogger() { return s_CoreLogger; } 20 | static Ref& GetClientLogger() { return s_ClientLogger; } 21 | private: 22 | static Ref s_CoreLogger; 23 | static Ref s_ClientLogger; 24 | }; 25 | } 26 | 27 | template 28 | inline OStream& operator<<(OStream& os, const glm::vec& vector) { 29 | return os << glm::to_string(vector); 30 | } 31 | 32 | template 33 | inline OStream& operator<<(OStream& os, const glm::mat& matrix) { 34 | return os << glm::to_string(matrix); 35 | } 36 | 37 | template 38 | inline OStream& operator<<(OStream& os, glm::qua quaternion) { 39 | return os << glm::to_string(quaternion); 40 | } 41 | 42 | // Core log macros 43 | #define GT_CORE_TRACE(...) ::Ghost::Log::GetCoreLogger()->trace(__VA_ARGS__) 44 | #define GT_CORE_INFO(...) ::Ghost::Log::GetCoreLogger()->info(__VA_ARGS__) 45 | #define GT_CORE_WARN(...) ::Ghost::Log::GetCoreLogger()->warn(__VA_ARGS__) 46 | #define GT_CORE_ERROR(...) ::Ghost::Log::GetCoreLogger()->error(__VA_ARGS__) 47 | #define GT_CORE_CRITICAL(...) ::Ghost::Log::GetCoreLogger()->critical(__VA_ARGS__) 48 | 49 | // Client log macros 50 | #define GT_TRACE(...) ::Ghost::Log::GetClientLogger()->trace(__VA_ARGS__) 51 | #define GT_INFO(...) ::Ghost::Log::GetClientLogger()->info(__VA_ARGS__) 52 | #define GT_WARN(...) ::Ghost::Log::GetClientLogger()->warn(__VA_ARGS__) 53 | #define GT_ERROR(...) ::Ghost::Log::GetClientLogger()->error(__VA_ARGS__) 54 | #define GT_CRITICAL(...) ::Ghost::Log::GetClientLogger()->critical(__VA_ARGS__) 55 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/MouseCodes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Ghost { 4 | using MouseCode = uint16_t; 5 | 6 | namespace Mouse 7 | { 8 | enum : MouseCode 9 | { 10 | // From glfw3.h 11 | Button0 = 0, 12 | Button1 = 1, 13 | Button2 = 2, 14 | Button3 = 3, 15 | Button4 = 4, 16 | Button5 = 5, 17 | Button6 = 6, 18 | Button7 = 7, 19 | 20 | ButtonLast = Button7, 21 | ButtonLeft = Button0, 22 | ButtonRight = Button1, 23 | ButtonMiddle = Button2 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/PlatformDetection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _WIN32 4 | #ifdef _WIN64 5 | #define GT_PLATFORM_WINDOWS 6 | #else 7 | #error "x86 builds are not supported!" 8 | #endif // _WIN64 9 | #elif defined(__APPLE__) || defined (__MACH__) 10 | #include 11 | #if TARGET_IPHONE_SIMULATOR == 1 12 | #error "iOS simulator is not supported!" 13 | #elif TARGET_OS_IPHONE == 1 14 | #define GT_PLATFORM_IOS 15 | #error "iOS is not supported!" 16 | #elif TARGET_OS_MAC == 1 17 | #define GT_PLATFORM_MACOS 18 | #error "MacOS is not supported!" 19 | #else 20 | #error "Unknown Apple platform!" 21 | #endif 22 | #elif defined(__ANDROID__) 23 | #define GT_PLATFORM_LINUX 24 | #error "Linux is not supported!" 25 | #else 26 | #error "Unknown platform!" 27 | #endif // _WIN32 -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Ghost 6 | { 7 | class Timer { 8 | public: 9 | Timer() { 10 | Reset(); 11 | } 12 | 13 | void Timer::Reset() { 14 | m_Start = std::chrono::high_resolution_clock::now(); 15 | } 16 | 17 | float Timer::Elapsed() { 18 | return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - 19 | m_Start).count() * 0.001f * 0.001f * 0.001f; 20 | } 21 | 22 | float Timer::ElapsedMillis() { 23 | return Elapsed() * 1000.0f; 24 | } 25 | 26 | private: 27 | std::chrono::time_point m_Start; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Timestep.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Ghost { 4 | class Timestep { 5 | public: 6 | Timestep(float time = 0.0f) 7 | :m_Time(time) 8 | { 9 | } 10 | 11 | operator float() const { return m_Time; } 12 | 13 | float GetSeconds() const { return m_Time; } 14 | float GetMilliseconds() const { return m_Time * 1000.0f; } 15 | private: 16 | float m_Time; 17 | }; 18 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/UUID.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include"Ghost/Core/UUID.h" 3 | 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | static std::random_device s_RandomDevice; 9 | static std::mt19937_64 s_RandomEngine(s_RandomDevice()); 10 | static std::uniform_int_distribution s_UniformDistribution; 11 | 12 | UUID::UUID() 13 | :m_UUID(s_UniformDistribution(s_RandomEngine)) {} 14 | 15 | UUID::UUID(uint64_t uuid) 16 | : m_UUID(uuid) {} 17 | 18 | UUID::UUID(const UUID& other) 19 | : m_UUID(other.m_UUID) {} 20 | } 21 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/UUID.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | class UUID { 9 | public: 10 | UUID(); 11 | UUID(uint64_t uuid); 12 | UUID(const UUID& other); 13 | 14 | operator uint64_t () { return m_UUID; } 15 | operator const uint64_t() const { return m_UUID; } 16 | 17 | private: 18 | uint64_t m_UUID; 19 | }; 20 | } 21 | 22 | namespace std 23 | { 24 | template<> 25 | struct hash { 26 | std::size_t operator()(const Ghost::UUID& uuid) const { 27 | return hash()((uint64_t)uuid); 28 | } 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Window.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Core/Window.h" 3 | 4 | #ifdef GT_PLATFORM_WINDOWS 5 | #include "Platform/Windows/WindowsWindow.h" 6 | #endif // GT_PLATFORM_WINDOWS 7 | 8 | namespace Ghost { 9 | Scope Window::Create(const WindowProps& props) { 10 | #ifdef GT_PLATFORM_WINDOWS 11 | return CreateScope(props); 12 | #else 13 | GT_CORE_ASSERT(false, "Unknown platform!"); 14 | return nullptr; 15 | #endif // GT_PLATFORM_WINDOWS 16 | } 17 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Core/Window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gtpch.h" 4 | 5 | #include "Ghost/Core/Base.h" 6 | #include "Ghost/Events/Event.h" 7 | #include "Ghost/Renderer/GraphicsContext.h" 8 | 9 | namespace Ghost { 10 | struct WindowProps { 11 | std::string Title; 12 | uint32_t Width; 13 | uint32_t Height; 14 | 15 | WindowProps(const std::string& title = "Ghost Engine", 16 | uint32_t width = 1920, 17 | uint32_t height = 1080) 18 | : Title(title), Width(width), Height(height) 19 | { 20 | } 21 | }; 22 | 23 | // Interface representing a desktop system based Window 24 | class Window { 25 | public: 26 | using EventCallbackFn = std::function; 27 | 28 | virtual ~Window() {} 29 | 30 | virtual void OnUpdate() = 0; 31 | 32 | virtual uint32_t GetWidth() const = 0; 33 | virtual uint32_t GetHeight() const = 0; 34 | 35 | // Window Attributes 36 | virtual void SetEventCallback(const EventCallbackFn& callback) = 0; 37 | virtual void SetVSync(bool enabled) = 0; 38 | virtual bool IsVSync() const = 0; 39 | 40 | virtual void* GetNativeWindow() const = 0; 41 | virtual ContextInfo GetGraphicsContextInfo() const = 0; 42 | 43 | static Scope Create(const WindowProps& props = WindowProps()); 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Events/ApplicationEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Events/Event.h" 4 | 5 | namespace Ghost { 6 | class WindowResizeEvent : public Event { 7 | public: 8 | WindowResizeEvent(unsigned int width, unsigned int height) 9 | : m_Width(width), m_Height(height) {} 10 | 11 | unsigned int GetWidth() const { return m_Width; } 12 | unsigned int GetHeight() const { return m_Height; } 13 | 14 | std::string ToString() const override { 15 | std::stringstream ss; 16 | ss << "WindowResizeEvent: " << m_Width << ", " << m_Height; 17 | return ss.str(); 18 | } 19 | 20 | EVENT_CLASS_TYPE(WindowResize) 21 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 22 | private: 23 | unsigned int m_Width, m_Height; 24 | }; 25 | 26 | class WindowCloseEvent : public Event { 27 | public: 28 | WindowCloseEvent() = default; 29 | 30 | EVENT_CLASS_TYPE(WindowClose) 31 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 32 | }; 33 | 34 | class AppTickEvent : public Event { 35 | public: 36 | AppTickEvent() = default; 37 | 38 | EVENT_CLASS_TYPE(AppTick) 39 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 40 | }; 41 | 42 | class AppUpdateEvent : public Event { 43 | public: 44 | AppUpdateEvent() = default; 45 | 46 | EVENT_CLASS_TYPE(AppUpdate) 47 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 48 | }; 49 | 50 | class AppRenderEvent : public Event { 51 | public: 52 | AppRenderEvent() = default; 53 | 54 | EVENT_CLASS_TYPE(AppRender) 55 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 56 | }; 57 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Events/Event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Ghost/Debug/Instrumentor.h" 6 | #include "Ghost/Core/Base.h" 7 | 8 | namespace Ghost { 9 | /* Events in Ghost are currently blocking, i.e., when an event occurs it 10 | immediately gets dispatched and must be dealt with with right then and there. 11 | For the future, a better strategy might be to buffer events in an event bus 12 | and process them during the "event" part of the update stage 13 | */ 14 | 15 | enum class EventType { 16 | None = 0, 17 | WindowClose, WindowResize, WindowFocus, WindowFocusLost, WindowMoved, 18 | AppTick, AppUpdate, AppRender, 19 | KeyPressed, KeyReleased, KeyTyped, 20 | MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled 21 | }; 22 | 23 | enum EventCategory { 24 | None = 0, 25 | EventCategoryApplication = BIT(0), 26 | EventCategoryInput = BIT(1), 27 | EventCategoryKeyboard = BIT(2), 28 | EventCategoryMouse = BIT(3), 29 | EventCategoryMouseButton = BIT(4) 30 | }; 31 | 32 | #define EVENT_CLASS_TYPE(type) static EventType GetStaticType() {return EventType::type; }\ 33 | virtual EventType GetEventType() const override{ return GetStaticType(); }\ 34 | virtual const char* GetName() const override {return #type;} 35 | 36 | #define EVENT_CLASS_CATEGORY(category) virtual int GetCategoryFlags() const override { return category; } 37 | 38 | class Event { 39 | friend class EventDispatcher; 40 | public: 41 | bool handled = false; 42 | 43 | virtual EventType GetEventType() const = 0; 44 | virtual const char* GetName() const = 0; 45 | virtual int GetCategoryFlags() const = 0; 46 | virtual std::string ToString() const { return GetName(); } 47 | 48 | bool IsInCategory(EventCategory category) { 49 | return GetCategoryFlags() & category; 50 | } 51 | }; 52 | 53 | class EventDispatcher { 54 | public: 55 | EventDispatcher(Event& event) 56 | :m_Event(event) { 57 | } 58 | 59 | // F will be deduced by the compiler 60 | template 61 | bool Dispatch(const F& func) { 62 | if (m_Event.GetEventType() == T::GetStaticType()) { 63 | m_Event.handled |= func(static_cast(m_Event)); 64 | return true; 65 | } 66 | return false; 67 | } 68 | private: 69 | Event& m_Event; 70 | }; 71 | 72 | inline std::ostream& operator<<(std::ostream& os, const Event& e) { 73 | return os << e.ToString(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Events/KeyEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Events/Event.h" 4 | #include "Ghost/Core/KeyCodes.h" 5 | 6 | namespace Ghost { 7 | class KeyEvent : public Event { 8 | public: 9 | KeyCode GetKeyCode() const { return m_KeyCode; } 10 | 11 | EVENT_CLASS_CATEGORY(EventCategoryKeyboard | EventCategoryInput) 12 | protected: 13 | KeyEvent(const KeyCode keycode) 14 | : m_KeyCode(keycode) {} 15 | 16 | KeyCode m_KeyCode; 17 | }; 18 | 19 | class KeyPressedEvent : public KeyEvent { 20 | public: 21 | KeyPressedEvent(const KeyCode keycode, const uint16_t repeatCount) 22 | : KeyEvent(keycode), m_RepeatCount(repeatCount) {} 23 | 24 | uint16_t GetRepeatCount() const { return m_RepeatCount; } 25 | 26 | std::string ToString() const override { 27 | std::stringstream ss; 28 | ss << "KeyPressedEvent: " << m_KeyCode << " (" << m_RepeatCount << " repeats)"; 29 | return ss.str(); 30 | } 31 | 32 | EVENT_CLASS_TYPE(KeyPressed) 33 | private: 34 | uint16_t m_RepeatCount; 35 | }; 36 | 37 | class KeyReleasedEvent : public KeyEvent { 38 | public: 39 | KeyReleasedEvent(const KeyCode keycode) 40 | :KeyEvent(keycode) {} 41 | 42 | std::string ToString() const override { 43 | std::stringstream ss; 44 | ss << "KeyReleasedEvent: " << m_KeyCode; 45 | return ss.str(); 46 | } 47 | 48 | EVENT_CLASS_TYPE(KeyReleased) 49 | }; 50 | 51 | class KeyTypedEvent : public KeyEvent { 52 | public: 53 | KeyTypedEvent(const KeyCode keycode) 54 | : KeyEvent(keycode) {} 55 | 56 | std::string ToString() const override { 57 | std::stringstream ss; 58 | ss << "KeyTypedEvent: " << m_KeyCode; 59 | return ss.str(); 60 | } 61 | 62 | EVENT_CLASS_TYPE(KeyTyped) 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Events/MouseEvent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Events/Event.h" 4 | #include "Ghost/Core/MouseCodes.h" 5 | 6 | namespace Ghost { 7 | class MouseMovedEvent : public Event { 8 | public: 9 | MouseMovedEvent(const float x, const float y) 10 | :m_MouseX(x), m_MouseY(y) {} 11 | 12 | float GetX() const { return m_MouseX; } 13 | float GetY() const { return m_MouseY; } 14 | 15 | std::string ToString() const override { 16 | std::stringstream ss; 17 | 18 | ss << "MouseMovedEvent: " << m_MouseX << ", " << m_MouseY; 19 | return ss.str(); 20 | } 21 | 22 | EVENT_CLASS_TYPE(MouseMoved) 23 | EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput | EventCategoryMouseButton) 24 | private: 25 | float m_MouseX, m_MouseY; 26 | }; 27 | 28 | class MouseScrolledEvent : public Event { 29 | public: 30 | MouseScrolledEvent(const float xOffset, const float yOffset) 31 | :m_XOffset(xOffset), m_YOffset(yOffset) {} 32 | 33 | float GetXOffset() const { return m_XOffset; } 34 | float GetYOffset() const { return m_YOffset; } 35 | 36 | std::string ToString() const override { 37 | std::stringstream ss; 38 | 39 | ss << "MouseScrolledEvent: " << GetXOffset() << ", " << GetYOffset(); 40 | return ss.str(); 41 | } 42 | 43 | EVENT_CLASS_TYPE(MouseScrolled) 44 | EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) 45 | private: 46 | float m_XOffset, m_YOffset; 47 | }; 48 | 49 | class MouseButtonEvent : public Event { 50 | public: 51 | MouseCode GetMouseButton() const { return m_Button; } 52 | 53 | EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) 54 | protected: 55 | MouseButtonEvent(const MouseCode button) 56 | :m_Button(button) {} 57 | 58 | MouseCode m_Button; 59 | }; 60 | 61 | class MouseButtonPressedEvent : public MouseButtonEvent { 62 | public: 63 | MouseButtonPressedEvent(const MouseCode button) 64 | :MouseButtonEvent(button) {} 65 | 66 | std::string ToString() const override { 67 | std::stringstream ss; 68 | ss << "MouseButtonPressedEvent: " << m_Button; 69 | return ss.str(); 70 | } 71 | 72 | EVENT_CLASS_TYPE(MouseButtonPressed) 73 | }; 74 | 75 | class MouseButtonReleasedEvent : public MouseButtonEvent { 76 | public: 77 | MouseButtonReleasedEvent(const MouseCode button) 78 | :MouseButtonEvent(button) {} 79 | 80 | std::string ToString() const override { 81 | std::stringstream ss; 82 | ss << "MouseButtonReleasedEvent: " << m_Button; 83 | return ss.str(); 84 | } 85 | 86 | EVENT_CLASS_TYPE(MouseButtonReleased) 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Juliette Foucaut and Doug Binks 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/ImGuiBuild.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #define IMGUI_IMPL_OPENGL_LOADER_GLAD 4 | #include 5 | #include 6 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/ImGuiLayer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/ImGui/ImGuiLayer.h" 3 | #include "Ghost/Fonts/IconsFontAwesome5Pro.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Ghost/Core/Application.h" 10 | 11 | // TEMPORARY 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace Ghost 18 | { 19 | ImGuiLayer::ImGuiLayer() 20 | :Layer("ImGuiLayer") {} 21 | 22 | ImGuiLayer::~ImGuiLayer() {} 23 | 24 | void ImGuiLayer::OnAttach() { 25 | GT_PROFILE_FUNCTION(); 26 | 27 | // Setup Dear ImGui context 28 | IMGUI_CHECKVERSION(); 29 | ImGui::CreateContext(); 30 | ImGuiIO& io = ImGui::GetIO(); (void)io; 31 | io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls 32 | // io.ConfigFlags != ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls 33 | io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking 34 | io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform windows 35 | //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskbarIcons; 36 | //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge; 37 | 38 | float fontSize = 18.0f; 39 | 40 | io.Fonts->AddFontFromFileTTF("assets/fonts/opensans/OpenSans-Bold.ttf", fontSize); 41 | 42 | // merge in icons from Font Awesome 43 | static const ImWchar icons_ranges_fontawesome[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; 44 | ImFontConfig icons_config_fontawesome; 45 | icons_config_fontawesome.MergeMode = true; 46 | icons_config_fontawesome.PixelSnapH = true; 47 | 48 | io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_FAS, fontSize, &icons_config_fontawesome, icons_ranges_fontawesome); 49 | 50 | io.FontDefault = io.Fonts->AddFontFromFileTTF("assets/fonts/opensans/OpenSans-Regular.ttf", fontSize); 51 | io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_FAS, fontSize, &icons_config_fontawesome, icons_ranges_fontawesome); 52 | 53 | // Setup Dear ImGui style 54 | ImGui::StyleColorsDark(); 55 | //ImGui::StyleColorsClassic(); 56 | 57 | // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to 58 | ImGuiStyle& style = ImGui::GetStyle(); 59 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 60 | { 61 | style.WindowRounding = 0.0f; 62 | style.Colors[ImGuiCol_WindowBg].w = 1.0f; 63 | } 64 | 65 | SetDarkThemeColors(); 66 | 67 | Application& app = Application::Get(); 68 | GLFWwindow* window = static_cast(app.GetWindow().GetNativeWindow()); 69 | 70 | // Setup Platform/Renderer Bindings 71 | 72 | ImGui_ImplGlfw_InitForOpenGL(window, true); 73 | ImGui_ImplOpenGL3_Init("#version 410"); 74 | } 75 | 76 | void ImGuiLayer::OnDetach() { 77 | GT_PROFILE_FUNCTION(); 78 | 79 | ImGui_ImplOpenGL3_Shutdown(); 80 | ImGui_ImplGlfw_Shutdown(); 81 | ImGui::DestroyContext(); 82 | } 83 | 84 | void ImGuiLayer::OnEvent(Event& e) { 85 | if (m_BlockEvents) 86 | { 87 | ImGuiIO& io = ImGui::GetIO(); 88 | e.handled |= e.IsInCategory(EventCategoryMouse) & io.WantCaptureMouse; 89 | e.handled |= e.IsInCategory(EventCategoryKeyboard) & io.WantCaptureKeyboard; 90 | } 91 | } 92 | 93 | void ImGuiLayer::Begin() { 94 | GT_PROFILE_FUNCTION(); 95 | 96 | ImGui_ImplOpenGL3_NewFrame(); 97 | ImGui_ImplGlfw_NewFrame(); 98 | ImGui::NewFrame(); 99 | ImGuizmo::BeginFrame(); 100 | } 101 | 102 | void ImGuiLayer::End() { 103 | GT_PROFILE_FUNCTION(); 104 | 105 | ImGuiIO& io = ImGui::GetIO(); 106 | Application& app = Application::Get(); 107 | io.DisplaySize = ImVec2((float)app.GetWindow().GetWidth(), (float)app.GetWindow().GetHeight()); 108 | 109 | // Rendering 110 | ImGui::Render(); 111 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); 112 | 113 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 114 | { 115 | GLFWwindow* backup_current_context = glfwGetCurrentContext(); 116 | ImGui::UpdatePlatformWindows(); 117 | ImGui::RenderPlatformWindowsDefault(); 118 | glfwMakeContextCurrent(backup_current_context); 119 | } 120 | } 121 | void ImGuiLayer::SetDarkThemeColors() { 122 | auto& colors = ImGui::GetStyle().Colors; 123 | colors[ImGuiCol_WindowBg] = ImVec4{ 0.1f, 0.105f, 0.11f, 1.0f }; 124 | 125 | // Headers 126 | colors[ImGuiCol_Header] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f }; 127 | colors[ImGuiCol_HeaderHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f }; 128 | colors[ImGuiCol_HeaderActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 129 | 130 | // Buttons 131 | colors[ImGuiCol_Button] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f }; 132 | colors[ImGuiCol_ButtonHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f }; 133 | colors[ImGuiCol_ButtonActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 134 | 135 | // Frame BG 136 | colors[ImGuiCol_FrameBg] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f }; 137 | colors[ImGuiCol_FrameBgHovered] = ImVec4{ 0.3f, 0.305f, 0.31f, 1.0f }; 138 | colors[ImGuiCol_FrameBgActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 139 | 140 | // Tabs 141 | colors[ImGuiCol_Tab] = ImVec4{ 0.15f,0.1505f, 0.151f, 1.0f }; 142 | colors[ImGuiCol_TabHovered] = ImVec4{ 0.38f, 0.3805f, 0.381f, 1.0f }; 143 | colors[ImGuiCol_TabActive] = ImVec4{ 0.28f, 0.2805f, 0.281f, 1.0f }; 144 | colors[ImGuiCol_TabUnfocused] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 145 | colors[ImGuiCol_TabUnfocusedActive] = ImVec4{ 0.2f, 0.205f, 0.21f, 1.0f }; 146 | 147 | // Title 148 | colors[ImGuiCol_TitleBg] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 149 | colors[ImGuiCol_TitleBgActive] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 150 | colors[ImGuiCol_TitleBgCollapsed] = ImVec4{ 0.15f, 0.1505f, 0.151f, 1.0f }; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/ImGuiLayer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include "Ghost/Core/Layer.h" 5 | #include "Ghost/Events/ApplicationEvent.h" 6 | #include "Ghost/Events/KeyEvent.h" 7 | #include "Ghost/Events/MouseEvent.h" 8 | 9 | namespace Ghost 10 | { 11 | class ImGuiLayer : public Layer { 12 | public: 13 | ImGuiLayer(); 14 | ~ImGuiLayer(); 15 | 16 | virtual void OnAttach() override; 17 | virtual void OnDetach() override; 18 | virtual void OnEvent(Event& e) override; 19 | 20 | void Begin(); 21 | void End(); 22 | 23 | void BlockEvents(bool block) { m_BlockEvents = block; } 24 | 25 | void SetDarkThemeColors(); 26 | private: 27 | bool m_BlockEvents = true; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/Utilities/ImGuiAssetBrowser.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | 5 | namespace Ghost { 6 | enum class AssetFileType { 7 | PNG = 0, 8 | GLSL = 1, 9 | TTF = 2, 10 | SCENE = 3, 11 | NONE = -1 12 | }; 13 | 14 | class ImGuiAssetBrowser { 15 | public: 16 | static void Init(); 17 | 18 | static void Draw(); 19 | private: 20 | static bool IsDirectory(const std::filesystem::path& path); 21 | static bool IsDirectoryEmpty(const std::filesystem::path& path); 22 | static bool HasSubDirectory(const std::filesystem::path& path); 23 | 24 | static void DrawLeftProjectPanel(); 25 | static void DrawRightProjectPanel(); 26 | 27 | static void DrawRecursive(const std::filesystem::path& path); 28 | static void DrawRightFilePathHeader(const std::filesystem::path& path); 29 | 30 | static AssetFileType GetFileType(const std::filesystem::path& path); 31 | private: 32 | static std::filesystem::path m_AssetDirectoryPath; 33 | static std::filesystem::path m_CurrentRightPanelDirectoryPath; 34 | 35 | inline static std::unordered_map m_FileExtensionMap = 36 | { 37 | {".png" , AssetFileType::PNG }, 38 | {".glsl", AssetFileType::GLSL}, 39 | {".ttf" , AssetFileType::TTF }, 40 | {".ghost", AssetFileType::SCENE} 41 | }; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/Utilities/ImGuiConsole.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/ImGui/Utilities/ImGuiConsole.h" 3 | #include "Ghost/Fonts/IconsFontAwesome5Pro.h" 4 | 5 | #include "imgui.h" 6 | 7 | namespace Ghost { 8 | uint32_t ImGuiConsole::s_LogMessageCount = 0; 9 | std::vector ImGuiConsole::s_MessageBuffer(0); 10 | 11 | static bool s_ShowInfoMessages = true; 12 | static bool s_ShowWarnMessages = true; 13 | static bool s_ShowErrorMessages = true; 14 | 15 | void ImGuiConsole::Draw() 16 | { 17 | if (ImGui::Button("Clear", { 50.0f, 30.0f })) { 18 | Clear(); 19 | } 20 | 21 | ImGui::SameLine(); 22 | if (ImGui::Button("Log", { 50.0f, 30.0f })) { 23 | s_ShowInfoMessages = !s_ShowInfoMessages; 24 | } 25 | 26 | ImGui::SameLine(); 27 | if (ImGui::Button("Warn", { 50.0f, 30.0f })) { 28 | s_ShowWarnMessages = !s_ShowWarnMessages; 29 | } 30 | 31 | ImGui::SameLine(); 32 | if (ImGui::Button("Error", { 50.0f, 30.0f })) { 33 | s_ShowErrorMessages = !s_ShowErrorMessages; 34 | } 35 | 36 | ImGui::Separator(); 37 | ImGui::Separator(); 38 | 39 | const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); 40 | ImGui::BeginChild("Scrolling Region", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); 41 | 42 | for (uint32_t i = 0; i < s_LogMessageCount; i++) { 43 | if (s_MessageBuffer.at(i).m_MessageLevel == Message::Level::Info && s_ShowInfoMessages) { 44 | ImGui::TextColored({ 1.0f, 1.0f, 1.0f, 1.0f }, s_MessageBuffer.at(i).m_MessageData.c_str()); 45 | ImGui::Separator(); 46 | continue; 47 | } 48 | if (s_MessageBuffer.at(i).m_MessageLevel == Message::Level::Warn && s_ShowWarnMessages) { 49 | ImGui::TextColored({ 1.0f, 1.0f, 0.0f, 1.0f }, s_MessageBuffer.at(i).m_MessageData.c_str()); 50 | ImGui::Separator(); 51 | continue; 52 | } 53 | if (s_MessageBuffer.at(i).m_MessageLevel == Message::Level::Error && s_ShowErrorMessages) { 54 | ImGui::TextColored({ 1.0f, 0.0f, 0.0f, 1.0f }, s_MessageBuffer.at(i).m_MessageData.c_str()); 55 | ImGui::Separator(); 56 | continue; 57 | } 58 | } 59 | 60 | ImGui::EndChild(); 61 | } 62 | 63 | void ImGuiConsole::Clear() 64 | { 65 | s_LogMessageCount = 0; 66 | s_MessageBuffer.clear(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/ImGui/Utilities/ImGuiConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | 5 | namespace Ghost { 6 | class Message { 7 | public: 8 | enum class Level : int8_t { 9 | Info = 0, 10 | Warn = 1, 11 | Error = 2 12 | }; 13 | public: 14 | Message() = default; 15 | Message(const std::string& message, Level level = Level::Info) 16 | :m_MessageData(message), m_MessageLevel(level) 17 | {} 18 | 19 | public: 20 | std::string m_MessageData; 21 | Level m_MessageLevel; 22 | }; 23 | 24 | class ImGuiConsole 25 | { 26 | public: 27 | ImGuiConsole() = default; 28 | 29 | static void Draw(); 30 | 31 | template 32 | static void Log(const std::string& data, Args&&... args); 33 | 34 | template 35 | static void LogWarning(const std::string& data, Args&&... args); 36 | 37 | template 38 | static void LogError(const std::string& data, Args&&... args); 39 | 40 | private: 41 | static void Clear(); 42 | 43 | template 44 | static std::string Format(const std::string& fmt, Args&&... args); 45 | 46 | private: 47 | static std::vector s_MessageBuffer; 48 | static uint32_t s_LogMessageCount; 49 | }; 50 | 51 | template 52 | inline std::string ImGuiConsole::Format(const std::string& fmt, Args && ...args) 53 | { 54 | size_t size = snprintf(nullptr, 0, fmt.c_str(), args...); 55 | std::string buffer; 56 | buffer.reserve(size + 1); 57 | buffer.resize(size); 58 | snprintf(&buffer[0], size + 1, fmt.c_str(), args...); 59 | return buffer; 60 | } 61 | 62 | // Logging Implementations 63 | template 64 | inline void ImGuiConsole::Log(const std::string& data, Args && ...args) 65 | { 66 | s_MessageBuffer.push_back({ ImGuiConsole::Format(data, args...) }); 67 | s_LogMessageCount++; 68 | } 69 | 70 | template 71 | inline void ImGuiConsole::LogWarning(const std::string& data, Args && ...args) 72 | { 73 | s_MessageBuffer.push_back({ ImGuiConsole::Format(data, args...), Message::Level::Warn }); 74 | s_LogMessageCount++; 75 | } 76 | 77 | template 78 | inline void ImGuiConsole::LogError(const std::string& data, Args && ...args) 79 | { 80 | s_MessageBuffer.push_back({ ImGuiConsole::Format(data, args...), Message::Level::Error }); 81 | s_LogMessageCount++; 82 | } 83 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Math/Math.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Math.h" 3 | 4 | #define GLM_ENABLE_EXPERIMENTAL 5 | #include 6 | 7 | namespace Ghost::Math { 8 | bool DecomposeTransform(const glm::mat4& transform, glm::vec3& translation, glm::vec3& rotation, glm::vec3& scale) 9 | { 10 | // From glm::decompose in matrix_decompose.inl 11 | 12 | using namespace glm; 13 | using T = float; 14 | 15 | mat4 LocalMatrix(transform); 16 | 17 | // Normalize the matrix. 18 | if (epsilonEqual(LocalMatrix[3][3], static_cast(0), epsilon())) 19 | return false; 20 | 21 | // First, isolate perspective. This is the messiest. 22 | if ( 23 | epsilonNotEqual(LocalMatrix[0][3], static_cast(0), epsilon()) || 24 | epsilonNotEqual(LocalMatrix[1][3], static_cast(0), epsilon()) || 25 | epsilonNotEqual(LocalMatrix[2][3], static_cast(0), epsilon())) 26 | { 27 | // Clear the perspective partition 28 | LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast(0); 29 | LocalMatrix[3][3] = static_cast(1); 30 | } 31 | 32 | // Next take care of translation (easy). 33 | translation = vec3(LocalMatrix[3]); 34 | LocalMatrix[3] = vec4(0, 0, 0, LocalMatrix[3].w); 35 | 36 | vec3 Row[3], Pdum3; 37 | 38 | // Now get scale and shear. 39 | for (length_t i = 0; i < 3; ++i) 40 | for (length_t j = 0; j < 3; ++j) 41 | Row[i][j] = LocalMatrix[i][j]; 42 | 43 | // Compute X scale factor and normalize first row. 44 | scale.x = length(Row[0]); 45 | Row[0] = detail::scale(Row[0], static_cast(1)); 46 | scale.y = length(Row[1]); 47 | Row[1] = detail::scale(Row[1], static_cast(1)); 48 | scale.z = length(Row[2]); 49 | Row[2] = detail::scale(Row[2], static_cast(1)); 50 | 51 | // At this point, the matrix (in rows[]) is orthonormal. 52 | // Check for a coordinate system flip. If the determinant 53 | // is -1, then negate the matrix and the scaling factors. 54 | #if 0 55 | Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3); 56 | if (dot(Row[0], Pdum3) < 0) 57 | { 58 | for (length_t i = 0; i < 3; i++) 59 | { 60 | scale[i] *= static_cast(-1); 61 | Row[i] *= static_cast(-1); 62 | } 63 | } 64 | #endif 65 | 66 | rotation.y = asin(-Row[0][2]); 67 | if (cos(rotation.y) != 0) { 68 | rotation.x = atan2(Row[1][2], Row[2][2]); 69 | rotation.z = atan2(Row[0][1], Row[0][0]); 70 | } 71 | else { 72 | rotation.x = atan2(-Row[2][0], Row[1][1]); 73 | rotation.z = 0; 74 | } 75 | 76 | return true; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Math/Math.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Ghost::Math { 6 | bool DecomposeTransform(const glm::mat4& tranform, glm::vec3& translation, glm::vec3& rotation, glm::vec3& scale); 7 | } 8 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Buffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/Buffer.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | 6 | #include "Platform/OpenGL/OpenGLBuffer.h" 7 | 8 | namespace Ghost { 9 | Ref VertexBuffer::Create(uint32_t size) 10 | { 11 | switch (Renderer::GetAPI()) { 12 | case RendererAPI::API::None: 13 | { 14 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported"); 15 | return nullptr; 16 | } 17 | case RendererAPI::API::OpenGL: 18 | { 19 | return CreateRef(size); 20 | } 21 | 22 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 23 | return nullptr; 24 | } 25 | } 26 | 27 | Ref VertexBuffer::Create(float* vertices, uint32_t size) { 28 | switch (Renderer::GetAPI()) { 29 | case RendererAPI::API::None: 30 | { 31 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported"); 32 | return nullptr; 33 | } 34 | case RendererAPI::API::OpenGL: 35 | { 36 | return CreateRef(vertices, size); 37 | } 38 | 39 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 40 | return nullptr; 41 | } 42 | } 43 | 44 | Ref IndexBuffer::Create(uint32_t* indices, uint32_t count) { 45 | switch (Renderer::GetAPI()) 46 | { 47 | case RendererAPI::API::None: 48 | { 49 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported"); 50 | return nullptr; 51 | } 52 | case RendererAPI::API::OpenGL: 53 | { 54 | return CreateRef(indices, count); 55 | } 56 | 57 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 58 | return nullptr; 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Ghost { 4 | enum class ShaderDataType : uint8_t 5 | { 6 | None = 0, Float, Float2, Float3, Float4, Mat3, Mat4, Int, Int2, Int3, Int4, Bool 7 | }; 8 | 9 | static uint32_t ShaderDataTypeSize(ShaderDataType type) { 10 | switch (type) { 11 | case ShaderDataType::Float: return 4; 12 | case ShaderDataType::Float2: return 4 * 2; 13 | case ShaderDataType::Float3: return 4 * 3; 14 | case ShaderDataType::Float4: return 4 * 4; 15 | case ShaderDataType::Mat3: return 4 * 3 * 3; 16 | case ShaderDataType::Mat4: return 4 * 4 * 4; 17 | case ShaderDataType::Int: return 4; 18 | case ShaderDataType::Int2: return 4 * 2; 19 | case ShaderDataType::Int3: return 4 * 3; 20 | case ShaderDataType::Int4: return 4 * 4; 21 | case ShaderDataType::Bool: return 1; 22 | } 23 | 24 | GT_CORE_ASSERT(false, "Unknown ShaderDataType!"); 25 | return 0; 26 | } 27 | 28 | struct BufferElement 29 | { 30 | std::string Name; 31 | ShaderDataType Type; 32 | uint32_t Size; 33 | size_t Offset; 34 | bool Normalized; 35 | 36 | BufferElement() = default; 37 | 38 | BufferElement(ShaderDataType type, const std::string& name, bool normalized = false) 39 | : Name(name), Type(type), Size(ShaderDataTypeSize(type)), Offset(0), Normalized(normalized) 40 | { 41 | } 42 | 43 | uint32_t GetComponentCount() const 44 | { 45 | switch (Type) { 46 | case ShaderDataType::Float: return 1; 47 | case ShaderDataType::Float2: return 2; 48 | case ShaderDataType::Float3: return 3; 49 | case ShaderDataType::Float4: return 4; 50 | case ShaderDataType::Mat3: return 3; 51 | case ShaderDataType::Mat4: return 4; 52 | case ShaderDataType::Int: return 1; 53 | case ShaderDataType::Int2: return 2; 54 | case ShaderDataType::Int3: return 3; 55 | case ShaderDataType::Int4: return 4; 56 | case ShaderDataType::Bool: return 1; 57 | } 58 | 59 | GT_CORE_ASSERT(false, "Unknown ShaderDataType!"); 60 | return 0; 61 | } 62 | }; 63 | 64 | class BufferLayout { 65 | public: 66 | BufferLayout() {} 67 | 68 | BufferLayout(std::initializer_list elements) 69 | :m_Elements(elements) 70 | { 71 | CalculateOffsetsAndStride(); 72 | } 73 | 74 | uint32_t GetStride() const { return m_Stride; } 75 | 76 | const std::vector& GetElements() const { return m_Elements; } 77 | 78 | std::vector::iterator begin() { return m_Elements.begin(); } 79 | std::vector::iterator end() { return m_Elements.end(); } 80 | std::vector::const_iterator begin() const { return m_Elements.begin(); } 81 | std::vector::const_iterator end() const { return m_Elements.end(); } 82 | private: 83 | void CalculateOffsetsAndStride() { 84 | size_t offset = 0; 85 | m_Stride = 0; 86 | for (BufferElement& element : m_Elements) { 87 | element.Offset = offset; 88 | offset += element.Size; 89 | m_Stride += element.Size; 90 | } 91 | } 92 | private: 93 | std::vector m_Elements; 94 | uint32_t m_Stride = 0; 95 | }; 96 | 97 | class VertexBuffer { 98 | public: 99 | virtual ~VertexBuffer() = default; 100 | 101 | virtual void Bind() const = 0; 102 | virtual void Unbind() const = 0; 103 | 104 | virtual void SetData(const void* data, uint32_t size) = 0; 105 | 106 | virtual const BufferLayout& GetLayout() const = 0; 107 | virtual void SetLayout(const BufferLayout& layout) = 0; 108 | 109 | static Ref Create(uint32_t size); 110 | static Ref Create(float* vertices, uint32_t size); 111 | }; 112 | 113 | // Currently Ghost only supports 32-bit index buffers 114 | class IndexBuffer { 115 | public: 116 | virtual ~IndexBuffer() = default; 117 | 118 | virtual void Bind() const = 0; 119 | virtual void Unbind() const = 0; 120 | 121 | virtual uint32_t GetCount() const = 0; 122 | 123 | static Ref Create(uint32_t* indices, uint32_t count); 124 | }; 125 | } 126 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/EditorCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #include "Ghost/Renderer/EditorCamera.h" 4 | 5 | #include "Ghost/Core/Input.h" 6 | #include "Ghost/Core/KeyCodes.h" 7 | #include "Ghost/Core/MouseCodes.h" 8 | 9 | #include 10 | 11 | #define GLM_ENABLE_EXPERIMENTAL 12 | #include 13 | 14 | namespace Ghost { 15 | EditorCamera::EditorCamera(float fov, float aspectRatio, float nearClip, float farClip) 16 | : m_FOV(fov), m_AspectRatio(aspectRatio), m_NearClip(nearClip), m_FarClip(farClip), 17 | Camera(glm::perspective(glm::radians(fov), aspectRatio, nearClip, farClip)) 18 | { 19 | UpdateView(); 20 | } 21 | 22 | void EditorCamera::UpdateProjection() 23 | { 24 | m_AspectRatio = m_ViewportWidth / m_ViewportHeight; 25 | m_Projection = glm::perspective(glm::radians(m_FOV), m_AspectRatio, m_NearClip, m_FarClip); 26 | } 27 | 28 | void EditorCamera::UpdateView() 29 | { 30 | // m_Yaw = m_Pitch = 0.0f; // Lock the camera's rotation 31 | m_Position = CalculatePositions(); 32 | 33 | glm::quat orientation = GetOrientation(); 34 | m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_Position) * glm::toMat4(orientation); 35 | m_ViewMatrix = glm::inverse(m_ViewMatrix); 36 | } 37 | 38 | std::pair EditorCamera::PanSpeed() const 39 | { 40 | float x = std::min(m_ViewportWidth / 1000.0f, 2.4f); // max = 2.4f 41 | float xFactor = 0.0366f * (x * x) - 0.1778f * x + 0.3021f; 42 | 43 | float y = std::min(m_ViewportHeight / 1000.0f, 2.4f); // max = 2.4f 44 | float yFactor = 0.0366f * (x * x) - 0.1778f * x + 0.3021f; 45 | 46 | return { xFactor, yFactor }; 47 | } 48 | 49 | float EditorCamera::RotationSpeed() const 50 | { 51 | return 0.8f; 52 | } 53 | 54 | float EditorCamera::ZoomSpeed() const 55 | { 56 | float distance = m_Distance * 0.2f; 57 | distance = std::max(distance, 0.0f); 58 | float speed = distance * distance; 59 | speed = std::min(speed, 100.0f); // max speed = 100 60 | return speed; 61 | } 62 | 63 | void EditorCamera::OnUpdate(Timestep ts) 64 | { 65 | if (Input::IsKeyPressed(Key::LeftAlt)) { 66 | const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; 67 | glm::vec2 delta = (mouse - m_InitialMousePosition) * 0.003f; 68 | m_InitialMousePosition = mouse; 69 | 70 | if (Input::IsMouseButtonPressed(Mouse::ButtonMiddle)) { 71 | MousePan(delta); 72 | } 73 | else if (Input::IsMouseButtonPressed(Mouse::ButtonLeft)) { 74 | MouseRotate(delta); 75 | } 76 | else if (Input::IsMouseButtonPressed(Mouse::ButtonRight)) { 77 | MouseZoom(delta.y); 78 | } 79 | } 80 | 81 | UpdateView(); 82 | } 83 | 84 | void EditorCamera::OnEvent(Event& e) 85 | { 86 | EventDispatcher dispatcher(e); 87 | dispatcher.Dispatch(GT_BIND_EVENT_FN(EditorCamera::OnMouseScroll)); 88 | } 89 | 90 | bool EditorCamera::OnMouseScroll(MouseScrolledEvent& e) 91 | { 92 | float delta = e.GetYOffset() * 0.1f; 93 | MouseZoom(delta); 94 | UpdateView(); 95 | return false; 96 | } 97 | 98 | void EditorCamera::MousePan(const glm::vec2& delta) 99 | { 100 | auto [xSpeed, ySpeed] = PanSpeed(); 101 | m_FocalPoint += -GetRightDirection() * delta.x * xSpeed * m_Distance; 102 | m_FocalPoint += GetUpDirection() * delta.y * ySpeed * m_Distance; 103 | } 104 | 105 | void EditorCamera::MouseRotate(const glm::vec2& delta) 106 | { 107 | float yawSign = GetUpDirection().y < 0 ? -1.0f : 1.0f; 108 | m_Yaw += yawSign * delta.x * RotationSpeed(); 109 | m_Pitch += delta.y * RotationSpeed(); 110 | } 111 | 112 | void EditorCamera::MouseZoom(float delta) 113 | { 114 | m_Distance -= delta * ZoomSpeed(); 115 | if (m_Distance < 1.0f) { 116 | m_FocalPoint += GetForwardDirection(); 117 | m_Distance = 1.0f; 118 | } 119 | } 120 | 121 | glm::vec3 EditorCamera::GetUpDirection() const 122 | { 123 | return glm::rotate(GetOrientation(), glm::vec3(0.0f, 1.0f, 0.0f)); 124 | } 125 | 126 | glm::vec3 EditorCamera::GetRightDirection() const 127 | { 128 | return glm::rotate(GetOrientation(), glm::vec3(1.0f, 0.0f, 0.0f)); 129 | } 130 | 131 | glm::vec3 EditorCamera::GetForwardDirection() const 132 | { 133 | return glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f)); 134 | } 135 | 136 | glm::vec3 EditorCamera::CalculatePositions() const 137 | { 138 | return m_FocalPoint - GetForwardDirection() * m_Distance; 139 | } 140 | 141 | glm::quat EditorCamera::GetOrientation() const 142 | { 143 | return glm::quat(glm::vec3(-m_Pitch, -m_Yaw, 0.0f)); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/EditorCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Camera/Camera.h" 4 | #include "Ghost/Core/Timestep.h" 5 | #include "Ghost/Events/Event.h" 6 | #include "Ghost/Events/MouseEvent.h" 7 | 8 | #include 9 | 10 | namespace Ghost { 11 | class EditorCamera : public Camera 12 | { 13 | public: 14 | EditorCamera() = default; 15 | EditorCamera(float fov, float aspectRatio, float nearClip, float farClip); 16 | 17 | void OnUpdate(Timestep ts); 18 | void OnEvent(Event& e); 19 | 20 | float GetDistance() const { return m_Distance; } 21 | void SetDistance(float distance) { m_Distance = distance; } 22 | 23 | void SetViewportSize(float width, float height) { m_ViewportWidth = width; m_ViewportHeight = height; UpdateProjection(); } 24 | 25 | const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; } 26 | glm::mat4 GetViewProjection() const { return m_Projection * m_ViewMatrix; } 27 | 28 | glm::vec3 GetUpDirection() const; 29 | glm::vec3 GetRightDirection() const; 30 | glm::vec3 GetForwardDirection() const; 31 | const glm::vec3& GetPosition() const { return m_Position; } 32 | glm::quat GetOrientation() const; 33 | 34 | float GetPitch() const { return m_Pitch; } 35 | float GetYaw() const { return m_Yaw; } 36 | private: 37 | void UpdateProjection(); 38 | void UpdateView(); 39 | 40 | bool OnMouseScroll(MouseScrolledEvent& e); 41 | 42 | void MousePan(const glm::vec2& delta); 43 | void MouseRotate(const glm::vec2& delta); 44 | void MouseZoom(float delta); 45 | 46 | glm::vec3 CalculatePositions() const; 47 | 48 | std::pair PanSpeed() const; 49 | float RotationSpeed() const; 50 | float ZoomSpeed() const; 51 | private: 52 | float m_FOV = 45.0f, m_AspectRatio = 1.778f, m_NearClip = 0.1f, m_FarClip = 1000.0f; 53 | 54 | glm::mat4 m_ViewMatrix; 55 | glm::vec3 m_Position = { 0.0f, 0.0f, 0.0f, }; 56 | glm::vec3 m_FocalPoint = { 0.0f, 0.0f, 0.0f }; 57 | 58 | glm::vec2 m_InitialMousePosition = { 0.0f, 0.0f }; 59 | 60 | float m_Distance = 10.0f; 61 | float m_Pitch = 0.0f, m_Yaw = 0.0f; 62 | 63 | float m_ViewportWidth = 1280, m_ViewportHeight = 720; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Framebuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/Framebuffer.h" 3 | #include "Ghost/Renderer/Renderer.h" 4 | 5 | #include "Platform/OpenGL/OpenGLFramebuffer.h" 6 | 7 | namespace Ghost { 8 | Ref Framebuffer::Create(const FramebufferSpecification& spec) 9 | { 10 | switch (Renderer::GetAPI()) { 11 | case RendererAPI::API::None: 12 | { 13 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); 14 | return nullptr; 15 | } 16 | case RendererAPI::API::OpenGL: 17 | { 18 | return CreateRef(spec); 19 | } 20 | } 21 | 22 | GT_CORE_ASSERT(false, "Unknown RendererAPI!"); 23 | return nullptr; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Framebuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | 5 | namespace Ghost 6 | { 7 | enum class FramebufferTextureFormat { 8 | None = 0, 9 | 10 | // Color 11 | RGBA8, 12 | RED_INTEGER, 13 | 14 | // Depth/Stencil 15 | DEPTH24STENCIL8, 16 | 17 | // Defaults 18 | Depth = DEPTH24STENCIL8 19 | }; 20 | 21 | struct FramebufferTextureSpecification { 22 | FramebufferTextureSpecification() = default; 23 | FramebufferTextureSpecification(FramebufferTextureFormat format) 24 | : TextureFormat(format) {} 25 | 26 | FramebufferTextureFormat TextureFormat = FramebufferTextureFormat::None; 27 | // TODO: filtering/wrap 28 | }; 29 | 30 | struct FramebufferAttachmentSpecification { 31 | FramebufferAttachmentSpecification() = default; 32 | FramebufferAttachmentSpecification(const std::initializer_list attachments) 33 | : Attachments(attachments) {} 34 | 35 | std::vector Attachments; 36 | }; 37 | 38 | struct FramebufferSpecification { 39 | uint32_t Width = 0, Height = 0; 40 | FramebufferAttachmentSpecification Attachments; 41 | uint32_t Samples = 1; 42 | bool SwapChainTarget = false; 43 | }; 44 | 45 | class Framebuffer { 46 | public: 47 | virtual ~Framebuffer() = default; 48 | 49 | virtual void Bind() = 0; 50 | virtual void Unbind() = 0; 51 | 52 | virtual void Resize(uint32_t width, uint32_t height) = 0; 53 | virtual int ReadPixel(uint32_t attachmentIndex, int x, int y) = 0; 54 | 55 | virtual void ClearAttachment(uint32_t attachmentIndex, int value) = 0; 56 | 57 | virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const = 0; 58 | 59 | virtual const FramebufferSpecification& GetSpecification() const = 0; 60 | 61 | static Ref Create(const FramebufferSpecification& spec); 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/GraphicsContext.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/GraphicsContext.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | #include "Platform/OpenGL/OpenGLContext.h" 6 | 7 | namespace Ghost { 8 | Scope GraphicsContext::Create(void* window) 9 | { 10 | switch (Renderer::GetAPI()) { 11 | case RendererAPI::API::None: 12 | { 13 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); 14 | return nullptr; 15 | } 16 | case RendererAPI::API::OpenGL: 17 | { 18 | return CreateScope(static_cast(window)); 19 | } 20 | 21 | GT_CORE_ASSERT(false, "Unknown RendererAPI!"); 22 | return nullptr; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/GraphicsContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Ghost { 4 | struct ContextInfo { 5 | unsigned char* Vendor; 6 | unsigned char* Renderer; 7 | unsigned char* Version; 8 | }; 9 | 10 | class GraphicsContext { 11 | public: 12 | virtual void Init() = 0; 13 | virtual void SwapBuffers() = 0; 14 | 15 | virtual ContextInfo GetContextInfo() = 0; 16 | 17 | static Scope Create(void* window); 18 | }; 19 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/RenderCommand.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/RenderCommand.h" 3 | 4 | namespace Ghost { 5 | Scope RenderCommand::s_RendererAPI = RendererAPI::Create(); 6 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/RenderCommand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/RendererAPI.h" 4 | 5 | namespace Ghost { 6 | class RenderCommand 7 | { 8 | public: 9 | static void Init() { 10 | s_RendererAPI->Init(); 11 | } 12 | 13 | static void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { 14 | s_RendererAPI->SetViewport(x, y, width, height); 15 | } 16 | 17 | static void SetClearColor(const glm::vec4& color) { 18 | s_RendererAPI->SetClearColor(color); 19 | } 20 | 21 | static void Clear() { 22 | s_RendererAPI->Clear(); 23 | } 24 | 25 | static void DrawIndexed(const Ref& vertexArray, uint32_t count = 0) { 26 | s_RendererAPI->DrawIndexed(vertexArray, count); 27 | } 28 | 29 | private: 30 | static Scope s_RendererAPI; 31 | }; 32 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Renderer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/Renderer.h" 3 | #include "Ghost/Renderer/Renderer2D.h" 4 | 5 | namespace Ghost { 6 | Scope Renderer::s_SceneData = CreateScope(); 7 | 8 | void Renderer::Init() 9 | { 10 | GT_PROFILE_FUNCTION(); 11 | 12 | RenderCommand::Init(); 13 | Renderer2D::Init(); 14 | } 15 | 16 | void Renderer::Shutdown() { 17 | Renderer2D::Shutdown(); 18 | } 19 | 20 | void Renderer::OnWindowResize(uint32_t width, uint32_t height) 21 | { 22 | RenderCommand::SetViewport(0, 0, width, height); 23 | } 24 | 25 | void Renderer::BeginScene(OrthographicCamera& camera) 26 | { 27 | s_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix(); 28 | } 29 | 30 | void Renderer::EndScene() 31 | { 32 | } 33 | 34 | void Renderer::Submit(const Ref& shader, 35 | const Ref& vertexArray, 36 | const glm::mat4& transform) 37 | { 38 | shader->Bind(); 39 | shader->SetMat4("u_ViewProjection", s_SceneData->ViewProjectionMatrix); 40 | shader->SetMat4("u_Transform", transform); 41 | 42 | vertexArray->Bind(); 43 | RenderCommand::DrawIndexed(vertexArray); 44 | } 45 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/RenderCommand.h" 4 | #include "Ghost/Camera/OrthographicCamera.h" 5 | #include "Ghost/Renderer/Shader.h" 6 | 7 | namespace Ghost { 8 | class Renderer { 9 | public: 10 | static void Init(); 11 | static void Shutdown(); 12 | 13 | static void OnWindowResize(uint32_t width, uint32_t height); 14 | 15 | static void BeginScene(OrthographicCamera& camera); 16 | static void EndScene(); 17 | 18 | static void Submit(const Ref& shader, 19 | const Ref& vertexArray, 20 | const glm::mat4& transform = glm::mat4(1.0f)); 21 | 22 | static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); } 23 | private: 24 | struct SceneData { 25 | glm::mat4 ViewProjectionMatrix; 26 | }; 27 | 28 | static Scope s_SceneData; 29 | }; 30 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Renderer2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Camera/Camera.h" 4 | #include "Ghost/Camera/OrthographicCamera.h" 5 | #include "Ghost/Renderer/Texture.h" 6 | 7 | #include "Ghost/Renderer/EditorCamera.h" 8 | #include "Ghost/Scene/Components.h" 9 | 10 | namespace Ghost 11 | { 12 | class Renderer2D { 13 | public: 14 | static void Init(); 15 | static void Shutdown(); 16 | 17 | static void BeginScene(const Camera& camera, const glm::mat4& transform); 18 | static void BeginScene(const EditorCamera& editorCamera); 19 | static void BeginScene(const OrthographicCamera& camera); // TODO: Remove 20 | static void EndScene(); 21 | static void Flush(); 22 | 23 | // Primitives 24 | static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color); 25 | static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color); 26 | static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture, 27 | float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); 28 | static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref& texture, 29 | float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); 30 | 31 | static void DrawQuad(const glm::mat4& transform, const glm::vec4& color, int entityID = -1); 32 | static void DrawQuad(const glm::mat4& transform, const Ref& texture, 33 | float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f), int entityID = -1); 34 | 35 | static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color); 36 | static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color); 37 | static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, 38 | const Ref& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); 39 | static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, 40 | const Ref& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f)); 41 | 42 | static void DrawSprite(const glm::mat4& transform, SpriteRendererComponent& src, int entityID); 43 | 44 | // Stats 45 | struct Statistics { 46 | uint32_t DrawCalls = 0; 47 | uint32_t QuadCount = 0; 48 | 49 | uint32_t GetTotalVertexCount() const { return QuadCount * 4; } 50 | uint32_t GetTotalIndexCount() const { return QuadCount * 6; } 51 | }; 52 | 53 | static void ResetStats(); 54 | static Statistics GetStats(); 55 | 56 | private: 57 | static void StartBatch(); 58 | static void NextBatch(); 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/RendererAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/RendererAPI.h" 3 | 4 | #include "Platform/OpenGL/OpenGLRendererAPI.h" 5 | 6 | namespace Ghost { 7 | RendererAPI::API RendererAPI::s_API = RendererAPI::API::OpenGL; 8 | 9 | Scope RendererAPI::Create() 10 | { 11 | switch (s_API) { 12 | case RendererAPI::API::None: 13 | { 14 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported"); 15 | return nullptr; 16 | } 17 | case RendererAPI::API::OpenGL: 18 | { 19 | return CreateScope(); 20 | } 21 | } 22 | 23 | GT_CORE_ASSERT(false, "Unknown RendererAPI!"); 24 | return nullptr; 25 | } 26 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/RendererAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "Ghost/Renderer/VertexArray.h" 6 | 7 | namespace Ghost { 8 | class RendererAPI { 9 | public: 10 | enum class API 11 | { 12 | None = 0, OpenGL = 1 13 | }; 14 | 15 | public: 16 | virtual void Init() = 0; 17 | virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; 18 | virtual void SetClearColor(const glm::vec4& color) = 0; 19 | virtual void Clear() = 0; 20 | 21 | virtual void DrawIndexed(const Ref& vertexArray, uint32_t indexCount = 0) = 0; 22 | 23 | static API GetAPI() { return s_API; } 24 | static Scope Create(); 25 | private: 26 | static API s_API; 27 | }; 28 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Shader.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Shader.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | 6 | #include "Platform/OpenGL/OpenGLShader.h" 7 | 8 | namespace Ghost 9 | { 10 | Ref Shader::Create(const std::string& filepath) { 11 | switch (Renderer::GetAPI()) 12 | { 13 | case RendererAPI::API::None: 14 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); 15 | return nullptr; 16 | 17 | case RendererAPI::API::OpenGL: 18 | return CreateRef(filepath); 19 | } 20 | 21 | GT_CORE_ASSERT(false, "Unknown RendererAPI!"); 22 | return nullptr; 23 | } 24 | 25 | Ref Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc) { 26 | switch (Renderer::GetAPI()) 27 | { 28 | case RendererAPI::API::None: 29 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); 30 | return nullptr; 31 | 32 | case RendererAPI::API::OpenGL: 33 | return CreateRef(name, vertexSrc, fragmentSrc); 34 | } 35 | 36 | GT_CORE_ASSERT(false, "Unknown RendererAPI!"); 37 | return nullptr; 38 | } 39 | 40 | void ShaderLibrary::Add(const std::string& name, const Ref& shader) { 41 | GT_CORE_ASSERT(!Exists(name), "Shader already exists!"); 42 | m_Shaders[name] = shader; 43 | } 44 | 45 | void ShaderLibrary::Add(const Ref& shader) { 46 | auto& name = shader->GetName(); 47 | Add(name, shader); 48 | } 49 | 50 | Ref ShaderLibrary::Load(const std::string& filepath) { 51 | auto shader = Shader::Create(filepath); 52 | Add(shader); 53 | return shader; 54 | } 55 | 56 | Ref ShaderLibrary::Load(const std::string& name, const std::string& filepath) { 57 | auto shader = Shader::Create(filepath); 58 | Add(name, shader); 59 | return shader; 60 | } 61 | 62 | Ref ShaderLibrary::Get(const std::string& name) { 63 | GT_CORE_ASSERT(Exists(name), "Shader not found!"); 64 | return m_Shaders[name]; 65 | } 66 | 67 | bool ShaderLibrary::Exists(const std::string& name) const { 68 | return m_Shaders.find(name) != m_Shaders.end(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Shader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace Ghost 9 | { 10 | class Shader { 11 | public: 12 | virtual ~Shader() = default; 13 | 14 | virtual void Bind() const = 0; 15 | virtual void Unbind() const = 0; 16 | 17 | virtual void SetInt(const std::string& name, int value) = 0; 18 | virtual void SetIntArray(const std::string& name, int* values, uint32_t count) = 0; 19 | virtual void SetFloat(const std::string& name, float value) = 0; 20 | virtual void SetFloat2(const std::string& name, const glm::vec2& value) = 0; 21 | virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0; 22 | virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0; 23 | virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0; 24 | 25 | virtual const std::string& GetName() const = 0; 26 | 27 | static Ref Create(const std::string& filepath); 28 | static Ref Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); 29 | }; 30 | 31 | class ShaderLibrary { 32 | public: 33 | void Add(const std::string& name, const Ref& shader); 34 | void Add(const Ref& shader); 35 | 36 | Ref Load(const std::string& filepath); 37 | Ref Load(const std::string& name, const std::string& filepath); 38 | 39 | Ref Get(const std::string& name); 40 | 41 | bool Exists(const std::string& name) const; 42 | private: 43 | std::unordered_map> m_Shaders; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/SubTexture2D.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/SubTexture2D.h" 3 | 4 | namespace Ghost { 5 | SubTexture2D::SubTexture2D(const Ref& texture, const glm::vec2& min, const glm::vec2& max) 6 | : m_Texture(texture) 7 | { 8 | m_TexCoords[0] = { min.x, min.y }; 9 | m_TexCoords[1] = { max.x, min.y }; 10 | m_TexCoords[2] = { max.x, max.y }; 11 | m_TexCoords[3] = { min.x, max.y }; 12 | } 13 | 14 | Ref SubTexture2D::CreateFromCoords(const Ref& texture, 15 | const glm::vec2& coords, const glm::vec2& cellSize, const glm::vec2& spriteSize) 16 | { 17 | glm::vec2 min = { (coords.x * cellSize.x) / (float)texture->GetWidth(), 18 | (coords.y * cellSize.y) / (float)texture->GetHeight() }; 19 | glm::vec2 max = { ((coords.x + spriteSize.x) * cellSize.x) / (float)texture->GetWidth(), 20 | ((coords.y + spriteSize.y) * cellSize.y) / (float)texture->GetHeight() }; 21 | 22 | return CreateRef(texture, min, max); 23 | } 24 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/SubTexture2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/Texture.h" 4 | 5 | #include 6 | #include 7 | 8 | namespace Ghost { 9 | class SubTexture2D { 10 | public: 11 | SubTexture2D(const Ref& texture, const glm::vec2& min, const glm::vec2& max); 12 | 13 | const Ref GetTexture() const { return m_Texture; } 14 | const glm::vec2* GetTexCoords() const { return m_TexCoords; } 15 | 16 | static Ref CreateFromCoords(const Ref& texture, 17 | const glm::vec2& coords, const glm::vec2& cellSize, const glm::vec2& spriteSize); 18 | private: 19 | Ref m_Texture; 20 | 21 | glm::vec2 m_TexCoords[4]; 22 | }; 23 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Texture.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/Texture.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | #include "Platform/OpenGL/OpenGLTexture.h" 6 | 7 | namespace Ghost { 8 | Ref Texture2D::Create(uint32_t width, uint32_t height) 9 | { 10 | switch (Renderer::GetAPI()) { 11 | case RendererAPI::API::None: 12 | { 13 | GT_CORE_ASSERT(false, "RendererAPI::None currently not supported"); 14 | return nullptr; 15 | } 16 | case RendererAPI::API::OpenGL: 17 | { 18 | return CreateRef(width, height); 19 | } 20 | } 21 | } 22 | 23 | Ref Texture2D::Create(const std::string& path) 24 | { 25 | switch (Renderer::GetAPI()) { 26 | case RendererAPI::API::None: 27 | { 28 | GT_CORE_ASSERT(false, "RendererAPI::None currently not supported"); 29 | return nullptr; 30 | } 31 | case RendererAPI::API::OpenGL: 32 | { 33 | return CreateRef(path); 34 | } 35 | } 36 | 37 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 38 | return nullptr; 39 | } 40 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/Texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | class Texture { 9 | public: 10 | virtual ~Texture() = default; 11 | 12 | virtual uint32_t GetWidth() const = 0; 13 | virtual uint32_t GetHeight() const = 0; 14 | 15 | virtual uint32_t GetRendererID() const = 0; 16 | 17 | virtual void SetData(void* data, uint32_t size) = 0; 18 | 19 | virtual void Bind(uint32_t slot = 0) const = 0; 20 | 21 | virtual bool IsLoaded() const = 0; 22 | 23 | virtual bool operator ==(const Texture& other) const = 0; 24 | }; 25 | 26 | class Texture2D : public Texture { 27 | public: 28 | static Ref Create(uint32_t width, uint32_t height); 29 | static Ref Create(const std::string& path); 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/UniformBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/UniformBuffer.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | #include "Platform/OpenGL/OpenGLUniformBuffer.h" 6 | 7 | namespace Ghost 8 | { 9 | Ref UniformBuffer::Create(uint32_t size, uint32_t binding) { 10 | switch (Renderer::GetAPI()) 11 | { 12 | case RendererAPI::API::None: 13 | GT_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); 14 | return nullptr; 15 | 16 | case RendererAPI::API::OpenGL: 17 | return CreateRef(size, binding); 18 | } 19 | 20 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 21 | return nullptr; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/UniformBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Base.h" 4 | 5 | namespace Ghost 6 | { 7 | class UniformBuffer { 8 | public: 9 | virtual ~UniformBuffer() {} 10 | virtual void SetData(const void* data, uint32_t size, uint32_t offset = 0) = 0; 11 | 12 | static Ref Create(uint32_t size, uint32_t binding); 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/VertexArray.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Renderer/VertexArray.h" 3 | 4 | #include "Ghost/Renderer/Renderer.h" 5 | 6 | #include "Platform/OpenGL/OpenGLVertexArray.h" 7 | 8 | namespace Ghost { 9 | Ref VertexArray::Create() 10 | { 11 | switch (Renderer::GetAPI()) { 12 | case RendererAPI::API::None: 13 | { 14 | GT_CORE_ASSERT(false, "RendererAPI::None currently not supported"); 15 | return nullptr; 16 | } 17 | case RendererAPI::API::OpenGL: 18 | { 19 | return CreateRef(); 20 | } 21 | } 22 | 23 | GT_CORE_ASSERT(false, "Unknown RendererAPI"); 24 | return nullptr; 25 | } 26 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Renderer/VertexArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "Ghost/Renderer/Buffer.h" 5 | 6 | namespace Ghost { 7 | class VertexArray { 8 | public: 9 | virtual ~VertexArray() = default; 10 | 11 | virtual void Bind() const = 0; 12 | virtual void Unbind() const = 0; 13 | 14 | virtual void AddVertexBuffer(const Ref& vertexBuffer) = 0; 15 | virtual void SetIndexBuffer(const Ref& indexBuffer) = 0; 16 | 17 | virtual const std::vector>& GetVertexBuffers() const = 0; 18 | virtual const Ref& GetIndexBuffer() const = 0; 19 | 20 | static Ref Create(); 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/Components.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/UUID.h" 4 | #include "Ghost/Renderer/Texture.h" 5 | 6 | #include "Ghost/Scene/SceneCamera.h" 7 | 8 | #include 9 | #include 10 | 11 | #define GLM_ENABLE_EXPERIMENTAL 12 | #include 13 | 14 | namespace Ghost 15 | { 16 | struct IDComponent { 17 | UUID ID; 18 | 19 | IDComponent() = default; 20 | IDComponent(const IDComponent&) = default; 21 | }; 22 | 23 | struct TagComponent { 24 | std::string Tag; 25 | 26 | TagComponent() = default; 27 | TagComponent(const TagComponent&) = default; 28 | TagComponent(const std::string& tag) 29 | :Tag(tag) {} 30 | }; 31 | 32 | struct TransformComponent { 33 | glm::vec3 Translation = { 0.0f, 0.0f, 0.0f }; 34 | glm::vec3 Rotation = { 0.0f, 0.0f, 0.0f }; 35 | glm::vec3 Scale = { 1.0f, 1.0f, 1.0f }; 36 | 37 | TransformComponent() = default; 38 | TransformComponent(const TransformComponent&) = default; 39 | TransformComponent(const glm::vec3& translation) 40 | :Translation(translation) {} 41 | 42 | glm::mat4 GetTransform() const { 43 | glm::mat4 rotation = glm::toMat4(glm::quat(Rotation)); 44 | 45 | return glm::translate(glm::mat4(1.0f), Translation) * rotation 46 | * glm::scale(glm::mat4(1.0f), Scale); 47 | } 48 | }; 49 | 50 | struct SpriteRendererComponent { 51 | glm::vec4 Color{ 1.0f, 1.0f, 1.0f, 1.0f }; 52 | Ref Texture; 53 | float TilingFactor = 1.0f; 54 | 55 | SpriteRendererComponent() = default; 56 | SpriteRendererComponent(const SpriteRendererComponent&) = default; 57 | SpriteRendererComponent(const glm::vec4& color) 58 | :Color(color) { 59 | Texture = nullptr; 60 | } 61 | SpriteRendererComponent(const glm::vec4& color, const Ref& texture) 62 | :Color(color), Texture(texture) {} 63 | }; 64 | 65 | struct CameraComponent { 66 | SceneCamera Camera; 67 | 68 | bool Primary = true; // TODO: think about moving to Scene 69 | bool FixedAspectRatio = false; 70 | 71 | CameraComponent() = default; 72 | CameraComponent(const CameraComponent&) = default; 73 | }; 74 | 75 | class ScriptableEntity; 76 | 77 | struct NativeScriptComponent { 78 | ScriptableEntity* Instance = nullptr; 79 | 80 | ScriptableEntity* (*InstantiateScript)(); 81 | void (*DestroyScript)(NativeScriptComponent*); 82 | 83 | template 84 | void Bind() { 85 | InstantiateScript = []() { return static_cast(new T()); }; 86 | DestroyScript = [](NativeScriptComponent* nsc) { delete nsc->Instance; nsc->Instance = nullptr; }; 87 | } 88 | }; 89 | 90 | // Physics 91 | 92 | struct Rigidbody2DComponent { 93 | enum class BodyType { Static = 0, Dynamic, Kinematic }; 94 | BodyType Type = BodyType::Static; 95 | bool FixedRotation = false; 96 | 97 | // Storage for runtime 98 | void* RuntimeBody = nullptr; 99 | 100 | Rigidbody2DComponent() = default; 101 | Rigidbody2DComponent(const Rigidbody2DComponent&) = default; 102 | }; 103 | 104 | struct BoxCollider2DComponent { 105 | glm::vec2 Offset = { 0.0f, 0.0f }; 106 | glm::vec2 Size = { 0.5f, 0.5f }; 107 | 108 | float Density = 1.0f; 109 | float Friction = 0.5f; 110 | // Bounciness 111 | float Restitution = 0.0f; 112 | float RestitutionThreshold = 0.5f; 113 | 114 | // Storage for runtime 115 | void* RuntimeFixture = nullptr; 116 | 117 | BoxCollider2DComponent() = default; 118 | BoxCollider2DComponent(const BoxCollider2DComponent&) = default; 119 | }; 120 | 121 | 122 | 123 | // For internal use 124 | struct SceneComponent { 125 | UUID SceneID; 126 | }; 127 | } 128 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/Entity.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Scene/Entity.h" 3 | 4 | namespace Ghost { 5 | Entity::Entity(entt::entity handle, Scene* scene) 6 | :m_EntityHandle(handle), m_Scene(scene) 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/Entity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/UUID.h" 4 | #include "Ghost/Scene/Scene.h" 5 | #include "Ghost/Scene/Components.h" 6 | 7 | #include "entt.hpp" 8 | 9 | namespace Ghost 10 | { 11 | class Entity { 12 | public: 13 | Entity() = default; 14 | Entity(entt::entity handle, Scene* scene); 15 | Entity(const Entity& other) = default; 16 | 17 | template 18 | T& AddComponent(Args&&... args) { 19 | GT_CORE_ASSERT(!HasComponent(), "Entity already has component!"); 20 | T& component = m_Scene->m_Registry.emplace(m_EntityHandle, std::forward(args)...); 21 | m_Scene->OnComponentAdded(*this, component); 22 | return component; 23 | } 24 | 25 | template 26 | T& AddOrReplaceComponent(Args&&... args) { 27 | T& component = m_Scene->m_Registry.emplace_or_replace(m_EntityHandle, std::forward(args)...); 28 | m_Scene->OnComponentAdded(*this, component); 29 | return component; 30 | } 31 | 32 | template 33 | T& GetComponent() { 34 | GT_CORE_ASSERT(HasComponent(), "Entity does not have component!"); 35 | return m_Scene->m_Registry.get(m_EntityHandle); 36 | } 37 | 38 | template 39 | bool HasComponent() { 40 | return m_Scene->m_Registry.all_of(m_EntityHandle); 41 | } 42 | 43 | template 44 | void RemoveComponent() { 45 | GT_CORE_ASSERT(HasComponent(), "Entity does not have component!"); 46 | m_Scene->m_Registry.remove(m_EntityHandle); 47 | } 48 | 49 | operator bool() const { return m_EntityHandle != entt::null; } 50 | operator entt::entity() const { return m_EntityHandle; } 51 | operator uint32_t() const { return (uint32_t)m_EntityHandle; } 52 | 53 | UUID GetUUID() { return GetComponent().ID; } 54 | const std::string& GetName() { return GetComponent().Tag; } 55 | 56 | bool operator==(const Entity& other) const { 57 | return m_EntityHandle == other.m_EntityHandle && m_Scene == other.m_Scene; 58 | } 59 | 60 | bool operator!= (const Entity& other) const { 61 | return !(*this == other); 62 | } 63 | 64 | private: 65 | entt::entity m_EntityHandle{ entt::null }; 66 | Scene* m_Scene; // 12 bytes of memory 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/Scene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "entt.hpp" 4 | 5 | #include "Ghost/Core/Timestep.h" 6 | #include "Ghost/Core/UUID.h" 7 | #include "Ghost/Renderer/EditorCamera.h" 8 | 9 | class b2World; 10 | 11 | namespace Ghost 12 | { 13 | class Entity; 14 | 15 | class Scene { 16 | public: 17 | Scene(); 18 | ~Scene(); 19 | 20 | static Ref Copy(Refother); 21 | 22 | Entity CreateEntity(const std::string& name = std::string()); 23 | Entity CreateEntityWithUUID(UUID uuid, const std::string& name = std::string()); 24 | void DestroyEntity(Entity entity); 25 | 26 | void OnRuntimeStart(); 27 | void OnRuntimeStop(); 28 | 29 | void OnUpdateRuntime(Timestep ts); 30 | void OnUpdateEditor(Timestep ts, EditorCamera& camera); 31 | void OnViewportResize(uint32_t width, uint32_t height); 32 | 33 | void DuplicateEntity(Entity entity); 34 | 35 | Entity GetPrimaryCameraEntity(); 36 | private: 37 | template 38 | void OnComponentAdded(Entity entity, T& component); 39 | private: 40 | UUID m_SceneID; 41 | entt::registry m_Registry; 42 | uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0; 43 | 44 | entt::entity m_SceneEntity; 45 | 46 | b2World* m_PhysicsWorld = nullptr; 47 | 48 | friend class Entity; 49 | friend class SceneSerializer; 50 | friend class SceneHierarchyPanel; 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/SceneCamera.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #include "Ghost/Scene/SceneCamera.h" 4 | 5 | #include 6 | 7 | namespace Ghost 8 | { 9 | SceneCamera::SceneCamera() { 10 | RecalculateProjection(); 11 | } 12 | 13 | void SceneCamera::SetPerspective(float verticalFOV, float nearClip, float farClip) { 14 | m_ProjectionType = ProjectionType::Perspective; 15 | 16 | m_PerspectiveFOV = verticalFOV; 17 | m_PerspectiveNear = nearClip; 18 | m_PerspectiveFar = farClip; 19 | 20 | RecalculateProjection(); 21 | } 22 | 23 | void SceneCamera::SetOrthographic(float size, float nearClip, float farClip) { 24 | m_ProjectionType = ProjectionType::Orthographic; 25 | 26 | m_OrthographicSize = size; 27 | m_OrthographicNear = nearClip; 28 | m_OrthographicFar = farClip; 29 | 30 | RecalculateProjection(); 31 | } 32 | 33 | void SceneCamera::SetViewportSize(uint32_t width, uint32_t height) { 34 | GT_CORE_ASSERT(width > 0 && height > 0); 35 | m_AspectRatio = (float)width / (float)height; 36 | RecalculateProjection(); 37 | } 38 | 39 | void SceneCamera::RecalculateProjection() { 40 | if (m_ProjectionType == ProjectionType::Perspective) 41 | { 42 | m_Projection = glm::perspective(m_PerspectiveFOV, m_AspectRatio, m_PerspectiveNear, m_PerspectiveFar); 43 | } 44 | else 45 | { 46 | float orthoLeft = -m_OrthographicSize * m_AspectRatio * 0.5f; 47 | float orthoRight = m_OrthographicSize * m_AspectRatio * 0.5f; 48 | float orthoBottom = -m_OrthographicSize * 0.5f; 49 | float orthoTop = m_OrthographicSize * 0.5f; 50 | 51 | m_Projection = glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, m_OrthographicNear, m_OrthographicFar); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/SceneCamera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Camera/Camera.h" 4 | 5 | namespace Ghost { 6 | class SceneCamera : public Camera { 7 | public: 8 | enum class ProjectionType { Perspective = 0, Orthographic = 1 }; 9 | public: 10 | SceneCamera(); 11 | virtual ~SceneCamera() = default; 12 | 13 | void SetPerspective(float verticalFOV, float nearClip, float farClip); 14 | void SetOrthographic(float size, float nearClip, float farClip); 15 | 16 | void SetViewportSize(uint32_t width, uint32_t height); 17 | 18 | float GetPerspectiveVerticalFOV() const { return m_PerspectiveFOV; } 19 | void SetPerspectiveVerticalFOV(float verticalFov) { m_PerspectiveFOV = verticalFov, RecalculateProjection(); } 20 | float GetPerspectiveNearClip() const { return m_PerspectiveNear; } 21 | void SetPerspectiveNearClip(float nearClip) { m_PerspectiveNear = nearClip, RecalculateProjection(); } 22 | float GetPerspectiveFarClip() const { return m_PerspectiveFar; } 23 | void SetPerspectiveFarClip(float farClip) { m_PerspectiveFar = farClip, RecalculateProjection(); } 24 | 25 | float GetOrthographicSize() const { return m_OrthographicSize; } 26 | void SetOrthographicSize(float size) { m_OrthographicSize = size; RecalculateProjection(); } 27 | float GetOrthographicNearClip() const { return m_OrthographicNear; } 28 | void SetOrthographicNearClip(float nearClip) { m_OrthographicNear = nearClip; RecalculateProjection(); } 29 | float GetOrthographicFarClip() const { return m_OrthographicFar; } 30 | void SetOrthographicFarClip(float farClip) { m_OrthographicFar = farClip; RecalculateProjection(); } 31 | 32 | ProjectionType GetProjectionType() const { return m_ProjectionType; } 33 | void SetProjectionType(ProjectionType type) { m_ProjectionType = type; RecalculateProjection(); } 34 | 35 | private: 36 | void RecalculateProjection(); 37 | private: 38 | ProjectionType m_ProjectionType = ProjectionType::Orthographic; 39 | 40 | float m_PerspectiveFOV = glm::radians(45.0f); 41 | float m_PerspectiveNear = 0.01f, m_PerspectiveFar = 1000.0f; 42 | 43 | float m_OrthographicSize = 10.0f; 44 | float m_OrthographicNear = -1.0f, m_OrthographicFar = 1.0f; 45 | 46 | float m_AspectRatio = 1.0f; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/SceneSerializer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Scene/Scene.h" 4 | 5 | namespace Ghost { 6 | class SceneSerializer 7 | { 8 | public: 9 | SceneSerializer(const Ref& scene); 10 | 11 | void Serialize(const std::string& filepath); 12 | void SerializeRuntime(const std::string& filepath); 13 | 14 | bool Deserialize(const std::string& filepath); 15 | bool DeserializeRuntime(const std::string& filepath); 16 | private: 17 | Ref m_Scene; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /Ghost/src/Ghost/Scene/ScriptableEntity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Scene/Entity.h" 4 | 5 | namespace Ghost { 6 | class ScriptableEntity { 7 | public: 8 | virtual ~ScriptableEntity() {} 9 | 10 | template 11 | T& GetComponent() { 12 | return m_Entity.GetComponent(); 13 | } 14 | protected: 15 | virtual void OnCreate() {} 16 | virtual void OnDestroy() {} 17 | virtual void OnUpdate(Timestep ts) {} 18 | 19 | private: 20 | Entity m_Entity; 21 | friend class Scene; 22 | }; 23 | } -------------------------------------------------------------------------------- /Ghost/src/Ghost/Utils/PlatformUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Ghost 6 | { 7 | class FileDialogs { 8 | public: 9 | // These return empty strings if cancelled 10 | static std::string OpenFile(const char* filter); 11 | static std::string SaveFile(const char* filter); 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLBuffer.h" 3 | 4 | #include 5 | 6 | namespace Ghost { 7 | #pragma region VertexBuffer 8 | 9 | OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size) 10 | { 11 | GT_PROFILE_FUNCTION(); 12 | 13 | glCreateBuffers(1, &m_RendererID); 14 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 15 | glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); 16 | } 17 | 18 | OpenGLVertexBuffer::OpenGLVertexBuffer(float* vertices, uint32_t size) 19 | { 20 | GT_PROFILE_FUNCTION(); 21 | 22 | glCreateBuffers(1, &m_RendererID); 23 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 24 | glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); 25 | } 26 | 27 | OpenGLVertexBuffer::~OpenGLVertexBuffer() { 28 | GT_PROFILE_FUNCTION(); 29 | 30 | glDeleteBuffers(1, &m_RendererID); 31 | } 32 | 33 | void OpenGLVertexBuffer::Bind() const 34 | { 35 | GT_PROFILE_FUNCTION(); 36 | 37 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 38 | } 39 | 40 | void OpenGLVertexBuffer::Unbind() const 41 | { 42 | GT_PROFILE_FUNCTION(); 43 | 44 | glBindBuffer(GL_ARRAY_BUFFER, 0); 45 | } 46 | 47 | void OpenGLVertexBuffer::SetData(const void* data, uint32_t size) 48 | { 49 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 50 | glBufferSubData(GL_ARRAY_BUFFER, 0, size, data); 51 | } 52 | 53 | #pragma endregion 54 | 55 | #pragma region IndexBuffer 56 | 57 | OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t* indices, uint32_t count) 58 | :m_Count(count) 59 | { 60 | GT_PROFILE_FUNCTION(); 61 | 62 | glCreateBuffers(1, &m_RendererID); 63 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 64 | glBufferData(GL_ARRAY_BUFFER, count * sizeof(uint32_t), indices, GL_STATIC_DRAW); 65 | } 66 | 67 | OpenGLIndexBuffer::~OpenGLIndexBuffer() 68 | { 69 | GT_PROFILE_FUNCTION(); 70 | 71 | glDeleteBuffers(1, &m_RendererID); 72 | } 73 | 74 | void OpenGLIndexBuffer::Bind() const 75 | { 76 | GT_PROFILE_FUNCTION(); 77 | 78 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID); 79 | } 80 | 81 | void OpenGLIndexBuffer::Unbind() const 82 | { 83 | GT_PROFILE_FUNCTION(); 84 | 85 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 86 | } 87 | 88 | #pragma endregion 89 | } -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/Buffer.h" 4 | 5 | namespace Ghost { 6 | class OpenGLVertexBuffer : public VertexBuffer { 7 | public: 8 | OpenGLVertexBuffer(uint32_t size); 9 | OpenGLVertexBuffer(float* vertices, uint32_t size); 10 | virtual ~OpenGLVertexBuffer(); 11 | 12 | virtual void Bind() const override; 13 | virtual void Unbind() const override; 14 | 15 | virtual void SetData(const void* data, uint32_t size) override; 16 | 17 | virtual const BufferLayout& GetLayout() const override { return m_Layout; } 18 | virtual void SetLayout(const BufferLayout& layout) override { m_Layout = layout; } 19 | private: 20 | uint32_t m_RendererID; 21 | BufferLayout m_Layout; 22 | }; 23 | 24 | class OpenGLIndexBuffer : public IndexBuffer { 25 | public: 26 | OpenGLIndexBuffer(uint32_t* indices, uint32_t count); 27 | virtual ~OpenGLIndexBuffer(); 28 | 29 | virtual void Bind() const override; 30 | virtual void Unbind() const override; 31 | 32 | virtual uint32_t GetCount() const { return m_Count; } 33 | private: 34 | uint32_t m_RendererID; 35 | uint32_t m_Count; 36 | }; 37 | } -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLContext.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLContext.h" 3 | 4 | #include 5 | #include 6 | 7 | namespace Ghost { 8 | OpenGLContext::OpenGLContext(GLFWwindow* windowHandle) 9 | :m_WindowHandle(windowHandle) 10 | { 11 | GT_CORE_ASSERT(windowHandle, "Window handle is null!"); 12 | } 13 | 14 | void OpenGLContext::Init() 15 | { 16 | GT_PROFILE_FUNCTION(); 17 | 18 | glfwMakeContextCurrent(m_WindowHandle); 19 | int status = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); 20 | GT_CORE_ASSERT(status, "Failed to initialize Glad!"); 21 | 22 | GT_CORE_INFO("Vendor : {0}", glGetString(GL_VENDOR)); 23 | GT_CORE_INFO("Hardware : {0}", glGetString(GL_RENDERER)); 24 | GT_CORE_INFO("OpenGL Version : {0}", glGetString(GL_VERSION)); 25 | 26 | m_ContextInfo.Vendor = (unsigned char*)glGetString(GL_VENDOR); 27 | m_ContextInfo.Renderer = (unsigned char*)glGetString(GL_RENDERER); 28 | m_ContextInfo.Version = (unsigned char*)glGetString(GL_VERSION); 29 | 30 | #ifdef GT_ENABLE_ASSERTS 31 | int versionMajor; 32 | int versionMinor; 33 | glGetIntegerv(GL_MAJOR_VERSION, &versionMajor); 34 | glGetIntegerv(GL_MINOR_VERSION, &versionMinor); 35 | 36 | GT_CORE_ASSERT(versionMajor > 4 || (versionMajor == 4 && versionMinor >= 5), "Ghost requires atleast OpenGL version 4.5"); 37 | #endif // GT_ENABLE_ASSERTS 38 | GT_CORE_ASSERT(GLVersion.major > 4 || (GLVersion.major == 4 && GLVersion.minor >= 5), 39 | "Ghost requires atleast OpenGL version 4.5"); 40 | } 41 | 42 | void OpenGLContext::SwapBuffers() 43 | { 44 | GT_PROFILE_FUNCTION(); 45 | 46 | glfwSwapBuffers(m_WindowHandle); 47 | } 48 | 49 | ContextInfo OpenGLContext::GetContextInfo() 50 | { 51 | return m_ContextInfo; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLContext.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/GraphicsContext.h" 4 | 5 | struct GLFWwindow; // Forward Declaration 6 | 7 | namespace Ghost { 8 | class OpenGLContext : public GraphicsContext { 9 | public: 10 | OpenGLContext(GLFWwindow* windowHandle); 11 | 12 | virtual void Init() override; 13 | virtual void SwapBuffers() override; 14 | 15 | virtual ContextInfo GetContextInfo() override; 16 | 17 | private: 18 | GLFWwindow* m_WindowHandle; 19 | ContextInfo m_ContextInfo; 20 | }; 21 | } -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLFramebuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/Framebuffer.h" 4 | 5 | namespace Ghost 6 | { 7 | class OpenGLFramebuffer : public Framebuffer { 8 | public: 9 | OpenGLFramebuffer(const FramebufferSpecification& spec); 10 | virtual ~OpenGLFramebuffer(); 11 | 12 | void Invalidate(); 13 | 14 | virtual void Bind() override; 15 | virtual void Unbind() override; 16 | 17 | virtual void Resize(uint32_t width, uint32_t height) override; 18 | virtual int ReadPixel(uint32_t attachmentIndex, int x, int y) override; 19 | 20 | virtual void ClearAttachment(uint32_t attachmentIndex, int value) override; 21 | 22 | virtual uint32_t GetColorAttachmentRendererID(uint32_t index = 0) const override { 23 | GT_CORE_ASSERT(index < m_ColorAttachments.size()); 24 | return m_ColorAttachments[index]; 25 | } 26 | 27 | virtual const FramebufferSpecification& GetSpecification() const override { return m_Specification; } 28 | private: 29 | uint32_t m_RendererID = 0; 30 | FramebufferSpecification m_Specification; 31 | 32 | std::vector m_ColorAttachmentSpecifications; 33 | FramebufferTextureSpecification m_DepthAttachmentSpecification = FramebufferTextureFormat::None; 34 | 35 | std::vector m_ColorAttachments; 36 | uint32_t m_DepthAttachment = 0; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLRendererAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLRendererAPI.h" 3 | 4 | #include 5 | 6 | namespace Ghost { 7 | void OpenGLMessageCallback( 8 | unsigned source, 9 | unsigned type, 10 | unsigned id, 11 | unsigned severity, 12 | int length, 13 | const char* message, 14 | const void* userParam) 15 | { 16 | switch (severity) 17 | { 18 | case GL_DEBUG_SEVERITY_HIGH: return; 19 | case GL_DEBUG_SEVERITY_MEDIUM: return; 20 | case GL_DEBUG_SEVERITY_LOW: return; 21 | case GL_DEBUG_SEVERITY_NOTIFICATION: return; 22 | } 23 | 24 | GT_CORE_ASSERT(false, "Unknown severity level!"); 25 | } 26 | 27 | void OpenGLRendererAPI::Init() 28 | { 29 | #ifdef GT_DEBUG 30 | glEnable(GL_DEBUG_OUTPUT); 31 | glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); 32 | glDebugMessageCallback(OpenGLMessageCallback, nullptr); 33 | 34 | glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE); 35 | #endif // GT_DEBUG 36 | 37 | glEnable(GL_BLEND); 38 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 39 | 40 | glEnable(GL_DEPTH_TEST); 41 | } 42 | 43 | void OpenGLRendererAPI::SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) 44 | { 45 | glViewport(x, y, width, height); 46 | } 47 | 48 | void OpenGLRendererAPI::SetClearColor(const glm::vec4& color) 49 | { 50 | glClearColor(color.r, color.g, color.b, color.a); 51 | } 52 | 53 | void OpenGLRendererAPI::Clear() 54 | { 55 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 56 | } 57 | 58 | void OpenGLRendererAPI::DrawIndexed(const Ref& vertexArray, uint32_t indexCount) 59 | { 60 | uint32_t count = indexCount ? indexCount : vertexArray->GetIndexBuffer()->GetCount(); 61 | glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr); 62 | glBindTexture(GL_TEXTURE_2D, 0); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLRendererAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/RendererAPI.h" 4 | 5 | namespace Ghost { 6 | class OpenGLRendererAPI : public RendererAPI { 7 | public: 8 | virtual void Init() override; 9 | virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; 10 | 11 | virtual void SetClearColor(const glm::vec4& color) override; 12 | virtual void Clear() override; 13 | 14 | virtual void DrawIndexed(const Ref& vertexArray, uint32_t indexCount = 0) override; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLShader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/Shader.h" 4 | 5 | #include 6 | 7 | // TODO: REMOVE! 8 | typedef unsigned int GLenum; 9 | 10 | namespace Ghost 11 | { 12 | class OpenGLShader : public Shader { 13 | public: 14 | OpenGLShader(const std::string& filepath); 15 | OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); 16 | virtual ~OpenGLShader(); 17 | 18 | virtual void Bind() const override; 19 | virtual void Unbind() const override; 20 | 21 | virtual void SetInt(const std::string& name, int value) override; 22 | virtual void SetIntArray(const std::string& name, int* values, uint32_t count) override; 23 | virtual void SetFloat(const std::string& name, float value) override; 24 | virtual void SetFloat2(const std::string& name, const glm::vec2& value) override; 25 | virtual void SetFloat3(const std::string& name, const glm::vec3& value) override; 26 | virtual void SetFloat4(const std::string& name, const glm::vec4& value) override; 27 | virtual void SetMat4(const std::string& name, const glm::mat4& value) override; 28 | 29 | virtual const std::string& GetName() const override { return m_Name; } 30 | 31 | void UploadUniformInt(const std::string& name, int value); 32 | void UploadUniformIntArray(const std::string& name, int* values, uint32_t count); 33 | 34 | void UploadUniformFloat(const std::string& name, float value); 35 | void UploadUniformFloat2(const std::string& name, const glm::vec2& values); 36 | void UploadUniformFloat3(const std::string& name, const glm::vec3& values); 37 | void UploadUniformFloat4(const std::string& name, const glm::vec4& values); 38 | 39 | void UploadUniformMat3(const std::string& name, const glm::mat3& matrix); 40 | void UploadUniformMat4(const std::string& name, const glm::mat4& matrix); 41 | 42 | private: 43 | std::string ReadFile(const std::string& filepath); 44 | std::unordered_map PreProcess(const std::string& source); 45 | 46 | void CompileOrGetVulkanBinaries(const std::unordered_map& shaderSources); 47 | void CompileOrGetOpenGLBinaries(); 48 | void CreateProgram(); 49 | void Reflect(GLenum stage, const std::vector& shaderData); 50 | 51 | private: 52 | uint32_t m_RendererID; 53 | std::string m_FilePath; 54 | std::string m_Name; 55 | 56 | std::unordered_map> m_VulkanSPIRV; 57 | std::unordered_map> m_OpenGLSPIRV; 58 | 59 | std::unordered_map m_OpenGLSourceCode; 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLTexture.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLTexture.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace Ghost 9 | { 10 | OpenGLTexture2D::OpenGLTexture2D(uint32_t width, uint32_t height) 11 | :m_Width(width), m_Height(height) { 12 | GT_PROFILE_FUNCTION(); 13 | 14 | m_InternalFormat = GL_RGBA8; 15 | m_DataFormat = GL_RGBA; 16 | 17 | glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID); 18 | glTextureStorage2D(m_RendererID, 1, m_InternalFormat, m_Width, m_Height); 19 | 20 | glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 21 | glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 22 | 23 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT); 24 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); 25 | } 26 | 27 | OpenGLTexture2D::OpenGLTexture2D(const std::string& path) 28 | :m_Path(path) { 29 | GT_PROFILE_FUNCTION(); 30 | 31 | int width, height, channels; 32 | stbi_set_flip_vertically_on_load(1); 33 | 34 | stbi_uc* data = nullptr; 35 | { 36 | GT_PROFILE_SCOPE("stbi_load - OpenGLTexture2D::OpenGLTexture2D(const std::string&)"); 37 | data = stbi_load(path.c_str(), &width, &height, &channels, 0); 38 | } 39 | 40 | if (data) 41 | { 42 | m_IsLoaded = true; 43 | 44 | m_Width = width; 45 | m_Height = height; 46 | 47 | GLenum internalFormat = 0, dataFormat = 0; 48 | if (channels == 4) 49 | { 50 | internalFormat = GL_RGBA8; 51 | dataFormat = GL_RGBA; 52 | } 53 | else if (channels == 3) 54 | { 55 | internalFormat = GL_RGB8; 56 | dataFormat = GL_RGB; 57 | } 58 | 59 | m_InternalFormat = internalFormat; 60 | m_DataFormat = dataFormat; 61 | 62 | GT_CORE_ASSERT(internalFormat & dataFormat, "Format not supported!"); 63 | 64 | glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID); 65 | glTextureStorage2D(m_RendererID, 1, internalFormat, m_Width, m_Height); 66 | 67 | glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 68 | glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 69 | 70 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT); 71 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); 72 | 73 | glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, dataFormat, GL_UNSIGNED_BYTE, data); 74 | 75 | stbi_image_free(data); 76 | } 77 | } 78 | 79 | OpenGLTexture2D::~OpenGLTexture2D() { 80 | GT_PROFILE_FUNCTION(); 81 | 82 | glDeleteTextures(1, &m_RendererID); 83 | } 84 | 85 | void OpenGLTexture2D::SetData(void* data, uint32_t size) { 86 | GT_PROFILE_FUNCTION(); 87 | 88 | uint32_t bpp = m_DataFormat == GL_RGBA ? 4 : 3; // Bytes per pixel 89 | GT_CORE_ASSERT(size == m_Width * m_Height * bpp, "Data must be entire texture!"); 90 | glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_DataFormat, GL_UNSIGNED_BYTE, data); 91 | } 92 | 93 | void OpenGLTexture2D::Bind(uint32_t slot) const { 94 | GT_PROFILE_FUNCTION(); 95 | 96 | glBindTextureUnit(slot, m_RendererID); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLTexture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/Texture.h" 4 | 5 | #include 6 | 7 | namespace Ghost 8 | { 9 | class OpenGLTexture2D : public Texture2D { 10 | public: 11 | OpenGLTexture2D(uint32_t width, uint32_t height); 12 | OpenGLTexture2D(const std::string& path); 13 | virtual ~OpenGLTexture2D(); 14 | 15 | virtual uint32_t GetWidth() const override { return m_Width; } 16 | virtual uint32_t GetHeight() const override { return m_Height; } 17 | virtual uint32_t GetRendererID() const override { return m_RendererID; } 18 | 19 | virtual void SetData(void* data, uint32_t size) override; 20 | 21 | virtual void Bind(uint32_t slot = 0) const override; 22 | 23 | virtual bool IsLoaded() const override { return m_IsLoaded; } 24 | 25 | virtual bool operator==(const Texture& other) const override { 26 | return m_RendererID == ((OpenGLTexture2D&)other).m_RendererID; 27 | } 28 | 29 | private: 30 | std::string m_Path; 31 | bool m_IsLoaded = false; 32 | uint32_t m_Width, m_Height; 33 | uint32_t m_RendererID; 34 | GLenum m_InternalFormat, m_DataFormat; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLUniformBuffer.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLUniformBuffer.h" 3 | 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | OpenGLUniformBuffer::OpenGLUniformBuffer(uint32_t size, uint32_t binding) { 9 | glCreateBuffers(1, &m_RendererID); 10 | glNamedBufferData(m_RendererID, size, nullptr, GL_DYNAMIC_DRAW); // TODO: investigate usage hint 11 | glBindBufferBase(GL_UNIFORM_BUFFER, binding, m_RendererID); 12 | } 13 | 14 | OpenGLUniformBuffer::~OpenGLUniformBuffer() { 15 | glDeleteBuffers(1, &m_RendererID); 16 | } 17 | 18 | void OpenGLUniformBuffer::SetData(const void* data, uint32_t size, uint32_t offset) { 19 | glNamedBufferSubData(m_RendererID, offset, size, data); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLUniformBuffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/UniformBuffer.h" 4 | 5 | namespace Ghost 6 | { 7 | class OpenGLUniformBuffer : public UniformBuffer { 8 | public: 9 | OpenGLUniformBuffer(uint32_t size, uint32_t binding); 10 | virtual ~OpenGLUniformBuffer(); 11 | 12 | virtual void SetData(const void* data, uint32_t size, uint32_t offset = 0) override; 13 | 14 | private: 15 | uint32_t m_RendererID = 0; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLVertexArray.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/OpenGL/OpenGLVertexArray.h" 3 | 4 | #include 5 | 6 | namespace Ghost 7 | { 8 | static GLenum ShaderDataTypeToOpenGLBaseType(ShaderDataType type) { 9 | switch (type) 10 | { 11 | case ShaderDataType::Float: return GL_FLOAT; 12 | case ShaderDataType::Float2: return GL_FLOAT; 13 | case ShaderDataType::Float3: return GL_FLOAT; 14 | case ShaderDataType::Float4: return GL_FLOAT; 15 | case ShaderDataType::Mat3: return GL_FLOAT; 16 | case ShaderDataType::Mat4: return GL_FLOAT; 17 | case ShaderDataType::Int: return GL_INT; 18 | case ShaderDataType::Int2: return GL_INT; 19 | case ShaderDataType::Int3: return GL_INT; 20 | case ShaderDataType::Int4: return GL_INT; 21 | case ShaderDataType::Bool: return GL_BOOL; 22 | } 23 | 24 | GT_CORE_ASSERT(false, "Unknown ShaderDataType"); 25 | return 0; 26 | } 27 | 28 | OpenGLVertexArray::OpenGLVertexArray() { 29 | GT_PROFILE_FUNCTION(); 30 | 31 | glCreateVertexArrays(1, &m_RendererID); 32 | } 33 | 34 | OpenGLVertexArray::~OpenGLVertexArray() { 35 | GT_PROFILE_FUNCTION(); 36 | 37 | glDeleteVertexArrays(1, &m_RendererID); 38 | } 39 | 40 | void OpenGLVertexArray::Bind() const { 41 | GT_PROFILE_FUNCTION(); 42 | 43 | glBindVertexArray(m_RendererID); 44 | } 45 | 46 | void OpenGLVertexArray::Unbind() const { 47 | GT_PROFILE_FUNCTION(); 48 | 49 | glBindVertexArray(0); 50 | } 51 | 52 | void OpenGLVertexArray::AddVertexBuffer(const Ref& vertexBuffer) { 53 | GT_PROFILE_FUNCTION(); 54 | 55 | GT_CORE_ASSERT(vertexBuffer->GetLayout().GetElements().size(), "Vertex Buffer has no layout!"); 56 | 57 | glBindVertexArray(m_RendererID); 58 | vertexBuffer->Bind(); 59 | 60 | const auto& layout = vertexBuffer->GetLayout(); 61 | for (const auto& element : layout) 62 | { 63 | switch (element.Type) 64 | { 65 | case ShaderDataType::Float: 66 | case ShaderDataType::Float2: 67 | case ShaderDataType::Float3: 68 | case ShaderDataType::Float4: 69 | { 70 | glEnableVertexAttribArray(m_VertexBufferIndex); 71 | glVertexAttribPointer(m_VertexBufferIndex, 72 | element.GetComponentCount(), 73 | ShaderDataTypeToOpenGLBaseType(element.Type), 74 | element.Normalized ? GL_TRUE : GL_FALSE, 75 | layout.GetStride(), 76 | (const void*)element.Offset); 77 | m_VertexBufferIndex++; 78 | break; 79 | } 80 | case ShaderDataType::Bool: 81 | { 82 | glEnableVertexAttribArray(m_VertexBufferIndex); 83 | glVertexAttribIPointer(m_VertexBufferIndex, 84 | element.GetComponentCount(), 85 | ShaderDataTypeToOpenGLBaseType(element.Type), 86 | layout.GetStride(), 87 | (const void*)element.Offset); 88 | m_VertexBufferIndex++; 89 | break; 90 | } 91 | case ShaderDataType::Mat3: 92 | case ShaderDataType::Mat4: 93 | { 94 | uint8_t count = element.GetComponentCount(); 95 | for (uint8_t i = 0; i < count; i++) 96 | { 97 | glEnableVertexAttribArray(m_VertexBufferIndex); 98 | glVertexAttribPointer(m_VertexBufferIndex, 99 | count, 100 | ShaderDataTypeToOpenGLBaseType(element.Type), 101 | element.Normalized ? GL_TRUE : GL_FALSE, 102 | layout.GetStride(), 103 | (const void*)(element.Offset + sizeof(float) * count * i)); 104 | glVertexAttribDivisor(m_VertexBufferIndex, 1); 105 | m_VertexBufferIndex++; 106 | } 107 | break; 108 | } 109 | case ShaderDataType::Int: 110 | case ShaderDataType::Int2: 111 | case ShaderDataType::Int3: 112 | case ShaderDataType::Int4: 113 | { 114 | glEnableVertexAttribArray(m_VertexBufferIndex); 115 | glVertexAttribIPointer(m_VertexBufferIndex, 116 | element.GetComponentCount(), 117 | ShaderDataTypeToOpenGLBaseType(element.Type), 118 | layout.GetStride(), 119 | (const void*)element.Offset); 120 | m_VertexBufferIndex++; 121 | break; 122 | } 123 | default: 124 | GT_CORE_ASSERT(false, "Unknown ShaderDataType!"); 125 | } 126 | } 127 | 128 | m_VertexBuffers.push_back(vertexBuffer); 129 | } 130 | 131 | void OpenGLVertexArray::SetIndexBuffer(const Ref& indexBuffer) { 132 | GT_PROFILE_FUNCTION(); 133 | 134 | glBindVertexArray(m_RendererID); 135 | indexBuffer->Bind(); 136 | 137 | m_IndexBuffer = indexBuffer; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Ghost/src/Platform/OpenGL/OpenGLVertexArray.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Renderer/VertexArray.h" 4 | 5 | namespace Ghost { 6 | class OpenGLVertexArray : public VertexArray { 7 | public: 8 | OpenGLVertexArray(); 9 | virtual ~OpenGLVertexArray(); 10 | 11 | virtual void Bind() const override; 12 | virtual void Unbind() const override; 13 | 14 | virtual void AddVertexBuffer(const Ref& vertexBuffer) override; 15 | virtual void SetIndexBuffer(const Ref& indexBuffer) override; 16 | 17 | virtual const std::vector>& GetVertexBuffers() const { return m_VertexBuffers; } 18 | virtual const Ref& GetIndexBuffer() const { return m_IndexBuffer; } 19 | 20 | private: 21 | uint32_t m_RendererID; 22 | uint32_t m_VertexBufferIndex = 0; 23 | std::vector> m_VertexBuffers; 24 | Ref m_IndexBuffer; 25 | }; 26 | } -------------------------------------------------------------------------------- /Ghost/src/Platform/Windows/WindowsInput.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #include "Ghost/Core/Input.h" 4 | #include "Ghost/Core/Application.h" 5 | 6 | #include 7 | 8 | namespace Ghost { 9 | static std::unordered_map s_KeyStateMap(0); 10 | static std::unordered_map s_MouseButtonStateMap(0); 11 | 12 | static std::vector s_AllKeys = 13 | { 14 | Key::Space, 15 | Key::Apostrophe, 16 | Key::Comma, 17 | Key::Minus, 18 | Key::Period, 19 | Key::Slash, 20 | Key::D0, 21 | Key::D1, 22 | Key::D2, 23 | Key::D3, 24 | Key::D4, 25 | Key::D5, 26 | Key::D6, 27 | Key::D7, 28 | Key::D8, 29 | Key::D9, 30 | Key::Semicolon, 31 | Key::Equal, 32 | Key::A, 33 | Key::B, 34 | Key::C, 35 | Key::D, 36 | Key::E, 37 | Key::F, 38 | Key::G, 39 | Key::H, 40 | Key::I, 41 | Key::J, 42 | Key::K, 43 | Key::L, 44 | Key::M, 45 | Key::N, 46 | Key::O, 47 | Key::P, 48 | Key::Q, 49 | Key::R, 50 | Key::S, 51 | Key::T, 52 | Key::U, 53 | Key::V, 54 | Key::W, 55 | Key::X, 56 | Key::Y, 57 | Key::Z, 58 | Key::LeftBracket, 59 | Key::Backslash, 60 | Key::RightBracket, 61 | Key::GraveAccent, 62 | Key::World1, 63 | Key::World2, 64 | Key::Escape, 65 | Key::Enter, 66 | Key::Tab, 67 | Key::Backspace, 68 | Key::Insert, 69 | Key::Delete, 70 | Key::Right, 71 | Key::Left, 72 | Key::Down, 73 | Key::Up, 74 | Key::PageUp, 75 | Key::PageDown, 76 | Key::Home, 77 | Key::End, 78 | Key::CapsLock, 79 | Key::ScrollLock, 80 | Key::NumLock, 81 | Key::PrintScreen, 82 | Key::Pause, 83 | Key::F1, 84 | Key::F2, 85 | Key::F3, 86 | Key::F4, 87 | Key::F5, 88 | Key::F6, 89 | Key::F7, 90 | Key::F8, 91 | Key::F9, 92 | Key::F10, 93 | Key::F11, 94 | Key::F12, 95 | Key::F13, 96 | Key::F14, 97 | Key::F15, 98 | Key::F16, 99 | Key::F17, 100 | Key::F18, 101 | Key::F19, 102 | Key::F20, 103 | Key::F21, 104 | Key::F22, 105 | Key::F23, 106 | Key::F24, 107 | Key::F25, 108 | Key::KP0, 109 | Key::KP1, 110 | Key::KP2, 111 | Key::KP3, 112 | Key::KP4, 113 | Key::KP5, 114 | Key::KP6, 115 | Key::KP7, 116 | Key::KP8, 117 | Key::KP9, 118 | Key::KPDecimal, 119 | Key::KPDivide, 120 | Key::KPMultiply, 121 | Key::KPSubtract, 122 | Key::KPAdd, 123 | Key::KPEnter, 124 | Key::KPEqual, 125 | Key::LeftShift, 126 | Key::LeftControl, 127 | Key::LeftAlt, 128 | Key::LeftSuper, 129 | Key::RightShift, 130 | Key::RightControl, 131 | Key::RightAlt, 132 | Key::RightSuper, 133 | Key::Menu 134 | }; 135 | 136 | static std::vector s_AllMouseButtons = 137 | { 138 | Mouse::Button0, 139 | Mouse::Button1, 140 | Mouse::Button2, 141 | Mouse::Button3, 142 | Mouse::Button4, 143 | Mouse::Button5, 144 | Mouse::Button6, 145 | Mouse::Button7 146 | }; 147 | 148 | bool Input::IsKeyPressed(const KeyCode keycode) 149 | { 150 | auto* window = static_cast(Application::Get().GetWindow().GetNativeWindow()); 151 | auto state = glfwGetKey(window, static_cast(keycode)); 152 | return state == GLFW_PRESS || state == GLFW_REPEAT; 153 | } 154 | 155 | bool Input::IsKeyDown(const KeyCode keycode) 156 | { 157 | return GetKey(keycode) && !s_KeyStateMap[keycode]; 158 | } 159 | 160 | bool Input::IsKeyUp(const KeyCode keycode) 161 | { 162 | return !GetKey(keycode) && s_KeyStateMap[keycode]; 163 | } 164 | 165 | bool Input::IsMouseButtonPressed(const MouseCode button) { 166 | auto* window = static_cast(Application::Get().GetWindow().GetNativeWindow()); 167 | auto state = glfwGetMouseButton(window, static_cast(button)); 168 | return state == GLFW_PRESS; 169 | } 170 | 171 | bool Input::IsMouseButtonDown(const MouseCode button) 172 | { 173 | return GetMouseButton(button) && !s_MouseButtonStateMap[button]; 174 | } 175 | 176 | bool Input::IsMouseButtonUp(const MouseCode button) 177 | { 178 | return !GetMouseButton(button) && s_MouseButtonStateMap[button]; 179 | } 180 | 181 | glm::vec2 Input::GetMousePosition() 182 | { 183 | auto* window = static_cast(Application::Get().GetWindow().GetNativeWindow()); 184 | double xpos, ypos; 185 | glfwGetCursorPos(window, &xpos, &ypos); 186 | return { (float)xpos,(float)ypos }; 187 | } 188 | 189 | float Input::GetMouseX() 190 | { 191 | return GetMousePosition().x; 192 | } 193 | 194 | float Input::GetMouseY() 195 | { 196 | return GetMousePosition().y; 197 | } 198 | 199 | bool Input::GetKey(const KeyCode keycode) 200 | { 201 | return glfwGetKey(static_cast(Application::Get().GetWindow().GetNativeWindow()), 202 | static_cast(keycode)) == GLFW_PRESS; 203 | } 204 | 205 | bool Input::GetMouseButton(const MouseCode mousecode) 206 | { 207 | return glfwGetMouseButton(static_cast(Application::Get().GetWindow().GetNativeWindow()), 208 | static_cast(mousecode)) == GLFW_PRESS; 209 | } 210 | 211 | void Input::OnUpdate() 212 | { 213 | for (KeyCode key : s_AllKeys) { 214 | s_KeyStateMap[key] = GetKey(key); 215 | } 216 | 217 | for (MouseCode mouseButton : s_AllMouseButtons) { 218 | s_MouseButtonStateMap[mouseButton] = GetMouseButton(mouseButton); 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /Ghost/src/Platform/Windows/WindowsPlatformUtils.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Ghost/Utils/PlatformUtils.h" 3 | #include "Ghost/Core/Application.h" 4 | 5 | #include 6 | #include 7 | 8 | #define GLFW_EXPOSE_NATIVE_WIN32 9 | #include 10 | 11 | namespace Ghost 12 | { 13 | std::string FileDialogs::OpenFile(const char* filter) { 14 | OPENFILENAMEA ofn; 15 | CHAR szFile[260] = { 0 }; 16 | CHAR currentDir[256] = { 0 }; 17 | 18 | ZeroMemory(&ofn, sizeof(OPENFILENAME)); 19 | ofn.lStructSize = sizeof(OPENFILENAME); 20 | ofn.hwndOwner = glfwGetWin32Window((GLFWwindow*)Application::Get().GetWindow().GetNativeWindow()); 21 | ofn.lpstrFile = szFile; 22 | ofn.nMaxFile = sizeof(szFile); 23 | 24 | if (GetCurrentDirectoryA(256, currentDir)) 25 | { 26 | ofn.lpstrInitialDir = currentDir; 27 | } 28 | 29 | ofn.lpstrFilter = filter; 30 | ofn.nFilterIndex = 1; 31 | ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; 32 | if (GetOpenFileNameA(&ofn) == TRUE) 33 | { 34 | return ofn.lpstrFile; 35 | } 36 | 37 | return std::string(); 38 | } 39 | 40 | std::string FileDialogs::SaveFile(const char* filter) { 41 | OPENFILENAMEA ofn; 42 | CHAR szFile[260] = { 0 }; 43 | CHAR currentDir[256] = { 0 }; 44 | 45 | ZeroMemory(&ofn, sizeof(OPENFILENAME)); 46 | ofn.lStructSize = sizeof(OPENFILENAME); 47 | ofn.hwndOwner = glfwGetWin32Window((GLFWwindow*)Application::Get().GetWindow().GetNativeWindow()); 48 | ofn.lpstrFile = szFile; 49 | ofn.nMaxFile = sizeof(szFile); 50 | 51 | if (GetCurrentDirectoryA(256, currentDir)) 52 | { 53 | ofn.lpstrInitialDir = currentDir; 54 | } 55 | 56 | ofn.lpstrFilter = filter; 57 | ofn.nFilterIndex = 1; 58 | 59 | // Sets the default extension by extracting it from the filter 60 | ofn.lpstrDefExt = strchr(filter, '\0') + 1; 61 | 62 | ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR; 63 | if (GetSaveFileNameA(&ofn) == TRUE) 64 | { 65 | return ofn.lpstrFile; 66 | } 67 | 68 | return std::string(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Ghost/src/Platform/Windows/WindowsWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | #include "Platform/Windows/WindowsWindow.h" 3 | 4 | #include "Ghost/Core/Input.h" 5 | 6 | #include "Ghost/Events/ApplicationEvent.h" 7 | #include "Ghost/Events/MouseEvent.h" 8 | #include "Ghost/Events/KeyEvent.h" 9 | 10 | #include "Platform/OpenGL/OpenGLContext.h" 11 | 12 | namespace Ghost { 13 | static uint8_t s_GLFWWindowCount = 0; 14 | 15 | static void GLFWErrorCallback(int error, const char* description) { 16 | GT_CORE_ERROR("GLFW Error ({0}): {1}", error, description); 17 | } 18 | 19 | WindowsWindow::WindowsWindow(const WindowProps& props) 20 | { 21 | GT_PROFILE_FUNCTION(); 22 | 23 | Init(props); 24 | } 25 | 26 | WindowsWindow::~WindowsWindow() 27 | { 28 | GT_PROFILE_FUNCTION(); 29 | 30 | Shutdown(); 31 | } 32 | 33 | void WindowsWindow::Init(const WindowProps& props) { 34 | GT_PROFILE_FUNCTION(); 35 | 36 | m_Data.Title = props.Title; 37 | m_Data.Width = props.Width; 38 | m_Data.Height = props.Height; 39 | 40 | GT_CORE_INFO("Creating window {0} ({1}, {2})", props.Title, props.Width, props.Height); 41 | 42 | if (s_GLFWWindowCount == 0) { 43 | GT_PROFILE_SCOPE("glfwInit"); 44 | int success = glfwInit(); 45 | GT_CORE_ASSERT(success, "Could not initialize GLFW!"); 46 | glfwSetErrorCallback(GLFWErrorCallback); 47 | } 48 | 49 | { 50 | GT_PROFILE_SCOPE("glfwCreateWindow"); 51 | m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr); 52 | ++s_GLFWWindowCount; 53 | } 54 | 55 | m_Context = GraphicsContext::Create(m_Window); 56 | m_Context->Init(); 57 | 58 | glfwSetWindowUserPointer(m_Window, &m_Data); 59 | SetVSync(true); 60 | 61 | // Set GLFW Callbacks 62 | glfwSetWindowSizeCallback(m_Window, [](GLFWwindow* window, int width, int height) { 63 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 64 | data.Width = width; 65 | data.Height = height; 66 | 67 | WindowResizeEvent event(width, height); 68 | data.EventCallback(event); 69 | }); 70 | 71 | glfwSetWindowCloseCallback(m_Window, [](GLFWwindow* window) { 72 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 73 | 74 | WindowCloseEvent event; 75 | data.EventCallback(event); 76 | }); 77 | 78 | glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { 79 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 80 | 81 | switch (action) { 82 | case GLFW_PRESS: { 83 | KeyPressedEvent event(key, 0); 84 | data.EventCallback(event); 85 | break; 86 | } 87 | case GLFW_RELEASE: { 88 | KeyReleasedEvent event(key); 89 | data.EventCallback(event); 90 | break; 91 | } 92 | case GLFW_REPEAT: { 93 | KeyPressedEvent event(key, 1); 94 | data.EventCallback(event); 95 | break; 96 | } 97 | } 98 | }); 99 | 100 | glfwSetCharCallback(m_Window, [](GLFWwindow* window, unsigned int keycode) { 101 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 102 | KeyTypedEvent event(keycode); 103 | data.EventCallback(event); 104 | }); 105 | 106 | glfwSetMouseButtonCallback(m_Window, [](GLFWwindow* window, int button, int action, int mods) { 107 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 108 | 109 | switch (action) 110 | { 111 | case GLFW_PRESS: { 112 | MouseButtonPressedEvent event(button); 113 | data.EventCallback(event); 114 | break; 115 | } 116 | case GLFW_RELEASE: { 117 | MouseButtonReleasedEvent event(button); 118 | data.EventCallback(event); 119 | break; 120 | } 121 | } 122 | }); 123 | 124 | glfwSetScrollCallback(m_Window, [](GLFWwindow* window, double xOffset, double yOffset) { 125 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 126 | 127 | MouseScrolledEvent event((float)xOffset, (float)yOffset); 128 | data.EventCallback(event); 129 | }); 130 | 131 | glfwSetCursorPosCallback(m_Window, [](GLFWwindow* window, double xPos, double yPos) { 132 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 133 | 134 | MouseMovedEvent event((float)xPos, (float)yPos); 135 | data.EventCallback(event); 136 | }); 137 | } 138 | 139 | void WindowsWindow::Shutdown() { 140 | GT_PROFILE_FUNCTION(); 141 | 142 | glfwDestroyWindow(m_Window); 143 | 144 | --s_GLFWWindowCount; 145 | if (s_GLFWWindowCount == 0) { 146 | GT_CORE_INFO("Terminating GLFW"); 147 | glfwTerminate(); 148 | } 149 | } 150 | 151 | void WindowsWindow::OnUpdate() { 152 | GT_PROFILE_FUNCTION(); 153 | 154 | glfwPollEvents(); 155 | m_Context->SwapBuffers(); 156 | } 157 | 158 | void WindowsWindow::SetVSync(bool enabled) { 159 | GT_PROFILE_FUNCTION(); 160 | 161 | if (enabled) { 162 | glfwSwapInterval(1); 163 | } 164 | else { 165 | glfwSwapInterval(0); 166 | } 167 | 168 | m_Data.VSync = enabled; 169 | } 170 | 171 | bool WindowsWindow::IsVSync() const 172 | { 173 | return m_Data.VSync; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Ghost/src/Platform/Windows/WindowsWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/Window.h" 4 | #include "Ghost/Renderer/GraphicsContext.h" 5 | 6 | #include "GLFW/glfw3.h" 7 | 8 | namespace Ghost { 9 | class WindowsWindow : public Window { 10 | public: 11 | WindowsWindow(const WindowProps& props); 12 | virtual ~WindowsWindow(); 13 | 14 | void OnUpdate() override; 15 | 16 | unsigned int GetWidth() const override { return m_Data.Width; } 17 | unsigned int GetHeight() const override { return m_Data.Height; } 18 | 19 | // Window Attributes 20 | void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; } 21 | void SetVSync(bool enabled) override; 22 | bool IsVSync() const override; 23 | 24 | virtual void* GetNativeWindow() const { return m_Window; } 25 | virtual ContextInfo GetGraphicsContextInfo() const { return m_Context->GetContextInfo(); } 26 | 27 | private: 28 | virtual void Init(const WindowProps& props); 29 | virtual void Shutdown(); 30 | private: 31 | GLFWwindow* m_Window; 32 | Scope m_Context; 33 | 34 | struct WindowData { 35 | std::string Title; 36 | unsigned int Width, Height; 37 | bool VSync; 38 | 39 | EventCallbackFn EventCallback; 40 | }; 41 | 42 | WindowData m_Data; 43 | }; 44 | } -------------------------------------------------------------------------------- /Ghost/src/gtpch.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" -------------------------------------------------------------------------------- /Ghost/src/gtpch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost/Core/PlatformDetection.h" 4 | 5 | #ifdef GT_PLATFORM_WINDOWS 6 | #ifndef NOMINMAX 7 | // See github.com/skypjack/entt/wiki/Frequently-Asked-Questions#warning-c4003-the-min-the-max-and-the-macro 8 | #define NOMINMAX 9 | #endif // !NOMINMAX 10 | 11 | #endif // GT_PLATFORM_WINDOWS 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "Ghost/Core/Base.h" 29 | 30 | #include "Ghost/Core/Log.h" 31 | #include "Ghost/ImGui/Utilities/ImGuiConsole.h" 32 | 33 | #include "Ghost/Debug/Instrumentor.h" 34 | 35 | #ifdef GT_PLATFORM_WINDOWS 36 | #include 37 | #endif // GT_PLATFORM_WINDOWS 38 | -------------------------------------------------------------------------------- /Ghost/vendor/Glad/Glad.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {89AF369E-F58E-B539-FEA6-40106A051C9B} 6 | 7 | 8 | {7D5AC031-E90F-3927-7204-33FEDEB82F2B} 9 | 10 | 11 | {30A0DB69-1C03-6B0E-C588-A3C4B1CA3691} 12 | 13 | 14 | {2DAB880B-99B4-887C-2230-9F7C8E38947C} 15 | 16 | 17 | 18 | 19 | include\KHR 20 | 21 | 22 | include\glad 23 | 24 | 25 | 26 | 27 | src 28 | 29 | 30 | -------------------------------------------------------------------------------- /Ghost/vendor/Glad/premake5.lua: -------------------------------------------------------------------------------- 1 | project "Glad" 2 | kind "StaticLib" 3 | language "C" 4 | staticruntime "off" 5 | 6 | targetdir ("bin/" .. outputdir .. "/%{prj.name}") 7 | objdir ("bin-int/" .. outputdir .. "/%{prj.name}") 8 | 9 | files 10 | { 11 | "include/glad/glad.h", 12 | "include/KHR/khrplatform.h", 13 | "src/glad.c" 14 | } 15 | 16 | includedirs 17 | { 18 | "include" 19 | } 20 | 21 | filter "system:windows" 22 | systemversion "latest" 23 | 24 | filter "configurations:Debug" 25 | runtime "Debug" 26 | symbols "on" 27 | 28 | filter "configurations:Release" 29 | runtime "Release" 30 | optimize "on" 31 | -------------------------------------------------------------------------------- /Ghost/vendor/entt/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2020 Michele Caini 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copy of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copy or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Ghost/vendor/stb_image/stb_image.cpp: -------------------------------------------------------------------------------- 1 | #include "gtpch.h" 2 | 3 | #define STB_IMAGE_IMPLEMENTATION 4 | #include "stb_image.h" -------------------------------------------------------------------------------- /Images/Screenshot_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Images/Screenshot_1.jpg -------------------------------------------------------------------------------- /Images/Screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Images/Screenshot_2.png -------------------------------------------------------------------------------- /Images/Screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Images/Screenshot_3.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ghost-Engine 2 | ### *A Work-In-Progress C++ game engine* 3 | 4 | *** 5 | 6 | **Description:** 7 | 8 | Ghost Engine is a **C++17** based game engine which 9 | uses **OpenGL** as it's rendering API. The project files can be easily generated 10 | using premake scripts. It supports basic features such as rendering - drawing quads, 11 | textures, handling input, logging support, ImGui UI panels and viewports. 12 | Scripts can be written in C++ inside the project itself, and attached to entities. 13 | 14 | Right now, this engine has been developed for the **Windows OS only**, with 15 | **Visual Studio 2019** as the IDE of choice. 16 | 17 | *** 18 | 19 | **Implemented Features:** 20 | 21 | * Premake Setup 22 | * Console Logging 23 | * Event System and Events 24 | * LayerStack and Layers 25 | * Internal Key, Mouse Codes and Input polling 26 | * Timesteps, Vsync, Delta Time 27 | * Visual Profiling (uses [Chrome Tracing](chrome://tracing)) 28 | * Modern OpenGL setup, using Glad 29 | * 2D Rendering pipeline - VertexBuffers, IndexBuffers, VertexArrays 30 | * ImGui, Docking, Frambuffers and ImGui Viewport 31 | * Shaders and Textures 32 | * Simplified API for drawing colored and textured quads 33 | * Entity Component System 34 | * Native C++ scripting 35 | * ImGui Console Logging 36 | * ImGui Scene Hierarchy Panel 37 | * ImGui Properties Panel 38 | * Scene Serialization and Deserialization using YAML 39 | * Editor Gizmos 40 | * Editor Camera 41 | 42 | *** 43 | 44 | **Cloning:** 45 | 46 | Clone this repository to a local destination using git: 47 | `git clone --recursive https://github.com/CybernetHacker14/Ghost-Engine` 48 | 49 | *** 50 | 51 | **Project Creation:** 52 | 53 | *Windows-* Run the `Setup.bat` file in `scripts` folder. 54 | This will generate a Visual Studio 2019 solution with appropriate settings, as well as download the required SPIR-V and Vulkan SDK libraries. 55 | 56 | *** 57 | 58 | **Technical Information:** 59 | 60 | *Supported IDEs:* 61 | * Visual Studio 2017 62 | * Visual Studio 2019 63 | 64 | *Languages:* 65 | * C++17 (Core) 66 | * GLSL (Shader Language) 67 | * Lua (Premake) 68 | 69 | *External Libraries Used:* 70 | * [GLFW](https://www.glfw.org/) 71 | * [Glad](https://glad.dav1d.de/) 72 | * [ImGui](https://github.com/ocornut/imgui) 73 | * [spdlog](https://github.com/gabime/spdlog) 74 | * [glm](https://glm.g-truc.net/0.9.9/index.html) 75 | * [stb_image](https://github.com/nothings/stb/blob/master/stb_image.h) 76 | * [entt](https://github.com/skypjack/entt) 77 | * [yaml-cpp](https://github.com/jbeder/yaml-cpp) 78 | * [IconFontCppHeaders](https://github.com/juliettef/IconFontCppHeaders) 79 | * [ImGuizmo](https://github.com/CedricGuillemet/ImGuizmo) 80 | 81 | *** 82 | 83 | **Screenshot:** 84 | 85 | ![Screenshot_3](Images/Screenshot_3.png) 86 | 87 | *** 88 | 89 | **Note from the creator:** 90 | 91 | This project serves as a means for me to learning core engine development, graphics programming, 92 | mathematics and other stuff. This is formed by watching YouTube series on engine development 93 | as well as implementing my own little additions. This is NOT, by any means, an entire, 94 | from-scratch, all-by-myself, engine, as I am still learning what it takes to make a game 95 | engine in the hopes that one day I will be able to atleast create a minimum viable product 96 | all by myself. -------------------------------------------------------------------------------- /Sandbox/assets/shaders/FlatColor.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 460 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | 6 | uniform mat4 u_ViewProjection; 7 | uniform mat4 u_Transform; 8 | 9 | void main() 10 | { 11 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position,1.0); 12 | } 13 | 14 | #type fragment 15 | #version 460 core 16 | 17 | layout(location = 0) out vec4 color; 18 | 19 | uniform vec4 u_Color; 20 | 21 | void main() 22 | { 23 | color = u_Color; 24 | } -------------------------------------------------------------------------------- /Sandbox/assets/shaders/Texture.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 460 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec4 a_Color; 6 | layout(location = 2) in vec2 a_TexCoord; 7 | layout(location = 3) in float a_TexIndex; 8 | layout(location = 4) in float a_TilingFactor; 9 | 10 | uniform mat4 u_ViewProjection; 11 | 12 | out vec4 v_Color; 13 | out vec2 v_TexCoord; 14 | out float v_TexIndex; 15 | out float v_TilingFactor; 16 | 17 | void main() 18 | { 19 | v_Color = a_Color; 20 | v_TexCoord = a_TexCoord; 21 | v_TexIndex = a_TexIndex; 22 | v_TilingFactor = a_TilingFactor; 23 | gl_Position = u_ViewProjection * vec4(a_Position,1.0); 24 | } 25 | 26 | #type fragment 27 | #version 460 core 28 | 29 | layout(location = 0) out vec4 color; 30 | 31 | in vec4 v_Color; 32 | in vec2 v_TexCoord; 33 | in float v_TexIndex; 34 | in float v_TilingFactor; 35 | 36 | uniform sampler2D u_Textures[32]; 37 | 38 | void main() 39 | { 40 | vec4 texColor = v_Color; 41 | switch(int(v_TexIndex)) 42 | { 43 | case 0: texColor *= texture(u_Textures[0], v_TexCoord * v_TilingFactor); break; 44 | case 1: texColor *= texture(u_Textures[1], v_TexCoord * v_TilingFactor); break; 45 | case 2: texColor *= texture(u_Textures[2], v_TexCoord * v_TilingFactor); break; 46 | case 3: texColor *= texture(u_Textures[3], v_TexCoord * v_TilingFactor); break; 47 | case 4: texColor *= texture(u_Textures[4], v_TexCoord * v_TilingFactor); break; 48 | case 5: texColor *= texture(u_Textures[5], v_TexCoord * v_TilingFactor); break; 49 | case 6: texColor *= texture(u_Textures[6], v_TexCoord * v_TilingFactor); break; 50 | case 7: texColor *= texture(u_Textures[7], v_TexCoord * v_TilingFactor); break; 51 | case 8: texColor *= texture(u_Textures[8], v_TexCoord * v_TilingFactor); break; 52 | case 9: texColor *= texture(u_Textures[9], v_TexCoord * v_TilingFactor); break; 53 | case 10: texColor *= texture(u_Textures[10], v_TexCoord * v_TilingFactor); break; 54 | case 11: texColor *= texture(u_Textures[11], v_TexCoord * v_TilingFactor); break; 55 | case 12: texColor *= texture(u_Textures[12], v_TexCoord * v_TilingFactor); break; 56 | case 13: texColor *= texture(u_Textures[13], v_TexCoord * v_TilingFactor); break; 57 | case 14: texColor *= texture(u_Textures[14], v_TexCoord * v_TilingFactor); break; 58 | case 15: texColor *= texture(u_Textures[15], v_TexCoord * v_TilingFactor); break; 59 | case 16: texColor *= texture(u_Textures[16], v_TexCoord * v_TilingFactor); break; 60 | case 17: texColor *= texture(u_Textures[17], v_TexCoord * v_TilingFactor); break; 61 | case 18: texColor *= texture(u_Textures[18], v_TexCoord * v_TilingFactor); break; 62 | case 19: texColor *= texture(u_Textures[19], v_TexCoord * v_TilingFactor); break; 63 | case 20: texColor *= texture(u_Textures[20], v_TexCoord * v_TilingFactor); break; 64 | case 21: texColor *= texture(u_Textures[21], v_TexCoord * v_TilingFactor); break; 65 | case 22: texColor *= texture(u_Textures[22], v_TexCoord * v_TilingFactor); break; 66 | case 23: texColor *= texture(u_Textures[23], v_TexCoord * v_TilingFactor); break; 67 | case 24: texColor *= texture(u_Textures[24], v_TexCoord * v_TilingFactor); break; 68 | case 25: texColor *= texture(u_Textures[25], v_TexCoord * v_TilingFactor); break; 69 | case 26: texColor *= texture(u_Textures[26], v_TexCoord * v_TilingFactor); break; 70 | case 27: texColor *= texture(u_Textures[27], v_TexCoord * v_TilingFactor); break; 71 | case 28: texColor *= texture(u_Textures[28], v_TexCoord * v_TilingFactor); break; 72 | case 29: texColor *= texture(u_Textures[29], v_TexCoord * v_TilingFactor); break; 73 | case 30: texColor *= texture(u_Textures[30], v_TexCoord * v_TilingFactor); break; 74 | case 31: texColor *= texture(u_Textures[31], v_TexCoord * v_TilingFactor); break; 75 | } 76 | color = texColor; 77 | } -------------------------------------------------------------------------------- /Sandbox/assets/textures/crate2_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Sandbox/assets/textures/crate2_diffuse.png -------------------------------------------------------------------------------- /Sandbox/assets/textures/test_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/Sandbox/assets/textures/test_texture.png -------------------------------------------------------------------------------- /Sandbox/premake5.lua: -------------------------------------------------------------------------------- 1 | project "Sandbox" 2 | kind "ConsoleApp" 3 | language "C++" 4 | cppdialect "C++17" 5 | staticruntime "on" 6 | 7 | targetdir ("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") 8 | objdir ("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") 9 | 10 | files 11 | { 12 | "src/**.h", 13 | "src/**.cpp" 14 | } 15 | 16 | includedirs 17 | { 18 | "%{wks.location}/Ghost/vendor/spdlog/include", 19 | "%{wks.location}/Ghost/src", 20 | "%{wks.location}/Ghost/vendor", 21 | "%{IncludeDir.glm}", 22 | "%{IncludeDir.entt}" 23 | } 24 | 25 | links 26 | { 27 | "Ghost" 28 | } 29 | 30 | filter "system:windows" 31 | systemversion "latest" 32 | 33 | filter "configurations:Debug" 34 | defines "GT_DEBUG" 35 | runtime "Debug" 36 | symbols "on" 37 | 38 | postbuildcommands 39 | { 40 | "{COPY} %{LibraryDir.VulkanSDK_DebugDLL} %{cfg.targetdir}" 41 | } 42 | 43 | filter "configurations:Release" 44 | defines "GT_RELEASE" 45 | runtime "Release" 46 | optimize "on" 47 | 48 | filter "configurations:Dist" 49 | defines "GT_DIST" 50 | runtime "Release" 51 | optimize "on" -------------------------------------------------------------------------------- /Sandbox/src/Sandbox2D.cpp: -------------------------------------------------------------------------------- 1 | #include "Sandbox2D.h" 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | Sandbox2D::Sandbox2D() 8 | :Layer("Sandbox2D"), m_CameraController(1600.0f / 900.0f) 9 | { 10 | } 11 | 12 | void Sandbox2D::OnAttach() 13 | { 14 | GT_PROFILE_FUNCTION(); 15 | 16 | m_Texture = Ghost::Texture2D::Create("assets/textures/crate2_diffuse.png"); 17 | } 18 | 19 | void Sandbox2D::OnDetach() 20 | { 21 | GT_PROFILE_FUNCTION(); 22 | } 23 | 24 | void Sandbox2D::OnUpdate(Ghost::Timestep ts) 25 | { 26 | GT_PROFILE_FUNCTION(); 27 | 28 | // Update 29 | m_CameraController.OnUpdate(ts); 30 | 31 | // Render 32 | Ghost::Renderer2D::ResetStats(); 33 | Ghost::RenderCommand::SetClearColor({ 0.1f,0.1f,0.1f,1 }); 34 | Ghost::RenderCommand::Clear(); 35 | 36 | { 37 | static float rotation = 30.0f; 38 | rotation += 1.0f; 39 | 40 | Ghost::Renderer2D::BeginScene(m_CameraController.GetCamera()); 41 | 42 | Ghost::Renderer2D::DrawQuad({ -1.0f, 0.0f }, { 0.8f, 0.8f }, { 0.8f, 0.2f, 0.3f, 1.0f }); 43 | Ghost::Renderer2D::DrawRotatedQuad({ 0.5f, -0.5f }, { 0.5f, 0.75f }, glm::radians(-25.0f), { 0.2f, 0.3f, 0.8f, 1.0f }); 44 | Ghost::Renderer2D::DrawQuad({ 0.0f, 0.0f, -0.1f }, { 5.0f, 5.0f }, m_Texture); 45 | Ghost::Renderer2D::DrawRotatedQuad({ -5.0f, 0.0f, 0.1f }, { 3.0f, 3.0f }, glm::radians(rotation), m_Texture); 46 | 47 | Ghost::Renderer2D::EndScene(); 48 | } 49 | 50 | { 51 | Ghost::Renderer2D::BeginScene(m_CameraController.GetCamera()); 52 | for (float y = -5.0f; y < 5.0f; y += 0.5f) { 53 | for (float x = -5.0f; x < 5.0f; x += 0.5f) { 54 | glm::vec4 color = { (x + 5.0f) / 10.0f, 0.4f,(y + 5.0f) / 10.0f,0.7f }; 55 | Ghost::Renderer2D::DrawQuad({ x,y }, { 0.45f,0.45f }, color); 56 | } 57 | } 58 | Ghost::Renderer2D::EndScene(); 59 | } 60 | } 61 | 62 | void Sandbox2D::OnImGuiRender() 63 | { 64 | GT_PROFILE_FUNCTION(); 65 | 66 | ImGui::Begin("Settings"); 67 | auto stats = Ghost::Renderer2D::GetStats(); 68 | ImGui::Text("Renderer2D Stats :"); 69 | ImGui::Text("Draw Calls: %d", stats.DrawCalls); 70 | ImGui::Text("Quads: %d", stats.QuadCount); 71 | ImGui::Text("Vertices: %d", stats.GetTotalVertexCount()); 72 | ImGui::Text("Indices: %d", stats.GetTotalIndexCount()); 73 | 74 | uint32_t textureID = m_Texture->GetRendererID(); 75 | ImGui::Image((void*)textureID, ImVec2(256.0f, 256.0f)); 76 | ImGui::End(); 77 | } 78 | 79 | void Sandbox2D::OnEvent(Ghost::Event& e) 80 | { 81 | m_CameraController.OnEvent(e); 82 | } -------------------------------------------------------------------------------- /Sandbox/src/Sandbox2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Ghost.h" 4 | 5 | class Sandbox2D : public Ghost::Layer { 6 | public: 7 | Sandbox2D(); 8 | virtual ~Sandbox2D() = default; 9 | 10 | virtual void OnAttach() override; 11 | virtual void OnDetach() override; 12 | 13 | void OnUpdate(Ghost::Timestep ts) override; 14 | virtual void OnImGuiRender() override; 15 | void OnEvent(Ghost::Event& e) override; 16 | 17 | private: 18 | Ghost::OrthographicCameraController m_CameraController; 19 | 20 | // Temp 21 | Ghost::Ref m_SquareVA; 22 | Ghost::Ref m_FlatColorShader; 23 | 24 | Ghost::Ref m_Texture; 25 | }; -------------------------------------------------------------------------------- /Sandbox/src/SandboxApp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "Platform/OpenGL/OpenGLShader.h" 5 | 6 | #include 7 | #include 8 | 9 | #include "imgui/imgui.h" 10 | 11 | #include "Sandbox2D.h" 12 | 13 | class Sandbox : public Ghost::Application { 14 | public: 15 | Sandbox(Ghost::ApplicationCommandLineArgs args) 16 | : Application("Sandbox", args) { 17 | //PushLayer(new ExampleLayer()); 18 | } 19 | 20 | ~Sandbox() {} 21 | }; 22 | 23 | Ghost::Application* Ghost::CreateApplication(ApplicationCommandLineArgs args) { 24 | return new Sandbox(args); // reference using extern in EntryPoint.h 25 | } 26 | -------------------------------------------------------------------------------- /premake5.lua: -------------------------------------------------------------------------------- 1 | include "./vendor/premake/premake_customization/solution_items.lua" 2 | include "Dependencies.lua" 3 | 4 | workspace "Ghost" 5 | architecture "x86_64" 6 | startproject "Ghost-Editor" 7 | 8 | configurations 9 | { 10 | "Debug", 11 | "Release", 12 | "Dist" 13 | } 14 | 15 | solution_items 16 | { 17 | ".editorconfig" 18 | } 19 | 20 | flags 21 | { 22 | "MultiProcessorCompile" 23 | } 24 | 25 | outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" 26 | 27 | group "Dependencies" 28 | include "vendor/premake" 29 | include "Ghost/vendor/Box2D" 30 | include "Ghost/vendor/GLFW" 31 | include "Ghost/vendor/Glad" 32 | include "Ghost/vendor/imgui" 33 | include "Ghost/vendor/yaml-cpp" 34 | group "" 35 | 36 | include "Ghost" 37 | include "Ghost-Editor" 38 | -------------------------------------------------------------------------------- /scripts/Setup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | python Setup.py 3 | PAUSE -------------------------------------------------------------------------------- /scripts/Setup.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import subprocess 4 | import platform 5 | 6 | from SetupPython import PythonConfiguration as PythonRequirements 7 | 8 | # Make sure everything we need for the setup is installed 9 | PythonRequirements.Validate() 10 | 11 | from SetupPremake import PremakeConfiguration as PremakeRequirements 12 | from SetupVulkan import VulkanConfiguration as VulkanRequirements 13 | os.chdir('./../') # Change from devtools/scripts directory to root 14 | 15 | premakeInstalled = PremakeRequirements.Validate() 16 | VulkanRequirements.Validate() 17 | 18 | print("\nUpdating submodules...") 19 | subprocess.call(["git", "submodule", "update", "--init", "--recursive"]) 20 | 21 | if (premakeInstalled): 22 | if platform.system() == "Windows": 23 | print("\nRunning premake...") 24 | subprocess.call([os.path.abspath("./scripts/Win-GenProjects.bat"), "nopause"]) 25 | 26 | print("\nSetup completed!") 27 | else: 28 | print("Ghost requires Premake to generate project files.") 29 | 30 | -------------------------------------------------------------------------------- /scripts/SetupPremake.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | from pathlib import Path 4 | 5 | import Utils 6 | 7 | class PremakeConfiguration: 8 | premakeVersion = "5.0.0-alpha16" 9 | premakeZipUrls = f"https://github.com/premake/premake-core/releases/download/v{premakeVersion}/premake-{premakeVersion}-windows.zip" 10 | premakeLicenseUrl = "https://raw.githubusercontent.com/premake/premake-core/master/LICENSE.txt" 11 | premakeDirectory = "./vendor/premake/bin" 12 | 13 | @classmethod 14 | def Validate(cls): 15 | if (not cls.CheckIfPremakeInstalled()): 16 | print("Premake is not installed.") 17 | return False 18 | 19 | print(f"Correct Premake located at {os.path.abspath(cls.premakeDirectory)}") 20 | return True 21 | 22 | @classmethod 23 | def CheckIfPremakeInstalled(cls): 24 | premakeExe = Path(f"{cls.premakeDirectory}/premake5.exe"); 25 | if (not premakeExe.exists()): 26 | return cls.InstallPremake() 27 | 28 | return True 29 | 30 | @classmethod 31 | def InstallPremake(cls): 32 | permissionGranted = False 33 | while not permissionGranted: 34 | reply = str(input("Premake not found. Would you like to download Premake {0:s}? [Y/N]: ".format(cls.premakeVersion))).lower().strip()[:1] 35 | if reply == 'n': 36 | return False 37 | permissionGranted = (reply == 'y') 38 | 39 | premakePath = f"{cls.premakeDirectory}/premake-{cls.premakeVersion}-windows.zip" 40 | print("Downloading {0:s} to {1:s}".format(cls.premakeZipUrls, premakePath)) 41 | Utils.DownloadFile(cls.premakeZipUrls, premakePath) 42 | print("Extracting", premakePath) 43 | Utils.UnzipFile(premakePath, deleteZipFile=True) 44 | print(f"Premake {cls.premakeVersion} has been downloaded to '{cls.premakeDirectory}'") 45 | 46 | premakeLicensePath = f"{cls.premakeDirectory}/LICENSE.txt" 47 | print("Downloading {0:s} to {1:s}".format(cls.premakeLicenseUrl, premakeLicensePath)) 48 | Utils.DownloadFile(cls.premakeLicenseUrl, premakeLicensePath) 49 | print(f"Premake License file has been downloaded to '{cls.premakeDirectory}'") 50 | 51 | return True 52 | -------------------------------------------------------------------------------- /scripts/SetupPython.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import subprocess 3 | import importlib.util as importlib_util 4 | 5 | class PythonConfiguration: 6 | @classmethod 7 | def Validate(cls): 8 | if not cls.__ValidatePython(): 9 | return # cannot validate further 10 | 11 | for packageName in ["requests"]: 12 | if not cls.__ValidatePackage(packageName): 13 | return # cannot validate further 14 | 15 | @classmethod 16 | def __ValidatePython(cls, versionMajor = 3, versionMinor = 3): 17 | if sys.version is not None: 18 | print("Python version {0:d}.{1:d}.{2:d} detected.".format( \ 19 | sys.version_info.major, sys.version_info.minor, sys.version_info.micro)) 20 | if sys.version_info.major < versionMajor or (sys.version_info.major == versionMajor and sys.version_info.minor < versionMinor): 21 | print("Python version too low, expected version {0:d}.{1:d} or higher.".format( \ 22 | versionMajor, versionMinor)) 23 | return False 24 | return True 25 | 26 | @classmethod 27 | def __ValidatePackage(cls, packageName): 28 | if importlib_util.find_spec(packageName) is None: 29 | return cls.__InstallPackage(packageName) 30 | return True 31 | 32 | @classmethod 33 | def __InstallPackage(cls, packageName): 34 | permissionGranted = False 35 | while not permissionGranted: 36 | reply = str(input("Would you like to install Python package '{0:s}'? [Y/N]: ".format(packageName))).lower().strip()[:1] 37 | if reply == 'n': 38 | return False 39 | permissionGranted = (reply == 'y') 40 | 41 | print(f"Installing {packageName} module...") 42 | subprocess.check_call(['python', '-m', 'pip', 'install', packageName]) 43 | 44 | return cls.__ValidatePackage(packageName) 45 | 46 | if __name__ == "__main__": 47 | PythonConfiguration.Validate() 48 | -------------------------------------------------------------------------------- /scripts/SetupVulkan.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import subprocess 4 | from pathlib import Path 5 | 6 | import Utils 7 | 8 | from io import BytesIO 9 | from urllib.request import urlopen 10 | 11 | class VulkanConfiguration: 12 | requiredVulkanVersion = "1.2.170.0" 13 | vulkanDirectory = "./Ghost/vendor/VulkanSDK" 14 | 15 | @classmethod 16 | def Validate(cls): 17 | if (not cls.CheckVulkanSDK()): 18 | print("Vulkan SDK not installed correctly.") 19 | return 20 | 21 | if (not cls.CheckVulkanSDKDebugLibs()): 22 | print("Vulkan SDK debug libs not found.") 23 | 24 | @classmethod 25 | def CheckVulkanSDK(cls): 26 | vulkanSDK = os.environ.get("VULKAN_SDK") 27 | if (vulkanSDK is None): 28 | print("\nYou don't have the Vulkan SDK installed!") 29 | cls.__InstallVulkanSDK() 30 | return False 31 | else: 32 | print(f"\nLocated Vulkan SDK at {vulkanSDK}") 33 | 34 | if (cls.requiredVulkanVersion not in vulkanSDK): 35 | print(f"You don't have the correct Vulkan SDK version! (Engine requires {cls.requiredVulkanVersion})") 36 | cls.__InstallVulkanSDK() 37 | return False 38 | 39 | print(f"Correct Vulkan SDK located at {vulkanSDK}") 40 | return True 41 | 42 | @classmethod 43 | def __InstallVulkanSDK(cls): 44 | permissionGranted = False 45 | while not permissionGranted: 46 | reply = str(input("Would you like to install VulkanSDK {0:s}? [Y/N]: ".format(cls.requiredVulkanVersion))).lower().strip()[:1] 47 | if reply == 'n': 48 | return 49 | permissionGranted = (reply == 'y') 50 | 51 | vulkanInstallURL = f"https://sdk.lunarg.com/sdk/download/{cls.requiredVulkanVersion}/windows/VulkanSDK-{cls.requiredVulkanVersion}-Installer.exe" 52 | vulkanPath = f"{cls.vulkanDirectory}/VulkanSDK-{cls.requiredVulkanVersion}-Installer.exe" 53 | print("Downloading {0:s} to {1:s}".format(vulkanInstallURL, vulkanPath)) 54 | Utils.DownloadFile(vulkanInstallURL, vulkanPath) 55 | print("Running Vulkan SDK installer...") 56 | os.startfile(os.path.abspath(vulkanPath)) 57 | print("Re-run this script after installation!") 58 | quit() 59 | 60 | @classmethod 61 | def CheckVulkanSDKDebugLibs(cls): 62 | shadercdLib = Path(f"{cls.vulkanDirectory}/Lib/shaderc_sharedd.lib") 63 | 64 | VulkanSDKDebugLibsURLlist = [ 65 | f"https://sdk.lunarg.com/sdk/download/{cls.requiredVulkanVersion}/windows/VulkanSDK-{cls.requiredVulkanVersion}-DebugLibs.zip", 66 | f"https://files.lunarg.com/SDK-{cls.requiredVulkanVersion}/VulkanSDK-{cls.requiredVulkanVersion}-DebugLibs.zip" 67 | ] 68 | 69 | if not shadercdLib.exists(): 70 | print(f"\nNo Vulkan SDK debug libs found. (Checked {shadercdLib})") 71 | vulkanPath = f"{cls.vulkanDirectory}/VulkanSDK-{cls.requiredVulkanVersion}-DebugLibs.zip" 72 | Utils.DownloadFile(VulkanSDKDebugLibsURLlist, vulkanPath) 73 | print("Extracting", vulkanPath) 74 | Utils.UnzipFile(vulkanPath, deleteZipFile=False) 75 | print(f"Vulkan SDK debug libs installed at {os.path.abspath(cls.vulkanDirectory)}") 76 | else: 77 | print(f"\nVulkan SDK debug libs located at {os.path.abspath(cls.vulkanDirectory)}") 78 | return True 79 | 80 | if __name__ == "__main__": 81 | VulkanConfiguration.Validate() 82 | -------------------------------------------------------------------------------- /scripts/Utils.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import winreg 4 | 5 | import requests 6 | import time 7 | import urllib 8 | 9 | from zipfile import ZipFile 10 | 11 | def GetSystemEnvironmentVariable(name): 12 | key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, r"System\CurrentControlSet\Control\Session Manager\Environment") 13 | try: 14 | return winreg.QueryValueEx(key, name)[0] 15 | except: 16 | return None 17 | 18 | def GetUserEnvironmentVariable(name): 19 | key = winreg.CreateKey(winreg.HKEY_CURRENT_USER, r"Environment") 20 | try: 21 | return winreg.QueryValueEx(key, name)[0] 22 | except: 23 | return None 24 | 25 | def DownloadFile(url, filepath): 26 | path = filepath 27 | filepath = os.path.abspath(filepath) 28 | os.makedirs(os.path.dirname(filepath), exist_ok=True) 29 | 30 | if (type(url) is list): 31 | for url_option in url: 32 | print("Downloading", url_option) 33 | try: 34 | DownloadFile(url_option, filepath) 35 | return 36 | except urllib.error.URLError as e: 37 | print(f"URL Error encountered: {e.reason}. Proceeding with backup...\n\n") 38 | os.remove(filepath) 39 | pass 40 | except urllib.error.HTTPError as e: 41 | print(f"HTTP Error encountered: {e.code}. Proceeding with backup...\n\n") 42 | os.remove(filepath) 43 | pass 44 | except: 45 | print(f"Something went wrong. Proceeding with backup...\n\n") 46 | os.remove(filepath) 47 | pass 48 | raise ValueError(f"Failed to download {filepath}") 49 | if not(type(url) is str): 50 | raise TypeError("Argument 'url' must be of type list or string") 51 | 52 | with open(filepath, 'wb') as f: 53 | headers = {'User-Agent': "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"} 54 | response = requests.get(url, headers=headers, stream=True) 55 | total = response.headers.get('content-length') 56 | 57 | if total is None: 58 | f.write(response.content) 59 | else: 60 | downloaded = 0 61 | total = int(total) 62 | startTime = time.time() 63 | for data in response.iter_content(chunk_size=max(int(total/1000), 1024*1024)): 64 | downloaded += len(data) 65 | f.write(data) 66 | 67 | try: 68 | done = int(50*downloaded/total) if downloaded < total else 50 69 | percentage = (downloaded / total) * 100 if downloaded < total else 100 70 | except ZeroDivisionError: 71 | done = 50 72 | percentage = 100 73 | elapsedTime = time.time() - startTime 74 | try: 75 | avgKBPerSecond = (downloaded / 1024) / elapsedTime 76 | except ZeroDivisionError: 77 | avgKBPerSecond = 0.0 78 | 79 | avgSpeedString = '{:.2f} KB/s'.format(avgKBPerSecond) 80 | if (avgKBPerSecond > 1024): 81 | avgMBPerSecond = avgKBPerSecond / 1024 82 | avgSpeedString = '{:.2f} MB/s'.format(avgMBPerSecond) 83 | sys.stdout.write('\r[{}{}] {:.2f}% ({}) '.format('█' * done, '.' * (50-done), percentage, avgSpeedString)) 84 | sys.stdout.flush() 85 | sys.stdout.write('\n') 86 | 87 | def UnzipFile(filepath, deleteZipFile=True): 88 | zipFilePath = os.path.abspath(filepath) # get full path of files 89 | zipFileLocation = os.path.dirname(zipFilePath) 90 | 91 | zipFileContent = dict() 92 | zipFileContentSize = 0 93 | with ZipFile(zipFilePath, 'r') as zipFileFolder: 94 | for name in zipFileFolder.namelist(): 95 | zipFileContent[name] = zipFileFolder.getinfo(name).file_size 96 | zipFileContentSize = sum(zipFileContent.values()) 97 | extractedContentSize = 0 98 | startTime = time.time() 99 | for zippedFileName, zippedFileSize in zipFileContent.items(): 100 | UnzippedFilePath = os.path.abspath(f"{zipFileLocation}/{zippedFileName}") 101 | os.makedirs(os.path.dirname(UnzippedFilePath), exist_ok=True) 102 | if os.path.isfile(UnzippedFilePath): 103 | zipFileContentSize -= zippedFileSize 104 | else: 105 | zipFileFolder.extract(zippedFileName, path=zipFileLocation, pwd=None) 106 | extractedContentSize += zippedFileSize 107 | try: 108 | done = int(50*extractedContentSize/zipFileContentSize) 109 | percentage = (extractedContentSize / zipFileContentSize) * 100 110 | except ZeroDivisionError: 111 | done = 50 112 | percentage = 100 113 | elapsedTime = time.time() - startTime 114 | try: 115 | avgKBPerSecond = (extractedContentSize / 1024) / elapsedTime 116 | except ZeroDivisionError: 117 | avgKBPerSecond = 0.0 118 | avgSpeedString = '{:.2f} KB/s'.format(avgKBPerSecond) 119 | if (avgKBPerSecond > 1024): 120 | avgMBPerSecond = avgKBPerSecond / 1024 121 | avgSpeedString = '{:.2f} MB/s'.format(avgMBPerSecond) 122 | sys.stdout.write('\r[{}{}] {:.2f}% ({}) '.format('█' * done, '.' * (50-done), percentage, avgSpeedString)) 123 | sys.stdout.flush() 124 | sys.stdout.write('\n') 125 | 126 | if deleteZipFile: 127 | os.remove(zipFilePath) # delete zip file -------------------------------------------------------------------------------- /scripts/Win-GenProjects.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | pushd %~dp0\..\ 3 | call vendor\premake\bin\premake5.exe vs2019 4 | popd 5 | PAUSE 6 | -------------------------------------------------------------------------------- /vendor/premake/bin/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003-2016 Jason Perkins and individual contributors. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, 8 | this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of Premake nor the names of its contributors may be 15 | used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /vendor/premake/bin/premake5.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CybernetHacker14/Ghost-Engine/3fbb062de2e5a2895d6171fa6cd84225cb269a09/vendor/premake/bin/premake5.exe -------------------------------------------------------------------------------- /vendor/premake/premake5.lua: -------------------------------------------------------------------------------- 1 | project "Premake" 2 | kind "Utility" 3 | 4 | targetdir ("%{wks.location}/bin/" .. outputdir .. "/%{prj.name}") 5 | objdir ("%{wks.location}/bin-int/" .. outputdir .. "/%{prj.name}") 6 | 7 | files 8 | { 9 | "%{wks.location}/**premake5.lua" 10 | } 11 | 12 | postbuildmessage "Regenerating project files with Premake5!" 13 | postbuildcommands 14 | { 15 | "\"%{prj.location}bin/premake5\" %{_ACTION} --file=\"%{wks.location}premake5.lua\"" 16 | } 17 | -------------------------------------------------------------------------------- /vendor/premake/premake_customization/solution_items.lua: -------------------------------------------------------------------------------- 1 | -- Implement the solution_items command for solution-scope files 2 | require('vstudio') 3 | 4 | premake.api.register { 5 | name = "solution_items", 6 | scope = "workspace", 7 | kind = "list:string", 8 | } 9 | 10 | premake.override(premake.vstudio.sln2005, "projects", function(base, wks) 11 | if wks.solution_items and #wks.solution_items > 0 then 12 | local solution_folder_GUID = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}" -- See https://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs 13 | premake.push("Project(\"" .. solution_folder_GUID .. "\") = \"Solution Items\", \"Solution Items\", \"{" .. os.uuid("Solution Items:" .. wks.name) .. "}\"") 14 | premake.push("ProjectSection(SolutionItems) = preProject") 15 | 16 | for _, path in ipairs(wks.solution_items) do 17 | premake.w(path .. " = " .. path) 18 | end 19 | 20 | premake.pop("EndProjectSection") 21 | premake.pop("EndProject") 22 | end 23 | base(wks) 24 | end) 25 | --------------------------------------------------------------------------------