diff --git a/editor/include/editor.hpp b/editor/include/editor.hpp index 862529e..593a130 100755 --- a/editor/include/editor.hpp +++ b/editor/include/editor.hpp @@ -3,12 +3,6 @@ #include -#include "open_engine/core.hpp" -#include "open_engine/events/event.hpp" -#include "open_engine/events/key_event.hpp" -#include "open_engine/logging.hpp" -#include "open_engine/math/math.hpp" -#include "open_engine/scene/components.hpp" #include "panels/scene_hierarchy.hpp" //#include @@ -75,6 +69,8 @@ namespace OpenEngine { scene = CreateRef(); + editor_camera = EditorCamera(30.0f, 1920.0f/1080.0f, 0.1f, 1000.0f); + scene_hierarchy.SetContext(scene); } @@ -86,23 +82,23 @@ namespace OpenEngine { { FramebufferSpecification spec = framebuffer->GetSpecification(); if (viewport_size.x > 0.0f && viewport_size.y > 0.0f && - (spec.width != viewport_size.x || spec.height != viewport_size.y)) - { - framebuffer->Resize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y); - } - - { + (spec.width != viewport_size.x || spec.height != viewport_size.y)) { OE_PROFILE_SCOPE("Setting up Rendering"); - framebuffer->Bind(); + framebuffer->Resize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y); + + editor_camera.SetViewportSize(viewport_size.x, viewport_size.y); scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y); } + framebuffer->Bind(); Renderer2D::ResetStats(); RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); RenderCommand::Clear(); - scene->OnUpdate(); + editor_camera.OnUpdate(); + + scene->OnUpdateEditor(editor_camera); framebuffer->Unbind(); } @@ -142,6 +138,8 @@ namespace OpenEngine { { OE_PROFILE_FUNCTION(); + editor_camera.OnEvent(event); + EventDispatcher dispatcher(event); dispatcher.Dispatch(BIND_EVENT_FN(EditorLayer::EditorKeyBinds)); }; @@ -209,20 +207,6 @@ namespace OpenEngine { int max_x = viewport_size.x + imgui_cursor_position.x; int max_y = viewport_size.y + imgui_cursor_position.y; - if (focused || hovered) { - float x = mouse_position.x - imgui_cursor_position.x; - float y = mouse_position.y - imgui_cursor_position.y; - - /* - auto& cam = camera.GetCamera(); - world_pos_cursor = ScreenToWorld(x, y, 0.0f, - cam.GetViewMatrix(), - cam.GetProjectionMatrix(), - viewport_size.x, - viewport_size.y); - */ - } - uint32_t texture_id = framebuffer->GetColorAttachmentRendererID(); ImGui::Image((void*)(uint64_t)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 }); @@ -248,8 +232,8 @@ namespace OpenEngine { ImGui::Text("Renderer2D:"); ImGui::Text("\t\tDraw calls: %d", stats.draw_calls); 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::Text("\t\tVertices count: %d", stats.GetTotalVertexCount()); + ImGui::Text("\t\tIndices count: %d", stats.GetTotalIndexCount()); /* for (auto& result : profiling_results) @@ -287,10 +271,12 @@ namespace OpenEngine { auto window_size = ImGui::GetWindowSize(); ImGuizmo::SetRect(window_position.x, window_position.y, window_size.x, window_size.y); - auto camera_entity = scene->GetPrimaryCamera(); - auto camera = camera_entity.GetComponents().camera; - const glm::mat4& projection = camera.GetProjection(); - glm::mat4 camera_view = glm::inverse(camera_entity.GetComponents().GetTransform()); + //auto camera_entity = scene->GetPrimaryCamera(); + //auto camera = camera_entity.GetComponents().camera; + //const glm::mat4& projection = camera.GetProjection(); + //glm::mat4 camera_view = glm::inverse(camera_entity.GetComponents().GetTransform()); + const glm::mat4& camera_projection = editor_camera.GetProjection(); + glm::mat4 camera_view = editor_camera.GetViewMatrix(); auto& transform_comp = selected_entity.GetComponents(); glm::mat4 transform = transform_comp.GetTransform(); @@ -302,7 +288,7 @@ namespace OpenEngine { float snap_values[] = { snap_value, snap_value, snap_value }; - ImGuizmo::Manipulate(glm::value_ptr(camera_view), glm::value_ptr(projection), + ImGuizmo::Manipulate(glm::value_ptr(camera_view), glm::value_ptr(camera_projection), (ImGuizmo::OPERATION)guizmo_operation, ImGuizmo::LOCAL, glm::value_ptr(transform), nullptr, snap ? snap_values : nullptr); @@ -390,7 +376,7 @@ namespace OpenEngine { SceneHierarchy scene_hierarchy; - Entity camera_bis; + EditorCamera editor_camera; int guizmo_operation = -1; diff --git a/open_engine/CMakeLists.txt b/open_engine/CMakeLists.txt index 4416bee..a531afd 100644 --- a/open_engine/CMakeLists.txt +++ b/open_engine/CMakeLists.txt @@ -15,9 +15,11 @@ find_package(EnTT REQUIRED) find_package(yaml-cpp REQUIRED) file(GLOB_RECURSE SRC_FILES "src/*.cpp") +file(GLOB IMGUIZMO_SRC_FILES "${CMAKE_SOURCE_DIR}/vendor/ImGuizmo/*.cpp") add_library(${PROJECT_EXECUTABLE_NAME} STATIC ${SRC_FILES} "vendor/stb_image/stb_image.cpp" + ${IMGUIZMO_SRC_FILES} ) target_precompile_headers(${PROJECT_EXECUTABLE_NAME} PRIVATE @@ -33,6 +35,7 @@ target_include_directories(${PROJECT_EXECUTABLE_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "/home/erris/.conan2/p/b/imguic69fe98538919/p/include" "vendor/nativefiledialog-extended/src/include" + "${CMAKE_SOURCE_DIR}/vendor/ImGuizmo" ) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") @@ -56,7 +59,7 @@ target_link_libraries(${PROJECT_EXECUTABLE_NAME} PUBLIC #) add_subdirectory(vendor/glad - ./lib + ./glad ) add_subdirectory("vendor/nativefiledialog-extended") diff --git a/open_engine/include/open_engine.hpp b/open_engine/include/open_engine.hpp index 9b5c7f1..b82cd3a 100644 --- a/open_engine/include/open_engine.hpp +++ b/open_engine/include/open_engine.hpp @@ -5,6 +5,7 @@ #include "open_engine/imgui/imgui_layer.hpp" #include "open_engine/events/key_event.hpp" #include "open_engine/application.hpp" +#include "open_engine/math/math.hpp" #include "open_engine/ref_scope.hpp" #include "open_engine/logging.hpp" diff --git a/open_engine/include/open_engine/renderer/editor_camera.hpp b/open_engine/include/open_engine/renderer/editor_camera.hpp new file mode 100644 index 0000000..5059adc --- /dev/null +++ b/open_engine/include/open_engine/renderer/editor_camera.hpp @@ -0,0 +1,69 @@ +#ifndef EDITOR_CAMERA_HPP +#define EDITOR_CAMERA_HPP + +#include "camera.hpp" +#include "open_engine/events/event.hpp" +#include "open_engine/events/mouse_event.hpp" + +#include + +namespace OpenEngine { + + class EditorCamera : public OpenEngine::Camera + { + public: + EditorCamera() = default; + EditorCamera(float fov, float aspect_ratio, float near_clip, float far_clip); + + void OnUpdate(); + void OnEvent(Event& e); + + inline float GetDistance() const { return distance; } + inline void SetDistance(float _distance) { distance = _distance; } + + inline void SetViewportSize(float width, float height) { viewport_width = width; viewport_height = height; UpdateProjection(); } + + const glm::mat4& GetViewMatrix() const { return view_matrix; } + glm::mat4 GetViewProjection() const { return projection * view_matrix; } + + glm::vec3 GetUpDirection() const; + glm::vec3 GetRightDirection() const; + glm::vec3 GetForwardDirection() const; + const glm::vec3& GetPosition() const { return position; } + glm::quat GetOrientation() const; + + float GetPitch() const { return pitch; } + float GetYaw() const { return yaw; } + private: + void UpdateProjection(); + void UpdateView(); + + bool OnMouseScroll(MouseScrolledEvent& e); + + void MousePan(const glm::vec2& delta); + void MouseRotate(const glm::vec2& delta); + void MouseZoom(float delta); + + glm::vec3 CalculatePosition() const; + + std::pair PanSpeed() const; + float RotationSpeed() const; + float ZoomSpeed() const; + private: + float fov = 45.0f, aspect_ratio = 1.778f, near_clip = 0.1f, far_clip = 1000.0f; + + glm::mat4 view_matrix; + glm::vec3 position = { 0.0f, 0.0f, 0.0f }; + glm::vec3 focal_point = { 0.0f, 0.0f, 0.0f }; + + glm::vec2 initial_mouse_position = { 0.0f, 0.0f }; + + float distance = 10.0f; + float pitch = 0.0f, yaw = 0.0f; + + float viewport_width = 1280, viewport_height = 720; + }; + +} + +#endif // EDITOR_CAMERA_HPP diff --git a/open_engine/include/open_engine/renderer/renderer2d.hpp b/open_engine/include/open_engine/renderer/renderer2d.hpp index 8b09c26..d48146b 100644 --- a/open_engine/include/open_engine/renderer/renderer2d.hpp +++ b/open_engine/include/open_engine/renderer/renderer2d.hpp @@ -1,6 +1,7 @@ #ifndef RENDERER2D_HPP #define RENDERER2D_HPP +#include "open_engine/renderer/editor_camera.hpp" #include "open_engine/renderer/subtexture2d.hpp" #include "open_engine/orthographic_camera.hpp" #include "open_engine/renderer/texture.hpp" @@ -22,8 +23,8 @@ namespace OpenEngine { uint32_t draw_calls = 0; uint32_t quad_count = 0; - uint32_t GetToralVertexCount() { return quad_count * 4; }; - uint32_t GetToralIndexCount() { return quad_count * 6; }; + uint32_t GetTotalVertexCount() { return quad_count * 4; }; + uint32_t GetTotalIndexCount() { return quad_count * 6; }; }; class Renderer2D @@ -34,6 +35,7 @@ namespace OpenEngine { static void BeginScene(const OrthographicCamera& camera); static void BeginScene(const Camera& camera, const glm::mat4& transform); + static void BeginScene(const EditorCamera& camera); static void EndScene(); static void Flush(); @@ -50,6 +52,9 @@ namespace OpenEngine { private: static void FlushAndReset(); + + static void StartBatch(); + static void NextBatch(); }; } diff --git a/open_engine/include/open_engine/scene/scene.hpp b/open_engine/include/open_engine/scene/scene.hpp index 0339809..5d3bd0e 100644 --- a/open_engine/include/open_engine/scene/scene.hpp +++ b/open_engine/include/open_engine/scene/scene.hpp @@ -1,8 +1,10 @@ #ifndef SCENE_HPP #define SCENE_HPP -#include +#include "open_engine/renderer/editor_camera.hpp" + #include +#include namespace OpenEngine { @@ -17,7 +19,8 @@ namespace OpenEngine { Entity CreateEntity(const std::string& name = std::string()); void DeleteEntity(Entity entity); - void OnUpdate(); + void OnUpdateRuntime(); + void OnUpdateEditor(EditorCamera& camera); void OnViewportResize(uint32_t width, uint32_t height); entt::registry& GetRegistry() { return registry; }; diff --git a/open_engine/src/open_engine/renderer/editor_camera.cpp b/open_engine/src/open_engine/renderer/editor_camera.cpp new file mode 100644 index 0000000..4f6cc3c --- /dev/null +++ b/open_engine/src/open_engine/renderer/editor_camera.cpp @@ -0,0 +1,146 @@ +#include "logging.hpp" +#include + +#include + +#include +#include +#include + +#include + +#define GLM_ENABLE_EXPERIMENTAL +#include + +namespace OpenEngine { + + EditorCamera::EditorCamera(float fov, float aspect_ratio, float near_clip, float far_clip) + : fov(fov), aspect_ratio(aspect_ratio), near_clip(near_clip), far_clip(far_clip), Camera(glm::perspective(glm::radians(fov), aspect_ratio, near_clip, far_clip)) + { + UpdateView(); + } + + void EditorCamera::UpdateProjection() + { + aspect_ratio = viewport_width / viewport_height; + projection = glm::perspective(glm::radians(fov), aspect_ratio, near_clip, far_clip); + } + + void EditorCamera::UpdateView() + { + // m_Yaw = m_Pitch = 0.0f; // Lock the camera's rotation + position = CalculatePosition(); + + glm::quat orientation = GetOrientation(); + view_matrix = glm::translate(glm::mat4(1.0f), position) * glm::toMat4(orientation); + view_matrix = glm::inverse(view_matrix); + } + + std::pair EditorCamera::PanSpeed() const + { + float x = std::min(viewport_width / 1000.0f, 2.4f); // max = 2.4f + float x_factor = 0.0366f * (x * x) - 0.1778f * x + 0.3021f; + + float y = std::min(viewport_height / 1000.0f, 2.4f); // max = 2.4f + float y_factor = 0.0366f * (y * y) - 0.1778f * y + 0.3021f; + + return { x_factor, y_factor }; + } + + float EditorCamera::RotationSpeed() const + { + return 0.8f; + } + + float EditorCamera::ZoomSpeed() const + { + float _distance = distance * 0.2f; + _distance = std::max(_distance, 0.0f); + float speed = _distance * _distance; + speed = std::min(speed, 100.0f); // max speed = 100 + return speed; + } + + void EditorCamera::OnUpdate() + { + if (Input::IsKeyPressed(Key::LeftAlt)) + { + const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() }; + glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f; + initial_mouse_position = mouse; + + if (Input::IsMouseButtonPressed(Mouse::ButtonMiddle)) + MousePan(delta); + else if (Input::IsMouseButtonPressed(Mouse::ButtonLeft)) + MouseRotate(delta); + else if (Input::IsMouseButtonPressed(Mouse::ButtonRight)) + MouseZoom(delta.y); + } + + UpdateView(); + } + + void EditorCamera::OnEvent(Event& e) + { + EventDispatcher dispatcher(e); + dispatcher.Dispatch(BIND_EVENT_FN(EditorCamera::OnMouseScroll)); + } + + bool EditorCamera::OnMouseScroll(MouseScrolledEvent& e) + { + float delta = e.GetYOffset() * 0.1f; + MouseZoom(delta); + UpdateView(); + return false; + } + + void EditorCamera::MousePan(const glm::vec2& delta) + { + auto [x_speed, y_speed] = PanSpeed(); + + focal_point += -GetRightDirection() * delta.x * x_speed * distance; + focal_point += GetUpDirection() * delta.y * y_speed * distance; + } + + void EditorCamera::MouseRotate(const glm::vec2& delta) + { + float yaw_sign = GetUpDirection().y < 0 ? -1.0f : 1.0f; + yaw += yaw_sign * delta.x * RotationSpeed(); + pitch += delta.y * RotationSpeed(); + } + + void EditorCamera::MouseZoom(float delta) + { + distance -= delta * ZoomSpeed(); + if (distance < 1.0f) { + focal_point += GetForwardDirection(); + distance = 1.0f; + } + } + + glm::vec3 EditorCamera::GetUpDirection() const + { + return glm::rotate(GetOrientation(), glm::vec3(0.0f, 1.0f, 0.0f)); + } + + glm::vec3 EditorCamera::GetRightDirection() const + { + return glm::rotate(GetOrientation(), glm::vec3(1.0f, 0.0f, 0.0f)); + } + + glm::vec3 EditorCamera::GetForwardDirection() const + { + return glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f)); + } + + glm::vec3 EditorCamera::CalculatePosition() const + { + return focal_point - GetForwardDirection() * distance; + } + + glm::quat EditorCamera::GetOrientation() const + { + return glm::quat(glm::vec3(-pitch, -yaw, 0.0f)); + } + +} diff --git a/open_engine/src/open_engine/renderer/renderer.cpp b/open_engine/src/open_engine/renderer/renderer.cpp index 617027a..3704e83 100644 --- a/open_engine/src/open_engine/renderer/renderer.cpp +++ b/open_engine/src/open_engine/renderer/renderer.cpp @@ -2,7 +2,7 @@ #include "open_engine/renderer/renderer.hpp" #include "open_engine/renderer/render_command.hpp" -#include "renderer/renderer2d.hpp" +#include "open_engine/renderer/renderer2d.hpp" #include diff --git a/open_engine/src/open_engine/renderer/renderer2d.cpp b/open_engine/src/open_engine/renderer/renderer2d.cpp index e276df8..8479e4a 100755 --- a/open_engine/src/open_engine/renderer/renderer2d.cpp +++ b/open_engine/src/open_engine/renderer/renderer2d.cpp @@ -1,3 +1,4 @@ +#include "renderer/editor_camera.hpp" #include #include @@ -130,10 +131,7 @@ namespace OpenEngine { renderer_data.texture_shader->Bind(); renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); - renderer_data.quad_index_count = 0; - renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base; - - renderer_data.texture_slot_index = 1; + StartBatch(); } void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& transform) @@ -145,10 +143,19 @@ namespace OpenEngine { renderer_data.texture_shader->Bind(); renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection); - renderer_data.quad_index_count = 0; - renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base; + StartBatch(); + } - renderer_data.texture_slot_index = 1; + void Renderer2D::BeginScene(const EditorCamera& camera) + { + OE_PROFILE_FUNCTION(); + + glm::mat4 view_projection = camera.GetViewProjection(); + + renderer_data.texture_shader->Bind(); + renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection); + + StartBatch(); } void Renderer2D::EndScene() @@ -404,4 +411,18 @@ namespace OpenEngine { renderer_data.texture_slot_index = 1; } + + void Renderer2D::StartBatch() + { + renderer_data.quad_index_count = 0; + renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base; + + renderer_data.texture_slot_index = 1; + } + + void Renderer2D::NextBatch() + { + Flush(); + StartBatch(); + } } diff --git a/open_engine/src/open_engine/scene/scene.cpp b/open_engine/src/open_engine/scene/scene.cpp index 6692ef4..f4f49aa 100644 --- a/open_engine/src/open_engine/scene/scene.cpp +++ b/open_engine/src/open_engine/scene/scene.cpp @@ -22,7 +22,7 @@ namespace OpenEngine { registry.destroy(entity); } - void Scene::OnUpdate() + void Scene::OnUpdateRuntime() { { OE_PROFILE_SCOPE("Updating Sripts"); @@ -68,6 +68,21 @@ namespace OpenEngine { } } + void Scene::OnUpdateEditor(EditorCamera& camera) + { + Renderer2D::BeginScene(camera); + + auto group = registry.group(entt::get); + for (auto entity : group) + { + auto [transform, sprite] = group.get(entity); + + Renderer2D::DrawQuad(transform.GetTransform(), sprite.color); + } + + Renderer2D::EndScene(); + } + void Scene::OnViewportResize(uint32_t width, uint32_t height) { viewport_width = width;