diff --git a/editor/include/e_sandbox2d.hpp b/editor/include/e_sandbox2d.hpp new file mode 100755 index 0000000..20aa9b8 --- /dev/null +++ b/editor/include/e_sandbox2d.hpp @@ -0,0 +1,135 @@ +#ifndef SANDBOX2D_HPP +#define SANDBOX2D_HPP + +#include +#include + +#include +#include + +class Sandbox2DLayer : public ViewLayer +{ + public: + Sandbox2DLayer() + : ViewLayer("sandbox_2d", (float)OpenEngine::Application::Get().GetWindow().GetWidth() / + OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f) + { + } + ~Sandbox2DLayer() {}; + + void OnAttach() override + { + OE_PROFILE_FUNCTION(); + { + OE_PROFILE_SCOPE("Texture2D Creation"); + face = OpenEngine::Texture2D::Create("assets/textures/awesomeface.png"); + } + + OpenEngine::FramebufferSpecification specs; + specs.width = 1280; + specs.height = 720; + + GetFramebuffer() = OpenEngine::FrameBuffer::Create(specs); + + atlas = OpenEngine::Texture2D::Create("assets/textures/rpg-spritesheet.png"); + stairs = OpenEngine::Subtexture2D::CreateFromCoords(atlas, {7, 6}, {64, 64}, { 1, 1 }); + tree = OpenEngine::Subtexture2D::CreateFromCoords(atlas, {2, 1}, {64, 64}, { 1, 2 }); + + grid_camera = OpenEngine::CreateRef(-1, 1, -1, 1); + + grid_shader = OpenEngine::Shader::Create("assets/shaders/grid.glsl"); + } + + void OnDetach() override + { + } + + void OnUpdate() override + { + { + OE_PROFILE_SCOPE("Setting up Rendering"); + GetCamera().OnUpdate(); + GetFramebuffer()->Bind(); + + OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); + OpenEngine::RenderCommand::Clear(); + } + + { + OpenEngine::Renderer2D::BeginScene(*grid_camera); + + grid_shader->Bind(); + grid_shader->SetMat4("u_ViewProjection", grid_camera->GetViewProjectionMatrix()); + glm::mat4 inverseVP = glm::inverse(GetCamera().GetCamera().GetViewProjectionMatrix()); + grid_shader->SetMat4("u_InverseViewProjection", inverseVP); + + OpenEngine::Transform screen = {glm::vec3(0.0f, 0.0f, -0.9f), glm::vec3(2.0f, 2.0f, 0.0f), 0.0f}; + OpenEngine::Renderer2D::DrawQuad(screen, glm::vec4(0.8f, 0.4f, 0.3f, 1.0f)); + + OpenEngine::Renderer2D::EndScene(); + + grid_shader->Unbind(); + } + + OpenEngine::Renderer2D::BeginScene(GetCamera().GetCamera()); + { + OE_PROFILE_SCOPE("Drawing Quads"); + OpenEngine::Transform tr1 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 0.0f), angle}; + OpenEngine::Transform tr3 = {glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 0.5f, 0.0f), angle * 0.5f}; + OpenEngine::Renderer2D::DrawQuad(tr1, face); + OpenEngine::Renderer2D::DrawQuad(tr3, rectangle_color); + } + + OpenEngine::Renderer2D::EndScene(); + + OpenEngine::Renderer2D::BeginScene(GetCamera().GetCamera()); + + for (float y = -5.0f; y < 5.0f; y += 0.5f) { + for (float x = -5.0f; x < 5.0f; x += 0.5f) { + + glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f}; + OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); + + } + } + OpenEngine::Transform tr2 = {glm::vec3(0, 0, 0.2f), glm::vec3(1.0f, 1.0f, 0.0f), 0.0f}; + OpenEngine::Transform tr4 = {glm::vec3(-1.0, 0.0, 0.2f), glm::vec3(1.0f, 2.0f, 0.0f), 0.0f}; + OpenEngine::Renderer2D::DrawQuad(tr2, stairs); + OpenEngine::Renderer2D::DrawQuad(tr4, tree); + + auto& cursor = GetCursorPos(); + OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(0.1f, 0.1f, 0.0f), 0.0f}; + OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); + + OpenEngine::Renderer2D::EndScene(); + + GetFramebuffer()->Unbind(); + } + + void OnEvent(OpenEngine::Event& event) override + { + OE_PROFILE_FUNCTION(); + OpenEngine::EventDispatcher dispatcher(event); + + //dispatcher.Dispatch(BIND_EVENT_FN(Sandbox2DLayer::StopRunning)); + { + OE_PROFILE_SCOPE("Camera OnEvent"); + GetCamera().OnEvent(event); + } + } + + private: + OpenEngine::Ref face; + OpenEngine::Ref atlas; + OpenEngine::Ref stairs, tree; + + OpenEngine::Ref grid_shader; + + OpenEngine::Ref grid_camera; + + float angle; + + glm::vec4 rectangle_color = {0.8f, 0.2f, 0.7f, 1.0f}; +}; + +#endif // SANDBOX2D_HPP diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 6701efa..703f575 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -1,11 +1,13 @@ #ifndef EDITOR_HPP #define EDITOR_HPP -#include "open_engine/renderer/renderer2d.hpp" +#include "open_engine/input/input_system.hpp" +#include #include #include #include +#include #include #include #include @@ -14,9 +16,9 @@ class EditorLayer : public OpenEngine::Layer { public: - EditorLayer() + EditorLayer(OpenEngine::Ref& view_layer) : OpenEngine::Layer("editor_layer"), - camera(1280.0f / 720.0f, 1.0f) + view(view_layer) { } ~EditorLayer() {}; @@ -24,16 +26,6 @@ class EditorLayer : public OpenEngine::Layer void OnAttach() override { OE_PROFILE_FUNCTION(); - { - OE_PROFILE_SCOPE("Texture2D Creation"); - face = OpenEngine::Texture2D::Create("assets/textures/awesomeface.png"); - } - - OpenEngine::FramebufferSpecification specs; - specs.width = 1280; - specs.height = 720; - - framebuffer = OpenEngine::FrameBuffer::Create(specs); } void OnDetach() override @@ -44,41 +36,13 @@ class EditorLayer : public OpenEngine::Layer { OpenEngine::Renderer2D::ResetStats(); - OE_PROFILE_FUNCTION() { - camera.OnUpdate(); - framebuffer->Bind(); + OE_PROFILE_FUNCTION(); - OE_PROFILE_SCOPE("Setting up Rendering"); - - OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); - OpenEngine::RenderCommand::Clear(); - OpenEngine::Renderer2D::BeginScene(camera.GetCamera()); - } - { - OE_PROFILE_SCOPE("Drawing Quads"); - OpenEngine::Transform tr1 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 0.0f), angle}; - OpenEngine::Transform tr3 = {glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 0.5f, 0.0f), angle * 0.5f}; - OpenEngine::Renderer2D::DrawQuad(tr1, face); - OpenEngine::Renderer2D::DrawQuad(tr3, rectangle_color); + view->GetCamera().OnUpdate(); } OpenEngine::Renderer2D::EndScene(); - - OpenEngine::Renderer2D::BeginScene(camera.GetCamera()); - - for (float y = -5.0f; y < 5.0f; y += 0.5f) { - for (float x = -5.0f; x < 5.0f; x += 0.5f) { - - glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f}; - OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); - - } - } - - OpenEngine::Renderer2D::EndScene(); - - framebuffer->Unbind(); } void OnEvent(OpenEngine::Event& event) override @@ -87,20 +51,65 @@ class EditorLayer : public OpenEngine::Layer { OE_PROFILE_SCOPE("Camera OnEvent"); - camera.OnEvent(event); + view->GetCamera().OnEvent(event); } } + float remap(float value, float minInput, float maxInput, float minOutput, float maxOutput) { + // 1. Normalize the input to a 0.0 - 1.0 range + float t = (value - minInput) / (maxInput - minInput); + + // 2. Use glm::mix to interpolate between the output range + return glm::mix(minOutput, maxOutput, t); + } + + glm::vec3 ScreenToWorld( + float screenX, + float screenY, + float screenZ, // depth value (0.0 = near plane, 1.0 = far plane) + const glm::mat4& view, + const glm::mat4& projection, + int viewportWidth, + int viewportHeight) + { + // 1. Convert screen coordinates to normalized device coordinates (NDC) + // Screen space: origin at top-left, Y points down + // NDC space: origin at center, range [-1, 1] for x and y + + float x = (2.0f * screenX) / viewportWidth - 1.0f; + float y = 1.0f - (2.0f * screenY) / viewportHeight; // Flip Y + float z = 2.0f * screenZ - 1.0f; // [0,1] -> [-1,1] + + glm::vec4 clipCoords(x, y, z, 1.0f); + + // 2. Transform from clip space to view space + glm::mat4 invProjection = glm::inverse(projection); + glm::vec4 viewCoords = invProjection * clipCoords; + + // 3. Transform from view space to world space + glm::mat4 invView = glm::inverse(view); + glm::vec4 worldCoords = invView * viewCoords; + + // 4. Perspective divide + if (worldCoords.w != 0.0f) { + worldCoords /= worldCoords.w; + } + + return glm::vec3(worldCoords); + } + void OnImGuiRender() override { OE_PROFILE_FUNCTION(); + OpenEngine::Ref framebuffer = view->GetFramebuffer(); + ImGui::DockSpaceOverViewport(); ImGui::Begin("Square settings"); - ImGui::SliderFloat("Angle", &angle, -360, 360); - ImGui::ColorPicker4("Rectangle color", &rectangle_color[0]); + //ImGui::SliderFloat("Angle", &angle, -360, 360); + //ImGui::ColorPicker4("Rectangle color", &rectangle_color[0]); for (auto& result : profiling_results) { @@ -120,10 +129,51 @@ class EditorLayer : public OpenEngine::Layer framebuffer->Resize(viewport_panel_size.x, viewport_panel_size.y); viewport_size = { viewport_panel_size.x, viewport_panel_size.y }; - camera.OnResize(viewport_panel_size.x, viewport_panel_size.y); + view->GetCamera().OnResize(viewport_panel_size.x, viewport_panel_size.y); } uint32_t texture_id = framebuffer->GetColorAttachmentRendererID(); - ImGui::Image((void*)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + if (ImGui::BeginTabItem("Avocado")) + { + ImVec2 imgui_cursor_position = ImGui::GetCursorScreenPos(); + + auto pair_position = OpenEngine::Input::GetMousePosition(); + glm::vec2 mouse_position = { pair_position.first, pair_position.second }; + + int max_x = viewport_size.x + imgui_cursor_position.x; + int max_y = viewport_size.y + imgui_cursor_position.y; + + if ((mouse_position.x <= max_x && mouse_position.x >= imgui_cursor_position.x) + && (mouse_position.y <= max_y && mouse_position.y >= imgui_cursor_position.y)) { + + float x = mouse_position.x - imgui_cursor_position.x; + float y = mouse_position.y - imgui_cursor_position.y; + + auto& camera = view->GetCamera().GetCamera(); + auto world_coords = ScreenToWorld(x, y, 0.0f, + camera.GetViewMatrix(), + camera.GetProjectionMatrix(), + viewport_size.x, + viewport_size.y); + view->SetCursorPos({ world_coords.x, world_coords.y }); + } + ImGui::Image((void*)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Broccoli")) + { + ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Cucumber")) + { + ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } ImGui::End(); ImGui::PopStyleVar(); @@ -143,20 +193,16 @@ class EditorLayer : public OpenEngine::Layer ImGui::Text("\t\tQuad count: %d", stats.quad_count); ImGui::Text("\t\tVertices count: %d", stats.GetToralVertexCount()); ImGui::Text("\t\tIndices count: %d", stats.GetToralIndexCount()); + ImGui::ShowDemoWindow(); ImGui::End(); } private: - float angle = 0.0f; - OpenEngine::Ref face; - - OpenEngine::OrthographicCameraController camera; - std::vector profiling_results; glm::vec2 viewport_size = { 0.0f, 0.0f }; - OpenEngine::Ref framebuffer; - glm::vec4 rectangle_color = {0.8f, 0.2f, 0.7f, 1.0f}; + + OpenEngine::Ref view; }; class EditorApp : public OpenEngine::Application diff --git a/editor/include/level_editor.hpp b/editor/include/level_editor.hpp new file mode 100644 index 0000000..9b6aec6 --- /dev/null +++ b/editor/include/level_editor.hpp @@ -0,0 +1,76 @@ +#ifndef LEVEL_EDITOR_HPP +#define LEVEL_EDITOR_HPP + +#include + +#include + +class LevelEditor : public ViewLayer +{ + public: + LevelEditor() + : ViewLayer("level_editor", (float)OpenEngine::Application::Get().GetWindow().GetWidth() / + OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f) + { + } + + void OnAttach() override + { + OpenEngine::FramebufferSpecification specs; + specs.width = 1280; + specs.height = 720; + + GetFramebuffer() = OpenEngine::FrameBuffer::Create(specs); + + }; + + void OnUpdate() override + { + { + OE_PROFILE_SCOPE("Setting up Rendering"); + GetCamera().OnUpdate(); + GetFramebuffer()->Bind(); + } + + OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); + OpenEngine::RenderCommand::Clear(); + + OpenEngine::Renderer2D::BeginScene(GetCamera().GetCamera()); + + for (float y = -5.0f; y < 5.0f; y += 0.5f) { + for (float x = -5.0f; x < 5.0f; x += 0.5f) { + + glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f}; + OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color); + + } + } + + auto& cursor = GetCursorPos(); + OE_TRACE("world coordinates: {} {}", cursor.x, cursor.y); + OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(0.1f, 0.1f, 0.0f), 0.0f}; + OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); + + OpenEngine::Renderer2D::EndScene(); + + GetFramebuffer()->Unbind(); + }; + + void OnEvent(OpenEngine::Event& event) override + { + auto& cursor = GetCursorPos(); + OE_TRACE("world coordinates: {} {}", cursor.x, cursor.y); + OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(1.0f, 1.0f, 0.0f), 0.0f}; + OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1}); + + OpenEngine::Renderer2D::EndScene(); + + GetFramebuffer()->Unbind(); + }; + + void OnDetach() override {}; + + private: +}; + +#endif // LEVEL_EDITOR_HPP diff --git a/editor/include/sandbox2d.hpp b/editor/include/sandbox2d.hpp deleted file mode 100755 index 0abb22c..0000000 --- a/editor/include/sandbox2d.hpp +++ /dev/null @@ -1,130 +0,0 @@ -#ifndef SANDBOX2D_HPP -#define SANDBOX2D_HPP - -#include - -#include -#include "imgui.h" - -#include -#include - -class Sandbox2DLayer : public OpenEngine::Layer -{ - public: - Sandbox2DLayer() - : OpenEngine::Layer("sandbox_2d"), - camera((float)OpenEngine::Application::Get().GetWindow().GetWidth() / - OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f) - { - } - ~Sandbox2DLayer() {}; - - void OnAttach() override - { - OE_PROFILE_FUNCTION(); - bindings = { - {"fwd/bckwd", 1}, - {"right/left", 0}, - {"yaw", 2} - }; - - { - OE_PROFILE_SCOPE("Texture2D Creation"); - face = OpenEngine::Texture2D::Create("assets/textures/awesomeface.png"); - } - } - - void OnDetach() override - { - } - - void OnUpdate() override - { - OE_PROFILE_FUNCTION() - { - OE_PROFILE_SCOPE("Setting up Rendering"); - OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); - OpenEngine::RenderCommand::Clear(); - OpenEngine::Renderer2D::BeginScene(camera.GetCamera()); - } - static float angle = 0.0f; - float ts = OpenEngine::Time::DeltaTime(); - - if (angle >= 360) - angle = 0; - - angle += (ts * 500.0f); - { - OE_PROFILE_SCOPE("Drawing Quads"); - OpenEngine::Transform tr1 = {glm::vec3(0.5f, 0.5f, 0.2f), glm::vec3(0.3f), 20.0f}; - OpenEngine::Transform tr2 = {glm::vec3(-0.2f, -0.2f, 0.1f), glm::vec3(0.5f, 0.2f, 1.0f), angle}; - OpenEngine::Transform tr3 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 1.0f), 45.0f}; - - OpenEngine::Renderer2D::DrawQuad({glm::vec3(0.5f, 0.5f, 0.0f), glm::vec3(0.3f), 20.0f}, glm::vec4(color[0], color[1], color[2], color[3])); - OpenEngine::Renderer2D::DrawQuad(tr2, {0.5f, 0.3f, 0.8f, 1.0f}); - OpenEngine::Renderer2D::DrawQuad(tr3, face); - } - - OpenEngine::Renderer2D::EndScene(); - } - - bool StopRunning(OpenEngine::KeyPressedEvent& event) - { - if (event.GetKeyCode() == OE_KEY_ESCAPE) { - OpenEngine::Application::Get().StopRunning(); - - return true; - } - - return false; - } - - void OnEvent(OpenEngine::Event& event) override - { - OE_PROFILE_FUNCTION(); - OpenEngine::EventDispatcher dispatcher(event); - - //dispatcher.Dispatch(BIND_EVENT_FN(Sandbox2DLayer::StopRunning)); - { - OE_PROFILE_SCOPE("Camera OnEvent"); - camera.OnEvent(event); - } - } - - void OnImGuiRender() override - { - OE_PROFILE_FUNCTION(); - - ImGui::Begin("Square settings"); - - ImGui::ColorEdit4("Square color", color); - - for (auto& result : profiling_results) - { - char label[50]; - strcpy(label, "%.3fms "); - strcat(label, result.name); - ImGui::Text(label, result.duration); - } - - profiling_results.clear(); - - ImGui::End(); - } - - private: - //OpenEngine::ShaderLibrary shader_library; - glm::vec3 square_pos = glm::vec3(0.0f); - glm::vec4 square_color = glm::vec4(1.0f); - - float color[4] = {0.5f, 0.3f, 0.4f, 1.0f}; - OpenEngine::Ref face; - - std::unordered_map bindings; - OpenEngine::OrthographicCameraController camera; - - std::vector profiling_results; -}; - -#endif // SANDBOX2D_HPP diff --git a/editor/include/view_layer.hpp b/editor/include/view_layer.hpp new file mode 100644 index 0000000..7da59c0 --- /dev/null +++ b/editor/include/view_layer.hpp @@ -0,0 +1,28 @@ +#ifndef VIEW_LAYER_HPP +#define VIEW_LAYER_HPP + +#include + +class ViewLayer : public OpenEngine::Layer +{ + public: + ViewLayer(const char* layer_name, float ratio, float zoom_level) + : OpenEngine::Layer(layer_name), + camera(ratio, zoom_level) + { + } + + OpenEngine::Ref& GetFramebuffer() { return framebuffer; }; + OpenEngine::OrthographicCameraController& GetCamera() { return camera; }; + + void SetCursorPos(const glm::vec2& pos) { cursor_position = pos; }; + const glm::vec2& GetCursorPos() { return cursor_position; }; + + private: + OpenEngine::Ref framebuffer; + OpenEngine::OrthographicCameraController camera; + + glm::vec2 cursor_position = { 0.0f, 0.0f }; +}; + +#endif // VIEW_LAYER_HPP diff --git a/editor/src/control_layer.cpp b/editor/src/control_layer.cpp index 208c6df..184e0dc 100644 --- a/editor/src/control_layer.cpp +++ b/editor/src/control_layer.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include ControlLayer::ControlLayer(OpenEngine::Ref layer) @@ -15,7 +15,7 @@ void ControlLayer::OnUpdate() bool ControlLayer::StopRunning(OpenEngine::KeyPressedEvent& event) { if (event.GetKeyCode() == OE_KEY_ESCAPE) { - OpenEngine::Application::Get().StopRunning(); + OpenEngine::Application::Get().Close(); return true; } diff --git a/editor/src/editor.cpp b/editor/src/editor.cpp index e50eec9..f363e49 100644 --- a/editor/src/editor.cpp +++ b/editor/src/editor.cpp @@ -1,20 +1,25 @@ #include #include -#include +#include +#include +#include #include #include #include -#include +#include EditorApp::EditorApp() + : Application("OpenEngine Editor") { - OpenEngine::Ref initial_layer = std::make_shared(); - OpenEngine::Ref control_layer = std::make_shared(initial_layer); OpenEngine::Ref modding_layer = std::make_shared(); + OpenEngine::Ref view = OpenEngine::CreateRef(); + OpenEngine::Ref initial_layer = std::make_shared(view); + OpenEngine::Ref control_layer = std::make_shared(initial_layer); + QueueLayerPush(view); QueueLayerPush(initial_layer); QueueLayerPush(control_layer); QueueLayerPush(modding_layer);