From a1ec94e98396de9598b2bcf89cf97f462b050554 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sat, 12 Nov 2022 22:40:36 +0100 Subject: [PATCH] Applying better design choices for general engine Renderer is causing a big memory leak because it never deletes its Vertex Array --- Editor/src/EditorContext.h | 13 - Editor/src/Project/Project.cpp | 6 +- Editor/src/Project/Project.h | 2 +- Editor/src/SceneRuntime.h | 78 ----- Editor/src/UI/EditorWindow.h | 14 + Editor/src/UI/GUIRenderer.h | 64 ++++ Editor/src/UI/MainMenuBar.h | 145 +++++++++ Editor/src/UI/widgets.cpp | 219 ------------- Editor/src/UI/widgets.h | 236 +++++++++++++- Editor/src/app.cpp | 303 +++++------------- YoggieEngine/src/Application.h | 17 - YoggieEngine/src/EntryPoint.h | 2 +- .../src/Graphics/Memory/FrameBuffer.cpp | 7 +- .../src/Graphics/Primitives/Texture.cpp | 4 +- YoggieEngine/src/Platform/Window.cpp | 86 +++-- YoggieEngine/src/Platform/Window.h | 36 ++- YoggieEngine/src/Scene/Scene.cpp | 22 ++ YoggieEngine/src/Scene/Scene.h | 5 + YoggieEngine/src/YoggieEngine.h | 2 - 19 files changed, 626 insertions(+), 635 deletions(-) delete mode 100644 Editor/src/EditorContext.h delete mode 100644 Editor/src/SceneRuntime.h create mode 100644 Editor/src/UI/EditorWindow.h create mode 100644 Editor/src/UI/GUIRenderer.h create mode 100644 Editor/src/UI/MainMenuBar.h delete mode 100644 Editor/src/UI/widgets.cpp diff --git a/Editor/src/EditorContext.h b/Editor/src/EditorContext.h deleted file mode 100644 index 910db25..0000000 --- a/Editor/src/EditorContext.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "Project/Project.h" - - -struct EditorContext { - std::shared_ptr CurrentProject; - - Scene MainScene; - - EditorContext() = default; - EditorContext(EditorContext& other) = default; - ~EditorContext() = default; -}; diff --git a/Editor/src/Project/Project.cpp b/Editor/src/Project/Project.cpp index 05751cf..baba0ee 100644 --- a/Editor/src/Project/Project.cpp +++ b/Editor/src/Project/Project.cpp @@ -20,7 +20,7 @@ void Project::SaveProject(std::filesystem::path path, Project& project) projectFile.close(); } -void Project::LoadProject(std::filesystem::path path, std::shared_ptr& project) +void Project::LoadProject(std::filesystem::path path, std::unique_ptr& project) { std::string YAMLProject; std::stringstream sstream; @@ -36,8 +36,8 @@ void Project::LoadProject(std::filesystem::path path, std::shared_ptr& YAML::Node node = YAML::Load(YAMLProject); // this is probably not perfect but it seems to work for now - project.reset(); - project = std::make_shared(node.as()); + project.release(); + project = std::make_unique(node.as()); std::cout << "loading..." << project.get()->Name << std::endl; diff --git a/Editor/src/Project/Project.h b/Editor/src/Project/Project.h index 609c78f..f82561a 100644 --- a/Editor/src/Project/Project.h +++ b/Editor/src/Project/Project.h @@ -14,7 +14,7 @@ public: const std::filesystem::path GetProjectDirectory() { return ProjectDirectory; } static void SaveProject(std::filesystem::path path, Project& project); - static void LoadProject(std::filesystem::path path, std::shared_ptr& project); + static void LoadProject(std::filesystem::path path, std::unique_ptr& project); private: std::string Name; std::filesystem::path ProjectDirectory; diff --git a/Editor/src/SceneRuntime.h b/Editor/src/SceneRuntime.h deleted file mode 100644 index 62d8afe..0000000 --- a/Editor/src/SceneRuntime.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once -#include "../../YoggieEngine/src/AssetManager/ModelImporter.h" -#include "../../YoggieEngine/src/Graphics/Memory/Framebuffer.h" -#include "../../YoggieEngine/src/PerfCounter.h" -#include "../../YoggieEngine/src/Scene/Entity.h" -#include "Project/Project.h" -#include "AssetManagement/AssetManager.h" - - -class EditorRuntime : public ApplicationRuntime { - -public: - EditorRuntime() = default; - void Start() override - { - CurrentProject = std::make_shared("Random"); - - std::string path = (std::filesystem::current_path()).string(); - CurrentProject.get()->setProjectDirectory(path); - - AssetManager::Init(); - AssetManager::setAssetPath(CurrentProject.get()->GetProjectDirectory()); - AssetManager::BuildAssetView(); - - framebuffer = new Framebuffer(800, 600); - - // Create a level and load it as the current level - auto importer = ModelImporter(); - - // Create a cube - Model = importer.Import("build/Debug/Models/Cube.obj"); - cube = MainScene.AddEntity("cube"); - - auto& render3DComponent = cube.AddComponent(); - render3DComponent.mesh = *(Model->renderable->mesh); - - cube.GetComponent().Position = glm::vec3(1.0f, 0.0f, 5.0f); - - auto cube2 = MainScene.AddEntity("Cube1"); - auto& rendercube2 = cube2.AddComponent(); - rendercube2.mesh = *(Model->renderable->mesh); - - // create an ambient light source - auto AmbientLight = MainScene.AddEntity("AmbientLight"); - auto light = AmbientLight.AddComponent(); - light.Color = glm::vec3(1.0f); - light.Strength = 1.0f; - - Selected = (entt::entity)-1; - - } - - void Update() override - { - - } - - void FixedUpdate() override - { - } - - void Stop() override - { - } - - -private: - std::shared_ptr CurrentProject = nullptr; - Scene MainScene; - - Framebuffer* framebuffer; - SceneObject* Model; - Entity cube; - - - entt::entity Selected; - friend class Editor; -}; \ No newline at end of file diff --git a/Editor/src/UI/EditorWindow.h b/Editor/src/UI/EditorWindow.h new file mode 100644 index 0000000..bc8ed06 --- /dev/null +++ b/Editor/src/UI/EditorWindow.h @@ -0,0 +1,14 @@ +#pragma once +#include +#include + +class EditorWindow { + +public: + EditorWindow(const std::string& name ) { ImGui::Begin(name.c_str()); } + + + + ~EditorWindow() { ImGui::End(); } + +}; \ No newline at end of file diff --git a/Editor/src/UI/GUIRenderer.h b/Editor/src/UI/GUIRenderer.h new file mode 100644 index 0000000..7005e31 --- /dev/null +++ b/Editor/src/UI/GUIRenderer.h @@ -0,0 +1,64 @@ +#pragma once +#include +#include +#include +#include +#include "../../src/YoggieEngine.h" + + +class GUIRenderer { +public: + GUIRenderer(YoggieEngine::NativeWindow& window ) { + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_ViewportsEnable; + io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_DockingEnable; + io.Fonts->AddFontFromFileTTF("build/Debug/Fonts/Roboto-Regular.ttf", 18); + + + ImGui::StyleColorsDark(); + + ImGui_ImplGlfw_InitForOpenGL(window.GetGLFWHandle(), true); + ImGui_ImplOpenGL3_Init("#version 440"); + } + + void Begin () + { + ImGui_ImplGlfw_NewFrame(); + ImGui_ImplOpenGL3_NewFrame(); + + ImGui::NewFrame(); + + ImGuizmo::SetOrthographic(true); + ImGuizmo::BeginFrame(); + + } + + void End() + { + ImGui::EndFrame(); + + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + GLFWwindow* last_context = glfwGetCurrentContext(); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); + glfwMakeContextCurrent(last_context); + } + + } + + + ~GUIRenderer(){ + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + } +}; diff --git a/Editor/src/UI/MainMenuBar.h b/Editor/src/UI/MainMenuBar.h new file mode 100644 index 0000000..e8786f9 --- /dev/null +++ b/Editor/src/UI/MainMenuBar.h @@ -0,0 +1,145 @@ +#pragma once +#include + +class MainMenuBar { + +public: + MainMenuBar() { ImGui::BeginMainMenuBar(); } + + void ApplicationMenu(std::unique_ptr& project) { + + if (ImGui::BeginMenu("Application")) { + + if (ImGui::MenuItem("Load Project")) + { + nfdresult_t result = NFD_OpenDialog({ "yproj" }, NULL, &path); + switch (result) { + case(NFD_OKAY): + Project::LoadProject(path, project); + AssetManager::setAssetPath(project.get()->GetProjectDirectory()); + AssetManager::BuildAssetView(); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + std::cout << "NFD_Error: " << NFD_GetError() << std::endl; + break; + } + + } + + if (ImGui::MenuItem("Save project as...")) { + nfdresult_t result = NFD_SaveDialog({ "yproj" }, NULL, &path); + switch (result) { + case(NFD_OKAY): + std::cout << "Save as: " << path << std::endl; + Project::SaveProject(path, *project.get()); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + std::cout << "NFD_Error: " << NFD_GetError() << std::endl; + break; + } + } + + + + if (ImGui::MenuItem("Preferences")) + { + + } + + if (ImGui::MenuItem("Exit")) + { + // TODO: Exit application + } + + ImGui::EndMenu(); + } + } + + void SceneMenu(std::unique_ptr& project, Scene& scene) { + + if (ImGui::BeginMenu("Scene")) { + + if (ImGui::MenuItem("Save scene")) + { + nfdresult_t result = NFD_SaveDialog({ "yscene" }, NULL, &path); + switch (result) { + case(NFD_OKAY): + SaveScene(path, scene); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + std::cout << "NFD_Error: " << NFD_GetError() << std::endl; + break; + } + + } + + if (ImGui::MenuItem("Load scene")) + { + auto result = NFD_OpenDialog({ "yscene" }, NULL, &path); + switch (result) { + case (NFD_OKAY): + LoadScene(path, scene); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + std::cout << "NFD_Error: " << NFD_GetError() << std::endl; + break; + } + + } + + if (ImGui::MenuItem("Add Entity")) + { + scene.AddEntity("New Entity"); + } + + if (ImGui::MenuItem("Import Model")) + { + auto result = NFD_OpenDialog("obj,fbx,gltf", NULL, &path); + switch (result) { + case(NFD_OKAY): + // Import Model + AssetManager::LoadFromSource( + path, + project.get()->GetProjectDirectory() / "Assets" + ); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + std::cout << "NFD_Error: " << NFD_GetError() << std::endl; + break; + } + } + + if (ImGui::MenuItem("Import MeshAsset (temp)")) + { + auto result = NFD_OpenDialog("mesh", NULL, &path); + switch (result) { + case(NFD_OKAY): + AssetManager::LoadFromAssetFile(path); + break; + case(NFD_CANCEL): + break; + case(NFD_ERROR): + break; + } + + } + + ImGui::EndMenu(); + } + } + + ~MainMenuBar() { ImGui::EndMainMenuBar(); } +private: + char* path = nullptr; + +}; \ No newline at end of file diff --git a/Editor/src/UI/widgets.cpp b/Editor/src/UI/widgets.cpp deleted file mode 100644 index 030114e..0000000 --- a/Editor/src/UI/widgets.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "widgets.h" -#include "EditorConsole.h" -#include -#include "../../YoggieEngine/src/Scene/Components.h" -#include "../../YoggieEngine/src/Scene/Entity.h" -#include "../AssetManagement/AssetManager.h" -class Editor; - -void ComponentView(const std::string& componentName, voidFunction func) -{ - ImGuiWindowFlags_ window_flags = ImGuiWindowFlags_None; - ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild(componentName.c_str()); - - func(); - - ImGui::EndChild(); - ImGui::PopStyleVar(); -} - -void Inspector(entt::entity ent , Scene& scene) { - ImGui::Begin("Inspector"); - static char* names[] = { "Script Component", "Camera Component" }; - - static float Zoom = 90; - static glm::vec3 Position = glm::vec3(0.0f, 0.0f, 0.0f); - static glm::vec3 Rotation = glm::vec3(0.0f, 0.0f, 0.0f); - if (scene.getReg().valid(ent)) { - Entity entity = Entity(ent, &scene); - - if (ImGui::Button("Add Component")) - ImGui::OpenPopup("Component picker"); - - ImGui::SameLine(); - if (ImGui::BeginPopup("Component picker")) { - - for (int i = 0; i < IM_ARRAYSIZE(names); i++) - if (ImGui::MenuItem(names[i])) { - std::cout << "Add a " << names[i] << " to " - << entity.GetComponent().name << std::endl; - } - - ImGui::EndPopup(); - } - - ImGui::NewLine(); - - auto component = entity.GetComponent(); - char* buf = new char(component.name.size()); - strcpy(buf, component.name.c_str()); - ImGui::InputText("Name:",buf , sizeof(buf), ImGuiInputTextFlags_ReadOnly); - - - if (entity.HasComponent()) { - auto& transform = entity.GetComponent(); - if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::DragFloat3("Position", glm::value_ptr(transform.Position), 0.01f); - ImGui::DragFloat3("Rotation", glm::value_ptr(transform.Rotation), 0.01f); - ImGui::DragFloat3("Scale", glm::value_ptr(transform.Scale), 0.01f, 0.0f); - } - - } - - if (entity.HasComponent()) { - auto& render3d = entity.GetComponent(); - if (ImGui::CollapsingHeader("Render3D", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::ColorEdit3("Colour", glm::value_ptr(render3d.color)); - } - } - - if (entity.HasComponent()) { - auto& light = entity.GetComponent(); - if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::DragFloat("Strength", &light.Strength, 0.001f); - ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color)); - } - - } - - if (entity.HasComponent ()) { - auto& camera = entity.GetComponent(); - ComponentView("Camera", [] { - ImGui::SliderFloat("Zoom", &Zoom, 10, 190); - ImGui::InputFloat3("Position:", &Position[0]); - ImGui::InputFloat3("Rotation:", &Rotation[0]); - }); - } - - if (entity.HasComponent()) { - ComponentView("Scripting", [] { - ImGui::LabelText("##--", "Hello scripting"); - }); - } - - } - - ImGui::End(); -} - -void SceneExplorer(entt::entity& selected, Scene& scene ) -{ - ImGui::Begin("Scene Explorer"); - - scene.getReg().each([&](entt::entity enttNumber) { - Entity entity = Entity(enttNumber, &scene); - auto id = entity.GetComponent(); - - if (ImGui::Selectable(id.name.c_str(), enttNumber == selected )) { - selected = enttNumber; - } - - }); - - ImGui::End(); -} - -void Viewport(Framebuffer& framebuffer) { - - unsigned int viewportWindowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar ; - - ImGui::Begin("Viewport", false, viewportWindowFlags); - - - ImGui::Image((void*)(intptr_t)framebuffer.GetColourAttachment(), ImVec2{ (float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight()}); - - //ImGuizmo::SetDrawlist(); - //ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); - //ImGuizmo::Enable(true); - //ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(trans)); - - - ImGui::End(); - -} - -void GamePort(Framebuffer& framebuffer) -{ - unsigned int viewportWindowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar; - ImGui::Begin("Game", false, viewportWindowFlags); - - ImGui::Image((void*)(intptr_t)framebuffer.GetColourAttachment(), { ImGui::GetWindowWidth(), ImGui::GetWindowHeight() }); - - - ImGui::End(); - -} - -void Settings() { - ImGui::Begin("Settings"); - - ImGui::LabelText("##title-settings", "Fine grain control over your engine... "); - ImGui::End(); -} - -auto console = EditorConsole(); - -void Console() { - ImGui::Begin("Console", false); - console.Draw(); - ImGui::End(); -} - -void AssetsFinder() { - static YoggieEngine::Texture folderIcon ("rsc/folderIcon.png"); - static YoggieEngine::Texture AssetIcon("rsc/assetIcon.png"); - static int iconSize = 60; - - ImGui::Begin("Asset-Finder", false); - ImGui::DragInt("IconSize", &iconSize, 1, 30, 90); - - - if (ImGui::BeginTable("##resources", 3)) - { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f)); - - - int row = 0; - int column = 0 ; - for (auto& asset : AssetManager::assets) { - if (column % 3 == 0) { - ImGui::TableNextRow(); - column = 0; - row++; - } - - ImGui::TableSetColumnIndex(column); - - if (asset.isFolder) { - ImGui::ImageButton( - (ImTextureID)folderIcon.GetID(), - ImVec2{ (float)iconSize,(float)iconSize }); - ImGui::Text(asset.GetName(), row); - - } - else { - ImGui::ImageButton( - (ImTextureID)AssetIcon.GetID(), - ImVec2{ (float)iconSize, (float)iconSize }); - ImGui::Text(asset.GetName(), row); - - } - - - column++; - } - - - ImGui::PopStyleColor(3); - ImGui::EndTable(); - - } - - - - - ImGui::End(); -} \ No newline at end of file diff --git a/Editor/src/UI/widgets.h b/Editor/src/UI/widgets.h index b6275d1..066c9e2 100644 --- a/Editor/src/UI/widgets.h +++ b/Editor/src/UI/widgets.h @@ -1,28 +1,240 @@ #pragma once -#include -#include #include -#include -#include +#include +#include #include "../../libs/guizmo/ImGuizmo.h" + #include "../../YoggieEngine/src/YoggieEngine.h" +#include "../../src/Scene/Entity.h" + +#include "EditorWindow.h" +#include "EditorConsole.h" +#include "../Project/Project.h" +#include "../AssetManagement/AssetManager.h" + typedef void ( *voidFunction ) (void); using namespace YoggieEngine; -void ComponentView(const std::string& componentName, voidFunction func); +inline void ComponentView(const std::string& componentName, voidFunction func) +{ + ImGuiWindowFlags_ window_flags = ImGuiWindowFlags_None; + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild(componentName.c_str()); -void Inspector(entt::entity entity, Scene& scene); + func(); -void SceneExplorer(entt::entity& selected, Scene& scene); + ImGui::EndChild(); + ImGui::PopStyleVar(); +} -void Viewport(Framebuffer& framebuffer); +class Inspector : EditorWindow { +public: + Inspector() : EditorWindow("Inspector") {} -void GamePort(Framebuffer& framebuffer); + void AddComponentDropDown(Entity& selected ) + { + static char* names[] = { "Script Component", "Camera Component" }; + if (ImGui::Button("Add Component")) + ImGui::OpenPopup("Component picker"); -void Settings(); + ImGui::SameLine(); + if (ImGui::BeginPopup("Component picker")) { -void Console(); + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + if (ImGui::MenuItem(names[i])) { + std::cout << "Add a " << names[i] << " to " + << selected.GetComponent().name << std::endl; + } -void AssetsFinder(); \ No newline at end of file + ImGui::EndPopup(); + } + ImGui::NewLine(); + } + + void ShowComponents(Entity& selected) + { + auto component = selected.GetComponent(); + char* buf = new char(component.name.size()); + strcpy(buf, component.name.c_str()); + ImGui::InputText("Name:", buf, sizeof(buf), ImGuiInputTextFlags_ReadOnly); + + + if (selected.HasComponent()) { + auto& transform = selected.GetComponent(); + if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::DragFloat3("Position", glm::value_ptr(transform.Position), 0.01f); + ImGui::DragFloat3("Rotation", glm::value_ptr(transform.Rotation), 0.01f); + ImGui::DragFloat3("Scale", glm::value_ptr(transform.Scale), 0.01f, 0.0f); + } + + } + + if (selected.HasComponent()) { + auto& render3d = selected.GetComponent(); + if (ImGui::CollapsingHeader("Render3D", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::ColorEdit3("Colour", glm::value_ptr(render3d.color)); + } + } + + if (selected.HasComponent()) { + auto& light = selected.GetComponent(); + if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::DragFloat("Strength", &light.Strength, 0.001f); + ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color)); + } + + } + + if (selected.HasComponent ()) { + auto& camera = selected.GetComponent(); + static float Zoom = 90; + static glm::vec3 Position, Rotation = glm::vec3(0.0f); + ComponentView("Camera", [] { + ImGui::SliderFloat("Zoom", &Zoom, 10, 190); + ImGui::InputFloat3("Position:", &Position[0]); + ImGui::InputFloat3("Rotation:", &Rotation[0]); + }); + } + + if (selected.HasComponent()) { + ComponentView("Scripting", [] { + ImGui::LabelText("##--", "Hello scripting"); + }); + } + } + +}; + +class SceneExplorer : EditorWindow { +public: + SceneExplorer(entt::entity& selected , Scene& scene) : EditorWindow("SceneExplorer") { + scene.getReg().each([&](entt::entity enttNumber) { + Entity entity = Entity(enttNumber, &scene); + auto id = entity.GetComponent(); + + if (ImGui::Selectable(id.name.c_str(), enttNumber == selected)) { + selected = enttNumber; + } + + }); + + } +}; + +class Viewport : EditorWindow { +public: + Viewport (Scene& scene) : EditorWindow("SceneView") { + Framebuffer framebuffer = Framebuffer((int)ImGui::GetWindowWidth(),(int)ImGui::GetWindowHeight()); + + + Renderer renderer = Renderer(); + renderer.Prepare(scene); + renderer.Render(&framebuffer, scene); + + + + + + ImGui::Image( + (void*)(intptr_t)framebuffer.GetColourAttachment(), + ImVec2{ (float)ImGui::GetWindowWidth(),(float)ImGui::GetWindowHeight() } + ); + + + + + //ImGuizmo::SetDrawlist(); + //ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); + //ImGuizmo::Enable(true); + //ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(trans)); + + } + +}; + +class Settings : EditorWindow { +public: + Settings() : EditorWindow("Settings") { + ImGui::LabelText("##title-settings", "Fine grain control over your engine... "); + } +}; + +class ProjectInfo : EditorWindow { +public: + ProjectInfo(Project& project) : EditorWindow("Project Info") { + ImGui::Text("Project: %s", project.GetName().c_str()); + ImGui::Text("Directory: %s", project.GetProjectDirectory().u8string().c_str()); + } +}; + +class Console : EditorWindow { +public: + +Console() : EditorWindow("Console") { + s_console = std::make_unique(); +} +void Show() { + s_console.get()->Draw(); +} + +private: + std::unique_ptr s_console; +}; + +class AssetFinder : EditorWindow { +public: + AssetFinder() : EditorWindow("Assets") { + ImGui::DragInt("IconSize", &iconSize, 1, 30, 90); + + + if (ImGui::BeginTable("##resources", 3)) + { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.f, 0.f, 0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.f, 0.f, 0.f, 0.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.f, 1.f, 1.f, 0.2f)); + + + int row = 0; + int column = 0; + for (auto& asset : AssetManager::assets) { + if (column % 3 == 0) { + ImGui::TableNextRow(); + column = 0; + row++; + } + + ImGui::TableSetColumnIndex(column); + + if (asset.isFolder) { + ImGui::ImageButton( + (ImTextureID)folderIcon.GetID(), + ImVec2{ (float)iconSize,(float)iconSize }); + ImGui::Text(asset.GetName(), row); + + } + else { + ImGui::ImageButton( + (ImTextureID)AssetIcon.GetID(), + ImVec2{ (float)iconSize, (float)iconSize }); + ImGui::Text(asset.GetName(), row); + + } + + + column++; + } + + + ImGui::PopStyleColor(3); + ImGui::EndTable(); + + } + + } +private: + Texture folderIcon = Texture("rsc/folderIcon.png"); + Texture AssetIcon = Texture("rsc/assetIcon.png"); + int iconSize = 60; +}; \ No newline at end of file diff --git a/Editor/src/app.cpp b/Editor/src/app.cpp index 9910faf..d796432 100644 --- a/Editor/src/app.cpp +++ b/Editor/src/app.cpp @@ -1,8 +1,5 @@ #include "../../YoggieEngine/src/EntryPoint.h" -#include -#include -#include -#include +#include "../../YoggieEngine/src/AssetManager/ModelImporter.h" #include @@ -10,36 +7,37 @@ #include #include +#include "UI/GUIRenderer.h" #include "UI/Widgets.h" #include "Project/Project.h" #include "SceneSerializer.h" -#include "EditorContext.h" -#include "SceneRuntime.h" #include "AssetManagement/AssetManager.h" +#include "UI/MainMenuBar.h" const unsigned int MS_PER_UPDATE = 2; +void CreateTestProject(std::unique_ptr& project, Scene& scene); class Editor : public Application { public: Editor() : Application("Editor") {} + void Run() override { - BarinkWindow mainWindow = BarinkWindow(1200, 700); - InputSystem = new InputManager(); - renderer = new Renderer(); + auto NativeEditorWindow = NativeWindow(1200, 700); + //auto renderer = Renderer(); + auto GuiRenderer = GUIRenderer(NativeEditorWindow); - InputSystem->attach(&mainWindow); + Selected = (entt::entity)-1; - InitImGui(mainWindow); + CreateTestProject(CurrentProject, ActiveScene); - activeRuntime.Start(); + ActiveScene.Start(); double previous = glfwGetTime(); double lag = 0.0; - renderer->Prepare(activeRuntime.MainScene); - while (!mainWindow.WindowShouldClose()) + while (!NativeEditorWindow.WindowShouldClose()) { double current = glfwGetTime(); @@ -47,235 +45,77 @@ public: previous = current; lag += elapsed; - - InputSystem->PollEvents(); + NativeEditorWindow.Poll(); while (lag >= MS_PER_UPDATE) { - activeRuntime.Update(); + ActiveScene.Update(); lag -= MS_PER_UPDATE; } - renderer->Render(activeRuntime.framebuffer, activeRuntime.MainScene); + // renderer.Render(framebuffer, ActiveScene); - ImGuiBegin(); - RenderGUI(); - ImGuiEnd(); - mainWindow.SwapBuffers(); + GuiRenderer.Begin(); + RenderGUI(); + GuiRenderer.End(); + + NativeEditorWindow.SwapBuffers(); glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); } - activeRuntime.Stop(); - - delete InputSystem; - delete renderer; - - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); + ActiveScene.Stop(); } - void InitImGui(BarinkWindow& window ) - { - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_ViewportsEnable; - io.ConfigFlags |= ImGuiConfigFlags_::ImGuiConfigFlags_DockingEnable; - io.Fonts->AddFontFromFileTTF("build/Debug/Fonts/Roboto-Regular.ttf", 18); - - - ImGui::StyleColorsDark(); - - ImGui_ImplGlfw_InitForOpenGL(window.windowptr(), true); - ImGui_ImplOpenGL3_Init("#version 440"); - - - } - - void ImGuiBegin() { - ImGui_ImplGlfw_NewFrame(); - ImGui_ImplOpenGL3_NewFrame(); - - ImGui::NewFrame(); - - ImGuizmo::SetOrthographic(true); - ImGuizmo::BeginFrame(); - - } - - void ImGuiEnd() { - ImGui::EndFrame(); - - - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - GLFWwindow* last_context = glfwGetCurrentContext(); - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - glfwMakeContextCurrent(last_context); - } - } - - + void RenderGUI() { ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); // Show a menu bar + { + MainMenuBar menuBar= MainMenuBar(); + menuBar.ApplicationMenu(CurrentProject); + menuBar.SceneMenu(CurrentProject, ActiveScene); + } - ImGui::BeginMainMenuBar(); + { + ProjectInfo projectInfo(*(CurrentProject.get())); + } - if (ImGui::BeginMenu("Application")) { + { + Viewport sceneview = Viewport(ActiveScene); + } - if (ImGui::MenuItem("Load Project")) - { - nfdresult_t result = NFD_OpenDialog({ "yproj" }, NULL, &path); - switch (result) { - case(NFD_OKAY): - Project::LoadProject(path, activeRuntime.CurrentProject); - AssetManager::setAssetPath(activeRuntime.CurrentProject.get()->GetProjectDirectory()); - AssetManager::BuildAssetView(); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - std::cout << "NFD_Error: " << NFD_GetError() << std::endl; - break; - } - - } - - if (ImGui::MenuItem("Save project as...")) { - nfdresult_t result = NFD_SaveDialog({ "yproj" }, NULL, &savePath); - switch (result) { - case(NFD_OKAY): - std::cout << "Save as: " << savePath << std::endl; - Project::SaveProject(savePath, *activeRuntime.CurrentProject.get()); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - std::cout << "NFD_Error: " << NFD_GetError() << std::endl; - break; - } - } - - - - if (ImGui::MenuItem("Preferences")) - { - - } - - if (ImGui::MenuItem("Exit")) - { - // TODO: Exit application - } - - ImGui::EndMenu(); + { + SceneExplorer explorer(Selected, ActiveScene); } - if (ImGui::BeginMenu("Scene")) { - - if (ImGui::MenuItem("Save scene")) - { - nfdresult_t result = NFD_SaveDialog({ "yscene" }, NULL, &scenePath); - switch (result) { - case(NFD_OKAY): - SaveScene(scenePath, activeRuntime.MainScene); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - std::cout << "NFD_Error: " << NFD_GetError() << std::endl; - break; - } - + { + Inspector inspector = Inspector(); + if (ActiveScene.getReg().valid(Selected)) { + Entity SelectedEntity = Entity(Selected, &ActiveScene); + inspector.AddComponentDropDown(SelectedEntity); + inspector.ShowComponents(SelectedEntity); } - - if (ImGui::MenuItem("Load scene")) - { - auto result = NFD_OpenDialog({ "yscene" }, NULL, &openScenePath); - switch (result) { - case (NFD_OKAY): - LoadScene(openScenePath, activeRuntime.MainScene); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - std::cout << "NFD_Error: " << NFD_GetError() << std::endl; - break; - } - - } - - if (ImGui::MenuItem("Add Entity")) - { - activeRuntime.MainScene.AddEntity("New Entity"); - } - - if (ImGui::MenuItem("Import Model")) - { - auto result = NFD_OpenDialog( "obj,fbx,gltf" , NULL, &modelImportPath); - switch (result) { - case(NFD_OKAY): - // Import Model - AssetManager::LoadFromSource(modelImportPath, activeRuntime.CurrentProject.get()->GetProjectDirectory() / "Assets"); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - std::cout << "NFD_Error: " << NFD_GetError() << std::endl; - break; - } - } - - if (ImGui::MenuItem("Import MeshAsset (temp)")) - { - auto result = NFD_OpenDialog("mesh", NULL, &modelImportPath); - switch (result) { - case(NFD_OKAY): - AssetManager::LoadFromAssetFile(modelImportPath); - break; - case(NFD_CANCEL): - break; - case(NFD_ERROR): - break; - } - - } - - - - ImGui::EndMenu(); } + { + Settings(); + } - ImGui::EndMainMenuBar(); - - ImGui::Begin("ProjectInfo"); - ImGui::Text("Project: %s", activeRuntime.CurrentProject.get()->GetName().c_str()); - ImGui::Text("Directory: %s", activeRuntime.CurrentProject.get()->GetProjectDirectory().u8string().c_str()); - ImGui::End(); - - - //ShowStats(); - Viewport(*activeRuntime.framebuffer); - GamePort(*activeRuntime.framebuffer); - SceneExplorer(activeRuntime.Selected, activeRuntime.MainScene); - Inspector(activeRuntime.Selected, activeRuntime.MainScene); - - Settings(); - AssetsFinder(); - Console(); + { + AssetFinder assetsView = AssetFinder(); + } + + + { + Console console = Console(); + console.Show(); + } ImGui::ShowDemoWindow(); ImGui::ShowMetricsWindow(); @@ -284,14 +124,9 @@ public: private: - EditorContext context; - EditorRuntime activeRuntime ; - char* path = nullptr; - char* savePath = nullptr; - char* scenePath = nullptr; - char* openScenePath = nullptr; - char* modelImportPath = nullptr; - + std::unique_ptr CurrentProject; + Scene ActiveScene; + entt::entity Selected; }; @@ -301,12 +136,34 @@ YoggieEngine::Application* CreateApplication() { } +void CreateTestProject(std::unique_ptr& project, Scene& scene ) { + project = std::make_unique(); + std::string path = (std::filesystem::current_path()).string(); + project.get()->setProjectDirectory(path); + AssetManager::Init(); + AssetManager::setAssetPath(project.get()->GetProjectDirectory()); + AssetManager::BuildAssetView(); + // Create a level and load it as the current level + auto importer = ModelImporter(); + // Create a cube + auto model = importer.Import("build/Debug/Models/Cube.obj"); + auto cube = scene.AddEntity("cube"); + auto& render3DComponent = cube.AddComponent(); + render3DComponent.mesh = *(model->renderable->mesh); + cube.GetComponent().Position = glm::vec3(1.0f, 0.0f, 5.0f); + auto cube2 = scene.AddEntity("Cube1"); + auto& rendercube2 = cube2.AddComponent(); + rendercube2.mesh = *(model->renderable->mesh); - - + // create an ambient light source + auto AmbientLight = scene.AddEntity("AmbientLight"); + auto light = AmbientLight.AddComponent(); + light.Color = glm::vec3(1.0f); + light.Strength = 1.0f; +} diff --git a/YoggieEngine/src/Application.h b/YoggieEngine/src/Application.h index 20cf44e..2acb565 100644 --- a/YoggieEngine/src/Application.h +++ b/YoggieEngine/src/Application.h @@ -2,9 +2,6 @@ #include "YoggieEngine.h" namespace YoggieEngine { - // forward declaration - class InputManager; - class Application { public: Application(const std::string& name); @@ -13,21 +10,7 @@ namespace YoggieEngine { protected: std::string m_AppName; - Renderer* renderer = nullptr; - InputManager* InputSystem = nullptr; friend class ApplicationRuntime; }; - - class ApplicationRuntime { - - public: - virtual void Start() = 0; - virtual void Update() = 0; - virtual void FixedUpdate() = 0; - virtual void Stop() = 0; - - }; - - }; diff --git a/YoggieEngine/src/EntryPoint.h b/YoggieEngine/src/EntryPoint.h index 7a7c138..59188a0 100644 --- a/YoggieEngine/src/EntryPoint.h +++ b/YoggieEngine/src/EntryPoint.h @@ -1,5 +1,5 @@ #pragma once -#include "Application.h" +#include "YoggieEngine.h" extern YoggieEngine::Application* CreateApplication(); diff --git a/YoggieEngine/src/Graphics/Memory/FrameBuffer.cpp b/YoggieEngine/src/Graphics/Memory/FrameBuffer.cpp index df83a90..f2cfef2 100644 --- a/YoggieEngine/src/Graphics/Memory/FrameBuffer.cpp +++ b/YoggieEngine/src/Graphics/Memory/FrameBuffer.cpp @@ -55,10 +55,7 @@ namespace YoggieEngine { { std::cout << "Framebuffer is incomplete!" << std::endl; } - else { - std::cout << "Framebuffer is complete!" << std::endl; - } - + glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -67,7 +64,7 @@ namespace YoggieEngine { Framebuffer::~Framebuffer() { glDeleteTextures(1, &ColourAttachment); - glDeleteRenderbuffers(1, &DepthAttachment); + glDeleteTextures(1, &DepthAttachment); glDeleteFramebuffers(1, &Id); } } diff --git a/YoggieEngine/src/Graphics/Primitives/Texture.cpp b/YoggieEngine/src/Graphics/Primitives/Texture.cpp index d46dc9f..bec80fa 100644 --- a/YoggieEngine/src/Graphics/Primitives/Texture.cpp +++ b/YoggieEngine/src/Graphics/Primitives/Texture.cpp @@ -6,11 +6,9 @@ namespace YoggieEngine { Texture::Texture(const std::string texturePath) { - int width, height, channels; unsigned char* data = stbi_load(texturePath.c_str(), &width, &height, &channels, 0); - std::cout << channels << std::endl; - + if (data) { glGenTextures(1, &Id); diff --git a/YoggieEngine/src/Platform/Window.cpp b/YoggieEngine/src/Platform/Window.cpp index 4ae7530..08dbe66 100644 --- a/YoggieEngine/src/Platform/Window.cpp +++ b/YoggieEngine/src/Platform/Window.cpp @@ -1,17 +1,9 @@ #include #include "Window.h" namespace YoggieEngine { - bool BarinkWindow::InitGLFW() { - if (!glfwInit()) - { - spdlog::error("Failed to initialise GLFW!"); - return false; - } - - return true; - } - - BarinkWindow::BarinkWindow(const int width, const int height) : + void LoadGLExtensions(); + + NativeWindow::NativeWindow(const int width, const int height) : Width(width), Height(height), FullScreen(false) { if (InitGLFW() == false) { @@ -20,12 +12,13 @@ namespace YoggieEngine { glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE); glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_TRUE); - // No window decorations such as a border, a close widget - // glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); - // glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); - // Disable resizing the window - //glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - + + if( FullScreen ) + glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); + if( !Resizable) + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + if (!VSync) + glfwSwapInterval(0); window = glfwCreateWindow(Width, Height, "BarinkEngine", NULL, NULL); @@ -36,53 +29,58 @@ namespace YoggieEngine { return; } - glfwMakeContextCurrent(window); - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - spdlog::error("Failed to initialize GLAD!\n"); - exit(-1); - } - - // Set vsync off !! - glfwSwapInterval(0); - - VulkanSupported = glfwVulkanSupported(); - + SetContext(); glfwGetFramebufferSize(window, &Width, &Height); - glViewport(0, 0, Width, Height); - - - - glClearColor(0.2f, 0.2f, 0.2f, 1.0f); + LoadGLExtensions(); } - BarinkWindow::~BarinkWindow() { + void NativeWindow::SetViewPort(int width, int height) { + glViewport(0, 0, width, height); + } + + NativeWindow::~NativeWindow() { glfwTerminate(); } - GLFWwindow* BarinkWindow::windowptr() - { - return window; - } - - bool BarinkWindow::WindowShouldClose() { + bool NativeWindow::WindowShouldClose() { return glfwWindowShouldClose(window); } - void BarinkWindow::Poll() + void NativeWindow::SetContext() + { + glfwMakeContextCurrent(window); + } + + void NativeWindow::Poll() { glfwPollEvents(); } - void BarinkWindow::SwapBuffers() + void NativeWindow::SwapBuffers() { glfwSwapBuffers(window); } - void BarinkWindow::ReceiveEvent(Event& incident) + bool NativeWindow::InitGLFW() { - //std::cout << "EVENT RECEIVED: " << incident.name << std::endl; + if (!glfwInit()) + { + spdlog::error("Failed to initialise GLFW!"); + return false; + } + + return true; } + void LoadGLExtensions() + { + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + spdlog::error("Failed to initialize GLAD!\n"); + exit(-1); + } + } + + } diff --git a/YoggieEngine/src/Platform/Window.h b/YoggieEngine/src/Platform/Window.h index 6ef2438..0e7843c 100644 --- a/YoggieEngine/src/Platform/Window.h +++ b/YoggieEngine/src/Platform/Window.h @@ -7,27 +7,35 @@ #include "../EventSystem/Event.h" #include "../EventSystem/EventListener.h" namespace YoggieEngine { - class BarinkWindow : EventListener { - private: - GLFWwindow* window; - bool FullScreen; - bool VulkanSupported; - int Width, Height; - - static bool InitGLFW(); - + class NativeWindow { + public: - BarinkWindow(const int width, const int height); - ~BarinkWindow(); + NativeWindow(const int width, const int height); + ~NativeWindow(); - GLFWwindow* windowptr(); - - void ReceiveEvent(Event& incident) override; bool WindowShouldClose(); + void SetViewPort(int width , int height); void Poll(); void SwapBuffers(); + GLFWwindow* GetGLFWHandle() { return window; } + const int getWidth()const { return Width; } + const int getHeight()const { return Height; } + + + private: + GLFWwindow* window; + bool FullScreen = false; + bool Resizable = true; + bool VSync = false; + int Width, Height; + + void SetContext(); + static bool InitGLFW(); }; + + + } diff --git a/YoggieEngine/src/Scene/Scene.cpp b/YoggieEngine/src/Scene/Scene.cpp index ae46c4b..e6e1bd5 100644 --- a/YoggieEngine/src/Scene/Scene.cpp +++ b/YoggieEngine/src/Scene/Scene.cpp @@ -23,4 +23,26 @@ namespace YoggieEngine{ return entity; } + void Scene::Start() + { + // Execute start functions in scripts etc.... + } + + void Scene::Update() + { + // Execute Update functions in scripts etc.... + + } + + void Scene::FixedUpdate() + { + // Execute step through physics simulation step.... + + } + + void Scene::Stop() + { + // Execute stop functions in scripts etc.... + } + } diff --git a/YoggieEngine/src/Scene/Scene.h b/YoggieEngine/src/Scene/Scene.h index a6b8b29..b001f4f 100644 --- a/YoggieEngine/src/Scene/Scene.h +++ b/YoggieEngine/src/Scene/Scene.h @@ -9,6 +9,11 @@ namespace YoggieEngine { Entity AddEntity(std::string name); + void Start(); + void Update(); + void FixedUpdate(); + void Stop(); + entt::registry& getReg() { return m_registry; } private: diff --git a/YoggieEngine/src/YoggieEngine.h b/YoggieEngine/src/YoggieEngine.h index fc3be8f..01f3cd5 100644 --- a/YoggieEngine/src/YoggieEngine.h +++ b/YoggieEngine/src/YoggieEngine.h @@ -40,7 +40,5 @@ extern "C" #include "EventSystem/EventEmitter.h" #include "EventSystem/EventListener.h" -#include "Input/InputManager.h" - #include "Scene/Scene.h" #include "Application.h"