├── src ├── Engine │ ├── engine.cpp │ ├── engine.h │ ├── Platform │ │ └── OpenGL │ │ │ ├── opengl_time.cpp │ │ │ └── opengl_input.cpp │ ├── CMakeLists.txt │ ├── time.h │ ├── log.cpp │ ├── core.h │ ├── layer.h │ ├── log.h │ ├── profiler.h │ └── event_system.h ├── Renderer │ ├── tinyobjloader │ │ └── tiny_obj_loader.cc │ ├── renderAPI.cpp │ ├── context.h │ ├── command.cpp │ ├── CMakeLists.txt │ ├── Platform │ │ └── OpenGL │ │ │ ├── opengl_context.h │ │ │ ├── opengl_renderAPI.h │ │ │ ├── opengl_vao.h │ │ │ ├── opengl_context.cpp │ │ │ ├── opengl_texture.h │ │ │ ├── opengl_window.h │ │ │ ├── opengl_renderAPI.cpp │ │ │ ├── opengl_effect.h │ │ │ ├── opengl_buffer.h │ │ │ ├── opengl_shader.h │ │ │ ├── opengl_vao.cpp │ │ │ ├── opengl_texture.cpp │ │ │ ├── opengl_buffer.cpp │ │ │ └── opengl_window.cpp │ ├── vao.h │ ├── vao.cpp │ ├── renderAPI.h │ ├── renderer.h │ ├── effect.h │ ├── command.h │ ├── texture.h │ ├── Renderer2D.h │ ├── window.h │ ├── effect.cpp │ ├── texture.cpp │ ├── renderer.cpp │ ├── shader.h │ ├── primitive.h │ ├── camera.cpp │ ├── mesh.h │ ├── buffer.cpp │ ├── shader.cpp │ ├── camera.h │ ├── light.h │ ├── Renderer2D.cpp │ ├── buffer.h │ └── material.h ├── CMakeLists.txt ├── Gui │ ├── imgui_build.cpp │ ├── CMakeLists.txt │ ├── imgui_layer.h │ └── imgui_layer.cpp ├── Editor │ ├── terminal.h │ ├── menu.h │ ├── CMakeLists.txt │ ├── hierarchy.h │ ├── terminal.cpp │ ├── editor_layer.h │ ├── application.h │ ├── inspector.h │ ├── application.cpp │ ├── hierarchy.cpp │ ├── editor_layer.cpp │ ├── basic.h │ ├── FileDialog │ │ └── ImFileDialog.h │ ├── menu.cpp │ └── basic.cpp ├── App │ ├── main.cpp │ ├── CMakeLists.txt │ ├── app_init.h │ ├── app.h │ ├── log.txt │ ├── app.cpp │ └── imgui.ini └── Scene │ ├── CMakeLists.txt │ ├── maincamera_layer.h │ ├── scene.h │ ├── camera_controller.h │ ├── entity.h │ ├── scene_layer.h │ ├── maincamera_layer.cpp │ ├── scene_layer.cpp │ ├── scene.cpp │ ├── camera_controller.cpp │ └── entity.cpp ├── assets ├── shader │ ├── material │ │ ├── irradiance.glsl │ │ ├── default.glsl │ │ ├── emission.glsl │ │ ├── geo_texture.glsl │ │ └── phong.glsl │ └── environment │ │ ├── default.glsl │ │ ├── grid.glsl │ │ ├── background.glsl │ │ ├── equirectangular.glsl │ │ ├── irradiance.glsl │ │ ├── brdf.glsl │ │ └── prefilter.glsl └── fonts │ ├── ARIALN.TTF │ ├── ARIALNB.TTF │ ├── ARIALNI.TTF │ ├── arial.ttf │ ├── arialbd.ttf │ ├── arialbi.ttf │ ├── ariali.ttf │ ├── ariblk.ttf │ └── ARIALNBI.TTF ├── images ├── pbr.png ├── ui.png ├── phong.png └── wireframe.png ├── vendor ├── stb_image │ └── stb_image.cpp ├── glad │ ├── premake5.lua │ └── .gitignore ├── entt │ └── LICENSE.txt └── CMakeLists.txt ├── config └── Config.cmake.in ├── CMakeLists.txt ├── .gitmodules ├── .gitignore ├── cmake ├── Utility.cmake ├── Git.cmake ├── Download.cmake ├── Init.cmake └── Package.cmake ├── .github └── workflows │ └── windows.yml ├── LICENSE └── README.md /src/Engine/engine.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Engine/engine.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/shader/material/irradiance.glsl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/pbr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/images/pbr.png -------------------------------------------------------------------------------- /images/ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/images/ui.png -------------------------------------------------------------------------------- /images/phong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/images/phong.png -------------------------------------------------------------------------------- /images/wireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/images/wireframe.png -------------------------------------------------------------------------------- /vendor/stb_image/stb_image.cpp: -------------------------------------------------------------------------------- 1 | #define STB_IMAGE_IMPLEMENTATION 2 | #include 3 | 4 | -------------------------------------------------------------------------------- /assets/fonts/ARIALN.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ARIALN.TTF -------------------------------------------------------------------------------- /assets/fonts/ARIALNB.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ARIALNB.TTF -------------------------------------------------------------------------------- /assets/fonts/ARIALNI.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ARIALNI.TTF -------------------------------------------------------------------------------- /assets/fonts/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/arial.ttf -------------------------------------------------------------------------------- /assets/fonts/arialbd.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/arialbd.ttf -------------------------------------------------------------------------------- /assets/fonts/arialbi.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/arialbi.ttf -------------------------------------------------------------------------------- /assets/fonts/ariali.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ariali.ttf -------------------------------------------------------------------------------- /assets/fonts/ariblk.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ariblk.ttf -------------------------------------------------------------------------------- /assets/fonts/ARIALNBI.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chaphlagical/Chaf-Engine/HEAD/assets/fonts/ARIALNBI.TTF -------------------------------------------------------------------------------- /src/Renderer/tinyobjloader/tiny_obj_loader.cc: -------------------------------------------------------------------------------- 1 | #define TINYOBJLOADER_IMPLEMENTATION 2 | #include "tiny_obj_loader.h" 3 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(App) 2 | add_subdirectory(Editor) 3 | add_subdirectory(Engine) 4 | add_subdirectory(Gui) 5 | add_subdirectory(Renderer) 6 | add_subdirectory(Scene) -------------------------------------------------------------------------------- /src/Renderer/renderAPI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef CHAF_OPENGL_API 4 | Chaf::RenderAPI::API Chaf::RenderAPI::s_API = Chaf::RenderAPI::API::OpenGL; 5 | #endif -------------------------------------------------------------------------------- /src/Gui/imgui_build.cpp: -------------------------------------------------------------------------------- 1 | #ifdef CHAF_OPENGL_API 2 | #define IMGUI_IMPL_OPENGL_LOADER_GLAD 3 | #include 4 | #include 5 | #endif // CHAF_OPENGL_API -------------------------------------------------------------------------------- /src/Editor/terminal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API Terminal 8 | { 9 | public: 10 | static void LoggingConsole(bool* handle); 11 | }; 12 | } -------------------------------------------------------------------------------- /src/Renderer/context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Chaf 4 | { 5 | class GraphicsContext 6 | { 7 | public: 8 | virtual void Init() = 0; 9 | virtual void SwapBuffers() = 0; 10 | 11 | 12 | }; 13 | 14 | } -------------------------------------------------------------------------------- /src/App/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "app_init.h" 3 | 4 | int main() 5 | { 6 | Chaf::Log::Init(); 7 | 8 | auto app = Chaf::Create(); 9 | 10 | app->Run(); 11 | 12 | delete app; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /config/Config.cmake.in: -------------------------------------------------------------------------------- 1 | message(STATUS "config @PROJECT_NAME@ @PROJECT_VERSION@ ..") 2 | 3 | @PACKAGE_INIT@ 4 | 5 | include("${CMAKE_CURRENT_LIST_DIR}/Init.cmake") 6 | 7 | @CHAF_PACKAGE_INIT@ 8 | 9 | message(STATUS "config @PROJECT_NAME@ @PROJECT_VERSION@ done") -------------------------------------------------------------------------------- /src/Editor/menu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API Menu 8 | { 9 | public: 10 | static void ShowMainMenu(); 11 | static void ShowGuizmoMenu(); 12 | static void ShowInformation(); 13 | }; 14 | } -------------------------------------------------------------------------------- /src/Engine/Platform/OpenGL/opengl_time.cpp: -------------------------------------------------------------------------------- 1 | #ifdef CHAF_OPENGL_API 2 | #include 3 | 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | void Timestep::Update(float lastFrameTime) 9 | { 10 | m_Time = (float)glfwGetTime() - lastFrameTime; 11 | } 12 | } 13 | #endif // CHAF_OPENGL_API -------------------------------------------------------------------------------- /src/Scene/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE STATIC 3 | TARGET_NAME Scene 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | INC 8 | ${PROJECT_SOURCE_DIR}/src 9 | LIB 10 | entt 11 | Engine 12 | glm 13 | imgui 14 | ) -------------------------------------------------------------------------------- /src/Engine/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE STATIC 3 | TARGET_NAME Engine 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | CHAF_OPENGL_API 8 | INC 9 | ${PROJECT_SOURCE_DIR}/src 10 | LIB 11 | spdlog 12 | glfw 13 | glad 14 | ) -------------------------------------------------------------------------------- /src/Renderer/command.cpp: -------------------------------------------------------------------------------- 1 | #ifdef CHAF_OPENGL_API 2 | #include 3 | #endif // CHAF_OPENGL_API 4 | 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | #ifdef CHAF_OPENGL_API 10 | RenderAPI* RenderCommand::s_RenderAPI = new OpenGLRendererAPI; 11 | #endif // CHAF_OPENGL_API 12 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14 FATAL_ERROR) 2 | 3 | project(CEngine VERSION 0.0.1) 4 | message(STATUS "[Project] ${PROJECT_NAME} ${PROJECT_VERSION}") 5 | 6 | list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") 7 | include(Init) 8 | Init_Project() 9 | 10 | add_subdirectory(vendor) 11 | add_subdirectory(src) 12 | -------------------------------------------------------------------------------- /src/Editor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE STATIC 3 | TARGET_NAME Editor 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | INC 8 | ${PROJECT_SOURCE_DIR}/src 9 | LIB 10 | Gui 11 | Scene 12 | Engine 13 | Renderer 14 | dirent 15 | ) -------------------------------------------------------------------------------- /src/Gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE STATIC 3 | TARGET_NAME Gui 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | CHAF_OPENGL_API 8 | INC 9 | ${PROJECT_SOURCE_DIR}/src 10 | LIB 11 | imgui 12 | Engine 13 | glad 14 | glfw 15 | ) -------------------------------------------------------------------------------- /src/App/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE EXE 3 | TARGET_NAME App 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | INC 8 | ${PROJECT_SOURCE_DIR}/src 9 | LIB 10 | Engine 11 | Editor 12 | Gui 13 | Renderer 14 | Scene 15 | spdlog 16 | ) -------------------------------------------------------------------------------- /src/Editor/hierarchy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | 9 | class CHAF_API Hierachy 10 | { 11 | public: 12 | static void ShowHierarchy(bool* p_open); 13 | static void RecurseTree(Entity node); 14 | 15 | static void RemoveEntity(Entity& node); 16 | 17 | }; 18 | } -------------------------------------------------------------------------------- /src/Renderer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | SetTarget( 2 | MODE STATIC 3 | TARGET_NAME Renderer 4 | DEFINE 5 | PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}/" 6 | NOMINMAX 7 | CHAF_OPENGL_API 8 | INC 9 | ${PROJECT_SOURCE_DIR}/src 10 | LIB 11 | Engine 12 | glad 13 | glm 14 | glfw 15 | stb 16 | ) -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_context.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct GLFWwindow; 6 | 7 | namespace Chaf 8 | { 9 | class OpenGLContext :public GraphicsContext 10 | { 11 | public: 12 | OpenGLContext(GLFWwindow* windowHandle); 13 | 14 | virtual void Init() override; 15 | virtual void SwapBuffers() override; 16 | 17 | private: 18 | GLFWwindow* m_WindowHandle; 19 | }; 20 | 21 | } -------------------------------------------------------------------------------- /src/Engine/time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Chaf 4 | { 5 | class Timestep 6 | { 7 | public: 8 | Timestep(float time = 0.0f) 9 | : m_Time(time) 10 | { 11 | } 12 | 13 | operator float() const { return m_Time; } 14 | 15 | float GetSeconds() const { return m_Time; } 16 | float GetMilliseconds() const { return m_Time * 1000.0f; } 17 | void Update(float lastFrameTime = 0.0f); 18 | 19 | private: 20 | float m_Time; 21 | }; 22 | } -------------------------------------------------------------------------------- /assets/shader/environment/default.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | 8 | uniform mat4 u_ViewProjection; 9 | uniform mat4 u_Transform; 10 | 11 | void main() 12 | { 13 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | 19 | layout(location = 0) out vec4 FragColor; 20 | 21 | void main() 22 | { 23 | FragColor=vec4(1.0); 24 | } -------------------------------------------------------------------------------- /assets/shader/environment/grid.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | 8 | uniform mat4 u_ViewProjection; 9 | uniform mat4 u_Transform; 10 | 11 | void main() 12 | { 13 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | 19 | layout(location = 0) out vec4 FragColor; 20 | 21 | void main() 22 | { 23 | FragColor=vec4(1.0); 24 | } -------------------------------------------------------------------------------- /assets/shader/material/default.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | 8 | uniform mat4 u_ViewProjection; 9 | uniform mat4 u_Transform; 10 | 11 | void main() 12 | { 13 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | 19 | layout(location = 0) out vec4 FragColor; 20 | 21 | void main() 22 | { 23 | FragColor=vec4(1.0); 24 | } -------------------------------------------------------------------------------- /src/Editor/terminal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | void Terminal::LoggingConsole(bool* handle) 9 | { 10 | ImGui::Begin("console", handle); 11 | std::fstream file; 12 | file.open("log.txt"); 13 | 14 | std::string s; 15 | for (int i = 0; std::getline(file, s); i++) 16 | { 17 | if (i >= 4) 18 | ImGui::Text(s.data()); 19 | } 20 | for (int i = 0; i < 4; i++) 21 | ImGui::Text(""); 22 | file.close(); 23 | ImGui::End(); 24 | } 25 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_renderAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API OpenGLRendererAPI :public RenderAPI 8 | { 9 | public: 10 | virtual void Init() override; 11 | virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; 12 | virtual void SetLineMode(const bool enable) override; 13 | void SetClearColor(const glm::vec4& color) override; 14 | void Clear() override; 15 | 16 | void DrawIndexed(const Ref& vertexArray) override; 17 | }; 18 | 19 | } -------------------------------------------------------------------------------- /src/Engine/log.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | std::shared_ptr Log::s_CoreLogger; 8 | std::shared_ptr Log::s_ClientLogger; 9 | 10 | void Log::Init() 11 | { 12 | spdlog::flush_on(spdlog::level::info); 13 | 14 | s_CoreLogger = spdlog::stderr_color_mt("Chaf Engine Console"); 15 | s_CoreLogger->set_level(spdlog::level::trace); 16 | 17 | s_ClientLogger = spdlog::stderr_color_mt("App Console"); 18 | s_ClientLogger->set_level(spdlog::level::trace); 19 | } 20 | } -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/imgui"] 2 | path = vendor/imgui 3 | url = https://github.com/ocornut/imgui 4 | [submodule "vendor/GLFW"] 5 | path = vendor/GLFW 6 | url = https://github.com/Chaphlagical/glfw 7 | [submodule "vendor/glm"] 8 | path = vendor/glm 9 | url = https://github.com/g-truc/glm 10 | [submodule "vendor/spdlog"] 11 | path = vendor/spdlog 12 | url = https://github.com/gabime/spdlog 13 | [submodule "vendor/dirent"] 14 | path = vendor/dirent 15 | url = https://github.com/tronkko/dirent 16 | [submodule "vendor/implot"] 17 | path = vendor/implot 18 | url = https://github.com/epezent/implot 19 | -------------------------------------------------------------------------------- /src/Gui/imgui_layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | class CHAF_API ImGuiLayer :public Layer 10 | { 11 | public: 12 | ImGuiLayer(Ref window); 13 | ~ImGuiLayer(); 14 | 15 | virtual void OnAttach() override; 16 | virtual void OnDetach() override; 17 | 18 | void Begin(); 19 | void End(); 20 | 21 | void SetBlockEvents(bool block) { m_BlockEvents = block; } 22 | 23 | private: 24 | Ref m_Window; 25 | bool m_BlockEvents = true; 26 | float m_Time = 0; 27 | }; 28 | } -------------------------------------------------------------------------------- /vendor/glad/premake5.lua: -------------------------------------------------------------------------------- 1 | project "glad" 2 | kind "StaticLib" 3 | language "C" 4 | staticruntime "on" 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 | -------------------------------------------------------------------------------- /src/App/app_init.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "app.h" 8 | 9 | namespace Chaf 10 | { 11 | class App : public Application 12 | { 13 | public: 14 | App() 15 | :Application("Chaf Engine") 16 | { 17 | PushLayer(new MainCameraLayer()); 18 | PushLayer(new SceneLayer()); 19 | PushLayer(new EditorLayer()); 20 | PushLayer(new AppLayer()); 21 | } 22 | 23 | ~App() 24 | { 25 | 26 | } 27 | 28 | }; 29 | 30 | Application* Create() 31 | { 32 | return new App(); 33 | } 34 | } -------------------------------------------------------------------------------- /assets/shader/material/emission.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | 8 | uniform mat4 u_ViewProjection; 9 | uniform mat4 u_Transform; 10 | 11 | void main() 12 | { 13 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | 19 | layout(location = 0) out vec4 FragColor; 20 | 21 | uniform vec3 u_EmissionColor; 22 | uniform float u_Intensity; 23 | 24 | void main() 25 | { 26 | FragColor=vec4(u_EmissionColor*u_Intensity,1.0); 27 | } -------------------------------------------------------------------------------- /src/Editor/editor_layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | class EditorLayer: public Layer 13 | { 14 | public: 15 | EditorLayer() {} 16 | ~EditorLayer() = default; 17 | 18 | virtual void OnAttach() override; 19 | virtual void OnDetach() override {}; 20 | 21 | virtual void OnUpdate(Timestep timestep) override {}; 22 | virtual void OnImGuiRender() override; 23 | virtual void OnEvent(Event& event) override {}; 24 | }; 25 | 26 | } -------------------------------------------------------------------------------- /src/App/app.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Chaf 12 | { 13 | class AppLayer : public Layer 14 | { 15 | public: 16 | AppLayer(); 17 | virtual ~AppLayer() = default; 18 | 19 | virtual void OnAttach() override; 20 | virtual void OnDetach() override; 21 | 22 | virtual void OnUpdate(Timestep timestep) override; 23 | virtual void OnImGuiRender() override; 24 | virtual void OnEvent(Event& event) override; 25 | 26 | }; 27 | } -------------------------------------------------------------------------------- /src/Renderer/vao.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class CHAF_API VertexArray 9 | { 10 | public: 11 | virtual ~VertexArray() {} 12 | 13 | virtual void Bind() const = 0; 14 | virtual void Unbind() const = 0; 15 | 16 | virtual void AddVertexBuffer(const Ref& vertexBuffer) = 0; 17 | virtual void AddIndexBuffer(const Ref& indexBuffer) = 0; 18 | 19 | virtual const std::vector>& GetVertexBuffers() const = 0; 20 | virtual const Ref& GetIndexBuffer() const = 0; 21 | 22 | static Ref Create(); 23 | }; 24 | 25 | } -------------------------------------------------------------------------------- /vendor/glad/.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # folder 35 | **/build/ 36 | **/lib/ 37 | **/bin/ 38 | **/bin-int/ 39 | 40 | # visual studio 41 | *.sln 42 | *.vcxproj 43 | *.user 44 | *.filters 45 | */.vs/ 46 | 47 | #json 48 | *.json 49 | 50 | #other 51 | *.log 52 | *.tlog 53 | *.lastbuildstate 54 | *.idb 55 | *.pdb -------------------------------------------------------------------------------- /src/Renderer/vao.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #ifdef CHAF_OPENGL_API 4 | #include 5 | #endif // CHAF_OPENGL_API 6 | 7 | namespace Chaf 8 | { 9 | Ref VertexArray::Create() 10 | { 11 | 12 | switch (Renderer::GetAPI()) 13 | { 14 | case RenderAPI::API::None: 15 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 16 | return nullptr; 17 | case RenderAPI::API::OpenGL: 18 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 19 | return CreateRef(); 20 | default: 21 | break; 22 | } 23 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 24 | return nullptr; 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /assets/shader/material/geo_texture.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | 8 | uniform mat4 u_ViewProjection; 9 | uniform mat4 u_Transform; 10 | 11 | out vec4 o_Position; 12 | 13 | void main() 14 | { 15 | o_Position = vec4(a_Position, 1.0); 16 | gl_Position=vec4(a_TexCoord,0.0,1.0); 17 | // o_Position = vec4(a_Position, 1.0); 18 | // gl_Position=vec4(a_TexCoord,0.0,1.0); 19 | } 20 | 21 | #type fragment 22 | #version 330 core 23 | 24 | layout(location = 0) out vec4 FragColor; 25 | 26 | in vec4 o_Position; 27 | 28 | void main() 29 | { 30 | FragColor=o_Position; 31 | // FragColor=o_Position; 32 | } -------------------------------------------------------------------------------- /src/Renderer/renderAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | class CHAF_API RenderAPI 11 | { 12 | public: 13 | enum class API 14 | { 15 | None = 0, OpenGL = 1 16 | }; 17 | public: 18 | virtual void Init() = 0; 19 | virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; 20 | virtual void SetClearColor(const glm::vec4& color) = 0; 21 | virtual void SetLineMode(const bool enable) = 0; 22 | virtual void Clear() = 0; 23 | 24 | virtual void DrawIndexed(const Ref& vertexArray) = 0; 25 | 26 | inline static API GetAPI() { return s_API; } 27 | 28 | private: 29 | static API s_API; 30 | }; 31 | 32 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # folder 35 | **/build/ 36 | **/lib/ 37 | **/bin/ 38 | **/bin-int/ 39 | 40 | # visual studio 41 | *.sln 42 | *.vcxproj 43 | *.user 44 | *.filters 45 | */.vs/ 46 | 47 | #json 48 | *.json 49 | 50 | #other 51 | *.log 52 | *.tlog 53 | *.lastbuildstate 54 | *.idb 55 | *.pdb 56 | *.jpg 57 | *.obj 58 | *.hdr 59 | *.mtl 60 | *.blend 61 | *.blendl 62 | TODO.md -------------------------------------------------------------------------------- /src/Renderer/renderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | class CHAF_API Renderer 10 | { 11 | public: 12 | static void Init(); 13 | static void Shutdown(); 14 | 15 | static void OnWindowResize(uint32_t width, uint32_t height); 16 | 17 | static void BeginScene(Camera& camera); 18 | static void EndScene(); 19 | 20 | static void Submit(const Ref& vertexArray, const Ref& shader, const glm::mat4& transform = glm::mat4(1.0f)); 21 | 22 | inline static RenderAPI::API GetAPI() { return RenderAPI::GetAPI(); } 23 | 24 | private: 25 | struct SceneData 26 | { 27 | glm::mat4 ViewProjectionMatrix; 28 | }; 29 | 30 | static SceneData* m_SceneData; 31 | }; 32 | 33 | } -------------------------------------------------------------------------------- /cmake/Utility.cmake: -------------------------------------------------------------------------------- 1 | message(STATUS "include Utility.cmake successfully") 2 | 3 | function(GetCurrentDirName DirName) 4 | string(FIND ${CMAKE_CURRENT_SOURCE_DIR} "/" idx REVERSE) 5 | string(LENGTH ${CMAKE_CURRENT_SOURCE_DIR} len) 6 | string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${idx} ${len} res) 7 | string(REPLACE "/" "" res ${res}) 8 | set(${DirName} ${res} PARENT_SCOPE) 9 | endfunction() 10 | 11 | function(PrintList) 12 | cmake_parse_arguments("ARG" "" "TITLE;PREFIX" "STR" ${ARGN}) 13 | list(LENGTH ARG_STR len) 14 | if(NOT len) 15 | return() 16 | endif() 17 | if(NOT "${ARG_TITLE}" STREQUAL "") 18 | message(STATUS "${ARG_TITLE}") 19 | endif() 20 | foreach(str ${ARG_STR}) 21 | message(STATUS "${ARG_PREFIX}${str}") 22 | endforeach() 23 | endfunction() 24 | -------------------------------------------------------------------------------- /assets/shader/environment/background.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | layout (location = 0) in vec3 aPos; 4 | 5 | uniform mat4 projection; 6 | uniform mat4 view; 7 | 8 | out vec3 WorldPos; 9 | 10 | void main() 11 | { 12 | WorldPos = aPos; 13 | 14 | mat4 rotView = mat4(mat3(view)); 15 | vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0); 16 | 17 | gl_Position = clipPos.xyww; 18 | } 19 | 20 | #type fragment 21 | #version 330 core 22 | out vec4 FragColor; 23 | in vec3 WorldPos; 24 | 25 | uniform samplerCube environmentMap; 26 | 27 | void main() 28 | { 29 | vec3 envColor = texture(environmentMap, WorldPos).rgb; 30 | 31 | // HDR tonemap and gamma correct 32 | envColor = envColor / (envColor + vec3(1.0)); 33 | envColor = pow(envColor, vec3(1.0/2.2)); 34 | 35 | FragColor = vec4(envColor, 1.0); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/Renderer/effect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | class CHAF_API Cubemap 11 | { 12 | public: 13 | static RefCreate(const std::string& path); 14 | static RefCreate(); 15 | 16 | virtual ~Cubemap() = default; 17 | virtual uint32_t GetCubemapID() const = 0; 18 | virtual uint32_t GetTextureID() const = 0; 19 | virtual std::string GetPathName() const = 0; 20 | virtual Ref& GetTexture() = 0; 21 | 22 | virtual void BindCubeMap(Camera& camera, uint32_t slot = 0) const = 0; 23 | virtual void BindIrradianceMap(uint32_t slot = 0) const = 0; 24 | virtual void BindPrefilterMap(uint32_t slot = 0) const = 0; 25 | virtual void BindBRDFLUTTMap(uint32_t slot = 0) const = 0; 26 | }; 27 | } -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | pull_request: 5 | types: [master] 6 | push: 7 | branches: [master] 8 | 9 | jobs: 10 | build: 11 | name: "Build ${{ matrix.platform }} in ${{ matrix.build_type }}" 12 | strategy: 13 | matrix: 14 | platform: [windows] 15 | build_type: [Release] 16 | env: 17 | PARALLEL: -j 2 18 | runs-on: "${{ matrix.platform }}-latest" 19 | steps: 20 | - uses: actions/checkout@v2 21 | with: 22 | submodules: "recursive" 23 | 24 | - name: Configure 25 | run: cmake -H"." -B"build/${{ matrix.platform }}" -DBuild_Test_IlumEngine=OFF 26 | 27 | - name: "Build ${{ matrix.platform }} in ${{ matrix.build_type }}" 28 | run: cmake --build "build/${{ matrix.platform }}" --target ALL_BUILD --config ${{ matrix.build_type }} ${{ env.PARALLEL }} -------------------------------------------------------------------------------- /assets/shader/environment/equirectangular.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | layout (location = 0) in vec3 aPos; 4 | 5 | out vec3 v_FragPos; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | 10 | void main() 11 | { 12 | v_FragPos = aPos; 13 | gl_Position = projection * view * vec4(v_FragPos, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | out vec4 FragColor; 19 | in vec3 v_FragPos; 20 | 21 | uniform sampler2D equirectangularMap; 22 | 23 | const vec2 invAtan = vec2(0.1591, 0.3183); 24 | vec2 SampleSphericalMap(vec3 v) 25 | { 26 | vec2 uv = vec2(atan(v.z, v.x), asin(v.y)); 27 | uv *= invAtan; 28 | uv += 0.5; 29 | return uv; 30 | } 31 | 32 | void main() 33 | { 34 | vec2 uv = SampleSphericalMap(normalize(v_FragPos)); 35 | vec3 color = texture(equirectangularMap, uv).rgb; 36 | 37 | FragColor = vec4(color, 1.0); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/Renderer/command.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API RenderCommand 8 | { 9 | public: 10 | inline static void Init() 11 | { 12 | s_RenderAPI->Init(); 13 | } 14 | 15 | inline static void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) 16 | { 17 | s_RenderAPI->SetViewport(x, y, width, height); 18 | } 19 | 20 | inline static void SetLineMode(const bool enable) 21 | { 22 | s_RenderAPI->SetLineMode(enable); 23 | } 24 | 25 | inline static void SetClearColor(const glm::vec4& color) { s_RenderAPI->SetClearColor(color); } 26 | inline static void Clear() { s_RenderAPI->Clear(); } 27 | 28 | inline static void DrawIndexed(const Ref& vertexArray) 29 | { 30 | s_RenderAPI->DrawIndexed(vertexArray); 31 | } 32 | 33 | private: 34 | static RenderAPI* s_RenderAPI; 35 | }; 36 | 37 | } -------------------------------------------------------------------------------- /src/Renderer/texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class CHAF_API Texture 9 | { 10 | public: 11 | virtual ~Texture() = default; 12 | virtual uint32_t GetWidth() const = 0; 13 | virtual uint32_t GetHeight() const = 0; 14 | virtual uint32_t GetRendererID() const = 0; 15 | virtual std::string GetPathName() 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 | 22 | class CHAF_API Texture2D : public Texture 23 | { 24 | public: 25 | static Ref Create(const std::string& path, const bool hdr = false); 26 | static Ref Create(uint32_t width, uint32_t height); 27 | 28 | virtual uint32_t GetWidth() const = 0; 29 | virtual uint32_t GetHeight() const = 0; 30 | 31 | virtual bool HasImage() const = 0; 32 | }; 33 | } -------------------------------------------------------------------------------- /src/Scene/maincamera_layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | class CHAF_API MainCameraLayer :public Layer 10 | { 11 | public: 12 | MainCameraLayer(); 13 | virtual ~MainCameraLayer() = default; 14 | 15 | virtual void OnAttach() override {}; 16 | virtual void OnDetach() override {}; 17 | 18 | virtual void OnUpdate(Timestep timestep) override {}; 19 | virtual void OnImGuiRender() override; 20 | virtual void OnEvent(Event& event) override {}; 21 | 22 | bool& GetWindowHandle() { return m_WindowHandle; } 23 | 24 | public: 25 | static MainCameraLayer* GetInstance() { return s_Instance; } 26 | CameraController& GetCameraController() { return m_CameraController; } 27 | 28 | private: 29 | CameraController m_CameraController; 30 | static MainCameraLayer* s_Instance; 31 | bool m_WindowHandle = true; 32 | }; 33 | } -------------------------------------------------------------------------------- /cmake/Git.cmake: -------------------------------------------------------------------------------- 1 | message(STATUS "include Git.cmake successfully") 2 | 3 | macro(Git_Init) 4 | message(STATUS "--- Git Init ---") 5 | find_package(Git REQUIRED) 6 | message(STATUS "GIT_FOUND: ${GIT_FOUND}") 7 | message(STATUS "GIT_EXECUTABLE: ${GIT_EXECUTABLE}") 8 | message(STATUS "GIT_VERSION_STRING: ${GIT_VERSION_STRING}") 9 | endmacro() 10 | 11 | function(SubModuleUpdate) 12 | if(NOT GIT_FOUND) 13 | Git_Init() 14 | endif() 15 | execute_process( 16 | COMMAND ${GIT_EXECUTABLE} submodule init 17 | #OUTPUT_VARIABLE out 18 | #OUTPUT_STRIP_TRAILING_WHITESPACE 19 | #ERROR_QUIET 20 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 21 | ) 22 | execute_process( 23 | COMMAND ${GIT_EXECUTABLE} submodule update 24 | #OUTPUT_VARIABLE out 25 | #OUTPUT_STRIP_TRAILING_WHITESPACE 26 | #ERROR_QUIET 27 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 28 | ) 29 | endfunction() 30 | -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_vao.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API OpenGLVertexArray : public VertexArray 8 | { 9 | public: 10 | OpenGLVertexArray(); 11 | virtual ~OpenGLVertexArray(); 12 | 13 | virtual void Bind() const override; 14 | virtual void Unbind() const override; 15 | 16 | virtual void AddVertexBuffer(const std::shared_ptr& vertexBuffer) override; 17 | virtual void AddIndexBuffer(const std::shared_ptr& indexBuffer) override; 18 | 19 | virtual const std::vector>& GetVertexBuffers() const override { return m_VertexBuffers; } 20 | virtual const std::shared_ptr& GetIndexBuffer() const override { return m_IndexBuffer; } 21 | 22 | private: 23 | std::vector> m_VertexBuffers; 24 | std::shared_ptr m_IndexBuffer; 25 | uint32_t m_RendererID = 0; 26 | }; 27 | 28 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_context.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace Chaf 10 | { 11 | OpenGLContext::OpenGLContext(GLFWwindow* windowHandle) 12 | :m_WindowHandle(windowHandle) 13 | { 14 | CHAF_CORE_ASSERT(windowHandle, "Window handle is null!"); 15 | } 16 | 17 | void OpenGLContext::Init() 18 | { 19 | glfwMakeContextCurrent(m_WindowHandle); 20 | int status = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); 21 | CHAF_CORE_ASSERT(status, "Failed to initialize Glad!"); 22 | 23 | CHAF_CORE_INFO("Graphics API: OpenGL"); 24 | CHAF_CORE_INFO("Vendor: {0}", glGetString(GL_VENDOR)); 25 | CHAF_CORE_INFO("Renderer: {0}", glGetString(GL_RENDERER)); 26 | CHAF_CORE_INFO("Version: {0}", glGetString(GL_VERSION)); 27 | } 28 | 29 | void OpenGLContext::SwapBuffers() 30 | { 31 | glfwSwapBuffers(m_WindowHandle); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_texture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class CHAF_API OpenGLTexture2D :public Texture2D 9 | { 10 | public: 11 | OpenGLTexture2D(uint32_t width, uint32_t height); 12 | OpenGLTexture2D(const std::string& path, const bool hdr = false); 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 | virtual std::string GetPathName() const override { return m_Path; }; 19 | virtual bool HasImage() const override { return static_cast(m_Path.length()); } 20 | 21 | virtual void SetData(void* data, uint32_t size) override; 22 | 23 | virtual void Bind(uint32_t slot = 0) const override; 24 | 25 | private: 26 | std::string m_Path; 27 | uint32_t m_Width, m_Height; 28 | uint32_t m_RendererID; 29 | GLenum m_Format = 0; 30 | }; 31 | } -------------------------------------------------------------------------------- /src/App/log.txt: -------------------------------------------------------------------------------- 1 | [2020-10-28 20:49:06.695] [Chaf Engine] [info] Graphics API: OpenGL 2 | [2020-10-28 20:49:06.696] [Chaf Engine] [info] Vendor: NVIDIA Corporation 3 | [2020-10-28 20:49:06.697] [Chaf Engine] [info] Renderer: GeForce 940MX/PCIe/SSE2 4 | [2020-10-28 20:49:06.697] [Chaf Engine] [info] Version: 4.6.0 NVIDIA 441.22 5 | [2020-10-28 20:49:06.792] [Chaf Engine] [info] RendererAPI: OpenGL 6 | [2020-10-28 20:51:51.120] [App] [info] Create new object: mesh 7 | [2020-10-28 20:52:21.019] [App] [info] Create new object: mesh 8 | [2020-10-28 20:54:18.741] [App] [info] Create new object: New Object 9 | [2020-10-28 20:56:01.259] [App] [info] Create new object: New Object 10 | [2020-10-28 20:56:21.971] [App] [info] Create new object: New Object 11 | [2020-10-28 21:00:13.218] [App] [info] Create new object: New Object 12 | [2020-10-28 21:00:29.663] [App] [info] Create new object: New Object 13 | [2020-10-28 21:00:41.980] [App] [info] Create new object: New Object 14 | [2020-10-28 21:00:58.482] [App] [info] Create new object: New Object 15 | [2020-10-28 21:01:09.952] [App] [info] Create new object: New Object 16 | -------------------------------------------------------------------------------- /src/Renderer/Renderer2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class Renderer2D 9 | { 10 | public: 11 | static void Init(); 12 | static void Shutdown(); 13 | 14 | static void BeginScene(const Camera& camera); 15 | static void EndScene(); 16 | 17 | static void SetLineMode(const bool enable); 18 | 19 | // Primitives 20 | static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color); 21 | static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color); 22 | 23 | static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture); 24 | static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref& texture); 25 | 26 | static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture, const glm::vec4& color); 27 | static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref& texture, const glm::vec4& color); 28 | }; 29 | 30 | } -------------------------------------------------------------------------------- /src/Renderer/window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | struct WindowProps 11 | { 12 | std::string Title; 13 | uint32_t Width; 14 | uint32_t Height; 15 | 16 | WindowProps(const std::string& title = "Chaf Engine", 17 | uint32_t width = 1280, 18 | uint32_t height = 720) 19 | : Title(title), Width(width), Height(height) {} 20 | }; 21 | 22 | // abstraction window interface 23 | class CHAF_API Window 24 | { 25 | public: 26 | using EventCallbackFn = std::function; 27 | 28 | virtual ~Window() {} 29 | 30 | virtual void OnUpdate() = 0; 31 | 32 | virtual unsigned int GetWidth() const = 0; 33 | virtual unsigned int GetHeight() const = 0; 34 | 35 | // Attribue 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 | 42 | static Window* Create(const WindowProps& props = WindowProps()); 43 | }; 44 | 45 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Wenbo Chen 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 | copies 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 | copies 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. 22 | -------------------------------------------------------------------------------- /src/Editor/application.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | namespace Chaf 12 | { 13 | class CHAF_API Application 14 | { 15 | public: 16 | Application(const std::string name = "Chaf Engine"); 17 | virtual ~Application(); 18 | 19 | void Run(); 20 | void OnEvent(Event& e); 21 | void PushLayer(Layer* layer); 22 | void PushOverlay(Layer* layer); 23 | void Close(); 24 | public: 25 | inline static Application& Get() { return *s_Instance; } 26 | inline Window& GetWindow() { return *m_Window; } 27 | ImGuiLayer* GetImGuiLayer() { return m_ImGuiLayer; } 28 | private: 29 | bool OnWindowClose(WindowCloseEvent& e); 30 | bool OnWindowResize(WindowResizeEvent& e); 31 | private: 32 | bool m_Running = true; 33 | bool m_Minimized = false; 34 | float m_LastFrameTime = 0.0f; 35 | private: 36 | Ref m_Window; 37 | ImGuiLayer* m_ImGuiLayer; 38 | LayerStack m_LayerStack; 39 | private: 40 | static Application* s_Instance; 41 | }; 42 | 43 | // implement in client 44 | static Application* Create(); 45 | } -------------------------------------------------------------------------------- /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. 22 | -------------------------------------------------------------------------------- /src/Renderer/effect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | Ref Cubemap::Create(const std::string& path) 9 | { 10 | switch (Renderer::GetAPI()) 11 | { 12 | case RenderAPI::API::None: 13 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 14 | return nullptr; 15 | case RenderAPI::API::OpenGL: 16 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 17 | return CreateRef(path); 18 | default: 19 | break; 20 | } 21 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 22 | return nullptr; 23 | } 24 | 25 | Ref Cubemap::Create() 26 | { 27 | switch (Renderer::GetAPI()) 28 | { 29 | case RenderAPI::API::None: 30 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 31 | return nullptr; 32 | case RenderAPI::API::OpenGL: 33 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 34 | return CreateRef(); 35 | default: 36 | break; 37 | } 38 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 39 | return nullptr; 40 | } 41 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_window.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace Chaf 10 | { 11 | class WindowsWindow :public Window 12 | { 13 | public: 14 | WindowsWindow(const WindowProps& props); 15 | virtual ~WindowsWindow(); 16 | 17 | void OnUpdate() override; 18 | 19 | inline unsigned int GetWidth() const override { return m_Data.Width; } 20 | inline unsigned int GetHeight() const override { return m_Data.Height; } 21 | 22 | // Attribute 23 | inline void SetEventCallback(const EventCallbackFn& callback) override { m_Data.EventCallback = callback; } 24 | void SetVSync(bool enabled) override; 25 | bool IsVSync() const override; 26 | inline virtual void* GetNativeWindow() const { return m_Window; } 27 | 28 | private: 29 | virtual void Init(const WindowProps& props); 30 | virtual void Shutdown(); 31 | 32 | private: 33 | GLFWwindow* m_Window; 34 | GraphicsContext* m_Context; 35 | 36 | struct WindowData 37 | { 38 | std::string Title; 39 | unsigned int Width, Height; 40 | bool VSync; 41 | 42 | EventCallbackFn EventCallback; 43 | }; 44 | 45 | WindowData m_Data; 46 | }; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/Renderer/texture.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | Ref Texture2D::Create(const std::string& path, const bool hdr) 9 | { 10 | switch (Renderer::GetAPI()) 11 | { 12 | case RenderAPI::API::None: 13 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 14 | return nullptr; 15 | case RenderAPI::API::OpenGL: 16 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 17 | return CreateRef(path, hdr); 18 | default: 19 | break; 20 | } 21 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 22 | return nullptr; 23 | } 24 | 25 | Ref Texture2D::Create(uint32_t width, uint32_t height) 26 | { 27 | switch (Renderer::GetAPI()) 28 | { 29 | case RenderAPI::API::None: 30 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 31 | return nullptr; 32 | case RenderAPI::API::OpenGL: 33 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 34 | return CreateRef(width, height); 35 | default: 36 | break; 37 | } 38 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 39 | return nullptr; 40 | } 41 | } -------------------------------------------------------------------------------- /src/Renderer/renderer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #ifdef CHAF_OPENGL_API 5 | #include 6 | #endif // CHAF_OPENGL_API 7 | 8 | namespace Chaf 9 | { 10 | Renderer::SceneData* Renderer::m_SceneData = new Renderer::SceneData; 11 | 12 | void Renderer::Init() 13 | { 14 | RenderCommand::Init(); 15 | } 16 | 17 | void Renderer::Shutdown() 18 | { 19 | } 20 | 21 | void Renderer::OnWindowResize(uint32_t width, uint32_t height) 22 | { 23 | RenderCommand::SetViewport(0, 0, width, height); 24 | } 25 | 26 | void Renderer::BeginScene(Camera& camera) 27 | { 28 | m_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix(); 29 | } 30 | 31 | void Renderer::EndScene() 32 | { 33 | 34 | } 35 | 36 | void Renderer::Submit(const Ref& vertexArray, const Ref& shader, const glm::mat4& transform) 37 | { 38 | shader->Bind(); 39 | std::dynamic_pointer_cast(shader)->UploadUniformMat4("u_ViewProjection", m_SceneData->ViewProjectionMatrix); 40 | std::dynamic_pointer_cast(shader)->UploadUniformMat4("u_Transform", transform); 41 | 42 | vertexArray->Bind(); 43 | RenderCommand::DrawIndexed(vertexArray); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_renderAPI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | void OpenGLRendererAPI::Init() 8 | { 9 | glEnable(GL_BLEND); 10 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 11 | 12 | glEnable(GL_DEPTH_TEST); 13 | glDepthFunc(GL_LEQUAL); 14 | 15 | glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); 16 | } 17 | 18 | void OpenGLRendererAPI::SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) 19 | { 20 | glViewport(x, y, width, height); 21 | } 22 | 23 | void OpenGLRendererAPI::SetLineMode(const bool enable) 24 | { 25 | if (enable) 26 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 27 | else 28 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 29 | } 30 | 31 | void OpenGLRendererAPI::SetClearColor(const glm::vec4& color) 32 | { 33 | glClearColor(color.r, color.g, color.b, color.a); 34 | } 35 | 36 | void OpenGLRendererAPI::Clear() 37 | { 38 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 39 | } 40 | 41 | void OpenGLRendererAPI::DrawIndexed(const Ref& vertexArray) 42 | { 43 | glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr); 44 | glBindTexture(GL_TEXTURE_2D, 0); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/Scene/scene.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Chaf 12 | { 13 | struct Relationship 14 | { 15 | size_t children{}; 16 | entt::entity first{ entt::null }; 17 | entt::entity prev{ entt::null }; 18 | entt::entity next{ entt::null }; 19 | entt::entity parent{ entt::null }; 20 | }; 21 | 22 | class Entity; 23 | 24 | class Scene 25 | { 26 | friend class Entity; 27 | public: 28 | Scene(); 29 | ~Scene(); 30 | 31 | Entity CreateEntity(const std::string& name = std::string(), entt::entity parent = entt::null); 32 | 33 | void RenderObject(Camera& camera, const Ref& envMap); 34 | void RenderLight(const Camera& camera); 35 | 36 | Entity GetRoot(); 37 | bool Empty() { return (m_Root == entt::null); } 38 | void SetLineMode(const bool& enable) { m_LineMode = enable; } 39 | bool GetLineMode() { return m_LineMode; } 40 | 41 | private: 42 | entt::registry m_Registry; 43 | entt::entity m_Root = entt::null; 44 | Ref m_DefaultTexture; 45 | Ref m_DefaultShader; 46 | glm::vec4 m_DefaultColor; 47 | bool m_LineMode = false; 48 | }; 49 | } -------------------------------------------------------------------------------- /assets/shader/environment/irradiance.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | layout (location = 0) in vec3 aPos; 4 | 5 | out vec3 v_FragPos; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | 10 | void main() 11 | { 12 | v_FragPos = aPos; 13 | gl_Position = projection * view * vec4(v_FragPos, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | out vec4 FragColor; 19 | 20 | in vec3 v_FragPos; 21 | 22 | uniform samplerCube environmentMap; 23 | 24 | const float PI=3.14159265359; 25 | 26 | void main() 27 | { 28 | vec3 N=normalize(v_FragPos); 29 | vec3 irradiance=vec3(0.0); 30 | 31 | vec3 up=vec3(0.0,1.0,0.0); 32 | vec3 right=cross(up,N); 33 | up=cross(N,right); 34 | 35 | float sampleData=0.025; 36 | float nrSample=0.0; 37 | 38 | for(float phi=0.0;phi<2.0*PI;phi+=sampleData) 39 | { 40 | for(float theta=0.0;theta<0.5*PI;theta+=sampleData) 41 | { 42 | vec3 tangentSample=vec3(sin(theta)*cos(phi),sin(theta)*sin(phi),cos(theta)); 43 | vec3 sampleVec=tangentSample.x*right+tangentSample.y*up+tangentSample.z*N; 44 | 45 | irradiance+=texture(environmentMap,sampleVec).rgb*cos(theta)*sin(theta); 46 | nrSample++; 47 | } 48 | } 49 | irradiance=PI*irradiance*(1.0/float(nrSample)); 50 | FragColor=vec4(irradiance,1.0); 51 | } -------------------------------------------------------------------------------- /src/Scene/camera_controller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | class CHAF_API CameraController 11 | { 12 | public: 13 | CameraController(float fov, float aspect, CameraType type = CameraType::Perspective, float nearPlane = 0.1f, float farPlane = 100.0f, bool is_2D = false); 14 | void OnUpdate(Timestep ts); 15 | void OnEvent(Event& e); 16 | void OnResize(float width, float height); 17 | 18 | Camera& GetCamera() { return m_Camera; } 19 | const Camera& GetCamera() const { return m_Camera; } 20 | 21 | void SetActive(const bool enable) { m_Enable = enable; } 22 | void SetSensitivity(const float sensitivity) { m_Sensitivity = sensitivity; } 23 | void SetSpeed(const float speed) { m_Speed = speed; } 24 | 25 | float& GetSensitivity() { return m_Sensitivity; } 26 | float& GetSpeed() { return m_Speed; } 27 | 28 | private: 29 | bool OnMouseScrolled(MouseScrolledEvent& e); 30 | bool OnMouseMoved(MouseMovedEvent& e); 31 | bool OnWindowResized(WindowResizeEvent& e); 32 | 33 | private: 34 | bool IsCameraControllerActive(); 35 | bool IsMouseMiddlePress(); 36 | 37 | private: 38 | Camera m_Camera; 39 | float m_Speed = 10.0f; 40 | float m_Last_X = 0, m_Last_Y = 0; 41 | float m_Sensitivity = 0.1f; 42 | float m_Enable = false; 43 | }; 44 | } -------------------------------------------------------------------------------- /src/Renderer/shader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class CHAF_API Shader 9 | { 10 | public: 11 | ~Shader() = default; 12 | 13 | virtual void Bind() const = 0; 14 | virtual void UnBind() const = 0; 15 | 16 | virtual void SetMat4(const std::string& name, const glm::mat4& value) = 0; 17 | virtual void SetFloat(const std::string& name, const float& value) = 0; 18 | virtual void SetFloat3(const std::string& name, const glm::vec3& value) = 0; 19 | virtual void SetFloat4(const std::string& name, const glm::vec4& value) = 0; 20 | virtual void SetInt(const std::string& name, const int& value) = 0; 21 | virtual void SetBool(const std::string& name, const bool& value) = 0; 22 | 23 | virtual const std::string& GetName() const = 0; 24 | 25 | static Ref Create(const std::string& filepath); 26 | static Ref Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); 27 | }; 28 | 29 | class CHAF_API ShaderLibrary 30 | { 31 | public: 32 | void Add(const Ref& shader); 33 | void Add(const std::string& name, const Ref& shader); 34 | Ref Load(const std::string& filepath); 35 | Ref Load(const std::string& name, const std::string& filepath); 36 | 37 | Ref Get(const std::string& name); 38 | 39 | bool Exists(const std::string& name) const; 40 | private: 41 | std::unordered_map>m_Shaders; 42 | }; 43 | 44 | } -------------------------------------------------------------------------------- /src/App/app.cpp: -------------------------------------------------------------------------------- 1 | #include "app.h" 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | 14 | namespace Chaf 15 | { 16 | AppLayer::AppLayer() 17 | : Layer("AppLayer")//, m_CameraController(23.0f, 16.0f / 9.0f, CameraType::Perspective) 18 | { 19 | 20 | } 21 | 22 | void AppLayer::OnAttach() 23 | { 24 | /*Ref m_Mesh = CreateRef(); 25 | m_Mesh->Create("assets/mesh/cyborg/cyborg.obj"); 26 | //m_Mesh->Create(MeshType::Sphere); 27 | m_Mesh->SetTexture("assets/mesh/cyborg/cyborg_diffuse.png", 0); 28 | m_Mesh->AddTexture("assets/mesh/planet/mars.png"); 29 | SceneLayer::GetInstance()->PushMesh(m_Mesh); 30 | 31 | Ref m_Mesh1 = CreateRef(); 32 | m_Mesh1->Create("assets/mesh/planet/planet.obj"); 33 | //m_Mesh->Create(MeshType::Sphere); 34 | m_Mesh1->SetTexture("assets/mesh/planet/mars.png", 0); 35 | m_Mesh1->SetPosition(0.0f, 15.0f, 0.0f); 36 | SceneLayer::GetInstance()->PushMesh(m_Mesh1);*/ 37 | 38 | 39 | } 40 | 41 | void AppLayer::OnDetach() 42 | { 43 | 44 | } 45 | 46 | void AppLayer::OnUpdate(Timestep timestep) 47 | { 48 | 49 | } 50 | 51 | void AppLayer::OnImGuiRender() 52 | { 53 | 54 | } 55 | 56 | void AppLayer::OnEvent(Event& event) 57 | { 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chaf Engine 2 | 3 | My toy engine 4 | 5 | ## Updated 6 | 7 | I am currently working on a new renderer [IlumEngine](https://github.com/Chaf-Libraries/IlumEngine), so I may not add any new features to this renderer any longer. 8 | 9 | But I still use `Chaf-Engine` for my homework, check: 10 | 11 | [Computer Aided Geometric Design](https://github.com/Chaphlagical/CAGD) 12 | 13 | [Digital Image Process](https://github.com/Chaphlagical/DIP) 14 | 15 | ## Platform 16 | 17 | * **Windows 10** 18 | 19 | * **Visual Studio 2019** (Haven't tested on other version or platform) 20 | 21 | ## Installation 22 | 23 | Clone the repo 24 | 25 | ```shell 26 | git clone --recursive https://github.com/Chaphlagical/Chaf-Engine.git 27 | ``` 28 | 29 | Make sure you get CMake. Then run: 30 | 31 | ```shell 32 | mkdir build 33 | cd build 34 | cmake .. 35 | cmake --build ./ 36 | ``` 37 | 38 | ## Feature 39 | 40 | * Build: Premake5 41 | * Platform: Windows 10 42 | * Graphics API: OpenGL 43 | 44 | - [x] Component 45 | - [x] Transform 46 | - [x] Material 47 | - [x] Emisson 48 | - [x] Phong Lighting Model 49 | - [x] Cook Torrance PBR Model 50 | - [x] Geometry 51 | - [x] Sphere 52 | - [x] Plane 53 | - [x] Cube 54 | - [x] Load .obj from File 55 | - [x] Light Source 56 | - [x] Ideal Light 57 | - [x] Directional Light 58 | - [x] Point Light 59 | - [x] Spot Light 60 | 61 | ## Demo 62 | 63 | **UI** 64 | 65 | ![](./images/ui.png) 66 | 67 | **WireFrame** 68 | 69 | ![](./images/wireframe.png) 70 | 71 | **Phong Light Model** 72 | 73 | ![](./images/phong.png) 74 | 75 | **PBR** 76 | 77 | ![](./images/pbr.png) 78 | 79 | -------------------------------------------------------------------------------- /cmake/Download.cmake: -------------------------------------------------------------------------------- 1 | message(STATUS "include Download.cmake successfully") 2 | 3 | function(IsFileNotExist res filename hash_type hash) 4 | if(EXISTS ${filename}) 5 | file(${hash_type} ${filename} originFileHash) 6 | string(TOLOWER ${hash} lhash) 7 | string(TOLOWER ${originFileHash} loriginFileHash) 8 | if(${lhash} STREQUAL ${loriginFileHash}) 9 | set(${res} "FALSE" PARENT_SCOPE) 10 | endif() 11 | endif() 12 | set(${res} "TRUE" PARENT_SCOPE) 13 | endfunction() 14 | 15 | function(DownloadFile url filename hash_type hash) 16 | string(FIND "${url}" "." idx REVERSE) 17 | string(LENGTH "${url}" len) 18 | string(SUBSTRING "${url}" ${idx} ${len} suffix) 19 | string(REPLACE "." "" suffix ${suffix}) 20 | if("${suffix}" STREQUAL "zip") 21 | set(filename ${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${filename}) 22 | endif() 23 | IsFileNotExist(need ${filename} ${hash_type} ${hash}) 24 | if(${need} STREQUAL "FALSE") 25 | message(STATUS "Found File: ${filename}") 26 | return() 27 | endif() 28 | string(REGEX MATCH ".*/" dir ${filename}) 29 | file(MAKE_DIRECTORY ${dir}) 30 | message(STATUS "Download File: ${filename}") 31 | file(DOWNLOAD ${url} ${filename} 32 | #TIMEOUT 120 # seconds 33 | SHOW_PROGRESS 34 | EXPECTED_HASH ${hash_type}=${hash} 35 | TLS_VERIFY ON 36 | ) 37 | if("${suffix}" STREQUAL "zip") 38 | execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${filename} 39 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 40 | endif() 41 | endfunction() 42 | -------------------------------------------------------------------------------- /src/Engine/Platform/OpenGL/opengl_input.cpp: -------------------------------------------------------------------------------- 1 | #ifdef CHAF_OPENGL_API 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | 13 | bool Input::IsKeyPressed(void* window, KeyCode keycode) 14 | { 15 | auto state = glfwGetKey(static_cast(window), static_cast(keycode)); 16 | return state == GLFW_PRESS || state == GLFW_REPEAT; 17 | } 18 | 19 | 20 | bool Input::IsMouseButtonPressed(void* window, MouseCode button) 21 | { 22 | auto state = glfwGetMouseButton(static_cast(window), static_cast(button)); 23 | return state == GLFW_PRESS; 24 | } 25 | 26 | 27 | std::pair Input::GetMousePosition(void* window) 28 | { 29 | double xpos, ypos; 30 | glfwGetCursorPos(static_cast(window), &xpos, &ypos); 31 | return { float(xpos),float(ypos) }; 32 | } 33 | 34 | 35 | float Input::GetMouseX(void* window) 36 | { 37 | auto [x, y] = GetMousePosition(static_cast(window)); 38 | return (float)x; 39 | } 40 | 41 | 42 | float Input::GetMouseY(void* window) 43 | { 44 | auto [x, y] = GetMousePosition(static_cast(window)); 45 | return (float)y; 46 | } 47 | 48 | 49 | void Input::SetCursorHidden(void* window, const bool enable) 50 | { 51 | if (enable) 52 | { 53 | glfwSetInputMode(static_cast(window), GLFW_CURSOR, GLFW_CURSOR_DISABLED); 54 | } 55 | else 56 | glfwSetInputMode(static_cast(window), GLFW_CURSOR, GLFW_CURSOR_NORMAL); 57 | } 58 | } 59 | 60 | #endif // CHAF_OPENGL_API -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_effect.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Chaf 12 | { 13 | class CHAF_API OpenGLCubemap : public Cubemap 14 | { 15 | public: 16 | OpenGLCubemap(const std::string& path); 17 | OpenGLCubemap(); 18 | virtual ~OpenGLCubemap(); 19 | virtual uint32_t GetCubemapID() const override { return m_CubemapID; } 20 | virtual uint32_t GetTextureID() const override { return m_Texture->GetRendererID(); } 21 | virtual std::string GetPathName() const override { return m_Texture->GetPathName(); } 22 | virtual Ref& GetTexture() { return m_Texture; }; 23 | 24 | virtual void BindCubeMap(Camera& camera, uint32_t slot = 0) const override; 25 | virtual void BindIrradianceMap(uint32_t slot = 0) const override; 26 | virtual void BindPrefilterMap(uint32_t slot = 0) const override; 27 | virtual void BindBRDFLUTTMap(uint32_t slot = 0) const override; 28 | 29 | private: 30 | void GenCube(); 31 | void GenQuad(); 32 | void GenBuffer(); 33 | void RenderCube() const; 34 | void RenderQuad() const; 35 | private: 36 | Ref m_Texture; 37 | Ref m_EquirectangularToCubemapShader; 38 | Ref m_BackgroundShader; 39 | Ref m_IrradianceShader; 40 | Ref m_PrefilterShader; 41 | Ref m_BRDFShader; 42 | uint32_t m_CubemapID = 0; 43 | uint32_t m_IrradianceMapID = 0; 44 | uint32_t m_PrefilterMapID = 0; 45 | uint32_t m_BRDFLUTTextureID = 0; 46 | uint32_t m_CubeVAO = 0, m_CubeVBO = 0; 47 | uint32_t m_QuadVAO = 0, m_QuadVBO = 0; 48 | }; 49 | } -------------------------------------------------------------------------------- /src/Renderer/primitive.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define GLM_ENABLE_EXPERIMENTAL 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace Chaf 17 | { 18 | struct Vertex 19 | { 20 | glm::vec3 m_Position; 21 | glm::vec2 m_TexCoord; 22 | glm::vec3 m_Normal; 23 | glm::vec3 m_Tangent; 24 | glm::vec3 m_Bitangent; 25 | bool operator == (const Vertex& v) const 26 | { 27 | return m_Position == v.m_Position && 28 | m_TexCoord == v.m_TexCoord && 29 | m_Normal == v.m_Normal; 30 | }; 31 | }; 32 | 33 | struct Posture 34 | { 35 | glm::vec3 m_Position; 36 | glm::vec3 m_Rotation; 37 | glm::vec3 m_Scale; 38 | glm::mat4 m_Transform; 39 | void Update() 40 | { 41 | glm::mat4 translation = glm::translate(glm::mat4(1.0f), m_Position); 42 | glm::mat4 rotation = glm::mat4_cast(glm::qua(glm::radians(m_Rotation))); 43 | m_Transform = glm::scale(translation * rotation, m_Scale); 44 | }; 45 | }; 46 | 47 | struct Triangle 48 | { 49 | uint32_t idx1; 50 | uint32_t idx2; 51 | uint32_t idx3; 52 | }; 53 | 54 | enum class MeshType 55 | { 56 | None = 0, Plane = 1, Cube = 2, Sphere = 3, Model=4 57 | }; 58 | } 59 | 60 | namespace std { 61 | template<> struct hash { 62 | size_t operator()(Chaf::Vertex const& vertex) const 63 | { 64 | return ((hash()(vertex.m_Position) ^ 65 | (hash()(vertex.m_Normal) << 1)) >> 1) ^ 66 | (hash()(vertex.m_TexCoord) << 1); 67 | } 68 | }; 69 | } 70 | 71 | #define MAX_TEXTURE_NUM 10 -------------------------------------------------------------------------------- /src/Renderer/camera.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | Camera::Camera(float fov, float aspect, CameraType type, float nearPlane, float farPlane) 11 | :m_Fov(fov), m_Aspect(aspect), m_Type(type), m_NearPlane(nearPlane), m_FarPlane(farPlane), m_ViewMatrix(1.0f) 12 | { 13 | UpdateProjectionMatrix(); 14 | UpdateViewMatrix(); 15 | } 16 | 17 | void Camera::UpdateViewMatrix() 18 | { 19 | glm::vec3 front = glm::vec3(1.0f); 20 | 21 | front.x = cos(glm::radians(m_Pitch)) * cos(glm::radians(m_Yaw)); 22 | front.y = sin(glm::radians(m_Pitch)); 23 | front.z = cos(glm::radians(m_Pitch)) * sin(glm::radians(m_Yaw)); 24 | m_Front = glm::normalize(front); 25 | 26 | // right vector 27 | m_Right = glm::normalize(glm::cross(front, glm::vec3(0.0f, 1.0f, 0.0f))); 28 | 29 | // up vector 30 | m_Up = glm::normalize(glm::cross(m_Right, m_Front)); 31 | 32 | m_ViewMatrix = glm::lookAt(m_Position, m_Front + m_Position, m_Up); 33 | UpdateViewProjectionMatrix(); 34 | } 35 | 36 | void Camera::UpdateProjectionMatrix() 37 | { 38 | switch (m_Type) 39 | { 40 | case Chaf::CameraType::None: 41 | CHAF_ASSERT(false, "Unknown CameraType!"); 42 | return; 43 | case Chaf::CameraType::Orthographic: 44 | m_ProjectionMatrix = glm::ortho(-glm::radians(m_Fov), glm::radians(m_Fov), -glm::radians(m_Fov) / m_Aspect, glm::radians(m_Fov) / m_Aspect, m_NearPlane, m_FarPlane); 45 | UpdateViewProjectionMatrix(); 46 | return; 47 | case Chaf::CameraType::Perspective: 48 | m_ProjectionMatrix = glm::perspective(glm::radians(m_Fov), m_Aspect, m_NearPlane, m_FarPlane); 49 | UpdateViewProjectionMatrix(); 50 | return; 51 | } 52 | CHAF_ASSERT(false, "Unknown CameraType!"); 53 | return; 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /src/Engine/core.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #ifdef _WIN32 6 | #define CHAF_PLATFORM_WINDOWS 7 | #endif // !_WIN32 8 | 9 | #ifdef CHAF_PLATFORM_WINDOWS 10 | #if CHAF_DYNAMIC_LINK 11 | #ifdef CHAF_BUILD_DLL 12 | #define CHAF_API __declspec(dllexport) 13 | #else 14 | #define CHAF_API __declspec(dllimport) 15 | #endif // CHAF_BUILD_DLL 16 | #else 17 | #define CHAF_API 18 | #endif // CHAF_DYNAMIC_LINK 19 | #else 20 | #error Chaf only support Windows for now! 21 | #endif // CHAF_PLATFORM_WINDOWS 22 | 23 | #define BIT(x)(1< 46 | using Scope = std::unique_ptr; 47 | template 48 | constexpr Scope CreateScope(Args&& ... args) 49 | { 50 | return std::make_unique(std::forward(args)...); 51 | } 52 | 53 | template 54 | using Ref = std::shared_ptr; 55 | template 56 | constexpr Ref CreateRef(Args&& ... args) 57 | { 58 | return std::make_shared(std::forward(args)...); 59 | } 60 | template 61 | constexpr Ref CastRef(Args&& ... args) 62 | { 63 | return std::dynamic_pointer_cast(std::forward(args)...); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace Chaf 6 | { 7 | class CHAF_API OpenGLVertexBuffer :public VertexBuffer 8 | { 9 | public: 10 | OpenGLVertexBuffer(float* vertices, uint32_t size); 11 | OpenGLVertexBuffer(uint32_t size); 12 | virtual ~OpenGLVertexBuffer(); 13 | 14 | virtual void Bind() const; 15 | virtual void Unbind() const; 16 | 17 | virtual void SetLayout(const BufferLayout& layout) override { m_Layout = layout; } 18 | virtual const BufferLayout& GetLayout() const override { return m_Layout; } 19 | 20 | private: 21 | uint32_t m_RendererID = 0; 22 | BufferLayout m_Layout; 23 | }; 24 | 25 | class CHAF_API OpenGLIndexBuffer :public IndexBuffer 26 | { 27 | public: 28 | OpenGLIndexBuffer(uint32_t* indices, uint32_t count); 29 | virtual ~OpenGLIndexBuffer(); 30 | 31 | virtual void Bind() const override; 32 | virtual void Unbind() const override; 33 | 34 | virtual uint32_t GetCount() const { return m_Count; } 35 | 36 | private: 37 | uint32_t m_RendererID = 0; 38 | uint32_t m_Count = 0; 39 | }; 40 | 41 | class CHAF_API OpenGLFrameBuffer :public FrameBuffer 42 | { 43 | public: 44 | OpenGLFrameBuffer(const FrameBufferSpecification& spec); 45 | virtual ~OpenGLFrameBuffer(); 46 | 47 | void Invalidate(); 48 | 49 | virtual uint32_t GetColorAttachmentRendererID() const { return m_ColorAttachment; } 50 | 51 | FrameBufferSpecification& GetSpecification() override { return m_Specification; } 52 | const FrameBufferSpecification& GetSpecification() const override { return m_Specification; } 53 | 54 | virtual void Bind() override; 55 | virtual void Unbind() override; 56 | 57 | virtual void Resize(uint32_t width, uint32_t height) override; 58 | 59 | private: 60 | uint32_t m_RendererID = 0; 61 | uint32_t m_ColorAttachment = 0, m_DepthAttachment = 0; 62 | FrameBufferSpecification m_Specification; 63 | }; 64 | } -------------------------------------------------------------------------------- /src/Engine/layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | class CHAF_API Layer 13 | { 14 | public: 15 | Layer(const std::string& name = "Layer") 16 | :m_DebugName(name) {} 17 | virtual ~Layer() = default; 18 | 19 | virtual void OnAttach() {} 20 | virtual void OnDetach() {} 21 | virtual void OnUpdate(Timestep timestep) {} 22 | virtual void OnImGuiRender() {} 23 | virtual void OnEvent(Event& event) {} 24 | 25 | inline const std::string& GetName() const { return m_DebugName; } 26 | 27 | protected: 28 | std::string m_DebugName; 29 | }; 30 | 31 | /////////////////////// Stack /////////////////////////////// 32 | 33 | class CHAF_API LayerStack 34 | { 35 | public: 36 | LayerStack() {} 37 | ~LayerStack() 38 | { 39 | for (Layer* layer : m_Layers) 40 | delete layer; 41 | } 42 | 43 | void PushLayer(Layer* layer) 44 | { 45 | m_Layers.emplace(m_Layers.begin() + m_LayerInsertIndex, layer); 46 | m_LayerInsertIndex++; 47 | } 48 | 49 | void PushOverlay(Layer* overlay) { m_Layers.emplace_back(overlay); } 50 | 51 | void PopLayer(Layer* layer) 52 | { 53 | auto it = std::find(m_Layers.begin(), m_Layers.end(), layer); 54 | if (it != m_Layers.end()) 55 | { 56 | layer->OnDetach(); 57 | m_Layers.erase(it); 58 | m_LayerInsertIndex--; 59 | } 60 | } 61 | 62 | void PopOverlay(Layer* overlay) 63 | { 64 | auto it = std::find(m_Layers.begin(), m_Layers.end(), overlay); 65 | if (it != m_Layers.end()) 66 | { 67 | overlay->OnDetach(); 68 | m_Layers.erase(it); 69 | } 70 | } 71 | 72 | std::vector::iterator begin() { return m_Layers.begin(); } 73 | std::vector::iterator end() { return m_Layers.end(); } 74 | 75 | private: 76 | std::vector m_Layers; 77 | unsigned int m_LayerInsertIndex = 0; 78 | }; 79 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_shader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | class CHAF_API OpenGLShader : public Shader 9 | { 10 | public: 11 | OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc); 12 | OpenGLShader(const std::string& filepath); 13 | virtual ~OpenGLShader(); 14 | 15 | virtual void Bind() const override; 16 | virtual void UnBind() const override; 17 | 18 | virtual void SetMat4(const std::string& name, const glm::mat4& value) override; 19 | virtual void SetBool(const std::string& name, const bool& value) override; 20 | virtual void SetFloat(const std::string& name, const float& value) override; 21 | virtual void SetFloat3(const std::string& name, const glm::vec3& value) override; 22 | virtual void SetFloat4(const std::string& name, const glm::vec4& value) override; 23 | virtual void SetInt(const std::string& name, const int& value) override; 24 | 25 | virtual const std::string& GetName() const override { return m_Name; } 26 | 27 | void UploadUniformMat4(const std::string name, const glm::mat4& matrix); 28 | void UploadUniformMat3(const std::string name, const glm::mat3& matrix); 29 | 30 | void UploadUniformInt(const std::string name, const int& value); 31 | 32 | void UploadUniformBool(const std::string name, const bool& value); 33 | 34 | void UploadUniformFloat1(const std::string name, const float& value); 35 | void UploadUniformFloat2(const std::string name, const glm::vec2& value); 36 | void UploadUniformFloat3(const std::string name, const glm::vec3& value); 37 | void UploadUniformFloat4(const std::string name, const glm::vec4& value); 38 | 39 | private: 40 | std::string ReadFile(const std::string filepath); 41 | std::unordered_map PreProcess(const std::string& source); 42 | void Compile(std::unordered_map& shaderSources); 43 | 44 | private: 45 | uint32_t m_RendererID = 0; 46 | std::string m_Name; 47 | }; 48 | 49 | } -------------------------------------------------------------------------------- /src/Scene/entity.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | class Entity 10 | { 11 | public: 12 | Entity() = default; 13 | Entity(entt::entity handle, Scene* scene); 14 | Entity(const Entity& other) = default; 15 | 16 | template 17 | T& AddComponent(Args&&... args) 18 | { 19 | CHAF_CORE_ASSERT(!HasComponent(), "Entity already has component!"); 20 | return m_Scene->m_Registry.emplace(m_EntityHandle, std::forward(args)...); 21 | } 22 | 23 | template 24 | bool HasComponent() 25 | { 26 | return m_Scene->m_Registry.has(m_EntityHandle); 27 | } 28 | 29 | template 30 | void RemoveComponent() 31 | { 32 | CHAF_CORE_ASSERT(HasComponent(), "Entity doesn't have component!"); 33 | m_Scene->m_Registry.remove(m_EntityHandle); 34 | } 35 | 36 | template 37 | T& GetComponent() 38 | { 39 | CHAF_CORE_ASSERT(HasComponent(), "Entity doesn't have component!"); 40 | return m_Scene->m_Registry.get(m_EntityHandle); 41 | } 42 | 43 | operator bool() const 44 | { 45 | if (m_Scene == nullptr)return false; 46 | return m_Scene->m_Registry.valid(m_EntityHandle); 47 | } 48 | 49 | uint32_t ID() { return static_cast(m_EntityHandle); } 50 | 51 | void GetHandle(entt::entity& node) { node = m_EntityHandle; } 52 | bool SameOf(Entity& node); // not including same scene; 53 | bool HasParent(); 54 | bool HasChild(); 55 | bool IsRoot(); 56 | 57 | Entity GetFirstChild(); 58 | Entity GetNext(); 59 | Entity GetParent(); 60 | Entity GetPrev(); 61 | void AddChild(Entity& node); 62 | void AddSibling(Entity& node); 63 | void MoveAsChildOf(Entity& dstNode); // this -> disNode 64 | void Remove(); 65 | Entity CreateChild(const std::string& name = std::string()); 66 | private: 67 | bool IsSonOf(Entity& node); 68 | private: 69 | entt::entity m_EntityHandle{ entt::null }; 70 | Scene* m_Scene = nullptr; 71 | }; 72 | } -------------------------------------------------------------------------------- /src/Engine/log.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define SPDLOG_WCHAR_FILENAMES 3 | 4 | #include 5 | 6 | __pragma(warning(push, 0)) 7 | #include 8 | #include 9 | __pragma(warning(pop)) 10 | 11 | namespace Chaf 12 | { 13 | template class CHAF_API std::shared_ptr; 14 | 15 | class CHAF_API Log 16 | { 17 | public: 18 | static void Init(); 19 | 20 | static std::shared_ptr& GetCoreLogger() { return s_CoreLogger; } 21 | static std::shared_ptr& GetClientLogger() { return s_ClientLogger; } 22 | 23 | public: 24 | template 25 | static void Core_Log(spdlog::level::level_enum lvl, const FormatString& fmt, const Args&... args) 26 | { 27 | s_CoreLogger->log(lvl, fmt, args...); 28 | } 29 | 30 | template 31 | static void Client_Log(spdlog::level::level_enum lvl, const FormatString& fmt, const Args&... args) 32 | { 33 | s_ClientLogger ->log(lvl, fmt, args...); 34 | } 35 | 36 | private: 37 | static std::shared_ptr s_CoreLogger; 38 | static std::shared_ptr s_ClientLogger; 39 | }; 40 | } 41 | 42 | // core log macros 43 | #define CHAF_CORE_ERROR(...) ::Chaf::Log::Core_Log(spdlog::level::err, __VA_ARGS__) 44 | #define CHAF_CORE_WARN(...) ::Chaf::Log::Core_Log(spdlog::level::warn, __VA_ARGS__) 45 | #define CHAF_CORE_INFO(...) ::Chaf::Log::Core_Log(spdlog::level::info, __VA_ARGS__) 46 | #define CHAF_CORE_TRACE(...) ::Chaf::Log::Core_Log(spdlog::level::trace, __VA_ARGS__) 47 | #define CHAF_CORE_CRITICAL(...) ::Chaf::Log::Core_Log(spdlog::level::critical, __VA_ARGS__) 48 | 49 | // client log macros 50 | #define CHAF_ERROR(...) ::Chaf::Log::Client_Log(spdlog::level::err, __VA_ARGS__) 51 | #define CHAF_WARN(...) ::Chaf::Log::Client_Log(spdlog::level::warn, __VA_ARGS__) 52 | #define CHAF_INFO(...) ::Chaf::Log::Client_Log(spdlog::level::info, __VA_ARGS__) 53 | #define CHAF_CRITICAL(...) ::Chaf::Log::Client_Log(spdlog::level::critical, __VA_ARGS__) -------------------------------------------------------------------------------- /src/Renderer/mesh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | class CHAF_API TriMesh 10 | { 11 | public: 12 | static Ref Create() { return CreateRef(); } 13 | static Ref Create(const std::vector& vertices, const std::vector& indices) { return CreateRef(vertices, indices); } 14 | static Ref Create(const MeshType& type, const uint32_t& sample = 1) { return CreateRef(type, sample); } 15 | static Ref Create(const std::string& path) { return CreateRef(path); } 16 | 17 | TriMesh() 18 | :m_Type(MeshType::None), m_Name("mesh"), m_Path(" ") {} 19 | TriMesh(const std::vector& vertices, const std::vector& indices); 20 | TriMesh(const MeshType& type, const uint32_t& sample = 1); 21 | TriMesh(const std::string& path); 22 | 23 | ~TriMesh() = default; 24 | 25 | void Draw(bool lineMode = false); // Draw vertices 26 | public: 27 | // Get attribute 28 | const size_t GetVerticesNum() { return m_Vertices.size(); } 29 | const size_t GetTriangleNum() { return m_Triangle.size(); } 30 | const MeshType GetMeshType() { return m_Type; } 31 | const std::string GetPathName() { return m_Path; } 32 | const bool HasNormal() { return m_HasNormal; } 33 | const bool HasTexCoord() { return m_HasTexCoord; } 34 | 35 | private: 36 | void GenVertexArray(); 37 | void GenTBN(); 38 | private: 39 | void CreatePlane(const uint32_t& sample); 40 | void CreateCube(const uint32_t& sample); 41 | void CreateSphere(const uint32_t& sample); 42 | void ObjLoader(const std::string& path); 43 | 44 | private: 45 | std::string m_Name; 46 | std::string m_Path = std::string(); 47 | MeshType m_Type; 48 | 49 | // buffer 50 | Ref m_VertexArray; 51 | // mesh data 52 | std::vector m_Vertices; 53 | std::vector m_Indices; 54 | std::vector m_Triangle; 55 | // feature 56 | bool m_HasNormal = false; 57 | bool m_HasTexCoord = false; 58 | }; 59 | } -------------------------------------------------------------------------------- /src/Scene/scene_layer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | // TODO: Component System 12 | namespace Chaf 13 | { 14 | struct SceneRenderData 15 | { 16 | Ref whiteTexture; 17 | Ref checkboardTexture; 18 | glm::vec4 color; 19 | glm::mat4 transform; 20 | 21 | SceneRenderData() 22 | { 23 | whiteTexture = Texture2D::Create(1, 1); 24 | uint32_t defaultTextureData = 0xffffffff; 25 | whiteTexture->SetData(&defaultTextureData, sizeof(uint32_t)); 26 | checkboardTexture = Texture2D::Create("assets/texture/checkboard.png"); 27 | color = glm::vec4{ 1.0f }; 28 | transform = glm::mat4{ 1.0f }; 29 | } 30 | }; 31 | 32 | class CHAF_API SceneLayer 33 | : public Layer 34 | { 35 | public: 36 | SceneLayer(); 37 | ~SceneLayer() = default; 38 | 39 | virtual void OnAttach() override; 40 | virtual void OnDetach() override {}; 41 | 42 | virtual void OnUpdate(Timestep timestep) override; 43 | virtual void OnImGuiRender() override; 44 | virtual void OnEvent(Event& event) override; 45 | 46 | void BeginScene(); 47 | void EndScene(); 48 | void DrawGrid(); 49 | 50 | static SceneLayer* GetInstance() { return s_Instance; }; 51 | Ref& GetScene() { return m_MainScene; } 52 | Ref& GetSkybox() { return m_Cubemap; } 53 | static Ref& GetDefaultRenderData() { return m_DefaultSceneRenderData; } 54 | 55 | bool IsShowGrid() { return m_EnableGrid; } 56 | void SetShowGrid(const bool& enable) { m_EnableGrid = enable; } 57 | static void SetGuizmoFunc(std::function func) { m_GuizmoFunc = func; } 58 | 59 | private: 60 | static SceneLayer* s_Instance; 61 | Ref m_MainScene; 62 | 63 | private: 64 | Ref m_Cubemap; 65 | Ref m_FrameBuffer; 66 | Ref m_WireFrameShader; 67 | glm::vec2 m_ViewportSize = { 0.0f, 0.0f }; 68 | Ref m_Grid; 69 | bool m_EnableGrid = true; 70 | static Ref m_DefaultSceneRenderData; 71 | 72 | static std::function m_GuizmoFunc; 73 | }; 74 | } -------------------------------------------------------------------------------- /src/Editor/inspector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Chaf 10 | { 11 | class CHAF_API Inspector 12 | { 13 | public: 14 | static void ShowInspector(bool* p_open); 15 | 16 | static void ShowTransformComponent(); 17 | static void ShowMaterialComponent(); 18 | static void ShowMeshComponent(); 19 | static void ShowLightComponent(); 20 | 21 | static std::string BoolString(bool x) { if (x)return "true"; return "false"; } 22 | 23 | template 24 | static bool DeleteComponent(const std::string& label) 25 | { 26 | if (ImGui::BeginPopupContextItem(("Delete "+label).c_str())) 27 | { 28 | if (ImGui::MenuItem("Delete Component")) 29 | { 30 | EditorBasic::GetSelectEntity().RemoveComponent(); 31 | ImGui::End(); 32 | return true; 33 | } 34 | ImGui::EndPopup(); 35 | } 36 | return false; 37 | } 38 | 39 | template 40 | static void ShowSetTexture(Ref& texture, const std::string& label, T& handler) 41 | { 42 | ImGui::Columns(2, (label + " Texture").c_str()); 43 | ImGui::Text((label + " Texture").c_str()); 44 | EditorBasic::ShowTexture((label + " preview").c_str(), texture); 45 | 46 | ImGui::NextColumn(); 47 | ImGui::NewLine(); 48 | if (ImGui::MenuItem("Show Path")) 49 | ImGui::OpenPopup((label + " Path").c_str()); 50 | if (ImGui::BeginPopup((label + " Path").c_str())) 51 | { 52 | ImGui::Text((texture->GetPathName()).c_str()); 53 | ImGui::EndPopup(); 54 | } 55 | ImGui::NewLine(); 56 | ImGui::PushID(std::to_string(EditorBasic::GetSelectEntity().ID()).c_str()); 57 | if (ImGui::MenuItem("Load")) 58 | EditorBasic::SetPopupFlag(("Choose "+label).c_str()); 59 | EditorBasic::GetFileDialog(("Choose " + label).c_str(), ".png,.jpg,.bmp,.jpeg", [&](const std::string& filePathName) { 60 | handler->ResetTexture(texture, filePathName); 61 | }); 62 | ImGui::PopID(); 63 | ImGui::PushID(std::to_string(EditorBasic::GetSelectEntity().ID()).c_str()); 64 | ImGui::NewLine(); 65 | if (ImGui::MenuItem("Reset"))handler->ResetTexture(texture); 66 | ImGui::Columns(1); 67 | ImGui::PopID(); 68 | } 69 | }; 70 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_vao.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | static GLenum ShaderDataTypeToOpenGLBaseType(ShaderDataType type) 9 | { 10 | switch (type) 11 | { 12 | case ShaderDataType::Float: return GL_FLOAT; 13 | case ShaderDataType::Float2: return GL_FLOAT; 14 | case ShaderDataType::Float3: return GL_FLOAT; 15 | case ShaderDataType::Float4: return GL_FLOAT; 16 | case ShaderDataType::Mat3: return GL_FLOAT; 17 | case ShaderDataType::Mat4: return GL_FLOAT; 18 | case ShaderDataType::Int: return GL_INT; 19 | case ShaderDataType::Int2: return GL_INT; 20 | case ShaderDataType::Int3: return GL_INT; 21 | case ShaderDataType::Int4: return GL_INT; 22 | case ShaderDataType::Bool: return GL_BOOL; 23 | } 24 | CHAF_CORE_ASSERT(false, "Unknown ShaderDataType!"); 25 | return 0; 26 | } 27 | 28 | OpenGLVertexArray::OpenGLVertexArray() 29 | { 30 | glCreateVertexArrays(1, &m_RendererID); 31 | } 32 | 33 | OpenGLVertexArray::~OpenGLVertexArray() 34 | { 35 | glDeleteVertexArrays(1, &m_RendererID); 36 | } 37 | 38 | void OpenGLVertexArray::Bind() const 39 | { 40 | glBindVertexArray(m_RendererID); 41 | } 42 | 43 | void OpenGLVertexArray::Unbind() const 44 | { 45 | glBindVertexArray(0); 46 | } 47 | 48 | void OpenGLVertexArray::AddVertexBuffer(const std::shared_ptr& vertexBuffer) 49 | { 50 | glBindVertexArray(m_RendererID); 51 | vertexBuffer->Bind(); 52 | 53 | CHAF_CORE_ASSERT(vertexBuffer->GetLayout().GetElements().size(), "Vertex Buffer has no layout!"); 54 | 55 | uint32_t index = 0; 56 | for (const auto& element : vertexBuffer->GetLayout()) 57 | { 58 | glEnableVertexAttribArray(index); 59 | glVertexAttribPointer(index, 60 | element.GetComponentCount(), 61 | ShaderDataTypeToOpenGLBaseType(element.Type), 62 | element.Normalized ? GL_TRUE : GL_FALSE, 63 | vertexBuffer->GetLayout().GetStride(), 64 | (const void*)(element.Offset)); 65 | index++; 66 | } 67 | m_VertexBuffers.push_back(vertexBuffer); 68 | } 69 | 70 | void OpenGLVertexArray::AddIndexBuffer(const std::shared_ptr& indexBuffer) 71 | { 72 | glBindVertexArray(m_RendererID); 73 | indexBuffer->Bind(); 74 | 75 | m_IndexBuffer = indexBuffer; 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /src/Renderer/buffer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #ifdef CHAF_OPENGL_API 4 | #include 5 | #endif // CHAF_OPENGL_API 6 | 7 | namespace Chaf 8 | { 9 | Ref VertexBuffer::Create(uint32_t size) 10 | { 11 | switch (Renderer::GetAPI()) 12 | { 13 | case RenderAPI::API::None: 14 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 15 | return nullptr; 16 | case RenderAPI::API::OpenGL: 17 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 18 | return CreateRef(size); 19 | default: 20 | break; 21 | } 22 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 23 | return nullptr; 24 | } 25 | 26 | Ref VertexBuffer::Create(float* vertices, uint32_t size) 27 | { 28 | switch (Renderer::GetAPI()) 29 | { 30 | case RenderAPI::API::None: 31 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 32 | return nullptr; 33 | case RenderAPI::API::OpenGL: 34 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 35 | return CreateRef(vertices, size); 36 | default: 37 | break; 38 | } 39 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 40 | return nullptr; 41 | } 42 | 43 | Ref IndexBuffer::Create(uint32_t* indices, uint32_t size) 44 | { 45 | switch (Renderer::GetAPI()) 46 | { 47 | case RenderAPI::API::None: 48 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 49 | return nullptr; 50 | case RenderAPI::API::OpenGL: 51 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 52 | return CreateRef(indices, size); 53 | default: 54 | break; 55 | } 56 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 57 | return nullptr; 58 | } 59 | 60 | Ref FrameBuffer::Create(const FrameBufferSpecification& spec) 61 | { 62 | switch (Renderer::GetAPI()) 63 | { 64 | case RenderAPI::API::None: 65 | CHAF_CORE_ASSERT(false, "RendererAPI::API::None is not currently not supported!"); 66 | return nullptr; 67 | case RenderAPI::API::OpenGL: 68 | CHAF_CORE_INFO("RendererAPI: OpenGL"); 69 | return CreateRef(spec); 70 | default: 71 | break; 72 | } 73 | CHAF_CORE_ASSERT(false, "Unknown RendererAPI::API!"); 74 | return nullptr; 75 | } 76 | } -------------------------------------------------------------------------------- /src/Renderer/shader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #ifdef CHAF_OPENGL_API 7 | #include 8 | #endif // CHAF_OPENGL_API 9 | 10 | namespace Chaf 11 | { 12 | Ref Shader::Create(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc) 13 | { 14 | switch (Renderer::GetAPI()) 15 | { 16 | case RenderAPI::API::None: 17 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 18 | return nullptr; 19 | case RenderAPI::API::OpenGL: 20 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 21 | return CreateRef(name, vertexSrc, fragmentSrc); 22 | default: 23 | break; 24 | } 25 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 26 | return nullptr; 27 | } 28 | 29 | Ref Shader::Create(const std::string& filepath) 30 | { 31 | switch (Renderer::GetAPI()) 32 | { 33 | case RenderAPI::API::None: 34 | CHAF_CORE_ASSERT(false, "RenderAPI::API::None is not currently not supported!"); 35 | return nullptr; 36 | case RenderAPI::API::OpenGL: 37 | //CHAF_CORE_INFO("RenderAPI: OpenGL"); 38 | return CreateRef(filepath); 39 | default: 40 | break; 41 | } 42 | CHAF_CORE_ASSERT(false, "Unknown RenderAPI::API!"); 43 | return nullptr; 44 | } 45 | 46 | void ShaderLibrary::Add(const Ref& shader) 47 | { 48 | auto& name = shader->GetName(); 49 | Add(name, shader); 50 | } 51 | 52 | void ShaderLibrary::Add(const std::string& name, const Ref& shader) 53 | { 54 | CHAF_CORE_ASSERT(!Exists(name), "Shader already exists!"); 55 | m_Shaders[name] = shader; 56 | } 57 | 58 | Ref ShaderLibrary::Load(const std::string& filepath) 59 | { 60 | auto shader = Shader::Create(filepath); 61 | Add(shader); 62 | return shader; 63 | } 64 | 65 | Ref ShaderLibrary::Load(const std::string& name, const std::string& filepath) 66 | { 67 | auto shader = Shader::Create(filepath); 68 | Add(name, shader); 69 | return shader; 70 | } 71 | 72 | Ref ShaderLibrary::Get(const std::string& name) 73 | { 74 | m_Shaders; 75 | CHAF_CORE_ASSERT(Exists(name), "Shader not found!"); 76 | return m_Shaders[name]; 77 | } 78 | 79 | bool ShaderLibrary::Exists(const std::string& name) const 80 | { 81 | return m_Shaders.find(name) != m_Shaders.end(); 82 | } 83 | 84 | } -------------------------------------------------------------------------------- /vendor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # entt 2 | add_library(entt INTERFACE) 3 | target_include_directories(entt INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/entt/include") 4 | 5 | # Eigen 6 | add_library(Eigen INTERFACE) 7 | target_include_directories(Eigen INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/Eigen") 8 | 9 | # dirent 10 | add_library(dirent INTERFACE) 11 | target_include_directories(dirent INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/dirent/include") 12 | 13 | # glm 14 | add_library(glm INTERFACE) 15 | target_include_directories(glm INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/glm") 16 | 17 | # stb 18 | add_library(stb INTERFACE) 19 | target_include_directories(stb INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stb_image") 20 | 21 | # imgui 22 | set(IMGUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ImGui") 23 | set(IMGUI_FILES 24 | "${IMGUI_DIR}/imgui.cpp" 25 | "${IMGUI_DIR}/imgui_demo.cpp" 26 | "${IMGUI_DIR}/imgui_draw.cpp" 27 | "${IMGUI_DIR}/imgui_widgets.cpp" 28 | "${IMGUI_DIR}/imconfig.h" 29 | "${IMGUI_DIR}/imgui.h" 30 | "${IMGUI_DIR}/imgui_internal.h" 31 | "${IMGUI_DIR}/imstb_rectpack.h" 32 | "${IMGUI_DIR}/imstb_textedit.h" 33 | "${IMGUI_DIR}/imgui_tables.cpp" 34 | "${IMGUI_DIR}/imstb_truetype.h") 35 | add_library(imgui STATIC ${IMGUI_FILES}) 36 | target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}) 37 | set_property(TARGET imgui PROPERTY FOLDER "Extern/") 38 | 39 | # glad 40 | set(GLAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/glad") 41 | set(GLAD_FILES 42 | "${GLAD_DIR}/src/glad.c") 43 | add_library(glad STATIC ${GLAD_FILES}) 44 | target_include_directories(glad PUBLIC ${GLAD_DIR} ${GLAD_DIR}/include) 45 | set_property(TARGET glad PROPERTY FOLDER "Extern/") 46 | 47 | # GLFW 48 | add_subdirectory(GLFW) 49 | set_property(TARGET glfw PROPERTY FOLDER "Extern/GLFW3/") 50 | set_property(TARGET uninstall PROPERTY FOLDER "Extern/GLFW3/") 51 | 52 | # spdlog 53 | add_subdirectory(spdlog) 54 | set_property(TARGET spdlog PROPERTY FOLDER "Extern/spdlog") 55 | 56 | # implot 57 | set(IMPLOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/implot") 58 | set(IMPLOT_FILES 59 | "${IMPLOT_DIR}/implot.cpp" 60 | "${IMPLOT_DIR}/implot.h" 61 | "${IMPLOT_DIR}/implot_demo.cpp" 62 | "${IMPLOT_DIR}/implot_internal.h" 63 | "${IMPLOT_DIR}/implot_items.cpp") 64 | add_library(implot STATIC ${IMPLOT_FILES}) 65 | target_include_directories(implot PUBLIC ${IMPLOT_DIR} ${IMPLOT_DIR}) 66 | target_include_directories(implot PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}) 67 | set_property(TARGET implot PROPERTY FOLDER "Extern/") -------------------------------------------------------------------------------- /src/Scene/maincamera_layer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | namespace Chaf 5 | { 6 | MainCameraLayer* MainCameraLayer::s_Instance = nullptr; 7 | 8 | MainCameraLayer::MainCameraLayer() 9 | :Layer("WindowCamera"), m_CameraController(23.0f, 16.0f / 9.0f, CameraType::Perspective) 10 | { 11 | s_Instance = this; 12 | } 13 | 14 | void MainCameraLayer::OnImGuiRender() 15 | { 16 | if (m_WindowHandle) 17 | { 18 | ImGui::Begin("Camera Setting", &m_WindowHandle); 19 | ImGui::Text("Attribute"); 20 | 21 | int type = static_cast(m_CameraController.GetCamera().GetCameraType()) - 1; 22 | ImGui::Combo("type", (int*)&type, "Orthographic\0Perspective"); 23 | m_CameraController.GetCamera().SetCameraType(static_cast(type + 1)); 24 | 25 | float nearPlane = m_CameraController.GetCamera().GetNearPlane(); 26 | ImGui::DragFloat("near", (float*)&nearPlane, 0.1f); 27 | nearPlane = nearPlane < 0 ? 0 : nearPlane; 28 | m_CameraController.GetCamera().SetNearPlane(nearPlane); 29 | float farPlane = m_CameraController.GetCamera().GetFarPlane(); 30 | ImGui::DragFloat("far", (float*)&farPlane, 0.1f); 31 | farPlane = farPlane < nearPlane ? nearPlane + 0.1f : farPlane; 32 | m_CameraController.GetCamera().SetFarPlane(farPlane); 33 | 34 | float fov = m_CameraController.GetCamera().GetFov(); 35 | ImGui::SliderFloat("fov", &fov, 0.1f, 45.0f, "%.1f"); 36 | m_CameraController.GetCamera().SetFov(fov); 37 | 38 | float sensitivity = m_CameraController.GetSensitivity(); 39 | ImGui::SliderFloat("sensitivity", &sensitivity, 0.01f, 1.00f, "%.2f"); 40 | m_CameraController.SetSensitivity(sensitivity); 41 | 42 | float speed = m_CameraController.GetSpeed(); 43 | ImGui::SliderFloat("speed", &speed, 0.1f, 30.0f, "%.1f"); 44 | m_CameraController.SetSpeed(speed); 45 | 46 | ImGui::Separator(); 47 | 48 | glm::vec3 position = m_CameraController.GetCamera().GetPosition(); 49 | ImGui::DragFloat3("Position", (float*)&position, 0.1f); 50 | m_CameraController.GetCamera().SetPosition(position); 51 | 52 | ImGui::Separator(); 53 | 54 | ImGui::Text("Rotation"); 55 | float pitch = m_CameraController.GetCamera().GetPitch(); 56 | ImGui::DragFloat("Pitch", &pitch, 1.0f); 57 | m_CameraController.GetCamera().SetPitch(pitch); 58 | float yaw = m_CameraController.GetCamera().GetYaw(); 59 | ImGui::DragFloat("Yaw", &yaw, 1.0f); 60 | m_CameraController.GetCamera().SetYaw(yaw); 61 | 62 | ImGui::End(); 63 | } 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/Editor/application.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | #define BIND_EVENT_FN(x) std::bind(&Application::x ,this ,std::placeholders::_1) 9 | 10 | Application* Application::s_Instance = nullptr; 11 | 12 | Application::Application(const std::string name) 13 | { 14 | CHAF_CORE_ASSERT(!s_Instance, "Application already exists!"); 15 | s_Instance = this; 16 | 17 | m_Window = Ref(Window::Create(name)); 18 | m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent)); 19 | 20 | Renderer::Init(); 21 | 22 | m_ImGuiLayer = new ImGuiLayer(m_Window); 23 | PushOverlay(m_ImGuiLayer); 24 | } 25 | 26 | Application::~Application() 27 | { 28 | Renderer::Shutdown(); 29 | } 30 | 31 | void Application::OnEvent(Event& e) 32 | { 33 | EventDispatcher dispatcher(e); 34 | dispatcher.Dispatch(BIND_EVENT_FN(OnWindowClose)); 35 | dispatcher.Dispatch(BIND_EVENT_FN(OnWindowResize)); 36 | 37 | for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) 38 | { 39 | (*--it)->OnEvent(e); 40 | if (e.m_Handled) 41 | break; 42 | } 43 | } 44 | 45 | void Application::PushLayer(Layer* layer) 46 | { 47 | m_LayerStack.PushLayer(layer); 48 | layer->OnAttach(); 49 | } 50 | 51 | void Application::PushOverlay(Layer* layer) 52 | { 53 | m_LayerStack.PushOverlay(layer); 54 | layer->OnAttach(); 55 | } 56 | 57 | void Application::Close() 58 | { 59 | m_Running = false; 60 | } 61 | 62 | bool Application::OnWindowClose(WindowCloseEvent& e) 63 | { 64 | m_Running = false; 65 | return true; 66 | } 67 | 68 | bool Application::OnWindowResize(WindowResizeEvent& e) 69 | { 70 | if (e.GetWidth() == 0 || e.GetHeight() == 0) 71 | { 72 | m_Minimized = true; 73 | return false; 74 | } 75 | m_Minimized = false; 76 | Renderer::OnWindowResize(e.GetWidth(), e.GetHeight()); 77 | 78 | return false; 79 | } 80 | 81 | void Application::Run() 82 | { 83 | while (m_Running) 84 | { 85 | Timestep timestep; 86 | timestep.Update(m_LastFrameTime); 87 | m_LastFrameTime += timestep.GetSeconds(); 88 | 89 | if (!m_Minimized) 90 | { 91 | for (Layer* layer : m_LayerStack) 92 | layer->OnUpdate(timestep); 93 | m_ImGuiLayer->Begin(); 94 | { 95 | for (Layer* layer : m_LayerStack) 96 | layer->OnImGuiRender(); 97 | } 98 | m_ImGuiLayer->End(); 99 | } 100 | m_Window->OnUpdate(); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /src/Editor/hierarchy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | void Hierachy::ShowHierarchy(bool* p_open) 10 | { 11 | ImGui::Begin("Hierachy", p_open); 12 | auto& scene = SceneLayer::GetInstance()->GetScene(); 13 | if (!scene->Empty()) 14 | { 15 | auto node = scene->GetRoot(); 16 | while (node) 17 | { 18 | RecurseTree(node); 19 | node = node.GetNext(); 20 | } 21 | } 22 | ImGui::End(); 23 | } 24 | 25 | void Hierachy::RecurseTree(Entity node) 26 | { 27 | if (!node)return; 28 | 29 | ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(5, 5)); 30 | bool open = ImGui::TreeNodeEx(std::to_string(node.ID()).c_str(), 31 | ImGuiTreeNodeFlags_FramePadding | ImGuiTreeNodeFlags_DefaultOpen 32 | | (node.SameOf(EditorBasic::GetSelectEntity()) ? ImGuiTreeNodeFlags_Selected : 0) | (node.GetFirstChild() ? 0 : ImGuiTreeNodeFlags_Leaf), 33 | "%s", node.GetComponent().Tag.c_str()); 34 | ImGui::PopStyleVar(); 35 | 36 | ImGui::PushID(std::to_string(node.ID()).c_str()); 37 | if (ImGui::BeginPopupContextItem()) 38 | { 39 | ImGui::Text(node.GetComponent().Tag.c_str()); 40 | // new object menu 41 | EditorBasic::AddObjectMenu(node); 42 | ImGui::Separator(); 43 | // delete 44 | if (!node.IsRoot()) 45 | { 46 | if (ImGui::MenuItem("Delete")) 47 | RemoveEntity(node); 48 | } 49 | // rename 50 | if (node) 51 | { 52 | ImGui::Separator(); 53 | EditorBasic::Rename(node); 54 | } 55 | ImGui::EndPopup(); 56 | } 57 | ImGui::PopID(); 58 | 59 | // left click check 60 | if (ImGui::IsItemClicked()) EditorBasic::SetSelectEntity(node); 61 | // Drag&Drop Effect 62 | EditorBasic::SetDragDropSource("Hierarchy Drag&Drop", [&](){ 63 | ImGui::Text(node.GetComponent().Tag.c_str()); 64 | }, EditorBasic::GetSelectEntity()); 65 | 66 | EditorBasic::SetDragDropTarget("Hierarchy Drag&Drop", [&](Entity srcNode) { 67 | srcNode.MoveAsChildOf(node); 68 | auto& transform = srcNode.GetComponent(); 69 | transform.SetRelatePosition(srcNode.GetParent().GetComponent().Position); 70 | }); 71 | // Recurse 72 | if (open) 73 | { 74 | if (node) 75 | { 76 | auto child = node.GetFirstChild(); 77 | while (child) 78 | { 79 | RecurseTree(child); 80 | child = child.GetNext(); 81 | } 82 | } 83 | ImGui::TreePop(); 84 | } 85 | } 86 | 87 | void Hierachy::RemoveEntity(Entity& node) 88 | { 89 | auto tmp = node; 90 | node = node.GetNext(); 91 | tmp.Remove(); 92 | ImGui::CloseCurrentPopup(); 93 | } 94 | } -------------------------------------------------------------------------------- /src/Editor/editor_layer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace Chaf 17 | { 18 | void EditorLayer::OnAttach() 19 | { 20 | SceneLayer::SetGuizmoFunc([&](glm::vec2 viewportSize) { 21 | ImVec2 size = ImGui::GetContentRegionAvail(); 22 | ImVec2 cursorPos = ImGui::GetCursorScreenPos(); // "cursor" is where imgui will draw the image 23 | ImGuizmo::SetRect(cursorPos.x, cursorPos.y, size.x, size.y); 24 | if (EditorBasic::GetSelectEntity()&&!EditorBasic::GetSelectEntity().IsRoot()) 25 | { 26 | ImGuizmo::Manipulate(glm::value_ptr(MainCameraLayer::GetInstance()->GetCameraController().GetCamera().GetViewMatrix()), 27 | glm::value_ptr(MainCameraLayer::GetInstance()->GetCameraController().GetCamera().GetProjectionMatrix()), 28 | EditorBasic::mCurrentGizmoOperation, EditorBasic::mCurrentGizmoMode, 29 | &EditorBasic::GetSelectEntity().GetComponent().Transform[0][0] 30 | ); 31 | ImGuizmo::DecomposeMatrixToComponents(&EditorBasic::GetSelectEntity().GetComponent().Transform[0][0], 32 | &EditorBasic::GetSelectEntity().GetComponent().Position[0], 33 | &EditorBasic::GetSelectEntity().GetComponent().Rotation[0], 34 | &EditorBasic::GetSelectEntity().GetComponent().Scale[0]); 35 | EditorBasic::GetSelectEntity().GetComponent().Position = EditorBasic::GetSelectEntity().GetComponent().Position - EditorBasic::GetSelectEntity().GetComponent().RelatePosition; 36 | } 37 | }); 38 | } 39 | 40 | void EditorLayer::OnImGuiRender() 41 | { 42 | if (EditorBasic::m_FlagShowHierarchy) Hierachy::ShowHierarchy(&EditorBasic::m_FlagShowHierarchy); 43 | if (EditorBasic::m_FlagShowInspector) Inspector::ShowInspector(&EditorBasic::m_FlagShowInspector); 44 | if (EditorBasic::m_FlagTerminal) Terminal::LoggingConsole(&EditorBasic::m_FlagTerminal); 45 | if (EditorBasic::m_FlagDemoWindow)ImGui::ShowDemoWindow(&EditorBasic::m_FlagDemoWindow); 46 | 47 | if (EditorBasic::m_FlagStyleEditor) 48 | { 49 | ImGui::Begin("Style Editor", &EditorBasic::m_FlagStyleEditor); 50 | ImGui::ShowStyleEditor(); 51 | ImGui::End(); 52 | } 53 | Menu::ShowMainMenu(); 54 | Menu::ShowGuizmoMenu(); 55 | EditorBasic::AddObjectAnswer(); 56 | } 57 | } -------------------------------------------------------------------------------- /cmake/Init.cmake: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | # Copyright (c) 2020 Ubpa 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 | # copies 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 | # copies 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. 22 | 23 | message(STATUS "include Init.cmake successfully") 24 | 25 | include("${CMAKE_CURRENT_LIST_DIR}/Build.cmake") 26 | include("${CMAKE_CURRENT_LIST_DIR}/Utility.cmake") 27 | include("${CMAKE_CURRENT_LIST_DIR}/Package.cmake") 28 | include("${CMAKE_CURRENT_LIST_DIR}/Git.cmake") 29 | include("${CMAKE_CURRENT_LIST_DIR}/Download.cmake") 30 | 31 | macro(Init_Project) 32 | set(CMAKE_DEBUG_POSTFIX d) 33 | 34 | set(CMAKE_CXX_STANDARD 17) 35 | set(CMAKE_CXX_STANDARD_REQUIRED True) 36 | 37 | # install prefix 38 | 39 | 40 | set("Build_Test_${PROJECT_NAME}" FALSE CACHE BOOL "Build test of ${PROJECT_NAME}") 41 | 42 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") 43 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/bin") 44 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/bin") 45 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib") 46 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib") 47 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib") 48 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/lib") 49 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PROJECT_SOURCE_DIR}/lib") 50 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PROJECT_SOURCE_DIR}/lib") 51 | 52 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 53 | 54 | if(CMAKE_CONFIGURATION_TYPES) 55 | message("Multi-configuration generator") 56 | set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "My multi config types" FORCE) 57 | else() 58 | message("Single-configuration generator") 59 | endif() 60 | endmacro() -------------------------------------------------------------------------------- /src/App/imgui.ini: -------------------------------------------------------------------------------- 1 | [Window][DockSpace] 2 | Pos=0,0 3 | Size=1280,720 4 | Collapsed=0 5 | 6 | [Window][Debug##Default] 7 | Pos=60,60 8 | Size=400,400 9 | Collapsed=0 10 | 11 | [Window][Camera Setting] 12 | Pos=0,372 13 | Size=264,348 14 | Collapsed=0 15 | DockId=0x00000008,0 16 | 17 | [Window][Viewport] 18 | Pos=266,26 19 | Size=669,501 20 | Collapsed=0 21 | DockId=0x00000003,0 22 | 23 | [Window][Hierachy] 24 | Pos=0,26 25 | Size=264,344 26 | Collapsed=0 27 | DockId=0x00000007,0 28 | 29 | [Window][Inspector] 30 | Pos=937,26 31 | Size=343,694 32 | Collapsed=0 33 | DockId=0x00000006,0 34 | 35 | [Window][Choose File##Model] 36 | Pos=241,175 37 | Size=705,487 38 | Collapsed=0 39 | 40 | [Window][Choose File##Choose Diffuse] 41 | Pos=60,60 42 | Size=580,551 43 | Collapsed=0 44 | 45 | [Window][Choose File##Choose Skybox] 46 | Pos=368,127 47 | Size=665,431 48 | Collapsed=0 49 | 50 | [Window][Cube] 51 | Pos=127,44 52 | Size=650,388 53 | Collapsed=0 54 | 55 | [Window][Choose File##Choose Specular] 56 | Pos=59,60 57 | Size=626,534 58 | Collapsed=0 59 | 60 | [Window][Sphere] 61 | Pos=60,60 62 | Size=708,372 63 | Collapsed=0 64 | 65 | [Window][Choose File##Choose Normal] 66 | Pos=18,19 67 | Size=625,518 68 | Collapsed=0 69 | 70 | [Window][Plane] 71 | Pos=-85,11 72 | Size=611,368 73 | Collapsed=0 74 | 75 | [Window][Choose File##Choose Displacement] 76 | Pos=60,60 77 | Size=618,658 78 | Collapsed=0 79 | 80 | [Window][Choose File##Choose Albedo] 81 | Pos=60,60 82 | Size=596,537 83 | Collapsed=0 84 | 85 | [Window][Choose File##Choose Metallic] 86 | Pos=61,61 87 | Size=620,514 88 | Collapsed=0 89 | 90 | [Window][Choose File##Choose Roughness] 91 | Pos=60,60 92 | Size=550,544 93 | Collapsed=0 94 | 95 | [Window][Choose File##Choose AO] 96 | Pos=60,60 97 | Size=572,615 98 | Collapsed=0 99 | 100 | [Window][Choose File##Reload Model] 101 | Pos=60,60 102 | Size=679,620 103 | Collapsed=0 104 | 105 | [Window][Empty] 106 | Pos=-199,-103 107 | Size=478,266 108 | Collapsed=0 109 | 110 | [Window][console] 111 | Pos=266,529 112 | Size=669,191 113 | Collapsed=0 114 | DockId=0x00000004,0 115 | 116 | [Docking][Data] 117 | DockSpace ID=0x3FC20BEE Window=0x9A404470 Pos=293,-1885 Size=1280,694 Split=X Selected=0x995B0CF8 118 | DockNode ID=0x00000005 Parent=0x3FC20BEE SizeRef=935,694 Split=X 119 | DockNode ID=0x00000001 Parent=0x00000005 SizeRef=361,694 Split=Y Selected=0x250F03C4 120 | DockNode ID=0x00000007 Parent=0x00000001 SizeRef=264,344 Selected=0x17A9EF69 121 | DockNode ID=0x00000008 Parent=0x00000001 SizeRef=264,348 Selected=0x250F03C4 122 | DockNode ID=0x00000002 Parent=0x00000005 SizeRef=917,694 Split=Y Selected=0x995B0CF8 123 | DockNode ID=0x00000003 Parent=0x00000002 SizeRef=917,501 CentralNode=1 HiddenTabBar=1 Selected=0x995B0CF8 124 | DockNode ID=0x00000004 Parent=0x00000002 SizeRef=917,191 Selected=0x3603CFB6 125 | DockNode ID=0x00000006 Parent=0x3FC20BEE SizeRef=343,694 Selected=0xF02CD328 126 | 127 | -------------------------------------------------------------------------------- /src/Editor/basic.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Chaf 14 | { 15 | static std::unordered_map MeshType2Item = 16 | { 17 | {MeshType::None, "Empty"}, 18 | {MeshType::Plane, "Plane"}, 19 | {MeshType::Cube, "Cube"}, 20 | {MeshType::Sphere, "Sphere"}, 21 | {MeshType::Model, "Model"}, 22 | }; 23 | static std::unordered_map MeshItem2Type = 24 | { 25 | {"Empty", MeshType::None}, 26 | {"Plane", MeshType::Plane}, 27 | {"Cube", MeshType::Cube}, 28 | {"Sphere", MeshType::Sphere}, 29 | { "Model", MeshType::Model} 30 | }; 31 | 32 | /* 33 | m_PopupFlag: for 34 | */ 35 | 36 | class CHAF_API EditorBasic 37 | { 38 | public: 39 | static void SetSelectEntity(Entity& entity) { m_SelectEntity = entity; } 40 | static void SetPopupFlag(const std::string& flag) { m_PopupFlag = flag; } 41 | static Entity& GetSelectEntity() { return m_SelectEntity; } 42 | 43 | static void GetFileDialog(const std::string& label, const std::string& format, std::function func); 44 | 45 | static void ShowTexture(const char* label, const Ref& texture, std::function func = []() {}); 46 | 47 | static void Rename(Entity& entity); 48 | 49 | static void AddObjectMenu(Entity& entity); 50 | static void AddObjectAnswer(); 51 | 52 | template 53 | static void SetDragDropSource(const char* label, std::function func, T& data) 54 | { 55 | if (ImGui::BeginDragDropSource()) 56 | { 57 | ImGui::SetDragDropPayload(label, &data, sizeof(T)); 58 | func(); 59 | ImGui::EndDragDropSource(); 60 | } 61 | } 62 | 63 | template 64 | static void SetDragDropTarget(const char* label, std::function func) 65 | { 66 | if (ImGui::BeginDragDropTarget()) 67 | { 68 | if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(label)) 69 | { 70 | CHAF_CORE_ASSERT(payload->DataSize == sizeof(T), "payload error!"); 71 | T data = *(const T*)payload->Data; 72 | func(data); 73 | } 74 | ImGui::EndDragDropTarget(); 75 | } 76 | } 77 | 78 | template 79 | static void AddComponent() 80 | { 81 | if (!EditorBasic::GetSelectEntity().HasComponent() && !EditorBasic::GetSelectEntity().IsRoot()) 82 | EditorBasic::GetSelectEntity().AddComponent(); 83 | } 84 | 85 | private: 86 | static Entity m_SelectEntity; 87 | static std::string m_PopupFlag; 88 | public: 89 | static bool m_FlagShowHierarchy; 90 | static bool m_FlagShowInspector; 91 | static bool m_FlagDemoWindow; 92 | static bool m_FlagStyleEditor; 93 | static bool m_FlagTerminal; 94 | 95 | static ImGuizmo::OPERATION mCurrentGizmoOperation; 96 | static ImGuizmo::MODE mCurrentGizmoMode; 97 | 98 | static bool m_InitFileDialog; 99 | }; 100 | 101 | } -------------------------------------------------------------------------------- /src/Scene/scene_layer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Chaf 10 | { 11 | SceneLayer* SceneLayer::s_Instance = nullptr; 12 | Ref SceneLayer::m_DefaultSceneRenderData = nullptr; 13 | std::function SceneLayer::m_GuizmoFunc = [](glm::vec2) {}; 14 | 15 | SceneLayer::SceneLayer() 16 | { 17 | s_Instance = this; 18 | m_MainScene = CreateRef(); 19 | m_DefaultSceneRenderData = CreateRef(); 20 | } 21 | 22 | void SceneLayer::OnAttach() 23 | { 24 | m_Grid=TriMesh::Create(MeshType::Plane, 10); 25 | 26 | RenderCommand::Init(); 27 | 28 | FrameBufferSpecification fbSpec; 29 | fbSpec.Width = 1280; 30 | fbSpec.Height = 720; 31 | m_FrameBuffer = FrameBuffer::Create(fbSpec); 32 | 33 | m_WireFrameShader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/environment/grid.glsl").c_str()); 34 | 35 | m_Cubemap = Cubemap::Create(); 36 | } 37 | 38 | void SceneLayer::DrawGrid() 39 | { 40 | m_WireFrameShader->Bind(); 41 | m_WireFrameShader->SetMat4("u_ViewProjection", MainCameraLayer::GetInstance()->GetCameraController().GetCamera().GetViewProjectionMatrix()); 42 | m_WireFrameShader->SetMat4("u_Transform", glm::scale(m_DefaultSceneRenderData->transform, glm::vec3(20.0f))); 43 | m_DefaultSceneRenderData->whiteTexture->Bind(); 44 | if (m_EnableGrid) 45 | m_Grid->Draw(true); 46 | } 47 | 48 | void SceneLayer::BeginScene() 49 | { 50 | m_FrameBuffer->Bind(); 51 | RenderCommand::SetClearColor({ 0.0f, 0.0f, 0.0f, 1.0f }); 52 | RenderCommand::Clear(); 53 | DrawGrid(); 54 | 55 | } 56 | 57 | void SceneLayer::EndScene() 58 | { 59 | if (!SceneLayer::GetInstance()->GetScene()->GetLineMode()) 60 | { 61 | RenderCommand::SetLineMode(false); 62 | m_Cubemap->BindCubeMap(MainCameraLayer::GetInstance()->GetCameraController().GetCamera()); 63 | } 64 | m_FrameBuffer->Unbind(); 65 | } 66 | 67 | void SceneLayer::OnUpdate(Timestep timestep) 68 | { 69 | BeginScene(); 70 | MainCameraLayer::GetInstance()->GetCameraController().OnUpdate(timestep); 71 | m_MainScene->RenderObject(MainCameraLayer::GetInstance()->GetCameraController().GetCamera(), m_Cubemap); 72 | 73 | EndScene(); 74 | } 75 | 76 | void SceneLayer::OnImGuiRender() 77 | { 78 | ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0,0 }); 79 | ImGui::Begin("Viewport"); 80 | ImVec2 viewportPanelSize = ImGui::GetContentRegionAvail(); 81 | MainCameraLayer::GetInstance()->GetCameraController().SetActive(ImGui::IsWindowFocused()); 82 | if (m_ViewportSize != *((glm::vec2*) & viewportPanelSize)) 83 | { 84 | m_ViewportSize = { viewportPanelSize.x,viewportPanelSize.y }; 85 | m_FrameBuffer->Resize(m_ViewportSize.x, m_ViewportSize.y); 86 | MainCameraLayer::GetInstance()->GetCameraController().OnResize(m_ViewportSize.x, m_ViewportSize.y); 87 | } 88 | m_GuizmoFunc(m_ViewportSize); 89 | uint32_t textureID = m_FrameBuffer->GetColorAttachmentRendererID(); 90 | ImGui::Image((void*)textureID, ImVec2(m_ViewportSize.x, m_ViewportSize.y), ImVec2(0, 1), ImVec2(1, 0)); 91 | ImGui::End(); 92 | ImGui::PopStyleVar(); 93 | } 94 | 95 | void SceneLayer::OnEvent(Event& event) 96 | { 97 | MainCameraLayer::GetInstance()->GetCameraController().OnEvent(event); 98 | } 99 | } -------------------------------------------------------------------------------- /src/Renderer/camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | enum class CHAF_API CameraType 10 | { 11 | None = 0, 12 | Orthographic = 1, 13 | Perspective = 2 14 | }; 15 | 16 | class CHAF_API Camera 17 | { 18 | public: 19 | Camera(float fov, float aspect, CameraType type = CameraType::Perspective, float nearPlane = 0.1f, float farPlane = 100.0f); 20 | 21 | // Get parameter 22 | const CameraType& GetCameraType() const { return m_Type; } 23 | 24 | const float& GetPitch() const { return m_Pitch; } 25 | const float& GetYaw() const { return m_Yaw; } 26 | const float& GetFov() const { return m_Fov; } 27 | const float& GetAspect() const { return m_Aspect; } 28 | 29 | const glm::vec3& GetPosition() const { return m_Position; } 30 | const glm::vec3& GetUpVector() const { return m_Up; } 31 | const glm::vec3& GetFrontVector() const { return m_Front; } 32 | const glm::vec3& GetRightVector() const { return m_Right; } 33 | 34 | const glm::mat4& GetProjectionMatrix() const { return m_ProjectionMatrix; } 35 | const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; } 36 | const glm::mat4& GetViewProjectionMatrix() const { return m_ViewProjectionMatrix; } 37 | 38 | const float& GetNearPlane() const { return m_NearPlane; } 39 | const float& GetFarPlane() const { return m_FarPlane; } 40 | 41 | void SetPosition(const glm::vec3& position) 42 | { 43 | if (m_Position == position)return; 44 | m_Position = position; UpdateViewMatrix(); 45 | } 46 | 47 | void SetPitch(const float pitch) 48 | { 49 | if (m_Pitch == pitch)return; 50 | m_Pitch = pitch; UpdateViewMatrix(); 51 | } 52 | 53 | void SetYaw(const float yaw) 54 | { 55 | if (m_Yaw == yaw)return; 56 | m_Yaw = yaw; UpdateViewMatrix(); 57 | } 58 | 59 | void SetFov(float fov) 60 | { 61 | if (m_Fov == fov)return; 62 | m_Fov = fov; UpdateProjectionMatrix(); 63 | } 64 | 65 | void SetAspect(float aspect) 66 | { 67 | if (m_Aspect == aspect)return; 68 | m_Aspect = aspect; UpdateProjectionMatrix(); 69 | } 70 | 71 | void SetCameraType(const CameraType& type) 72 | { 73 | if (m_Type == type)return; 74 | m_Type = type; 75 | m_Pitch = 0.0f; 76 | m_Yaw = -90.0f; 77 | UpdateProjectionMatrix(); 78 | UpdateViewMatrix(); 79 | } 80 | 81 | void SetNearPlane(const float& val) 82 | { 83 | if (m_NearPlane == val)return; 84 | m_NearPlane = val; 85 | UpdateProjectionMatrix(); 86 | UpdateViewMatrix(); 87 | } 88 | 89 | void SetFarPlane(const float& val) 90 | { 91 | if (m_FarPlane == val)return; 92 | m_FarPlane = val; 93 | UpdateProjectionMatrix(); 94 | UpdateViewMatrix(); 95 | } 96 | 97 | private: 98 | void UpdateViewMatrix(); 99 | void UpdateProjectionMatrix(); 100 | void UpdateViewProjectionMatrix() { m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatrix; } 101 | 102 | private: 103 | CameraType m_Type; 104 | float m_Fov, m_Aspect, m_FarPlane, m_NearPlane; 105 | float m_Pitch= -30.0f, m_Yaw = -60.0f; 106 | glm::vec3 m_Position = { -17.0f, 23.0f, 32.0f }; 107 | glm::mat4 m_ViewMatrix; 108 | glm::mat4 m_ProjectionMatrix; 109 | glm::mat4 m_ViewProjectionMatrix; 110 | glm::vec3 m_Front = { 0.0f, 0.0f, -1.0f }, m_Up = { 0.0f, 1.0f, 0.0f }, m_Right = { 1.0f, 0.0f, 0.0f }; 111 | }; 112 | 113 | } -------------------------------------------------------------------------------- /src/Renderer/light.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | enum class LightType 11 | { 12 | LightType_None = 0, 13 | LightType_Basic = 1, 14 | LightType_DirLight = 2, 15 | LightType_PointLight = 3, 16 | LightType_SpotLight = 4 17 | }; 18 | 19 | static std::unordered_map LightTypeMap = 20 | { 21 | {LightType::LightType_None, "None"}, 22 | {LightType::LightType_Basic, "Basic"}, 23 | {LightType::LightType_DirLight, "DirLight"}, 24 | {LightType::LightType_PointLight, "PointLight"}, 25 | {LightType::LightType_SpotLight, "SpotLight"} 26 | }; 27 | 28 | struct Light 29 | { 30 | glm::vec3 Color{ 1.0f }; 31 | float Intensity = 1.0f; 32 | 33 | Light() = default; 34 | 35 | virtual void Bind(const Ref& shader, const glm::vec3& position, const uint32_t& slot) 36 | { 37 | shader->Bind(); 38 | shader->SetFloat3("u_Light[" + std::to_string(slot) + "].color", Color); 39 | shader->SetFloat3("u_Light[" + std::to_string(slot) + "].position", position); 40 | shader->SetFloat("u_Light[" + std::to_string(slot) + "].intensity", Intensity); 41 | } 42 | }; 43 | 44 | struct DirLight : public Light 45 | { 46 | glm::vec3 Direction{ 1.0f }; 47 | 48 | DirLight() = default; 49 | 50 | virtual void Bind(const Ref& shader, const glm::vec3& position, const uint32_t& slot) override 51 | { 52 | shader->Bind(); 53 | shader->SetFloat3("u_DirLight[" + std::to_string(slot) + "].color", Color); 54 | shader->SetFloat3("u_DirLight[" + std::to_string(slot) + "].direction", Direction); 55 | shader->SetFloat("u_DirLight[" + std::to_string(slot) + "].intensity", Intensity); 56 | } 57 | }; 58 | 59 | struct PointLight : public Light 60 | { 61 | float Constant = 1.0f; 62 | float Linear = 0.09f; 63 | float Quadratic = 0.032f; 64 | 65 | PointLight() = default; 66 | 67 | virtual void Bind(const Ref& shader, const glm::vec3& position, const uint32_t& slot) override 68 | { 69 | shader->Bind(); 70 | shader->SetFloat3("u_PointLight[" + std::to_string(slot) + "].color", Color); 71 | shader->SetFloat3("u_PointLight[" + std::to_string(slot) + "].position", position); 72 | shader->SetFloat("u_PointLight[" + std::to_string(slot) + "].constant", Constant); 73 | shader->SetFloat("u_PointLight[" + std::to_string(slot) + "].linear", Linear); 74 | shader->SetFloat("u_PointLight[" + std::to_string(slot) + "].quadratic", Quadratic); 75 | shader->SetFloat("u_PointLight[" + std::to_string(slot) + "].intensity", Intensity); 76 | } 77 | }; 78 | 79 | struct SpotLight : public Light 80 | { 81 | glm::vec3 Direction{ 1.0f }; 82 | float CutOff = glm::cos(glm::radians(12.5f)); 83 | float OuterCutOff = glm::cos(glm::radians(17.5f)); 84 | 85 | SpotLight() = default; 86 | 87 | virtual void Bind(const Ref& shader, const glm::vec3& position, const uint32_t& slot) override 88 | { 89 | shader->Bind(); 90 | shader->SetFloat3("u_SpotLight[" + std::to_string(slot) + "].color", Color); 91 | shader->SetFloat3("u_SpotLight[" + std::to_string(slot) + "].position", position); 92 | shader->SetFloat3("u_SpotLight[" + std::to_string(slot) + "].direction", Direction); 93 | shader->SetFloat("u_SpotLight[" + std::to_string(slot) + "].cutoff", CutOff); 94 | shader->SetFloat("u_SpotLight[" + std::to_string(slot) + "].outerCutOff", OuterCutOff); 95 | shader->SetFloat("u_SpotLight[" + std::to_string(slot) + "].intensity", Intensity); 96 | } 97 | }; 98 | } -------------------------------------------------------------------------------- /assets/shader/environment/brdf.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | layout (location = 0) in vec3 aPos; 4 | layout (location = 1) in vec2 aTexCoords; 5 | 6 | out vec2 TexCoords; 7 | 8 | void main() 9 | { 10 | TexCoords = aTexCoords; 11 | gl_Position = vec4(aPos, 1.0); 12 | } 13 | 14 | #type fragment 15 | #version 330 core 16 | out vec4 FragColor; 17 | in vec2 TexCoords; 18 | 19 | const float PI = 3.14159265359; 20 | 21 | float RadicalInverse_VdC(uint bits) 22 | { 23 | bits = (bits << 16u) | (bits >> 16u); 24 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 25 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 26 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 27 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 28 | return float(bits) * 2.3283064365386963e-10; // / 0x100000000 29 | } 30 | 31 | vec2 Hammersley(uint i, uint N) 32 | { 33 | return vec2(float(i)/float(N), RadicalInverse_VdC(i)); 34 | } 35 | 36 | vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) 37 | { 38 | float a = roughness*roughness; 39 | 40 | float phi = 2.0 * PI * Xi.x; 41 | float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); 42 | float sinTheta = sqrt(1.0 - cosTheta*cosTheta); 43 | 44 | vec3 H; 45 | H.x = cos(phi) * sinTheta; 46 | H.y = sin(phi) * sinTheta; 47 | H.z = cosTheta; 48 | 49 | vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 50 | vec3 tangent = normalize(cross(up, N)); 51 | vec3 bitangent = cross(N, tangent); 52 | 53 | vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z; 54 | return normalize(sampleVec); 55 | } 56 | 57 | float GeometrySchlickGGX(float NdotV, float roughness) 58 | { 59 | // note that we use a different k for IBL 60 | float a = roughness; 61 | float k = (a * a) / 2.0; 62 | 63 | float nom = NdotV; 64 | float denom = NdotV * (1.0 - k) + k; 65 | 66 | return nom / denom; 67 | } 68 | 69 | float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) 70 | { 71 | float NdotV = max(dot(N, V), 0.0); 72 | float NdotL = max(dot(N, L), 0.0); 73 | float ggx2 = GeometrySchlickGGX(NdotV, roughness); 74 | float ggx1 = GeometrySchlickGGX(NdotL, roughness); 75 | 76 | return ggx1 * ggx2; 77 | } 78 | vec2 IntegrateBRDF(float NdotV, float roughness) 79 | { 80 | vec3 V; 81 | V.x = sqrt(1.0 - NdotV*NdotV); 82 | V.y = 0.0; 83 | V.z = NdotV; 84 | 85 | float A = 0.0; 86 | float B = 0.0; 87 | 88 | vec3 N = vec3(0.0, 0.0, 1.0); 89 | 90 | const uint SAMPLE_COUNT = 1024u; 91 | for(uint i = 0u; i < SAMPLE_COUNT; ++i) 92 | { 93 | vec2 Xi = Hammersley(i, SAMPLE_COUNT); 94 | vec3 H = ImportanceSampleGGX(Xi, N, roughness); 95 | vec3 L = normalize(2.0 * dot(V, H) * H - V); 96 | 97 | float NdotL = max(L.z, 0.0); 98 | float NdotH = max(H.z, 0.0); 99 | float VdotH = max(dot(V, H), 0.0); 100 | 101 | if(NdotL > 0.0) 102 | { 103 | float G = GeometrySmith(N, V, L, roughness); 104 | float G_Vis = (G * VdotH) / (NdotH * NdotV); 105 | float Fc = pow(1.0 - VdotH, 5.0); 106 | 107 | A += (1.0 - Fc) * G_Vis; 108 | B += Fc * G_Vis; 109 | } 110 | } 111 | A /= float(SAMPLE_COUNT); 112 | B /= float(SAMPLE_COUNT); 113 | return vec2(A, B); 114 | } 115 | 116 | void main() 117 | { 118 | vec2 integratedBRDF = IntegrateBRDF(TexCoords.x, TexCoords.y); 119 | FragColor = vec4(integratedBRDF,0.0,1.0); 120 | } -------------------------------------------------------------------------------- /assets/shader/environment/prefilter.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | layout (location = 0) in vec3 aPos; 4 | 5 | out vec3 v_FragPos; 6 | 7 | uniform mat4 projection; 8 | uniform mat4 view; 9 | 10 | void main() 11 | { 12 | v_FragPos = aPos; 13 | gl_Position = projection * view * vec4(v_FragPos, 1.0); 14 | } 15 | 16 | #type fragment 17 | #version 330 core 18 | out vec4 FragColor; 19 | in vec3 v_FragPos; 20 | 21 | uniform samplerCube environmentMap; 22 | uniform float roughness; 23 | 24 | const float PI = 3.14159265359; 25 | 26 | float DistributionGGX(vec3 N, vec3 H, float roughness) 27 | { 28 | float a = roughness*roughness; 29 | float a2 = a*a; 30 | float NdotH = max(dot(N, H), 0.0); 31 | float NdotH2 = NdotH*NdotH; 32 | 33 | float nom = a2; 34 | float denom = (NdotH2 * (a2 - 1.0) + 1.0); 35 | denom = PI * denom * denom; 36 | 37 | return nom / denom; 38 | } 39 | 40 | float RadicalInverse_VdC(uint bits) 41 | { 42 | bits = (bits << 16u) | (bits >> 16u); 43 | bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); 44 | bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); 45 | bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); 46 | bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); 47 | return float(bits) * 2.3283064365386963e-10; // / 0x100000000 48 | } 49 | 50 | vec2 Hammersley(uint i, uint N) 51 | { 52 | return vec2(float(i)/float(N), RadicalInverse_VdC(i)); 53 | } 54 | 55 | vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) 56 | { 57 | float a = roughness*roughness; 58 | 59 | float phi = 2.0 * PI * Xi.x; 60 | float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); 61 | float sinTheta = sqrt(1.0 - cosTheta*cosTheta); 62 | 63 | vec3 H; 64 | H.x = cos(phi) * sinTheta; 65 | H.y = sin(phi) * sinTheta; 66 | H.z = cosTheta; 67 | 68 | vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); 69 | vec3 tangent = normalize(cross(up, N)); 70 | vec3 bitangent = cross(N, tangent); 71 | 72 | vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z; 73 | return normalize(sampleVec); 74 | } 75 | 76 | void main() 77 | { 78 | vec3 N = normalize(v_FragPos); 79 | 80 | vec3 R = N; 81 | vec3 V = R; 82 | 83 | const uint SAMPLE_COUNT = 1024u; 84 | vec3 prefilteredColor = vec3(0.0); 85 | float totalWeight = 0.0; 86 | 87 | for(uint i = 0u; i < SAMPLE_COUNT; ++i) 88 | { 89 | vec2 Xi = Hammersley(i, SAMPLE_COUNT); 90 | vec3 H = ImportanceSampleGGX(Xi, N, roughness); 91 | vec3 L = normalize(2.0 * dot(V, H) * H - V); 92 | 93 | float NdotL = max(dot(N, L), 0.0); 94 | if(NdotL > 0.0) 95 | { 96 | float D = DistributionGGX(N, H, roughness); 97 | float NdotH = max(dot(N, H), 0.0); 98 | float HdotV = max(dot(H, V), 0.0); 99 | float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; 100 | 101 | float resolution = 512.0; 102 | float saTexel = 4.0 * PI / (6.0 * resolution * resolution); 103 | float saSample = 1.0 / (float(SAMPLE_COUNT) * pdf + 0.0001); 104 | 105 | float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); 106 | 107 | prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb * NdotL; 108 | totalWeight += NdotL; 109 | } 110 | } 111 | 112 | prefilteredColor = prefilteredColor / totalWeight; 113 | 114 | FragColor = vec4(prefilteredColor, 1.0); 115 | } 116 | -------------------------------------------------------------------------------- /src/Scene/scene.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | Scene::Scene() 9 | { 10 | entt::entity entityIndex = m_Registry.create(); 11 | Entity entity = { entityIndex, this }; 12 | entity.AddComponent(); 13 | entity.AddComponent(); 14 | auto& tag = entity.AddComponent(); 15 | tag.Tag = "scene"; 16 | m_Root = entityIndex; 17 | 18 | m_DefaultTexture = Texture2D::Create(1, 1); 19 | uint32_t defaultData = 0xffffffff; 20 | m_DefaultTexture->SetData(&defaultData, sizeof(uint32_t)); 21 | m_DefaultColor = glm::vec4{ 1.0f }; 22 | 23 | m_DefaultShader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/environment/default.glsl").c_str()); 24 | } 25 | 26 | Scene::~Scene() 27 | { 28 | 29 | } 30 | 31 | Entity Scene::CreateEntity(const std::string& name, entt::entity parent) 32 | { 33 | if(parent==entt::null)parent=m_Root; 34 | entt::entity entityIndex = m_Registry.create(); 35 | Entity entity = { entityIndex, this }; 36 | entity.AddComponent(); 37 | entity.AddComponent(); 38 | auto& tag = entity.AddComponent(); 39 | tag.Tag = name.empty() ? "Entity" : name; 40 | auto root = Entity(parent, this); 41 | root.AddChild(entity); 42 | return entity; 43 | } 44 | 45 | void Scene::RenderLight(const Camera& camera) 46 | { 47 | auto group = m_Registry.group(entt::get<>); 48 | 49 | for (auto material : group) 50 | { 51 | if (m_Registry.has(material)) 52 | { 53 | std::vector index(5); 54 | m_Registry.get(material).ResetLight(); 55 | for (auto light : group) 56 | { 57 | if (m_Registry.has(light)) 58 | { 59 | m_Registry.get(material).AddLight(m_Registry.get(light).Type); 60 | auto& shader = m_Registry.get(material).GetShader(); 61 | auto& position = m_Registry.get(light).Position; 62 | m_Registry.get(light).Bind(shader, position, index[static_cast(m_Registry.get(light).Type)]); 63 | index[static_cast(m_Registry.get(light).Type)]++; 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | void Scene::RenderObject(Camera& camera, const Ref& envMap) 71 | { 72 | RenderLight(camera); 73 | auto group=m_Registry.group(entt::get<>); 74 | 75 | for (auto entity : group) 76 | { 77 | auto& transform = group.get(entity); 78 | transform.Update(); 79 | 80 | if (m_Registry.has(entity) && !m_LineMode) 81 | { 82 | m_Registry.get(entity).Bind(); 83 | auto& material = m_Registry.get(entity); 84 | material.Bind(envMap); 85 | material.Set(camera, transform); 86 | } 87 | else 88 | { 89 | m_DefaultShader->Bind(); 90 | m_DefaultShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); 91 | m_DefaultShader->SetMat4("u_Transform", transform); 92 | } 93 | 94 | if (m_Registry.has(entity)) 95 | { 96 | auto& mesh = m_Registry.get(entity); 97 | mesh.Mesh->Draw(m_LineMode); 98 | } 99 | } 100 | } 101 | 102 | Entity Scene::GetRoot() 103 | { 104 | //CHAF_CORE_ASSERT(m_Root == entt::null, "root doesn't exist!"); 105 | return { m_Root,this }; 106 | } 107 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_texture.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | #define STB_IMAGE_IMPLEMENTATION 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | /*OpenGLTexture2D*/ 13 | OpenGLTexture2D::OpenGLTexture2D(const std::string& path, const bool hdr) 14 | :m_Path(path) 15 | { 16 | int width, height, channels; 17 | stbi_set_flip_vertically_on_load(1); 18 | 19 | if (!hdr) 20 | { 21 | stbi_uc* data = stbi_load(path.c_str(), &width, &height, &channels, 0); 22 | 23 | CHAF_CORE_ASSERT(data, "Failed to load image!"); 24 | m_Width = width; 25 | m_Height = height; 26 | 27 | GLenum internalFormat = 0; 28 | 29 | switch (channels) 30 | { 31 | case 1: 32 | m_Format = GL_RED; 33 | internalFormat = GL_RED; 34 | break; 35 | case 3: 36 | m_Format = GL_RGB; 37 | internalFormat = GL_RGB8; 38 | break; 39 | case 4: 40 | m_Format = GL_RGBA; 41 | internalFormat = GL_RGBA8; 42 | break; 43 | default: 44 | CHAF_CORE_ASSERT(false, "Unknown image channels m_Format!"); 45 | m_Format = 0; 46 | break; 47 | } 48 | 49 | glGenTextures(1, &m_RendererID); 50 | glBindTexture(GL_TEXTURE_2D, m_RendererID); 51 | //glTextureStorage2D(m_RendererID, 1, internalFormat, m_Width, m_Height); 52 | glTexImage2D(GL_TEXTURE_2D, 0, m_Format, width, height, 0, m_Format, GL_UNSIGNED_BYTE, data); 53 | glGenerateMipmap(GL_TEXTURE_2D); 54 | 55 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 56 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 57 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 58 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 59 | 60 | //glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_Format, GL_UNSIGNED_BYTE, data); 61 | 62 | stbi_image_free(data); 63 | } 64 | else 65 | { 66 | float* data = stbi_loadf(path.c_str(), &width, &height, &channels, 0); 67 | 68 | if (data) 69 | { 70 | glGenTextures(1, &m_RendererID); 71 | glBindTexture(GL_TEXTURE_2D, m_RendererID); 72 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, data); // note how we specify the texture's data value to be float 73 | 74 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 75 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 76 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 77 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 78 | 79 | stbi_image_free(data); 80 | } 81 | else 82 | { 83 | CHAF_CORE_ASSERT(false, "Texture load failure!"); 84 | } 85 | } 86 | } 87 | 88 | OpenGLTexture2D::OpenGLTexture2D(uint32_t width, uint32_t height) 89 | :m_Width(width), m_Height(height), m_Path("") 90 | { 91 | GLenum internalFormat = GL_RGBA8; 92 | m_Format = GL_RGBA; 93 | 94 | glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID); 95 | glTextureStorage2D(m_RendererID, 1, internalFormat, m_Width, m_Height); 96 | 97 | glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 98 | glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 99 | 100 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT); 101 | glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT); 102 | } 103 | 104 | void OpenGLTexture2D::SetData(void* data, uint32_t size) 105 | { 106 | uint32_t channelNum = m_Format == GL_RGBA ? 4 : 3; 107 | CHAF_CORE_ASSERT(size == m_Width * m_Height * channelNum, "Data must be entire texture!"); 108 | glTextureSubImage2D(m_RendererID, 0, 0, 0, m_Width, m_Height, m_Format, GL_UNSIGNED_BYTE, data); 109 | } 110 | 111 | OpenGLTexture2D::~OpenGLTexture2D() 112 | { 113 | glDeleteTextures(1, &m_RendererID); 114 | } 115 | 116 | void OpenGLTexture2D::Bind(uint32_t slot) const 117 | { 118 | glBindTextureUnit(slot, m_RendererID); 119 | } 120 | } -------------------------------------------------------------------------------- /src/Gui/imgui_layer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef CHAF_OPENGL_API 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #endif // CHAF_OPENGL_API 12 | 13 | namespace Chaf 14 | { 15 | ImGuiLayer::ImGuiLayer(Ref window) 16 | : Layer("ImGuiLayer"), m_Window(window) 17 | { 18 | 19 | } 20 | 21 | ImGuiLayer::~ImGuiLayer() 22 | { 23 | 24 | } 25 | 26 | void ImGuiLayer::OnAttach() 27 | { 28 | IMGUI_CHECKVERSION(); 29 | ImGui::CreateContext(); 30 | ImGuiIO& io = ImGui::GetIO(); (void)io; 31 | io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; 32 | io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; 33 | io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; 34 | 35 | ImGui::StyleColorsDark(); 36 | 37 | ImGuiStyle& style = ImGui::GetStyle(); 38 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 39 | { 40 | style.WindowRounding = 0.0f; 41 | style.Colors[ImGuiCol_WindowBg].w = 1.0f; 42 | } 43 | 44 | io.Fonts->AddFontFromFileTTF("../assets/fonts/arialbd.ttf", 20.0f); 45 | io.Fonts->AddFontFromFileTTF("../assets/fonts/arial.ttf", 20.0f); 46 | 47 | GLFWwindow* window = static_cast(m_Window->GetNativeWindow()); 48 | 49 | ImGui_ImplGlfw_InitForOpenGL(window, true); 50 | ImGui_ImplOpenGL3_Init("#version 410"); 51 | } 52 | 53 | void ImGuiLayer::OnDetach() 54 | { 55 | ImGui_ImplOpenGL3_Shutdown(); 56 | ImGui_ImplGlfw_Shutdown(); 57 | ImGui::DestroyContext(); 58 | } 59 | 60 | void ImGuiLayer::Begin() 61 | { 62 | ImGui_ImplOpenGL3_NewFrame(); 63 | ImGui_ImplGlfw_NewFrame(); 64 | ImGui::NewFrame(); 65 | 66 | ImGuizmo::BeginFrame(); 67 | ImGuizmo::Enable(true); 68 | ///////////////////////////////////////////////// 69 | /*Docking Space*/ 70 | static bool p_open = true; 71 | static bool opt_fullscreen_persistant = true; 72 | bool opt_fullscreen = opt_fullscreen_persistant; 73 | static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None; 74 | 75 | ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; 76 | if (opt_fullscreen) 77 | { 78 | ImGuiViewport* viewport = ImGui::GetMainViewport(); 79 | ImGui::SetNextWindowPos(viewport->WorkPos); 80 | ImGui::SetNextWindowSize(viewport->WorkSize); 81 | ImGui::SetNextWindowViewport(viewport->ID); 82 | ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); 83 | ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); 84 | window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove; 85 | window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus; 86 | } 87 | if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) 88 | window_flags |= ImGuiWindowFlags_NoBackground; 89 | ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); 90 | ImGui::Begin("DockSpace", &p_open, window_flags); 91 | ImGui::PopStyleVar(); 92 | 93 | if (opt_fullscreen) 94 | ImGui::PopStyleVar(2); 95 | 96 | // DockSpace 97 | ImGuiIO& io = ImGui::GetIO(); 98 | if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) 99 | { 100 | ImGuiID dockspace_id = ImGui::GetID("DockSpace"); 101 | ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); 102 | } 103 | } 104 | 105 | void ImGuiLayer::End() 106 | { 107 | /*Docking Space*/ 108 | ImGui::End(); 109 | 110 | ImGuiIO& io = ImGui::GetIO(); 111 | io.DisplaySize = ImVec2((float)m_Window->GetWidth(), (float)m_Window->GetHeight()); 112 | 113 | ImGui::Render(); 114 | ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); 115 | 116 | if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) 117 | { 118 | GLFWwindow* backup_current_context = glfwGetCurrentContext(); 119 | ImGui::UpdatePlatformWindows(); 120 | ImGui::RenderPlatformWindowsDefault(); 121 | glfwMakeContextCurrent(backup_current_context); 122 | } 123 | } 124 | } -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_buffer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace Chaf 5 | { 6 | 7 | ///////////////////////////// Vertex Buffer ///////////////////////////////////////// 8 | OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size) 9 | { 10 | glCreateBuffers(1, &m_RendererID); 11 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 12 | glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); 13 | } 14 | 15 | OpenGLVertexBuffer::OpenGLVertexBuffer(float* vertices, uint32_t size) 16 | { 17 | glCreateBuffers(1, &m_RendererID); 18 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 19 | glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW); 20 | } 21 | 22 | OpenGLVertexBuffer::~OpenGLVertexBuffer() 23 | { 24 | glDeleteBuffers(1, &m_RendererID); 25 | } 26 | 27 | void OpenGLVertexBuffer::Bind() const 28 | { 29 | glBindBuffer(GL_ARRAY_BUFFER, m_RendererID); 30 | } 31 | 32 | void OpenGLVertexBuffer::Unbind() const 33 | { 34 | glBindBuffer(GL_ARRAY_BUFFER, 0); 35 | } 36 | 37 | ///////////////////////// Index Buffer //////////////////////////////////////// 38 | OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t* indices, uint32_t count) 39 | :m_Count(count) 40 | { 41 | glCreateBuffers(1, &m_RendererID); 42 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID); 43 | glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(count), indices, GL_STATIC_DRAW); 44 | } 45 | 46 | OpenGLIndexBuffer::~OpenGLIndexBuffer() 47 | { 48 | glDeleteBuffers(1, &m_RendererID); 49 | } 50 | 51 | void OpenGLIndexBuffer::Bind() const 52 | { 53 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID); 54 | } 55 | 56 | void OpenGLIndexBuffer::Unbind() const 57 | { 58 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 59 | } 60 | 61 | ///////////////////////// Frame Buffer //////////////////////////////////////// 62 | OpenGLFrameBuffer::OpenGLFrameBuffer(const FrameBufferSpecification& spec) 63 | :m_Specification(spec) 64 | { 65 | Invalidate(); 66 | } 67 | 68 | OpenGLFrameBuffer::~OpenGLFrameBuffer() 69 | { 70 | glDeleteFramebuffers(1, &m_RendererID); 71 | glDeleteTextures(1, &m_ColorAttachment); 72 | glDeleteTextures(1, &m_DepthAttachment); 73 | } 74 | 75 | void OpenGLFrameBuffer::Invalidate() 76 | { 77 | if (m_RendererID) 78 | { 79 | glDeleteFramebuffers(1, &m_RendererID); 80 | glDeleteTextures(1, &m_ColorAttachment); 81 | glDeleteTextures(1, &m_DepthAttachment); 82 | } 83 | 84 | glCreateFramebuffers(1, &m_RendererID); 85 | glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); 86 | 87 | glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment); 88 | glBindTexture(GL_TEXTURE_2D, m_ColorAttachment); 89 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); 90 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 91 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 92 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0); 93 | 94 | glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment); 95 | glBindTexture(GL_TEXTURE_2D, m_DepthAttachment); 96 | glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height); 97 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0); 98 | 99 | CHAF_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "FrameBuffer is incomplete!"); 100 | 101 | glBindFramebuffer(GL_FRAMEBUFFER, 0); 102 | } 103 | 104 | void OpenGLFrameBuffer::Bind() 105 | { 106 | glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); 107 | glViewport(0, 0, m_Specification.Width, m_Specification.Height); 108 | } 109 | 110 | void OpenGLFrameBuffer::Unbind() 111 | { 112 | glBindFramebuffer(GL_FRAMEBUFFER, 0); 113 | } 114 | 115 | void OpenGLFrameBuffer::Resize(uint32_t width, uint32_t height) 116 | { 117 | m_Specification.Width = width; 118 | m_Specification.Height = height; 119 | Invalidate(); 120 | } 121 | } -------------------------------------------------------------------------------- /src/Editor/FileDialog/ImFileDialog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include // std::min, std::max 11 | 12 | #define IFD_DIALOG_FILE 0 13 | #define IFD_DIALOG_DIRECTORY 1 14 | #define IFD_DIALOG_SAVE 2 15 | 16 | namespace ifd { 17 | class FileDialog { 18 | public: 19 | static inline FileDialog& Instance() 20 | { 21 | static FileDialog ret; 22 | return ret; 23 | } 24 | 25 | FileDialog(); 26 | ~FileDialog(); 27 | 28 | bool Save(const std::string& key, const std::string& title, const std::string& filter, const std::string& startingDir = ""); 29 | 30 | bool Open(const std::string& key, const std::string& title, const std::string& filter, bool isMultiselect = false, const std::string& startingDir = ""); 31 | 32 | bool IsDone(const std::string& key); 33 | 34 | inline bool HasResult() { return m_result.size(); } 35 | inline const std::filesystem::path& GetResult() { return m_result[0]; } 36 | inline const std::vector& GetResults() { return m_result; } 37 | 38 | void Close(); 39 | 40 | void RemoveFavorite(const std::string& path); 41 | void AddFavorite(const std::string& path); 42 | inline const std::vector& GetFavorites() { return m_favorites; } 43 | 44 | inline void SetZoom(float z) { 45 | m_zoom = std::min(25.0f, std::max(1.0f, z)); 46 | m_refreshIconPreview(); 47 | } 48 | inline float GetZoom() { return m_zoom; } 49 | 50 | std::function CreateTexture; // char -> fmt -> { 0 = BGRA, 1 = RGBA } 51 | std::function DeleteTexture; 52 | 53 | class FileTreeNode { 54 | public: 55 | FileTreeNode(const std::string& path) { 56 | Path = std::filesystem::u8path(path); 57 | Read = false; 58 | } 59 | 60 | std::filesystem::path Path; 61 | bool Read; 62 | std::vector Children; 63 | }; 64 | class FileData { 65 | public: 66 | FileData(const std::filesystem::path& path); 67 | 68 | std::filesystem::path Path; 69 | bool IsDirectory; 70 | size_t Size; 71 | time_t DateModified; 72 | 73 | bool HasIconPreview; 74 | void* IconPreview; 75 | uint8_t* IconPreviewData; 76 | int IconPreviewWidth, IconPreviewHeight; 77 | }; 78 | 79 | private: 80 | std::string m_currentKey; 81 | std::string m_currentTitle; 82 | std::filesystem::path m_currentDirectory; 83 | bool m_isMultiselect; 84 | bool m_isOpen; 85 | uint8_t m_type; 86 | char m_inputTextbox[1024]; 87 | char m_pathBuffer[1024]; 88 | char m_newEntryBuffer[1024]; 89 | char m_searchBuffer[128]; 90 | std::vector m_favorites; 91 | bool m_calledOpenPopup; 92 | std::stack m_backHistory, m_forwardHistory; 93 | float m_zoom; 94 | 95 | std::vector m_selections; 96 | int m_selectedFileItem; 97 | void m_select(const std::filesystem::path& path, bool isCtrlDown = false); 98 | 99 | std::vector m_result; 100 | bool m_finalize(const std::string& filename = ""); 101 | 102 | std::string m_filter; 103 | std::vector> m_filterExtensions; 104 | int m_filterSelection; 105 | void m_parseFilter(const std::string& filter); 106 | 107 | std::vector m_iconIndices; 108 | std::vector m_iconFilepaths; // m_iconIndices[x] <-> m_iconFilepaths[x] 109 | std::unordered_map m_icons; 110 | void* m_getIcon(const std::filesystem::path& path); 111 | void m_clearIcons(); 112 | void m_refreshIconPreview(); 113 | void m_clearIconPreview(); 114 | 115 | std::thread* m_previewLoader; 116 | bool m_previewLoaderRunning; 117 | void m_stopPreviewLoader(); 118 | void m_loadPreview(); 119 | 120 | std::vector m_treeCache; 121 | void m_clearTree(FileTreeNode* node); 122 | void m_renderTree(FileTreeNode* node); 123 | 124 | unsigned int m_sortColumn; 125 | unsigned int m_sortDirection; 126 | std::vector m_content; 127 | void m_setDirectory(const std::filesystem::path& p, bool addHistory = true); 128 | void m_sortContent(unsigned int column, unsigned int sortDirection); 129 | void m_renderContent(); 130 | 131 | void m_renderPopups(); 132 | void m_renderFileDialog(); 133 | }; 134 | 135 | static const char* GetDefaultFolderIcon(); 136 | static const char* GetDefaultFileIcon(); 137 | } 138 | -------------------------------------------------------------------------------- /src/Renderer/Renderer2D.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace Chaf 8 | { 9 | struct Renderer2DStorage 10 | { 11 | Ref QuadVertexArray; 12 | Ref TextureShader; 13 | Ref DefaultTexture; 14 | }; 15 | 16 | static Renderer2DStorage* s_Data; 17 | 18 | void Renderer2D::Init() 19 | { 20 | s_Data = new Renderer2DStorage(); 21 | 22 | s_Data->QuadVertexArray = Chaf::VertexArray::Create(); 23 | 24 | std::vector vertices = { 25 | -0.5f, -0.5f, 0.0f,0.0f,0.0f, 26 | 0.5f, -0.5f, 0.0f,1.0f,0.0f, 27 | 0.5f, 0.5f, 0.0f,1.0f,1.0f, 28 | -0.5f, 0.5f, 0.0f,0.0f,1.0f }; 29 | 30 | Chaf::Ref m_VertexBuffer; 31 | m_VertexBuffer = Chaf::VertexBuffer::Create(&*vertices.begin(), sizeof(float)*vertices.size()); 32 | 33 | Chaf::BufferLayout layout = { 34 | {Chaf::ShaderDataType::Float3,"a_Position"}, 35 | {Chaf::ShaderDataType::Float2,"a_TexCoord"} 36 | }; 37 | 38 | m_VertexBuffer->SetLayout(layout); 39 | s_Data->QuadVertexArray->AddVertexBuffer(m_VertexBuffer); 40 | 41 | uint32_t indices[6] = { 0,1,2, 2, 3, 0 }; 42 | Chaf::Ref m_IndexBuffer; 43 | m_IndexBuffer=Chaf::IndexBuffer::Create(indices, 6); 44 | s_Data->QuadVertexArray->AddIndexBuffer(m_IndexBuffer); 45 | 46 | s_Data->DefaultTexture = Texture2D::Create(1, 1); 47 | uint32_t defaultTextureData = 0xffffffff; 48 | s_Data->DefaultTexture->SetData(&defaultTextureData, sizeof(uint32_t)); 49 | 50 | s_Data->TextureShader = Chaf::Shader::Create("assets/shader/texture.glsl"); 51 | s_Data->TextureShader->Bind(); 52 | s_Data->TextureShader->SetInt("u_Texture", 0); 53 | } 54 | 55 | void Renderer2D::Shutdown() 56 | { 57 | delete s_Data; 58 | } 59 | 60 | void Renderer2D::BeginScene(const Camera& camera) 61 | { 62 | s_Data->TextureShader->Bind(); 63 | s_Data->TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); 64 | } 65 | 66 | void Renderer2D::EndScene() 67 | { 68 | 69 | } 70 | 71 | void Renderer2D::SetLineMode(const bool enable) 72 | { 73 | Chaf::RenderCommand::SetLineMode(enable); 74 | } 75 | 76 | void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture, const glm::vec4& color) 77 | { 78 | DrawQuad({ position.x, position.y, 0.0f }, size, texture, color); 79 | } 80 | 81 | void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref& texture, const glm::vec4& color) 82 | { 83 | s_Data->TextureShader->Bind(); 84 | 85 | glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f }); 86 | s_Data->TextureShader->SetMat4("u_Transform", transform); 87 | s_Data->TextureShader->SetFloat4("u_Color", color); 88 | 89 | texture->Bind(); 90 | 91 | s_Data->QuadVertexArray->Bind(); 92 | RenderCommand::DrawIndexed(s_Data->QuadVertexArray); 93 | } 94 | 95 | void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref& texture) 96 | { 97 | DrawQuad({ position.x, position.y, 0.0f }, size, texture); 98 | } 99 | 100 | void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref& texture) 101 | { 102 | 103 | 104 | s_Data->TextureShader->Bind(); 105 | 106 | glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f }); 107 | s_Data->TextureShader->SetMat4("u_Transform", transform); 108 | s_Data->TextureShader->SetFloat4("u_Color", glm::vec4(1.0f)); 109 | 110 | texture->Bind(); 111 | 112 | s_Data->QuadVertexArray->Bind(); 113 | RenderCommand::DrawIndexed(s_Data->QuadVertexArray); 114 | } 115 | 116 | void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color) 117 | { 118 | DrawQuad({ position.x, position.y, 0.0f }, size, color); 119 | } 120 | 121 | void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color) 122 | { 123 | s_Data->TextureShader->Bind(); 124 | 125 | glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f }); 126 | s_Data->TextureShader->SetMat4("u_Transform", transform); 127 | s_Data->TextureShader->SetFloat4("u_Color", color); 128 | 129 | s_Data->DefaultTexture->Bind(); 130 | 131 | s_Data->QuadVertexArray->Bind(); 132 | RenderCommand::DrawIndexed(s_Data->QuadVertexArray); 133 | } 134 | } -------------------------------------------------------------------------------- /src/Engine/profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | struct ProfileResult 13 | { 14 | std::string Name; 15 | long long Start, End; 16 | uint32_t ThreadID; 17 | }; 18 | 19 | struct InstrumentationSession 20 | { 21 | std::string Name; 22 | }; 23 | 24 | class Instrumentor 25 | { 26 | private: 27 | InstrumentationSession* m_CurrentSession; 28 | std::ofstream m_OutputStream; 29 | int m_ProfileCount; 30 | public: 31 | Instrumentor() 32 | : m_CurrentSession(nullptr), m_ProfileCount(0) 33 | { 34 | } 35 | 36 | void BeginSession(const std::string& name, const std::string& filepath = "results.json") 37 | { 38 | m_OutputStream.open(filepath); 39 | WriteHeader(); 40 | m_CurrentSession = new InstrumentationSession{ name }; 41 | } 42 | 43 | void EndSession() 44 | { 45 | WriteFooter(); 46 | m_OutputStream.close(); 47 | delete m_CurrentSession; 48 | m_CurrentSession = nullptr; 49 | m_ProfileCount = 0; 50 | } 51 | 52 | void WriteProfile(const ProfileResult& result) 53 | { 54 | if (m_ProfileCount++ > 0) 55 | m_OutputStream << ","; 56 | 57 | std::string name = result.Name; 58 | std::replace(name.begin(), name.end(), '"', '\''); 59 | 60 | m_OutputStream << "{"; 61 | m_OutputStream << "\"cat\":\"function\","; 62 | m_OutputStream << "\"dur\":" << (result.End - result.Start) << ','; 63 | m_OutputStream << "\"name\":\"" << name << "\","; 64 | m_OutputStream << "\"ph\":\"X\","; 65 | m_OutputStream << "\"pid\":0,"; 66 | m_OutputStream << "\"tid\":" << result.ThreadID << ","; 67 | m_OutputStream << "\"ts\":" << result.Start; 68 | m_OutputStream << "}"; 69 | 70 | m_OutputStream.flush(); 71 | } 72 | 73 | void WriteHeader() 74 | { 75 | m_OutputStream << "{\"otherData\": {},\"traceEvents\":["; 76 | m_OutputStream.flush(); 77 | } 78 | 79 | void WriteFooter() 80 | { 81 | m_OutputStream << "]}"; 82 | m_OutputStream.flush(); 83 | } 84 | 85 | static Instrumentor& Get() 86 | { 87 | static Instrumentor instance; 88 | return instance; 89 | } 90 | }; 91 | 92 | class InstrumentationTimer 93 | { 94 | public: 95 | InstrumentationTimer(const char* name) 96 | : m_Name(name), m_Stopped(false) 97 | { 98 | m_StartTimepoint = std::chrono::high_resolution_clock::now(); 99 | } 100 | 101 | ~InstrumentationTimer() 102 | { 103 | if (!m_Stopped) 104 | Stop(); 105 | } 106 | 107 | void Stop() 108 | { 109 | auto endTimepoint = std::chrono::high_resolution_clock::now(); 110 | 111 | long long start = std::chrono::time_point_cast(m_StartTimepoint).time_since_epoch().count(); 112 | long long end = std::chrono::time_point_cast(endTimepoint).time_since_epoch().count(); 113 | 114 | uint32_t threadID = std::hash{}(std::this_thread::get_id()); 115 | Instrumentor::Get().WriteProfile({ m_Name, start, end, threadID }); 116 | 117 | m_Stopped = true; 118 | } 119 | private: 120 | const char* m_Name; 121 | std::chrono::time_point m_StartTimepoint; 122 | bool m_Stopped; 123 | }; 124 | } 125 | 126 | #define CHAF_PROFILE 1 127 | #if CHAF_PROFILE 128 | #define CHAF_PROFILE_BEGIN_SESSION(name, filepath) ::Chaf::Instrumentor::Get().BeginSession(name, filepath) 129 | #define CHAF_PROFILE_END_SESSION() ::Chaf::Instrumentor::Get().EndSession() 130 | #define CHAF_PROFILE_SCOPE(name) ::Chaf::InstrumentationTimer timer##__LINE__(name); 131 | #define CHAF_PROFILE_FUNCTION() CHAF_PROFILE_SCOPE(__FUNCSIG__) 132 | #else 133 | #define CHAF_PROFILE_BEGIN_SESSION(name, filepath) 134 | #define CHAF_PROFILE_END_SESSION() 135 | #define CHAF_PROFILE_FUNCTION(name) 136 | #define CHAF_PROFILE_SCOPE() 137 | #endif -------------------------------------------------------------------------------- /src/Renderer/Platform/OpenGL/opengl_window.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | static bool s_GLFWInitialized = false; 9 | static void GLFWErrorCallback(int error, const char* description) 10 | { 11 | CHAF_CORE_ERROR("GLFW Error {0}: {1}", error, description); 12 | } 13 | 14 | Window* Window::Create(const WindowProps& props) 15 | { 16 | return new WindowsWindow(props); 17 | } 18 | 19 | WindowsWindow::WindowsWindow(const WindowProps& props) 20 | { 21 | Init(props); 22 | } 23 | 24 | WindowsWindow::~WindowsWindow() 25 | { 26 | Shutdown(); 27 | } 28 | 29 | void WindowsWindow::Init(const WindowProps& props) 30 | { 31 | m_Data.Title = props.Title; 32 | m_Data.Width = props.Width; 33 | m_Data.Height = props.Height; 34 | 35 | if (!s_GLFWInitialized) 36 | { 37 | int success = glfwInit(); 38 | CHAF_CORE_ASSERT(success, "Couldn't initalize GLFW!"); 39 | glfwSetErrorCallback(GLFWErrorCallback); 40 | s_GLFWInitialized = true; 41 | } 42 | 43 | m_Window = glfwCreateWindow((int)props.Width, (int)props.Height, m_Data.Title.c_str(), nullptr, nullptr); 44 | 45 | m_Context = new OpenGLContext(m_Window); 46 | m_Context->Init(); 47 | 48 | 49 | glfwSetWindowUserPointer(m_Window, &m_Data); 50 | SetVSync(true); 51 | 52 | // set glfw callback 53 | glfwSetWindowSizeCallback(m_Window, [](GLFWwindow* window, int width, int height) 54 | { 55 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 56 | 57 | data.Width = width; 58 | data.Height = height; 59 | 60 | WindowResizeEvent event(width, height); 61 | data.EventCallback(event); 62 | }); 63 | 64 | glfwSetWindowCloseCallback(m_Window, [](GLFWwindow* window) 65 | { 66 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 67 | WindowCloseEvent event; 68 | data.EventCallback(event); 69 | }); 70 | 71 | glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods) 72 | { 73 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 74 | 75 | switch (action) 76 | { 77 | case GLFW_PRESS: 78 | { 79 | KeyPressedEvent event(key, 0); 80 | data.EventCallback(event); 81 | break; 82 | } 83 | case GLFW_RELEASE: 84 | { 85 | KeyReleasedEvent event(key); 86 | data.EventCallback(event); 87 | break; 88 | } 89 | case GLFW_REPEAT: 90 | { 91 | KeyPressedEvent event(key, 1); 92 | data.EventCallback(event); 93 | break; 94 | } 95 | default: 96 | break; 97 | } 98 | }); 99 | 100 | glfwSetCharCallback(m_Window, [](GLFWwindow* window, unsigned int keycode) 101 | { 102 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 103 | KeyTypedEvent event(keycode); 104 | data.EventCallback(event); 105 | }); 106 | 107 | glfwSetMouseButtonCallback(m_Window, [](GLFWwindow* window, int button, int action, int mods) 108 | { 109 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 110 | 111 | switch (action) 112 | { 113 | case GLFW_PRESS: 114 | { 115 | MouseButtonPressedEvent event(button); 116 | data.EventCallback(event); 117 | break; 118 | } 119 | case GLFW_RELEASE: 120 | { 121 | MouseButtonReleasedEvent event(button); 122 | data.EventCallback(event); 123 | break; 124 | } 125 | default: 126 | break; 127 | } 128 | }); 129 | 130 | glfwSetScrollCallback(m_Window, [](GLFWwindow* window, double xOffset, double yOffset) 131 | { 132 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 133 | 134 | MouseScrolledEvent event((float)xOffset, (float)yOffset); 135 | data.EventCallback(event); 136 | }); 137 | 138 | glfwSetCursorPosCallback(m_Window, [](GLFWwindow* window, double xPos, double yPos) 139 | { 140 | WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window); 141 | 142 | MouseMovedEvent event((float)xPos, (float)yPos); 143 | data.EventCallback(event); 144 | }); 145 | } 146 | 147 | void WindowsWindow::Shutdown() 148 | { 149 | glfwDestroyWindow(m_Window); 150 | } 151 | 152 | void WindowsWindow::OnUpdate() 153 | { 154 | glfwPollEvents(); 155 | m_Context->SwapBuffers(); 156 | } 157 | 158 | void WindowsWindow::SetVSync(bool enabled) 159 | { 160 | if (enabled) 161 | glfwSwapInterval(1); 162 | else 163 | glfwSwapInterval(2); 164 | 165 | m_Data.VSync = enabled; 166 | } 167 | 168 | bool WindowsWindow::IsVSync() const 169 | { 170 | return m_Data.VSync; 171 | } 172 | } -------------------------------------------------------------------------------- /src/Scene/camera_controller.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Chaf 7 | { 8 | CameraController::CameraController(float fov, float aspect, CameraType type, float nearPlane, float farPlane, bool is_2D) 9 | :m_Camera(fov, aspect, type, nearPlane, farPlane) 10 | { 11 | 12 | } 13 | 14 | bool CameraController::IsCameraControllerActive() 15 | { 16 | auto window = Application::Get().GetWindow().GetNativeWindow(); 17 | return Input::IsMouseButtonPressed(window, CHAF_MOUSE_BUTTON_RIGHT) && m_Enable; 18 | } 19 | 20 | bool CameraController::IsMouseMiddlePress() 21 | { 22 | auto window = Application::Get().GetWindow().GetNativeWindow(); 23 | return Input::IsMouseButtonPressed(window, CHAF_MOUSE_BUTTON_MIDDLE) && m_Enable; 24 | } 25 | 26 | void CameraController::OnUpdate(Timestep ts) 27 | { 28 | glm::vec3 position = m_Camera.GetPosition(); 29 | auto window = Application::Get().GetWindow().GetNativeWindow(); 30 | 31 | if (IsCameraControllerActive() || IsMouseMiddlePress()) 32 | { 33 | Input::SetCursorHidden(window, true); 34 | 35 | if (Input::IsKeyPressed(window, CHAF_KEY_A)) 36 | position -= m_Speed * ts * m_Camera.GetRightVector(); 37 | if (Input::IsKeyPressed(window, CHAF_KEY_D)) 38 | position += m_Speed * ts * m_Camera.GetRightVector(); 39 | if (Input::IsKeyPressed(window, CHAF_KEY_W)) 40 | position += m_Speed * ts * m_Camera.GetFrontVector(); 41 | if (Input::IsKeyPressed(window, CHAF_KEY_S)) 42 | position -= m_Speed * ts * m_Camera.GetFrontVector(); 43 | if (Input::IsKeyPressed(window, CHAF_KEY_Q)) 44 | position += m_Speed * ts * m_Camera.GetUpVector(); 45 | if (Input::IsKeyPressed(window, CHAF_KEY_E)) 46 | position -= m_Speed * ts * m_Camera.GetUpVector(); 47 | } 48 | else 49 | Input::SetCursorHidden(window,false); 50 | m_Camera.SetPosition(position); 51 | } 52 | 53 | void CameraController::OnEvent(Event& e) 54 | { 55 | EventDispatcher dispatcher(e); 56 | dispatcher.Dispatch(CHAF_BIND_EVENT_FN(CameraController::OnMouseScrolled)); 57 | dispatcher.Dispatch(CHAF_BIND_EVENT_FN(CameraController::OnMouseMoved)); 58 | dispatcher.Dispatch(CHAF_BIND_EVENT_FN(CameraController::OnWindowResized)); 59 | } 60 | 61 | void CameraController::OnResize(float width, float height) 62 | { 63 | float aspect = width / height; 64 | m_Camera.SetAspect(aspect); 65 | } 66 | 67 | bool CameraController::OnMouseScrolled(MouseScrolledEvent& e) 68 | { 69 | if (IsCameraControllerActive()) 70 | { 71 | float m_Zoom = m_Camera.GetFov(); 72 | m_Zoom -= e.GetYOffset(); 73 | if (m_Camera.GetCameraType() == CameraType::Perspective) 74 | { 75 | if (m_Zoom <= 1.0f) 76 | m_Zoom = 1.0f; 77 | if (m_Zoom >= 45.0f) 78 | m_Zoom = 45.0f; 79 | } 80 | m_Camera.SetFov(m_Zoom); 81 | } 82 | return false; 83 | } 84 | 85 | bool CameraController::OnMouseMoved(MouseMovedEvent& e) 86 | { 87 | auto window = Application::Get().GetWindow().GetNativeWindow(); 88 | if (IsCameraControllerActive()) 89 | { 90 | if (m_Camera.GetCameraType() == CameraType::Perspective) 91 | { 92 | float yaw = m_Camera.GetYaw(), pitch = m_Camera.GetPitch(); 93 | yaw += (e.GetX() - m_Last_X) * m_Sensitivity; 94 | pitch -= (e.GetY() - m_Last_Y) * m_Sensitivity; 95 | if (pitch > 89.0f) 96 | pitch = 89.0f; 97 | else if (pitch < -89.0f) 98 | pitch = -89.0f; 99 | m_Camera.SetPitch(pitch); 100 | m_Camera.SetYaw(yaw); 101 | } 102 | else if (m_Camera.GetCameraType() == CameraType::Orthographic) 103 | { 104 | glm::vec3 position = m_Camera.GetPosition(); 105 | position += (e.GetX() - m_Last_X) * m_Camera.GetRightVector() * m_Sensitivity * 10.0f; 106 | position -= (e.GetY() - m_Last_Y) * m_Camera.GetUpVector() * m_Sensitivity * 10.0f; 107 | m_Camera.SetPosition(position); 108 | } 109 | } 110 | else if (IsMouseMiddlePress()) 111 | { 112 | glm::vec3 position = m_Camera.GetPosition(); 113 | position += (e.GetX() - m_Last_X) * m_Camera.GetRightVector() * m_Sensitivity / 100.0f; 114 | position -= (e.GetY() - m_Last_Y) * m_Camera.GetUpVector() * m_Sensitivity / 100.0f; 115 | m_Camera.SetPosition(position); 116 | } 117 | m_Last_X = e.GetX(); 118 | m_Last_Y = e.GetY(); 119 | return false; 120 | } 121 | 122 | bool CameraController::OnWindowResized(WindowResizeEvent& e) 123 | { 124 | if (e.GetWidth() != 0 && e.GetHeight() != 0) 125 | { 126 | float aspect = (float)e.GetWidth() / (float)e.GetHeight(); 127 | m_Camera.SetAspect(aspect); 128 | } 129 | return false; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/Editor/menu.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Chaf 14 | { 15 | void Menu::ShowMainMenu() 16 | { 17 | if (ImGui::BeginMenuBar()) 18 | { 19 | if (ImGui::BeginMenu("File")) 20 | { 21 | ImGui::EndMenu(); 22 | } 23 | if (ImGui::BeginMenu("Edit")) 24 | { 25 | bool linemode = SceneLayer::GetInstance()->GetScene()->GetLineMode(); 26 | std::string display = ""; 27 | if (linemode) 28 | display = "set polygon"; 29 | else display = "set wireframe"; 30 | if (ImGui::MenuItem(display.c_str())) linemode = !linemode; 31 | SceneLayer::GetInstance()->GetScene()->SetLineMode(linemode); 32 | bool gridFlag = SceneLayer::GetInstance()->IsShowGrid(); 33 | ImGui::MenuItem("Grid", NULL, &gridFlag); 34 | SceneLayer::GetInstance()->SetShowGrid(gridFlag); 35 | ImGui::EndMenu(); 36 | } 37 | if (ImGui::BeginMenu("Environment")) 38 | { 39 | //Load Skybox 40 | if (ImGui::BeginMenu("Skybox")) 41 | { 42 | ImGui::Image((void*)SceneLayer::GetInstance()->GetSkybox()->GetTextureID(), ImVec2(128, 128), ImVec2(0, 1), ImVec2(1, 0)); 43 | if (ImGui::BeginPopupContextItem("Delete Skybox")) 44 | { 45 | if (ImGui::MenuItem("Delete")) 46 | { 47 | SceneLayer::GetInstance()->GetSkybox().reset(); 48 | SceneLayer::GetInstance()->GetSkybox() = Cubemap::Create(); 49 | } 50 | ImGui::EndPopup(); 51 | } 52 | if (ImGui::IsItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) 53 | EditorBasic::SetPopupFlag("Choose Skybox"); 54 | ImGui::EndMenu(); 55 | } 56 | ImGui::EndMenu(); 57 | } 58 | EditorBasic::GetFileDialog("Choose Skybox", ".hdr", [&](const std::string& filePathName) { 59 | SceneLayer::GetInstance()->GetSkybox().reset(); 60 | SceneLayer::GetInstance()->GetSkybox() = Cubemap::Create(filePathName); 61 | }); 62 | /*Add Object*/ 63 | if (ImGui::BeginMenu("Obejct")) 64 | { 65 | MeshType type = MeshType::None; 66 | EditorBasic::AddObjectMenu(EditorBasic::GetSelectEntity()); 67 | ImGui::EndMenu(); 68 | } 69 | if (ImGui::BeginMenu("Component")) 70 | { 71 | if (ImGui::MenuItem("Material Component")) 72 | EditorBasic::AddComponent(); 73 | if (ImGui::MenuItem("Mesh Component")) 74 | EditorBasic::AddComponent(); 75 | if (ImGui::MenuItem("Light Component")) 76 | EditorBasic::AddComponent(); 77 | ImGui::EndMenu(); 78 | } 79 | if (ImGui::BeginMenu("Window")) 80 | { 81 | ImGui::MenuItem("Hierachy", NULL, &EditorBasic::m_FlagShowHierarchy); 82 | ImGui::MenuItem("Inspector", NULL, &EditorBasic::m_FlagShowInspector); 83 | ImGui::MenuItem("DemoWindow", NULL, &EditorBasic::m_FlagDemoWindow); 84 | ImGui::MenuItem("StyleEditor", NULL, &EditorBasic::m_FlagStyleEditor); 85 | ImGui::MenuItem("Terminal", NULL, &EditorBasic::m_FlagTerminal); 86 | ImGui::MenuItem("Camera Setting", NULL, &MainCameraLayer::GetInstance()->GetWindowHandle()); 87 | ImGui::EndMenu(); 88 | } 89 | if (ImGui::BeginMenu("About")) 90 | { 91 | ShowInformation(); 92 | ImGui::EndMenu(); 93 | } 94 | ImGui::EndMenuBar(); 95 | } 96 | } 97 | 98 | void Menu::ShowGuizmoMenu() 99 | { 100 | if (EditorBasic::m_FlagShowInspector) 101 | { 102 | ImGui::Begin("Inspector", &EditorBasic::m_FlagShowInspector); 103 | if (ImGui::BeginMenuBar()) 104 | { 105 | if (ImGui::RadioButton("Translate", EditorBasic::mCurrentGizmoOperation == ImGuizmo::TRANSLATE)) 106 | { 107 | EditorBasic::mCurrentGizmoOperation = ImGuizmo::TRANSLATE; 108 | EditorBasic::mCurrentGizmoMode = ImGuizmo::WORLD; 109 | } 110 | 111 | if (ImGui::RadioButton("Rotate", EditorBasic::mCurrentGizmoOperation == ImGuizmo::ROTATE)) 112 | { 113 | EditorBasic::mCurrentGizmoOperation = ImGuizmo::ROTATE; 114 | EditorBasic::mCurrentGizmoMode = ImGuizmo::LOCAL; 115 | } 116 | 117 | if (ImGui::RadioButton("Scale", EditorBasic::mCurrentGizmoOperation == ImGuizmo::SCALE)) 118 | EditorBasic::mCurrentGizmoOperation = ImGuizmo::SCALE; 119 | 120 | ImGui::EndMenuBar(); 121 | } 122 | ImGui::End(); 123 | } 124 | } 125 | 126 | void Menu::ShowInformation() 127 | { 128 | std::fstream file; 129 | file.open("log.txt"); 130 | 131 | std::string s; 132 | for (int i = 0; i < 4; i++) 133 | { 134 | std::getline(file, s); 135 | ImGui::Text(s.substr(46).data()); 136 | } 137 | file.close(); 138 | } 139 | } -------------------------------------------------------------------------------- /src/Renderer/buffer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | enum class CHAF_API API 11 | { 12 | None=0, OpenGL=1 13 | }; 14 | 15 | static API GetAPI(); 16 | 17 | /* 18 | - Shader data type 19 | */ 20 | enum class CHAF_API ShaderDataType :uint8_t 21 | { 22 | None=0, 23 | Float, Float2, Float3, Float4, Mat3, Mat4, Int, Int2, Int3, Int4, Bool 24 | }; 25 | 26 | /* 27 | - Calculate shader data type size 28 | */ 29 | static CHAF_API uint32_t ShaderDataTypeSize(ShaderDataType type) 30 | { 31 | switch (type) 32 | { 33 | case ShaderDataType::Float: return 4; 34 | case ShaderDataType::Float2: return 4 * 2; 35 | case ShaderDataType::Float3: return 4 * 3; 36 | case ShaderDataType::Float4: return 4 * 4; 37 | case ShaderDataType::Mat3: return 4 * 3 * 3; 38 | case ShaderDataType::Mat4: return 4 * 4 * 4; 39 | case ShaderDataType::Int: return 4; 40 | case ShaderDataType::Int2: return 4 * 2; 41 | case ShaderDataType::Int3: return 4 * 3; 42 | case ShaderDataType::Int4: return 4 * 4; 43 | case ShaderDataType::Bool: return 1; 44 | } 45 | CHAF_CORE_ASSERT(false, "Unknown ShaderDataType!"); 46 | return 0; 47 | } 48 | 49 | struct CHAF_API BufferElement 50 | { 51 | std::string Name; 52 | ShaderDataType Type; 53 | uint32_t Size; 54 | uint32_t Offset; 55 | bool Normalized; 56 | 57 | BufferElement() {} 58 | BufferElement(ShaderDataType type, const std::string& name, bool normalized = false) 59 | :Type(type), Name(name), Size(ShaderDataTypeSize(type)), Offset(0), Normalized(normalized) 60 | { 61 | 62 | } 63 | 64 | uint32_t CHAF_API GetComponentCount() const 65 | { 66 | switch (Type) 67 | { 68 | case ShaderDataType::Float: return 1; 69 | case ShaderDataType::Float2: return 2; 70 | case ShaderDataType::Float3: return 3; 71 | case ShaderDataType::Float4: return 4; 72 | case ShaderDataType::Mat3: return 3 * 3; 73 | case ShaderDataType::Mat4: return 4 * 4; 74 | case ShaderDataType::Int: return 1; 75 | case ShaderDataType::Int2: return 2; 76 | case ShaderDataType::Int3: return 3; 77 | case ShaderDataType::Int4: return 4; 78 | case ShaderDataType::Bool: return 1; 79 | } 80 | return 0; 81 | } 82 | }; 83 | 84 | struct CHAF_API FrameBufferSpecification 85 | { 86 | uint32_t Width, Height; 87 | uint32_t Samples = 1; 88 | bool SwapChainTarget = false; 89 | }; 90 | 91 | class CHAF_API BufferLayout 92 | { 93 | public: 94 | BufferLayout() {}; 95 | BufferLayout(const std::initializer_list& elements) 96 | :m_Elements(elements) 97 | { 98 | CalculateOffsetAndStride(); 99 | } 100 | 101 | inline uint32_t GetStride() const { return m_Stride; } 102 | inline const std::vector& GetElements() const { return m_Elements; } 103 | 104 | std::vector::iterator begin() { return m_Elements.begin(); } 105 | std::vector::iterator end() { return m_Elements.end(); } 106 | std::vector::const_iterator begin() const { return m_Elements.begin(); } 107 | std::vector::const_iterator end() const { return m_Elements.end(); } 108 | 109 | private: 110 | void CalculateOffsetAndStride() 111 | { 112 | uint32_t offset = 0; 113 | m_Stride = 0; 114 | for (auto& element : m_Elements) 115 | { 116 | element.Offset = offset; 117 | offset += element.Size; 118 | m_Stride += element.Size; 119 | } 120 | } 121 | 122 | private: 123 | std::vector m_Elements; 124 | uint32_t m_Stride = 0; 125 | }; 126 | 127 | class CHAF_API VertexBuffer 128 | { 129 | public: 130 | virtual ~VertexBuffer() = default; 131 | 132 | virtual void Bind() const = 0; 133 | virtual void Unbind() const = 0; 134 | virtual void SetLayout(const BufferLayout& layout) = 0; 135 | virtual const BufferLayout& GetLayout() const = 0; 136 | 137 | static Ref Create(float* vertices, uint32_t size); 138 | static Ref Create(uint32_t size); 139 | }; 140 | 141 | class CHAF_API IndexBuffer 142 | { 143 | public: 144 | virtual ~IndexBuffer() {} 145 | 146 | virtual void Bind() const = 0; 147 | virtual void Unbind() const = 0; 148 | virtual uint32_t GetCount() const = 0; 149 | 150 | static Ref Create(uint32_t* indices, uint32_t size); 151 | }; 152 | 153 | class CHAF_API FrameBuffer 154 | { 155 | public: 156 | virtual void Bind() = 0; 157 | virtual void Unbind() = 0; 158 | virtual void Resize(uint32_t width, uint32_t height) = 0; 159 | virtual uint32_t GetColorAttachmentRendererID() const = 0; 160 | virtual FrameBufferSpecification& GetSpecification() = 0; 161 | virtual const FrameBufferSpecification& GetSpecification() const = 0; 162 | static Ref Create(const FrameBufferSpecification& spec); 163 | }; 164 | } -------------------------------------------------------------------------------- /src/Renderer/material.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace Chaf 13 | { 14 | enum class MaterialType 15 | { 16 | Material_None = 0, 17 | Material_Emission = 1, 18 | Material_Phong = 2, 19 | Material_Cook_Torrance = 3 20 | }; 21 | 22 | static std::unordered_map < MaterialType, std::string > MaterialTypeMap = 23 | { 24 | {MaterialType::Material_None, "None"}, 25 | {MaterialType::Material_Emission, "Emisson"}, 26 | {MaterialType::Material_Phong, "Phong"} 27 | }; 28 | 29 | struct Material 30 | { 31 | Ref m_Shader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/material/default.glsl").c_str()); 32 | Material() = default; 33 | virtual ~Material() {} 34 | virtual void Bind(const Ref& envMap = nullptr) { m_Shader->Bind(); }; 35 | virtual void ResetTexture(Ref& texture, const std::string path = std::string()) 36 | { 37 | if (path.empty()) 38 | { 39 | texture = Texture2D::Create(1, 1); 40 | uint32_t data = 0xffffffff; 41 | texture->SetData(&data, sizeof(uint32_t)); 42 | } 43 | else 44 | { 45 | texture.reset(); 46 | texture = Texture2D::Create(path); 47 | } 48 | } 49 | }; 50 | 51 | struct EmissionMaterial :public Material 52 | { 53 | Ref m_Shader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/material/emission.glsl").c_str()); 54 | glm::vec3 EmissionColor{ 1.0f }; 55 | float Intensity = 1.0f; 56 | EmissionMaterial() = default; 57 | virtual ~EmissionMaterial() {} 58 | virtual void Bind(const Ref& envMap = nullptr) override 59 | { 60 | m_Shader->Bind(); 61 | m_Shader->SetFloat3("u_EmissionColor", EmissionColor); 62 | m_Shader->SetFloat("u_Intensity", Intensity); 63 | } 64 | }; 65 | 66 | struct PhongMaterial :public Material 67 | { 68 | Ref m_Shader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/material/phong.glsl").c_str()); 69 | Ref DiffuseTexture = nullptr; 70 | Ref SpecularTexture = nullptr; 71 | Ref NormalTexture = nullptr; 72 | Ref DisplacementTexture = nullptr; 73 | float HeightScale = 0; 74 | glm::vec3 Color{ 1.0f }; 75 | float Shininess = 32; 76 | PhongMaterial() 77 | { 78 | ResetTexture(DiffuseTexture); 79 | ResetTexture(SpecularTexture); 80 | ResetTexture(NormalTexture); 81 | ResetTexture(DisplacementTexture); 82 | } 83 | virtual ~PhongMaterial() {} 84 | virtual void Bind(const Ref& envMap = nullptr) override 85 | { 86 | m_Shader->Bind(); 87 | DiffuseTexture->Bind(0); 88 | m_Shader->SetInt("u_Material.diffuse", 0); 89 | SpecularTexture->Bind(1); 90 | m_Shader->SetInt("u_Material.specular", 1); 91 | if (NormalTexture->HasImage()) 92 | m_Shader->SetInt("u_UseNormalMap", 1); 93 | else 94 | m_Shader->SetInt("u_UseNormalMap", 0); 95 | NormalTexture->Bind(2); 96 | m_Shader->SetInt("u_Material.normalMap", 2); 97 | DisplacementTexture->Bind(3); 98 | m_Shader->SetInt("u_Material.displacementMap", 3); 99 | m_Shader->SetFloat3("u_Material.color", Color); 100 | m_Shader->SetFloat("u_HeightScale", HeightScale); 101 | m_Shader->SetFloat("u_Material.shininess", Shininess); 102 | } 103 | }; 104 | 105 | struct CookTorranceBRDF :public Material 106 | { 107 | Ref m_Shader = Shader::Create((std::string(PROJECT_SOURCE_DIR) + "assets/shader/material/pbr.glsl").c_str()); 108 | Ref AlbedoTexture = nullptr; 109 | Ref NormalTexture = nullptr; 110 | Ref MetallicTexture = nullptr; 111 | Ref RoughnessTexture = nullptr; 112 | Ref AOTexture = nullptr; 113 | Ref DisplacementTexture = nullptr; 114 | float HeightScale = 0.0f; 115 | glm::vec3 Color{ 1.0f }; 116 | float Metallic = 1.0f; 117 | float Roughness = 1.0f; 118 | CookTorranceBRDF() 119 | { 120 | ResetTexture(AlbedoTexture); 121 | ResetTexture(NormalTexture); 122 | ResetTexture(MetallicTexture); 123 | ResetTexture(RoughnessTexture); 124 | ResetTexture(AOTexture); 125 | ResetTexture(DisplacementTexture); 126 | } 127 | virtual ~CookTorranceBRDF() {} 128 | virtual void Bind(const Ref& envMap = nullptr) override 129 | { 130 | m_Shader->Bind(); 131 | if (envMap) 132 | { 133 | envMap->BindIrradianceMap(0); 134 | envMap->BindPrefilterMap(1); 135 | envMap->BindBRDFLUTTMap(2); 136 | m_Shader->SetInt("u_irradianceMap", 0); 137 | m_Shader->SetInt("u_prefilterMap", 1); 138 | m_Shader->SetInt("u_brdfLUT", 2); 139 | } 140 | else 141 | { 142 | m_Shader->SetInt("u_irradianceMap", -1); 143 | m_Shader->SetInt("u_prefilterMap", -1); 144 | m_Shader->SetInt("u_brdfLUT", -1); 145 | } 146 | AlbedoTexture->Bind(3); 147 | m_Shader->SetInt("u_Material.albedoMap", 3); 148 | NormalTexture->Bind(4); 149 | m_Shader->SetInt("u_Material.normalMap", 4); 150 | MetallicTexture->Bind(5); 151 | m_Shader->SetInt("u_Material.metallicMap", 5); 152 | RoughnessTexture->Bind(6); 153 | m_Shader->SetInt("u_Material.roughnessMap", 6); 154 | AOTexture->Bind(7); 155 | m_Shader->SetInt("u_Material.aoMap", 7); 156 | DisplacementTexture->Bind(8); 157 | m_Shader->SetInt("u_Material.displacementMap", 8); 158 | if(NormalTexture->HasImage()) 159 | m_Shader->SetInt("u_HasNormalMap", 1); 160 | else m_Shader->SetInt("u_HasNormalMap", 0); 161 | m_Shader->SetFloat3("u_Material.color", Color); 162 | m_Shader->SetFloat("u_Material.metallic", Metallic); 163 | m_Shader->SetFloat("u_Material.roughness", Roughness); 164 | m_Shader->SetFloat("u_HeightScale", HeightScale); 165 | } 166 | }; 167 | } -------------------------------------------------------------------------------- /src/Editor/basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace Chaf 11 | { 12 | Entity EditorBasic::m_SelectEntity = Entity(); 13 | std::string EditorBasic::m_PopupFlag = ""; 14 | bool EditorBasic::m_FlagShowHierarchy = true; 15 | bool EditorBasic::m_FlagShowInspector = true; 16 | bool EditorBasic::m_FlagDemoWindow = false; 17 | bool EditorBasic::m_FlagStyleEditor = false; 18 | bool EditorBasic::m_FlagTerminal = true; 19 | bool EditorBasic::m_InitFileDialog = false; 20 | 21 | ImGuizmo::OPERATION EditorBasic::mCurrentGizmoOperation = ImGuizmo::TRANSLATE; 22 | ImGuizmo::MODE EditorBasic::mCurrentGizmoMode = ImGuizmo::WORLD; 23 | 24 | void EditorBasic::AddObjectMenu(Entity& entity) 25 | { 26 | if (ImGui::BeginMenu("New Object")) 27 | { 28 | for (auto item : MeshType2Item) 29 | if (ImGui::MenuItem(item.second.c_str())) 30 | { 31 | m_PopupFlag = item.second; 32 | SetSelectEntity(entity); 33 | } 34 | ImGui::EndMenu(); 35 | } 36 | } 37 | 38 | void EditorBasic::GetFileDialog(const std::string& label, const std::string& format, std::function func) 39 | { 40 | if (!m_InitFileDialog) 41 | { 42 | ifd::FileDialog::Instance().CreateTexture = [](uint8_t* data, int w, int h, char fmt) -> void* { 43 | GLuint tex; 44 | 45 | glGenTextures(1, &tex); 46 | glBindTexture(GL_TEXTURE_2D, tex); 47 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 48 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 49 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 50 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 51 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, (fmt == 0) ? GL_BGRA : GL_RGBA, GL_UNSIGNED_BYTE, data); 52 | glGenerateMipmap(GL_TEXTURE_2D); 53 | glBindTexture(GL_TEXTURE_2D, 0); 54 | 55 | return (void*)tex; 56 | }; 57 | ifd::FileDialog::Instance().DeleteTexture = [](void* tex) { 58 | GLuint texID = (GLuint)tex; 59 | glDeleteTextures(1, &texID); 60 | }; 61 | 62 | m_InitFileDialog = true; 63 | } 64 | 65 | if (m_PopupFlag == label) 66 | ifd::FileDialog::Instance().Open(label, "Open a file", format + "{" + format + "}, .*"); 67 | 68 | if (ifd::FileDialog::Instance().IsDone(label)) { 69 | if (ifd::FileDialog::Instance().HasResult()) { 70 | std::string path = ifd::FileDialog::Instance().GetResult().u8string(); 71 | func(path); 72 | } 73 | ifd::FileDialog::Instance().Close(); 74 | m_PopupFlag = ""; 75 | } 76 | } 77 | 78 | void EditorBasic::Rename(Entity& entity) 79 | { 80 | ImGui::Text("Rename"); 81 | char buf[50]; 82 | std::string tmp = entity.GetComponent().Tag; 83 | std::string logstr = "Rename " + tmp + " to "; 84 | for (int i = 0; i < tmp.length(); i++) 85 | buf[i] = tmp[i]; 86 | buf[tmp.length()] = '\0'; 87 | ImGui::InputText("##edit", buf, 50); 88 | entity.GetComponent().Tag = buf; 89 | if (ImGui::Button("OK")) 90 | { 91 | ImGui::CloseCurrentPopup(); 92 | logstr += buf; 93 | CHAF_INFO(logstr); 94 | } 95 | 96 | } 97 | 98 | void EditorBasic::AddObjectAnswer() 99 | { 100 | if (m_PopupFlag != MeshType2Item[MeshType::Model] && MeshItem2Type.count(m_PopupFlag) > 0) 101 | { 102 | ImGui::Begin(m_PopupFlag.c_str()); 103 | 104 | ImGui::Text("Transform"); 105 | static glm::vec3 position{ 0.0f }; 106 | static glm::vec3 rotation{ 0.0f }; 107 | static glm::vec3 scale{ 1.0f }; 108 | ImGui::DragFloat3("Position", (float*)&position, 0.1f); 109 | ImGui::DragFloat3("Rotation", (float*)&rotation, 1.0f); 110 | ImGui::DragFloat3("Scale", (float*)&scale, 0.01f); 111 | 112 | static int sample = 1; 113 | if (MeshItem2Type[m_PopupFlag] != MeshType::None) 114 | { 115 | ImGui::Separator(); 116 | ImGui::Text("Sample"); 117 | ImGui::SliderInt("sample", &sample, 1, 30); 118 | } 119 | ImGui::Separator(); 120 | ImGui::Text("Name"); 121 | static char buf[32] = "New Object"; 122 | ImGui::InputText("##edit", buf, 50); 123 | 124 | ImGui::Separator(); 125 | 126 | if (ImGui::Button("Create")) 127 | { 128 | auto entity = m_SelectEntity.CreateChild(std::string(buf)); 129 | if (MeshItem2Type[m_PopupFlag] != MeshType::None) 130 | entity.AddComponent(MeshItem2Type[m_PopupFlag], sample); 131 | entity.GetComponent().Position = position; 132 | entity.GetComponent().Rotation = rotation; 133 | entity.GetComponent().Scale = scale; 134 | entity.GetComponent().Update(); 135 | m_PopupFlag = ""; 136 | m_SelectEntity = entity; 137 | CHAF_INFO("Create new object: " + entity.GetComponent().Tag); 138 | } 139 | ImGui::SameLine(); 140 | if (ImGui::Button("Cancel")) 141 | { 142 | ImGui::CloseCurrentPopup(); 143 | m_PopupFlag = ""; 144 | } 145 | ImGui::End(); 146 | } 147 | 148 | GetFileDialog("Model", ".obj", [](const std::string& path) 149 | { 150 | auto entity = m_SelectEntity.CreateChild(std::string("mesh")); 151 | entity.AddComponent(path); 152 | m_PopupFlag = ""; 153 | m_SelectEntity = entity; 154 | CHAF_INFO("Create new object: " + entity.GetComponent().Tag); 155 | }); 156 | } 157 | 158 | void EditorBasic::ShowTexture(const char* label, const Ref& texture, std::function func) 159 | { 160 | auto textureID = texture->HasImage() ? texture->GetRendererID() : SceneLayer::GetDefaultRenderData()->checkboardTexture->GetRendererID(); 161 | ImGui::Image((void*)textureID, ImVec2(128, 128), ImVec2(0, 1), ImVec2(1, 0)); 162 | if (ImGui::IsItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) 163 | ImGui::OpenPopup(label); 164 | if (ImGui::BeginPopup(label)) 165 | { 166 | ImGui::Image((void*)textureID, ImVec2(256, 256), ImVec2(0, 1), ImVec2(1, 0)); 167 | func(); 168 | ImGui::EndPopup(); 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /src/Scene/entity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace Chaf 4 | { 5 | Entity::Entity(entt::entity handle, Scene* scene) 6 | : m_EntityHandle(handle), m_Scene(scene) 7 | { 8 | 9 | } 10 | 11 | bool Entity::SameOf(Entity& node) 12 | { 13 | entt::entity nodeHandle; 14 | node.GetHandle(nodeHandle); 15 | return (nodeHandle == m_EntityHandle); 16 | } 17 | 18 | Entity Entity::GetFirstChild() 19 | { 20 | if (!m_Scene->m_Registry.valid(m_EntityHandle)) 21 | return { entt::null, m_Scene }; 22 | auto relation = m_Scene->m_Registry.get(m_EntityHandle); 23 | return { relation.first, m_Scene }; 24 | } 25 | 26 | Entity Entity::GetNext() 27 | { 28 | if (!m_Scene->m_Registry.valid(m_EntityHandle)) 29 | return { entt::null, m_Scene }; 30 | auto relation = m_Scene->m_Registry.get(m_EntityHandle); 31 | return { relation.next, m_Scene }; 32 | } 33 | 34 | Entity Entity::GetParent() 35 | { 36 | if (!m_Scene->m_Registry.valid(m_EntityHandle)) 37 | return { entt::null, m_Scene }; 38 | auto relation = m_Scene->m_Registry.get(m_EntityHandle); 39 | return { relation.parent, m_Scene }; 40 | } 41 | 42 | Entity Entity::GetPrev() 43 | { 44 | if (!m_Scene->m_Registry.valid(m_EntityHandle)) 45 | return { entt::null, m_Scene }; 46 | auto relation = m_Scene->m_Registry.get(m_EntityHandle); 47 | return { relation.prev, m_Scene }; 48 | } 49 | 50 | void Entity::AddChild(Entity& node) 51 | { 52 | entt::entity nodeHandle; 53 | node.GetHandle(nodeHandle); 54 | 55 | auto& relation_this = m_Scene->m_Registry.get(m_EntityHandle); 56 | auto& relation_node = m_Scene->m_Registry.get(nodeHandle); 57 | if (m_Scene->m_Registry.valid(relation_this.first)) 58 | { 59 | auto& relation_first = m_Scene->m_Registry.get(relation_this.first); 60 | relation_first.prev = nodeHandle; 61 | } 62 | relation_node.next = relation_this.first; 63 | relation_node.parent = m_EntityHandle; 64 | relation_this.first = nodeHandle; 65 | relation_this.children++; 66 | } 67 | 68 | void Entity::AddSibling(Entity& node) 69 | { 70 | entt::entity nodeHandle; 71 | node.GetHandle(nodeHandle); 72 | 73 | auto& relation_this = m_Scene->m_Registry.get(m_EntityHandle); 74 | auto& relation_node = m_Scene->m_Registry.get(nodeHandle); 75 | if (m_Scene->m_Registry.valid(relation_this.next)) 76 | { 77 | auto& relation_next = m_Scene->m_Registry.get(relation_this.next); 78 | relation_next.prev = nodeHandle; 79 | } 80 | relation_node.next = relation_this.next; 81 | relation_this.next = nodeHandle; 82 | relation_node.prev = m_EntityHandle; 83 | relation_node.parent = relation_this.parent; 84 | 85 | if (m_Scene->m_Registry.valid(relation_this.parent)) 86 | { 87 | auto& relation_this_parent = m_Scene->m_Registry.get(relation_this.parent); 88 | relation_this_parent.children++; 89 | } 90 | } 91 | 92 | void Entity::MoveAsChildOf(Entity& dstNode) 93 | { 94 | entt::entity dstNodeHandle; 95 | dstNode.GetHandle(dstNodeHandle); 96 | auto& relation_src = m_Scene->m_Registry.get(m_EntityHandle); 97 | auto& relation_dst = m_Scene->m_Registry.get(dstNodeHandle); 98 | auto& relation_src_parent = m_Scene->m_Registry.get(relation_src.parent); 99 | 100 | if (dstNode.IsSonOf((*this)) || (*this).SameOf(dstNode.GetParent())) 101 | return; 102 | 103 | relation_src_parent.children--; 104 | relation_dst.children++; 105 | 106 | if (m_Scene->m_Registry.valid(relation_src.next)) 107 | { 108 | auto& relation_src_next = m_Scene->m_Registry.get(relation_src.next); 109 | relation_src_next.prev = relation_src.prev; 110 | } 111 | if (m_Scene->m_Registry.valid(relation_src.prev)) 112 | { 113 | auto& relation_src_prev = m_Scene->m_Registry.get(relation_src.prev); 114 | relation_src_prev.next = relation_src.next; 115 | } 116 | else 117 | { 118 | relation_src_parent.first = relation_src.next; 119 | } 120 | relation_src.next = relation_dst.first; 121 | relation_src.prev = entt::null; 122 | relation_src.parent = dstNodeHandle; 123 | 124 | if (m_Scene->m_Registry.valid(relation_dst.first)) 125 | { 126 | auto& relation_dst_first = m_Scene->m_Registry.get(relation_dst.first); 127 | relation_dst_first.prev = m_EntityHandle; 128 | } 129 | relation_dst.first = m_EntityHandle; 130 | } 131 | 132 | void Entity::Remove() 133 | { 134 | auto& relation = m_Scene->m_Registry.get(m_EntityHandle); 135 | auto& relation_parent = m_Scene->m_Registry.get(relation.parent); 136 | relation_parent.children--; 137 | if (m_Scene->m_Registry.valid(relation.prev)) 138 | { 139 | auto& relation_prev = m_Scene->m_Registry.get(relation.prev); 140 | relation_prev.next = relation.next; 141 | } 142 | else 143 | relation_parent.first = relation.next; 144 | auto& child = (*this).GetFirstChild(); 145 | while (child) 146 | { 147 | auto tmp = child.GetNext(); 148 | child.Remove(); 149 | child = tmp; 150 | } 151 | m_Scene->m_Registry.destroy(m_EntityHandle); 152 | } 153 | 154 | bool Entity::IsSonOf(Entity& node) 155 | { 156 | if (!node)return false; 157 | if (node.SameOf(*this)) 158 | return true; 159 | auto child = node.GetFirstChild(); 160 | while (child) 161 | { 162 | if ((*this).SameOf(child)) 163 | return true; 164 | child = child.GetNext(); 165 | } 166 | return false; 167 | } 168 | 169 | bool Entity::HasParent() 170 | { 171 | auto& relation = m_Scene->m_Registry.get(m_EntityHandle); 172 | return (m_Scene->m_Registry.valid(relation.parent)); 173 | } 174 | 175 | bool Entity::HasChild() 176 | { 177 | auto& relation = m_Scene->m_Registry.get(m_EntityHandle); 178 | return (m_Scene->m_Registry.valid(relation.first)); 179 | } 180 | 181 | bool Entity::IsRoot() 182 | { 183 | return (m_Scene->m_Root == m_EntityHandle); 184 | } 185 | 186 | Entity Entity::CreateChild(const std::string& name) 187 | { 188 | return m_Scene->CreateEntity(name, m_EntityHandle); 189 | } 190 | } -------------------------------------------------------------------------------- /cmake/Package.cmake: -------------------------------------------------------------------------------- 1 | set(_${PROJECT_NAME}_have_dependencies 0) 2 | 3 | include(FetchContent) 4 | 5 | function(DecodeVersion major minor patch version) 6 | string(REGEX REPLACE "[^0-9 .]" "" version ${version}) 7 | if("${version}" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") 8 | set(${major} "${CMAKE_MATCH_1}" PARENT_SCOPE) 9 | set(${minor} "${CMAKE_MATCH_2}" PARENT_SCOPE) 10 | set(${patch} "${CMAKE_MATCH_3}" PARENT_SCOPE) 11 | elseif("${version}" MATCHES "^([0-9]+)\\.([0-9]+)") 12 | set(${major} "${CMAKE_MATCH_1}" PARENT_SCOPE) 13 | set(${minor} "${CMAKE_MATCH_2}" PARENT_SCOPE) 14 | set(${patch} "" PARENT_SCOPE) 15 | else() 16 | set(${major} "${CMAKE_MATCH_1}" PARENT_SCOPE) 17 | set(${minor} "" PARENT_SCOPE) 18 | set(${patch} "" PARENT_SCOPE) 19 | endif() 20 | endfunction() 21 | 22 | function(ToPackageName rst name version) 23 | set(tmp "${name}_${version}") 24 | string(REPLACE "." "_" tmp ${tmp}) 25 | set(${rst} "${tmp}" PARENT_SCOPE) 26 | endfunction() 27 | 28 | function(PackageName rst) 29 | ToPackageName(tmp ${PROJECT_NAME} ${PROJECT_VERSION}) 30 | set(${rst} ${tmp} PARENT_SCOPE) 31 | endfunction() 32 | 33 | macro(AddDepPro projectName name version author) 34 | set(_${projectName}_have_dependencies 1) 35 | list(FIND _${projectName}_dep_name_list "${name}" _idx) 36 | if("${_idx}" STREQUAL "-1") 37 | message(STATUS "start add dependence ${name} ${version}") 38 | set(_need_find TRUE) 39 | else() 40 | set(_A_version "${${name}_VERSION}") 41 | set(_B_version "${version}") 42 | DecodeVersion(_A_major _A_minor _A_patch "${_A_version}") 43 | DecodeVersion(_B_major _B_minor _B_patch "${_B_version}") 44 | if("${_A_version}" STREQUAL "${_B_version}") 45 | message(STATUS "Diamond dependence of ${name} with same version: ${_A_version} and ${_B_version}") 46 | set(_need_find FALSE) 47 | else() 48 | message(FATAL_ERROR "Diamond dependence of ${name} with incompatible version: ${_A_version} and ${_B_version}") 49 | endif() 50 | endif() 51 | if("${_need_find}" STREQUAL TRUE) 52 | list(APPEND _${projectName}_dep_name_list ${name}) 53 | list(APPEND _${projectName}_dep_version_list ${version}) 54 | message(STATUS "find package: ${name} ${version}") 55 | string(REGEX REPLACE "[^0-9 .]" "" _version ${version}) 56 | find_package(${name} ${_version} QUIET) 57 | if(${${name}_FOUND}) 58 | message(STATUS "${name} ${${name}_VERSION} found") 59 | else() 60 | if("${author}" STREQUAL "") 61 | set(_address "https://github.com/Chaphlagical/${name}") 62 | else() 63 | set(_address "https://github.com/${author}/${name}") 64 | endif() 65 | 66 | message(STATUS "${name} ${version} not found") 67 | message(STATUS "fetch: ${_address} with tag ${version}") 68 | FetchContent_Declare( 69 | ${name} 70 | GIT_REPOSITORY ${_address} 71 | GIT_TAG "${version}" 72 | ) 73 | FetchContent_MakeAvailable(${name}) 74 | message(STATUS "${name} ${version} build done") 75 | endif() 76 | endif() 77 | endmacro() 78 | 79 | macro(AddDep name version author) 80 | AddDepPro(${PROJECT_NAME} ${name} ${version} ${author}) 81 | endmacro() 82 | 83 | macro(ExportProject) 84 | cmake_parse_arguments("ARG" "" "TARGET" "DIRECTORIES" ${ARGN}) 85 | 86 | PackageName(package_name) 87 | message(STATUS "export ${package_name}") 88 | 89 | set(PACKAGE_INIT " 90 | get_filename_component(include_dir \"${CMAKE_CURRENT_LIST_DIR}/../include\" ABSOLUTE) 91 | include_directories(\"${include_dir}\")\n") 92 | 93 | if(${_${PROJECT_NAME}_have_dependencies}) 94 | set(PACKAGE_INIT "${PACKAGE_INIT} 95 | if(NOT FetchContent_FOUND) 96 | include(FetchContent) 97 | endif() 98 | if(NOT cpkg_FOUND) 99 | message(STATUS \"find package: cpkg ${cpkg_VERSION}\") 100 | find_package(cpkg ${cpkg_VERSION} QUIET) 101 | if(NOT cpkg_FOUND) 102 | set(_${PROJECT_NAME}_address \"https://github.com/Chaphlagical/cpkg\") 103 | message(STATUS \"cpkg ${cpkg_VERSION} not found\") 104 | message(STATUS \"fetch: ${_${PROJECT_NAME}_address} with tag ${cpkg_VERSION}\") 105 | FetchContent_Declare( 106 | cpkg 107 | GIT_REPOSITORY ${_${PROJECT_NAME}_address} 108 | GIT_TAG ${cpkg_VERSION} 109 | ) 110 | FetchContent_MakeAvailable(cpkg) 111 | message(STATUS \"cpkg ${cpkg_VERSION} build done\") 112 | endif() 113 | endif() 114 | " 115 | ) 116 | 117 | message(STATUS "[Dependencies]") 118 | list(LENGTH _${PROJECT_NAME}_dep_name_list _${PROJECT_NAME}_dep_num) 119 | math(EXPR _${PROJECT_NAME}_stop "${_${PROJECT_NAME}_dep_num}-1") 120 | foreach(index RANGE ${_${PROJECT_NAME}_stop}) 121 | list(GET _${PROJECT_NAME}_dep_name_list ${index} dep_name) 122 | list(GET _${PROJECT_NAME}_dep_version_list ${index} dep_version) 123 | message(STATUS "- ${dep_name} ${dep_version}") 124 | string(APPEND PACKAGE_INIT "AddDepPro(${PROJECT_NAME} ${dep_name} ${dep_version})\n") 125 | endforeach() 126 | endif() 127 | 128 | if(NOT "${ARG_TARGET}" STREQUAL "OFF") 129 | # generate the export targets for the build tree 130 | # needs to be after the install(TARGETS ) command 131 | export(EXPORT "${PROJECT_NAME}Targets" 132 | NAMESPACE "Chaf::" 133 | #FILE "CMAKECURRENTBINARYDIR/{PROJECT_NAME}Targets.cmake" 134 | ) 135 | 136 | # install the configuration targets 137 | install(EXPORT "${PROJECT_NAME}Targets" 138 | FILE "${PROJECT_NAME}Targets.cmake" 139 | NAMESPACE "Chaf::" 140 | DESTINATION "${package_name}/cmake" 141 | ) 142 | endif() 143 | 144 | include(CMakePackageConfigHelpers) 145 | # generate the config file that is includes the exports 146 | configure_package_config_file(${PROJECT_SOURCE_DIR}/config/Config.cmake.in 147 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 148 | INSTALL_DESTINATION "${package_name}/cmake" 149 | NO_SET_AND_CHECK_MACRO 150 | NO_CHECK_REQUIRED_COMPONENTS_MACRO 151 | ) 152 | 153 | # generate the version file for the config file 154 | write_basic_package_version_file( 155 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 156 | VERSION ${PROJECT_VERSION} 157 | COMPATIBILITY SameMinorVersion 158 | ) 159 | 160 | # install the configuration file 161 | install(FILES 162 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 163 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 164 | DESTINATION "${package_name}/cmake" 165 | ) 166 | 167 | foreach(dir ${ARG_DIRECTORIES}) 168 | string(REGEX MATCH "(.*)/" prefix ${dir}) 169 | if("${CMAKE_MATCH_1}" STREQUAL "") 170 | set(_destination "${package_name}") 171 | else() 172 | set(_destination "${package_name}/${CMAKE_MATCH_1}") 173 | endif() 174 | install(DIRECTORY ${dir} DESTINATION "${_destination}") 175 | endforeach() 176 | endmacro() -------------------------------------------------------------------------------- /assets/shader/material/phong.glsl: -------------------------------------------------------------------------------- 1 | #type vertex 2 | #version 330 core 3 | 4 | layout(location = 0) in vec3 a_Position; 5 | layout(location = 1) in vec2 a_TexCoord; 6 | layout(location = 2) in vec3 a_Normal; 7 | layout(location = 3) in vec3 a_Tangent; 8 | layout(location = 4) in vec3 a_Bitangent; 9 | 10 | struct Material 11 | { 12 | vec3 color; 13 | sampler2D diffuse; 14 | sampler2D specular; 15 | sampler2D normalMap; 16 | sampler2D displacementMap; 17 | float shininess; 18 | }; 19 | 20 | uniform mat4 u_ViewProjection; 21 | uniform mat4 u_Transform; 22 | uniform vec3 u_ViewPos; 23 | uniform float u_HeightScale; 24 | uniform Material u_Material; 25 | 26 | out vec2 v_TexCoords; 27 | out vec3 v_Normal; 28 | out vec3 v_FragPos; 29 | out mat3 TBN; 30 | out vec3 v_ViewPos; 31 | 32 | void main() 33 | { 34 | //TBN 35 | vec3 T=normalize(vec3(u_Transform*vec4(a_Tangent,0.0))); 36 | vec3 B=normalize(vec3(u_Transform*vec4(a_Bitangent,0.0))); 37 | vec3 N=normalize(vec3(u_Transform*vec4(a_Normal,0.0))); 38 | TBN=transpose(mat3(T,B,N)); 39 | if(a_TexCoord.x==a_TexCoord.y&&a_TexCoord.x==0) 40 | TBN=mat3(1.0); 41 | 42 | float height=texture(u_Material.displacementMap,a_TexCoord).r; 43 | height=u_HeightScale*height; 44 | 45 | v_Normal=TBN*mat3(transpose(inverse(u_Transform)))*a_Normal; 46 | //v_FragPos=TBN*vec3(u_Transform*vec4(a_Position,1.0)); 47 | v_FragPos=TBN*vec3(u_Transform*vec4(a_Position+a_Normal*height,1.0)); 48 | v_ViewPos=TBN*u_ViewPos; 49 | v_TexCoords=a_TexCoord; 50 | 51 | gl_Position = u_ViewProjection * u_Transform * vec4(a_Position+a_Normal*height, 1.0); 52 | } 53 | 54 | #type fragment 55 | #version 330 core 56 | 57 | layout(location = 0) out vec4 FragColor; 58 | 59 | in vec2 v_TexCoords; 60 | in vec3 v_Normal; 61 | in vec3 v_FragPos; 62 | in vec3 v_ViewPos; 63 | in mat3 TBN; 64 | 65 | struct Material 66 | { 67 | vec3 color; 68 | sampler2D diffuse; 69 | sampler2D specular; 70 | sampler2D normalMap; 71 | sampler2D displacementMap; 72 | float shininess; 73 | }; 74 | 75 | struct Light 76 | { 77 | vec3 color; 78 | vec3 position; 79 | float intensity; 80 | }; 81 | 82 | struct DirLight 83 | { 84 | vec3 color; 85 | vec3 direction; 86 | float intensity; 87 | }; 88 | 89 | struct PointLight 90 | { 91 | vec3 color; 92 | vec3 position; 93 | float constant; 94 | float linear; 95 | float quadratic; 96 | float intensity; 97 | }; 98 | 99 | struct SpotLight 100 | { 101 | vec3 color; 102 | vec3 position; 103 | vec3 direction; 104 | float cutoff; 105 | float outerCutOff; 106 | float intensity; 107 | }; 108 | 109 | #define MAX_LIGHT_NUM 10 110 | 111 | uniform Material u_Material; 112 | uniform Light u_Light[MAX_LIGHT_NUM]; 113 | uniform DirLight u_DirLight[MAX_LIGHT_NUM]; 114 | uniform PointLight u_PointLight[MAX_LIGHT_NUM]; 115 | uniform SpotLight u_SpotLight[MAX_LIGHT_NUM]; 116 | 117 | uniform int BasicNum; 118 | uniform int DirLightNum; 119 | uniform int PointLightNum; 120 | uniform int SpotLightNum; 121 | uniform int u_UseNormalMap; 122 | 123 | float Ambient=0.1; 124 | vec3 normal=vec3(0.0,0.0,0.0); 125 | 126 | // Calculate normal light 127 | vec3 CalculateLight(Light light) 128 | { 129 | // environment light 130 | vec3 ambient=Ambient*light.color*vec3(texture(u_Material.diffuse,v_TexCoords)); 131 | 132 | // diffuse light 133 | vec3 norm=normalize(normal); 134 | vec3 lightDir=normalize(TBN*light.position-v_FragPos); 135 | float diff=max(dot(norm,lightDir),0.0); 136 | vec3 diffuse=vec3(texture(u_Material.diffuse,v_TexCoords))*light.color*diff; 137 | 138 | // specular light 139 | vec3 viewDir=normalize(v_ViewPos-v_FragPos); 140 | vec3 reflectDir=reflect(-lightDir,norm); 141 | float spec=pow(max(dot(viewDir,reflectDir),0.0),u_Material.shininess); 142 | vec3 specular=vec3(texture(u_Material.specular,v_TexCoords))*spec*light.color; 143 | 144 | return (ambient+diffuse+specular)*light.intensity; 145 | } 146 | 147 | // Calculate directional light 148 | vec3 CalculateDirLight(DirLight light) 149 | { 150 | // environment light 151 | vec3 ambient=Ambient*light.color*vec3(texture(u_Material.diffuse,v_TexCoords)); 152 | 153 | // diffuse light 154 | vec3 norm=normalize(normal); 155 | vec3 lightDir=normalize(-light.direction); 156 | float diff=max(dot(norm,lightDir),0.0); 157 | vec3 diffuse=vec3(texture(u_Material.diffuse,v_TexCoords))*light.color*diff; 158 | 159 | // specular light 160 | vec3 viewDir=normalize(v_ViewPos-v_FragPos); 161 | vec3 reflectDir=reflect(-lightDir,norm); 162 | float spec=pow(max(dot(viewDir,reflectDir),0.0),u_Material.shininess); 163 | vec3 specular=vec3(texture(u_Material.specular,v_TexCoords))*spec*light.color; 164 | 165 | return (ambient+diffuse+specular)*light.intensity; 166 | } 167 | 168 | // Calculate point light 169 | vec3 CalculatePointLight(PointLight light) 170 | { 171 | // environment light 172 | vec3 ambient=Ambient*light.color*vec3(texture(u_Material.diffuse,v_TexCoords)); 173 | 174 | // diffuse light 175 | vec3 norm=normalize(normal); 176 | vec3 lightDir=normalize(TBN*light.position-v_FragPos); 177 | float diff=max(dot(norm,lightDir),0.0); 178 | vec3 diffuse=vec3(texture(u_Material.diffuse,v_TexCoords))*light.color*diff; 179 | 180 | // specular light 181 | vec3 viewDir=normalize(v_ViewPos-v_FragPos); 182 | vec3 reflectDir=reflect(-lightDir,norm); 183 | float spec=pow(max(dot(viewDir,reflectDir),0.0),u_Material.shininess); 184 | vec3 specular=vec3(texture(u_Material.specular,v_TexCoords))*spec*light.color; 185 | 186 | // attenuation factor 187 | float dist=length(TBN*light.position-v_FragPos); 188 | float attenuation=1.0/(light.constant+light.linear*dist+light.quadratic*(dist*dist)); 189 | 190 | return (ambient+diffuse+specular)*attenuation*light.intensity; 191 | } 192 | 193 | // Calculate Spot light 194 | vec3 CalculateSpotLight(SpotLight light) 195 | { 196 | // environment light 197 | vec3 ambient=Ambient*light.color*vec3(texture(u_Material.diffuse,v_TexCoords)); 198 | 199 | // diffuse light 200 | vec3 norm=normalize(normal); 201 | vec3 lightDir=normalize(TBN*light.position-v_FragPos); 202 | float diff=max(dot(norm,lightDir),0.0); 203 | 204 | float theta=dot(lightDir,normalize(light.direction)); 205 | float epsilon=light.cutoff - light.outerCutOff; 206 | float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); 207 | 208 | vec3 diffuse=vec3(texture(u_Material.diffuse,v_TexCoords))*light.color*diff; 209 | // specular light 210 | vec3 viewDir=normalize(v_ViewPos-v_FragPos); 211 | vec3 reflectDir=reflect(-lightDir,norm); 212 | float spec=pow(max(dot(viewDir,reflectDir),0.0),u_Material.shininess); 213 | vec3 specular=vec3(texture(u_Material.specular,v_TexCoords))*spec*light.color; 214 | return (ambient+diffuse+specular)*light.intensity*intensity; 215 | 216 | } 217 | 218 | void main() 219 | { 220 | if(u_UseNormalMap==1) 221 | normal=normalize(texture(u_Material.normalMap,v_TexCoords).rgb*2.0-1.0); 222 | else 223 | normal=v_Normal; 224 | 225 | vec3 result=vec3(0.0); 226 | for(int i=0;i 4 | #include 5 | 6 | #include 7 | 8 | namespace Chaf 9 | { 10 | enum class CHAF_API EventType 11 | { 12 | None = 0, 13 | WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved, 14 | AppTick, AppUpdate, AppRender, 15 | KeyPressed, KeyRelease, KeyTyped, 16 | MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled 17 | }; 18 | 19 | enum CHAF_API EventCategory 20 | { 21 | None = 0, 22 | EventCategoryApplication = BIT(0), 23 | EventCategoryInput = BIT(1), 24 | EventCategoryKeyboard = BIT(2), 25 | EventCategoryMouse = BIT(3), 26 | EventCategoryMouseButton = BIT(4) 27 | }; 28 | 29 | #define EVENT_CLASS_TYPE(type) static EventType GetStaticType() { return EventType::##type; }\ 30 | virtual EventType GetEventType() const override { return GetStaticType(); }\ 31 | virtual const char* GetName() const override { return #type; } 32 | 33 | #define EVENT_CLASS_CATEGORY(category) virtual int GetCategoryFlags() const override { return category; } 34 | 35 | /*Event*/ 36 | class CHAF_API Event 37 | { 38 | public: 39 | virtual EventType GetEventType() const = 0; 40 | virtual const char* GetName() const = 0; 41 | virtual int GetCategoryFlags() const = 0; 42 | virtual std::string ToString() const { return GetName(); } 43 | 44 | inline bool IsInCategory(EventCategory category) 45 | { 46 | return GetCategoryFlags() & category; 47 | } 48 | 49 | bool m_Handled = false; 50 | }; 51 | 52 | /*EventDispatcher*/ 53 | class CHAF_API EventDispatcher 54 | { 55 | template 56 | using EventFn = std::function; 57 | public: 58 | EventDispatcher(Event& event) 59 | : m_Event(event) {} 60 | 61 | template 62 | bool Dispatch(EventFn func) 63 | { 64 | if (m_Event.GetEventType() == T::GetStaticType()) 65 | { 66 | m_Event.m_Handled = func(*(T*)&m_Event); 67 | return true; 68 | } 69 | return false; 70 | } 71 | 72 | private: 73 | Event& m_Event; 74 | }; 75 | 76 | inline std::ostream& operator<<(std::ostream& os, const Event& e) 77 | { 78 | return os << e.ToString(); 79 | } 80 | 81 | /*KeyEvent*/ 82 | class CHAF_API KeyEvent :public Event 83 | { 84 | public: 85 | inline int GetKeyCode() const { return m_KeyCode; } 86 | 87 | EVENT_CLASS_CATEGORY(EventCategoryKeyboard | EventCategoryInput) 88 | 89 | protected: 90 | KeyEvent(int keycode) 91 | :m_KeyCode(keycode) {} 92 | 93 | int m_KeyCode; 94 | }; 95 | 96 | class CHAF_API KeyPressedEvent :public KeyEvent 97 | { 98 | public: 99 | KeyPressedEvent(int keycode, int repeatCount) 100 | :KeyEvent(keycode), m_RepeatCount(repeatCount) {} 101 | 102 | inline int GetRepeatCount() const { return m_RepeatCount; } 103 | 104 | std::string ToString()const override 105 | { 106 | std::stringstream ss; 107 | ss << "KeyPressEvent: " << m_KeyCode << "(" << m_RepeatCount << " repeats)"; 108 | return ss.str(); 109 | } 110 | 111 | EVENT_CLASS_TYPE(KeyPressed); 112 | 113 | private: 114 | int m_RepeatCount; 115 | }; 116 | 117 | class CHAF_API KeyReleasedEvent :public KeyEvent 118 | { 119 | public: 120 | KeyReleasedEvent(int keycode) 121 | :KeyEvent(keycode) {} 122 | 123 | std::string ToString()const override 124 | { 125 | std::stringstream ss; 126 | ss << "KeyReleasedEvent: " << m_KeyCode; 127 | return ss.str(); 128 | } 129 | 130 | EVENT_CLASS_TYPE(KeyRelease); 131 | }; 132 | 133 | class CHAF_API KeyTypedEvent :public KeyEvent 134 | { 135 | public: 136 | KeyTypedEvent(int keycode) 137 | :KeyEvent(keycode) {} 138 | 139 | std::string ToString()const override 140 | { 141 | std::stringstream ss; 142 | ss << "KeyTypedEvent: " << m_KeyCode; 143 | return ss.str(); 144 | } 145 | 146 | EVENT_CLASS_TYPE(KeyTyped); 147 | }; 148 | 149 | /*Mouse Event*/ 150 | class CHAF_API MouseMovedEvent :public Event 151 | { 152 | public: 153 | MouseMovedEvent(float x, float y) 154 | :m_MouseX(x), m_MouseY(y) {} 155 | 156 | inline float GetX() const { return m_MouseX; } 157 | inline float GetY() const { return m_MouseY; } 158 | 159 | std::string ToString() const override 160 | { 161 | std::stringstream ss; 162 | ss << "MouseMovedEvent: " << m_MouseX << ", " << m_MouseY; 163 | return ss.str(); 164 | } 165 | 166 | EVENT_CLASS_TYPE(MouseMoved) 167 | EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) 168 | 169 | private: 170 | float m_MouseX, m_MouseY; 171 | }; 172 | 173 | class CHAF_API MouseScrolledEvent : public Event 174 | { 175 | public: 176 | MouseScrolledEvent(float xOffset, float yOffset) 177 | :m_XOffset(xOffset), m_YOffset(yOffset) {} 178 | 179 | inline float GetXOffset() const { return m_XOffset; } 180 | inline float GetYOffset() const { return m_YOffset; } 181 | 182 | std::string ToString() const override 183 | { 184 | std::stringstream ss; 185 | ss << "MouseScrollEvent: " << m_XOffset << ", " << m_YOffset; 186 | return ss.str(); 187 | } 188 | 189 | EVENT_CLASS_TYPE(MouseScrolled) 190 | EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) 191 | 192 | private: 193 | float m_XOffset, m_YOffset; 194 | }; 195 | 196 | class CHAF_API MouseButtonEvent :public Event 197 | { 198 | public: 199 | inline int GetMouseButton() const { return m_Button; } 200 | 201 | EVENT_CLASS_CATEGORY(EventCategoryMouseButton | EventCategoryInput); 202 | protected: 203 | MouseButtonEvent(int button) 204 | :m_Button(button) {} 205 | 206 | int m_Button; 207 | }; 208 | 209 | class CHAF_API MouseButtonPressedEvent :public MouseButtonEvent 210 | { 211 | public: 212 | MouseButtonPressedEvent(int button) 213 | :MouseButtonEvent(button) {} 214 | 215 | std::string ToString() const override 216 | { 217 | std::stringstream ss; 218 | ss << "MouseButtonPressedEvent: " << m_Button; 219 | return ss.str(); 220 | } 221 | 222 | EVENT_CLASS_TYPE(MouseButtonPressed) 223 | }; 224 | 225 | class CHAF_API MouseButtonReleasedEvent :public MouseButtonEvent 226 | { 227 | public: 228 | MouseButtonReleasedEvent(int button) 229 | :MouseButtonEvent(button) {} 230 | 231 | std::string ToString() const override 232 | { 233 | std::stringstream ss; 234 | ss << "MouseButtonReleasedEvent: " << m_Button; 235 | return ss.str(); 236 | } 237 | 238 | EVENT_CLASS_TYPE(MouseButtonReleased) 239 | }; 240 | 241 | /*Application Event*/ 242 | class CHAF_API WindowCloseEvent :public Event 243 | { 244 | public: 245 | WindowCloseEvent() {} 246 | 247 | EVENT_CLASS_TYPE(WindowClose) 248 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 249 | }; 250 | 251 | class CHAF_API WindowResizeEvent : public Event 252 | { 253 | public: 254 | WindowResizeEvent(unsigned int width, unsigned int height) 255 | :m_Width(width), m_Height(height) {} 256 | 257 | inline unsigned int GetWidth() const { return m_Width; } 258 | inline unsigned int GetHeight() const { return m_Height; } 259 | 260 | std::string ToString() const override 261 | { 262 | std::stringstream ss; 263 | ss << "WindowResizedEvent: " << m_Width << ", " << m_Height; 264 | return ss.str(); 265 | } 266 | 267 | EVENT_CLASS_TYPE(WindowResize) 268 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 269 | 270 | private: 271 | unsigned int m_Width, m_Height; 272 | }; 273 | 274 | class CHAF_API AppTickEvent :public Event 275 | { 276 | public: 277 | AppTickEvent() {} 278 | 279 | EVENT_CLASS_TYPE(AppTick) 280 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 281 | }; 282 | 283 | class CHAF_API AppUpdateEvent :public Event 284 | { 285 | public: 286 | AppUpdateEvent() {} 287 | 288 | EVENT_CLASS_TYPE(AppUpdate) 289 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 290 | }; 291 | 292 | class CHAF_API AppRenderEvent :public Event 293 | { 294 | public: 295 | AppRenderEvent() {} 296 | 297 | EVENT_CLASS_TYPE(AppRender) 298 | EVENT_CLASS_CATEGORY(EventCategoryApplication) 299 | }; 300 | } --------------------------------------------------------------------------------