From b3b7638e30ac5d9efcf90fe955e18bcbcff44232 Mon Sep 17 00:00:00 2001 From: Huseyn Ismayilov Date: Tue, 30 Jul 2024 20:57:32 +0400 Subject: [PATCH] feat: Create classes for engine and editor --- editor/CMakeLists.txt | 4 +- editor/include/Editor.h | 28 +++++++ editor/include/UI.h | 34 ++++++++ editor/src/Editor.cpp | 59 ++++++++++++++ editor/src/UI.cpp | 135 +++++++++++++++++++++++++++++++ editor/src/main.cpp | 162 ++------------------------------------ engine/CMakeLists.txt | 9 ++- engine/include/Engine.h | 21 +++++ engine/include/Graphics.h | 23 ++++++ engine/src/Engine.cpp | 25 ++++++ engine/src/Graphics.cpp | 58 ++++++++++++++ engine/src/main.cpp | 0 12 files changed, 398 insertions(+), 160 deletions(-) create mode 100644 editor/include/Editor.h create mode 100644 editor/include/UI.h create mode 100644 editor/src/Editor.cpp create mode 100644 editor/src/UI.cpp create mode 100644 engine/include/Engine.h create mode 100644 engine/include/Graphics.h create mode 100644 engine/src/Engine.cpp create mode 100644 engine/src/Graphics.cpp delete mode 100644 engine/src/main.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index cca5ab6..6a079a0 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -1,3 +1,5 @@ +cmake_minimum_required(VERSION 3.22) + project(editor) set(NAME ferx) @@ -8,7 +10,7 @@ set(EDITOR_RESOURCES_DIR resources) file(GLOB_RECURSE EDITOR_SOURCES ${EDITOR_SOURCE_DIR}/*.cpp) file(COPY ${EDITOR_RESOURCES_DIR}/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -add_executable(${NAME} ${EDITOR_SOURCES} ${EDITOR_HEADERS}) +add_executable(${NAME}) target_sources(${NAME} PRIVATE ${EDITOR_SOURCES}) target_include_directories(${NAME} PRIVATE ${EDITOR_INCLUDE_DIR}) diff --git a/editor/include/Editor.h b/editor/include/Editor.h new file mode 100644 index 0000000..616b100 --- /dev/null +++ b/editor/include/Editor.h @@ -0,0 +1,28 @@ +#ifndef EDITOR_H +#define EDITOR_H + +#include "Engine.h" +#include "UI.h" + +class Editor +{ +public: + Editor(); + ~Editor(); + + void Initialize(); + void Run(); + void Shutdown(); + + GLFWwindow* GetWindow() const; + +private: + GLFWwindow* window; + Engine engine; + UI ui; + + void InitializeWindow(); + void InitializeImGui(); +}; + +#endif \ No newline at end of file diff --git a/editor/include/UI.h b/editor/include/UI.h new file mode 100644 index 0000000..b6caf09 --- /dev/null +++ b/editor/include/UI.h @@ -0,0 +1,34 @@ +#ifndef UI_H +#define UI_H + +#include +#include +#include + +class UI +{ +public: + UI(); + ~UI(); + + void Initialize(GLFWwindow* window); + void Run(); + void Render(); + void Shutdown(); + + void Print(const std::string& message); + + void ShowMenu(); + void ShowHierarchy(); + void ShowProject(); + void ShowConsole(); + void ShowScene(); + void ShowInspector(); + +private: + ImVec4 clearColor = ImVec4(0.0f, 0.0f, 0.0f, 1.00f); + ImVec4* styleColors; + std::string log; +}; + +#endif diff --git a/editor/src/Editor.cpp b/editor/src/Editor.cpp new file mode 100644 index 0000000..0359b8d --- /dev/null +++ b/editor/src/Editor.cpp @@ -0,0 +1,59 @@ +#include +#include "Editor.h" +#include "UI.h" + +Editor::Editor() : window(nullptr){} + +Editor::~Editor() +{ + Shutdown(); +} + +void Editor::Initialize() +{ + InitializeWindow(); + engine.Initialize(window); + ui.Initialize(window); + Run(); +} + +void Editor::Run() { + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + ui.Run(); + engine.Render(); + ui.Render(); + glfwSwapBuffers(window); + } +} + +void Editor::Shutdown() { + engine.Shutdown(); + ui.Shutdown(); + glfwDestroyWindow(window); + glfwTerminate(); +} + +GLFWwindow* Editor::GetWindow() const { + return window; +} + +void Editor::InitializeWindow() { + if (!glfwInit()) { + std::cerr << "Failed to initialize GLFW" << std::endl; + return; + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + window = glfwCreateWindow(1280, 720, "Editor", nullptr, nullptr); + if (!window) { + std::cerr << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return; + } + + glfwMakeContextCurrent(window); +} \ No newline at end of file diff --git a/editor/src/UI.cpp b/editor/src/UI.cpp new file mode 100644 index 0000000..9bdd73c --- /dev/null +++ b/editor/src/UI.cpp @@ -0,0 +1,135 @@ +#include +#include +#include +#include "UI.h" + +UI::UI(): styleColors(nullptr){} + +UI::~UI(){} + +void UI::Initialize(GLFWwindow* window) +{ + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + + ImGuiStyle& style = ImGui::GetStyle(); + styleColors = style.Colors; + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init(); +} + +void UI::Run() +{ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); + styleColors[ImGuiCol_DockingEmptyBg] = clearColor; +} + +void UI::Render() +{ + ShowConsole(); + ShowHierarchy(); + ShowInspector(); + ShowMenu(); + ShowProject(); + ShowScene(); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); +} + +void UI::Shutdown() +{ + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + +void UI::Print(const std::string& message) +{ + log = message; +} + +void UI::ShowConsole(){ + ImGui::Begin("Console"); + + if(ImGui::Button("Clear")){ + Print(""); + } + + ImGui::SameLine(); + + if(ImGui::Button("Debug")){ + Print("Debug message"); + } + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + + ImGui::Text("%s", log.c_str()); + + ImGui::End(); +} + +void UI::ShowHierarchy() +{ + ImGui::Begin("Hierarchy"); + + ImGui::End(); +} + +void UI::ShowInspector() +{ + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Inspector"); + + ImGui::Text("This is some useful text."); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clearColor); + + if (ImGui::Button("Button")) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::End(); +} + +void UI::ShowMenu() +{ + if(ImGui::BeginMainMenuBar()){ + if(ImGui::BeginMenu("File")){ + if (ImGui::MenuItem("Open..", "Ctrl+O")) { } + if (ImGui::MenuItem("Save", "Ctrl+S")) { } + if (ImGui::MenuItem("Close", "Ctrl+W")) { } + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } +} + +void UI::ShowProject() +{ + ImGui::Begin("Project"); + + ImGui::End(); +} + +void UI::ShowScene() +{ + ImGui::Begin("Scene"); + + ImGui::End(); +} + + + diff --git a/editor/src/main.cpp b/editor/src/main.cpp index 61407d9..ad83cbe 100644 --- a/editor/src/main.cpp +++ b/editor/src/main.cpp @@ -1,158 +1,8 @@ -#include -#include -#include -#include "imgui.h" -#include "imgui_impl_glfw.h" -#include "imgui_impl_opengl3.h" +#include "Editor.h" -// Global variables -std::string log_message; -int display_w = 800, display_h = 600; -ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); +int main(int argc, char** argv) +{ + Editor editor; -void debug(std::string message){ - log_message = message; -} - -void show_menu(){ - if(ImGui::BeginMainMenuBar()){ - if(ImGui::BeginMenu("File")){ - if (ImGui::MenuItem("Open..", "Ctrl+O")) { } - if (ImGui::MenuItem("Save", "Ctrl+S")) { } - if (ImGui::MenuItem("Close", "Ctrl+W")) { } - ImGui::EndMenu(); - } - ImGui::EndMainMenuBar(); - } -} - -void show_hierarchy(){ - ImGui::Begin("Hierarchy"); - - ImGui::End(); -} - -void show_project(){ - ImGui::Begin("Project"); - - ImGui::End(); -} - -void show_console(){ - ImGui::Begin("Console"); - - if(ImGui::Button("Clear")){ - debug(""); - } - - ImGui::SameLine(); - - if(ImGui::Button("Debug")){ - debug("Debug message"); - } - - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - - ImGui::Text("%s", log_message.c_str()); - - ImGui::End(); -} - -void show_scene(){ - ImGui::Begin("Scene"); - - ImGui::End(); -} - -void show_inspector(){ - static float f = 0.0f; - static int counter = 0; - - ImGui::Begin("Inspector"); - - ImGui::Text("This is some useful text."); - - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - - if (ImGui::Button("Button")) - counter++; - ImGui::SameLine(); - ImGui::Text("counter = %d", counter); - - ImGui::End(); -} - -int main(void){ - if(!glfwInit()) - return -1; - - GLFWwindow* window = glfwCreateWindow(display_w, display_h, "Ferx", NULL, NULL); - if(!window){ - glfwTerminate(); - return -1; - } - - glfwMakeContextCurrent(window); - - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) - { - std::cout << "Failed to initialize GLAD" << std::endl; - return -1; - } - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - - ImGuiStyle& style = ImGui::GetStyle(); - ImVec4* colors = style.Colors; - ImGui::StyleColorsDark(); - - // Setup Platform/Renderer backends - ImGui_ImplGlfw_InitForOpenGL(window, true); - ImGui_ImplOpenGL3_Init(); - - while(!glfwWindowShouldClose(window)){ - // Set up draw data for rendering - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - // Setup docking - ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); - colors[ImGuiCol_DockingEmptyBg] = clear_color; - - // Show windows - show_menu(); - show_hierarchy(); - show_scene(); - show_project(); - show_console(); - show_inspector(); - - // Rendering - ImGui::Render(); - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - ImGui::EndFrame(); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - // Cleanup - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplGlfw_Shutdown(); - ImGui::DestroyContext(); - - glfwDestroyWindow(window); - glfwTerminate(); - - return 0; -} + editor.Initialize(); +} \ No newline at end of file diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index de3a54b..fd0240b 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -7,10 +7,13 @@ file(GLOB_RECURSE ENGINE_SOURCES ${ENGINE_SOURCE_DIR}/*.cpp) add_library(${PROJECT_NAME}) -target_compile_definitions(${PROJECT_NAME} PUBLIC RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/") # This is useful to get an ASSETS_PATH in your IDE during development but you should comment this if you compile a release version and uncomment the next line -#target_compile_definitions(${PROJECT_NAME} PUBLIC RESOURCES_PATH="./resources/") # Uncomment this line to setup the ASSETS_PATH macro to the final assets directory when you share the game +if(CMAKE_BUILD_TYPE STREQUAL "Release") + target_compile_definitions(${PROJECT_NAME} PUBLIC RESOURCES_PATH="./resources/") +else() + target_compile_definitions(${PROJECT_NAME} PUBLIC RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/") +endif() target_sources(${PROJECT_NAME} PRIVATE ${ENGINE_SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE ${ENGINE_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PUBLIC ${ENGINE_INCLUDE_DIR}) target_link_libraries(${PROJECT_NAME} glfw glad glm imgui) diff --git a/engine/include/Engine.h b/engine/include/Engine.h new file mode 100644 index 0000000..d659740 --- /dev/null +++ b/engine/include/Engine.h @@ -0,0 +1,21 @@ +#ifndef ENGINE_H +#define ENGINE_H + +#include +#include "Graphics.h" + +class Engine +{ +public: + Engine(); + ~Engine(); + + void Initialize(GLFWwindow* window); + void Render(); + void Shutdown(); + +private: + Graphics graphics; +}; + +#endif diff --git a/engine/include/Graphics.h b/engine/include/Graphics.h new file mode 100644 index 0000000..278db7e --- /dev/null +++ b/engine/include/Graphics.h @@ -0,0 +1,23 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include + +class Graphics +{ +public: + Graphics(); + ~Graphics(); + + void Initialize(GLFWwindow* window); + void Render(); + void Shutdown(); + +private: + GLFWwindow* window; + unsigned int VAO, VBO; + + void SetupBuffers(); +}; + +#endif \ No newline at end of file diff --git a/engine/src/Engine.cpp b/engine/src/Engine.cpp new file mode 100644 index 0000000..00dd847 --- /dev/null +++ b/engine/src/Engine.cpp @@ -0,0 +1,25 @@ +#include "Engine.h" + +Engine::Engine(){} + +Engine::~Engine() +{ + Shutdown(); +} + +void Engine::Initialize(GLFWwindow* window) +{ + graphics.Initialize(window); +} + +void Engine::Render() +{ + graphics.Render(); +} + +void Engine::Shutdown() +{ + graphics.Shutdown(); +} + + diff --git a/engine/src/Graphics.cpp b/engine/src/Graphics.cpp new file mode 100644 index 0000000..b80e171 --- /dev/null +++ b/engine/src/Graphics.cpp @@ -0,0 +1,58 @@ +#include +#include +#include "Graphics.h" + +Graphics::Graphics() : window(nullptr), VAO(0), VBO(0) {} + +Graphics::~Graphics() +{ + Shutdown(); +} + +void Graphics::Initialize(GLFWwindow* window) +{ + this->window = window; + + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + std::cerr << "Failed to initialize GLAD" << std::endl; + return; + } + + SetupBuffers(); +} + +void Graphics::SetupBuffers() +{ + float vertices[] = { + 0.0f, 0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f + }; + + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void Graphics::Render() { + glClear(GL_COLOR_BUFFER_BIT); + + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 3); +} + +void Graphics::Shutdown() +{ + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); +} diff --git a/engine/src/main.cpp b/engine/src/main.cpp deleted file mode 100644 index e69de29..0000000