diff --git a/.gitmodules b/.gitmodules index 218c126..15f707d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,9 @@ [submodule "_ThirdParty/glm"] path = _ThirdParty/glm url = https://github.com/g-truc/glm.git +[submodule "_ThirdParty/imgui"] + path = _ThirdParty/imgui + url = https://github.com/ocornut/imgui.git +[submodule "_ThirdParty/fmt"] + path = _ThirdParty/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 8df89b2..bca2836 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,29 +21,19 @@ add_subdirectory(_ThirdParty/glm) add_subdirectory(_ThirdParty/entt) +add_subdirectory(_ThirdParty/fmt) + +include_directories(_ThirdParty/imgui/lib) +file(GLOB_RECURSE IMGUI_SOURCES _ThirdParty/imgui/lib/*.cpp) + +file(GLOB_RECURSE SOURCES ${CMAKE_SOURCE_DIR}/src/*.cpp) +file(GLOB_RECURSE HEADERS ${CMAKE_SOURCE_DIR}/src/*.h) + add_executable(${PROJECT_NAME} - src/main.cpp + ${IMGUI_SOURCES} ${GLAD_SOURCE_DIR}/gl.c - src/Mesh.cpp - src/Mesh.h - src/Model.h - src/Material.h - src/ModelManager.cpp - src/ModelManager.h - src/ShaderProgram.cpp - src/ShaderProgram.h - src/Texture.h - src/TextureManager.cpp - src/TextureManager.h - src/ShaderManager.cpp - src/ShaderManager.h - src/FreeCamera.cpp - src/FreeCamera.h - src/InputManager.cpp - src/InputManager.h - src/Components.h - src/Scene.cpp - src/Scene.h) + ${SOURCES} + ${HEADERS}) add_custom_target(copy_resources COMMAND ${CMAKE_COMMAND} -E copy_directory @@ -52,5 +42,5 @@ add_custom_target(copy_resources COMMENT "Copying resources..." ) -target_link_libraries(${PROJECT_NAME} glfw spdlog assimp glm EnTT) +target_link_libraries(${PROJECT_NAME} glfw spdlog assimp glm EnTT fmt) target_include_directories(${PROJECT_NAME} PRIVATE ${ASSIMP_INCLUDE_INSTALL_DIR}) diff --git a/_ThirdParty/fmt b/_ThirdParty/fmt new file mode 160000 index 0000000..9cb8c0f --- /dev/null +++ b/_ThirdParty/fmt @@ -0,0 +1 @@ +Subproject commit 9cb8c0f92b4c345fb974a75d71370c23047528aa diff --git a/_ThirdParty/imgui b/_ThirdParty/imgui new file mode 160000 index 0000000..80987f1 --- /dev/null +++ b/_ThirdParty/imgui @@ -0,0 +1 @@ +Subproject commit 80987f1c40482c2dfb5ff7fcc4af0e56fc415a7f diff --git a/src/Components.h b/src/Components.h index a83cc63..46f367b 100644 --- a/src/Components.h +++ b/src/Components.h @@ -36,6 +36,10 @@ namespace Components { glm::vec3 diffuse{}; glm::vec3 specular{}; }; + + struct Tag { + std::string name; + }; } diff --git a/src/Scene.cpp b/src/Scene.cpp index 6c8b7e3..dc56dab 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -5,6 +5,7 @@ #include "Scene.h" #include "Components.h" +#include "fmt/format.h" Scene::Scene() { root = _registry.create(); @@ -20,6 +21,8 @@ entt::entity Scene::create_game_object(entt::entity parent) { const entt::entity entity = _registry.create(); attach_component(entity); attach_component(entity); + auto& tag = attach_component(entity); + tag.name = fmt::format("entity {0}", (int)entity); add_child(parent, entity); @@ -67,11 +70,17 @@ void Scene::draw_scene(ShaderProgram *shader) { } } +entt::entity Scene::get_root() const { + return root; +} + void Scene::add_child(entt::entity parent, entt::entity child) { auto& parentRelationship = fetch_component(parent); if (parentRelationship.first_child == entt::null) { parentRelationship.first_child = child; + auto& childRelationship = fetch_component(child); + childRelationship.parent = parent; return; } diff --git a/src/Scene.h b/src/Scene.h index 309d239..f01b022 100644 --- a/src/Scene.h +++ b/src/Scene.h @@ -33,6 +33,8 @@ public: void update_transforms(); void draw_scene(ShaderProgram* program); + + [[nodiscard]] entt::entity get_root() const; private: entt::registry _registry{}; entt::entity root{entt::null}; diff --git a/src/main.cpp b/src/main.cpp index 94b0f00..50815f7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,9 @@ #define STB_IMAGE_IMPLEMENTATION #include "Components.h" #include "FreeCamera.h" +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" #include "InputManager.h" #include "stb_image.h" @@ -23,9 +26,11 @@ #include "Texture.h" #include "TextureManager.h" +#include "fmt/base.h" + GLFWwindow* gWindow = nullptr; -int gWindowWidth = 800; -int gWindowHeight = 600; +int gWindowWidth = 1920; +int gWindowHeight = 1080; int glVersionMajor = 0; int glVersionMinor = 0; @@ -45,12 +50,14 @@ void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height); void init_glfw(); void create_main_window(); void load_gl(); +void load_imgui(); void init_camera(); void load_default_textures(); void load_shaders(); void load_inputs(); void load_default_models(); void loop(); +void draw_ui(); auto xAxis = glm::vec3{1.f, 0.f, 0.f}; auto yAxis = glm::vec3{0.f, 1.f, 0.f}; @@ -65,6 +72,8 @@ int main() { load_gl(); + load_imgui(); + init_camera(); stbi_set_flip_vertically_on_load(true); @@ -84,6 +93,9 @@ int main() { diffuse = {0.5f, 0.5f, 0.5f}; specular = {1.0f, 1.0f, 1.0f}; + auto& tag = gScene.fetch_component(dirLight); + tag.name = "directional light"; + loop(); ShaderManager::shaders.clear(); @@ -159,6 +171,15 @@ void load_gl() glEnable(GL_MULTISAMPLE); } +void load_imgui() { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + + ImGui::StyleColorsDark(); + ImGui_ImplGlfw_InitForOpenGL(gWindow, true); + ImGui_ImplOpenGL3_Init("#version 330"); +} + void init_camera() { gCamera = {{5.f, 5.f, 5.f}, 0, 0, gAspectRatio}; gCamera.rotate_yaw(-135.f); @@ -241,10 +262,14 @@ void loop() { gCamera.move(DOWN, .05); } + draw_ui(); + // gl frame prep glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + const auto shader = ShaderManager::shaders["phong_shader"]; shader->bind(); shader->setMat4("projection", gCamera.projection()); @@ -259,4 +284,53 @@ void loop() { // gl end frame stuff glfwSwapBuffers(gWindow); } +} + +void draw_ui() { + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + { + if (ImGui::Begin("Scene")) { + ImGui::Text("Scene"); + const auto root = gScene.get_root(); + auto entity = gScene.fetch_component(root).first_child; + while (entity != entt::null) { + const auto&[name] = gScene.fetch_component(entity); + std::string text = fmt::format(" {0}", name); + ImGui::Text((char*)text.data()); + entity = gScene.fetch_component(entity).next_sibling; + } + ImGui::End(); + } + + if (ImGui::BeginMainMenuBar()) { + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("New Scene", "Ctrl+N")) { + /* Handle New File logic */ + } + if (ImGui::MenuItem("Open Scene", "Ctrl+O")) { + /* Handle Open logic */ + } + ImGui::Separator(); // Adds a visual line between sections + if (ImGui::MenuItem("Save", "Ctrl+S")) { + /* Handle Save logic */ + } + if (ImGui::MenuItem("Exit", "Alt+F4")) { + /* Handle Exit logic */ + } + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Scene")) { + if (ImGui::MenuItem("New Scene Object")) { + gScene.create_game_object(); + // Do other stuff here, open this entity in the entity editor, etc... + } + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } + } + ImGui::Render(); } \ No newline at end of file