editor camera!

This commit is contained in:
Erris
2026-02-21 01:11:24 +01:00
parent 02430073ec
commit cb064bdb46
10 changed files with 299 additions and 50 deletions

View File

@@ -3,12 +3,6 @@
#include <open_engine.hpp> #include <open_engine.hpp>
#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 "panels/scene_hierarchy.hpp"
//#include <imfilebrowser.h> //#include <imfilebrowser.h>
@@ -75,6 +69,8 @@ namespace OpenEngine {
scene = CreateRef<Scene>(); scene = CreateRef<Scene>();
editor_camera = EditorCamera(30.0f, 1920.0f/1080.0f, 0.1f, 1000.0f);
scene_hierarchy.SetContext(scene); scene_hierarchy.SetContext(scene);
} }
@@ -86,23 +82,23 @@ namespace OpenEngine {
{ {
FramebufferSpecification spec = framebuffer->GetSpecification(); FramebufferSpecification spec = framebuffer->GetSpecification();
if (viewport_size.x > 0.0f && viewport_size.y > 0.0f && if (viewport_size.x > 0.0f && viewport_size.y > 0.0f &&
(spec.width != viewport_size.x || spec.height != viewport_size.y)) (spec.width != viewport_size.x || spec.height != viewport_size.y)) {
{
framebuffer->Resize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
}
{
OE_PROFILE_SCOPE("Setting up Rendering"); 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); scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
} }
framebuffer->Bind();
Renderer2D::ResetStats(); Renderer2D::ResetStats();
RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f}); RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
RenderCommand::Clear(); RenderCommand::Clear();
scene->OnUpdate(); editor_camera.OnUpdate();
scene->OnUpdateEditor(editor_camera);
framebuffer->Unbind(); framebuffer->Unbind();
} }
@@ -142,6 +138,8 @@ namespace OpenEngine {
{ {
OE_PROFILE_FUNCTION(); OE_PROFILE_FUNCTION();
editor_camera.OnEvent(event);
EventDispatcher dispatcher(event); EventDispatcher dispatcher(event);
dispatcher.Dispatch<KeyPressedEvent>(BIND_EVENT_FN(EditorLayer::EditorKeyBinds)); dispatcher.Dispatch<KeyPressedEvent>(BIND_EVENT_FN(EditorLayer::EditorKeyBinds));
}; };
@@ -209,20 +207,6 @@ namespace OpenEngine {
int max_x = viewport_size.x + imgui_cursor_position.x; int max_x = viewport_size.x + imgui_cursor_position.x;
int max_y = viewport_size.y + imgui_cursor_position.y; 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(); 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 }); 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("Renderer2D:");
ImGui::Text("\t\tDraw calls: %d", stats.draw_calls); ImGui::Text("\t\tDraw calls: %d", stats.draw_calls);
ImGui::Text("\t\tQuad count: %d", stats.quad_count); ImGui::Text("\t\tQuad count: %d", stats.quad_count);
ImGui::Text("\t\tVertices count: %d", stats.GetToralVertexCount()); ImGui::Text("\t\tVertices count: %d", stats.GetTotalVertexCount());
ImGui::Text("\t\tIndices count: %d", stats.GetToralIndexCount()); ImGui::Text("\t\tIndices count: %d", stats.GetTotalIndexCount());
/* /*
for (auto& result : profiling_results) for (auto& result : profiling_results)
@@ -287,10 +271,12 @@ namespace OpenEngine {
auto window_size = ImGui::GetWindowSize(); auto window_size = ImGui::GetWindowSize();
ImGuizmo::SetRect(window_position.x, window_position.y, window_size.x, window_size.y); ImGuizmo::SetRect(window_position.x, window_position.y, window_size.x, window_size.y);
auto camera_entity = scene->GetPrimaryCamera(); //auto camera_entity = scene->GetPrimaryCamera();
auto camera = camera_entity.GetComponents<CameraComponent>().camera; //auto camera = camera_entity.GetComponents<CameraComponent>().camera;
const glm::mat4& projection = camera.GetProjection(); //const glm::mat4& projection = camera.GetProjection();
glm::mat4 camera_view = glm::inverse(camera_entity.GetComponents<TransformComponent>().GetTransform()); //glm::mat4 camera_view = glm::inverse(camera_entity.GetComponents<TransformComponent>().GetTransform());
const glm::mat4& camera_projection = editor_camera.GetProjection();
glm::mat4 camera_view = editor_camera.GetViewMatrix();
auto& transform_comp = selected_entity.GetComponents<TransformComponent>(); auto& transform_comp = selected_entity.GetComponents<TransformComponent>();
glm::mat4 transform = transform_comp.GetTransform(); glm::mat4 transform = transform_comp.GetTransform();
@@ -302,7 +288,7 @@ namespace OpenEngine {
float snap_values[] = { snap_value, snap_value, snap_value }; 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, (ImGuizmo::OPERATION)guizmo_operation, ImGuizmo::LOCAL,
glm::value_ptr(transform), nullptr, glm::value_ptr(transform), nullptr,
snap ? snap_values : nullptr); snap ? snap_values : nullptr);
@@ -390,7 +376,7 @@ namespace OpenEngine {
SceneHierarchy scene_hierarchy; SceneHierarchy scene_hierarchy;
Entity camera_bis; EditorCamera editor_camera;
int guizmo_operation = -1; int guizmo_operation = -1;

View File

@@ -15,9 +15,11 @@ find_package(EnTT REQUIRED)
find_package(yaml-cpp REQUIRED) find_package(yaml-cpp REQUIRED)
file(GLOB_RECURSE SRC_FILES "src/*.cpp") file(GLOB_RECURSE SRC_FILES "src/*.cpp")
file(GLOB IMGUIZMO_SRC_FILES "${CMAKE_SOURCE_DIR}/vendor/ImGuizmo/*.cpp")
add_library(${PROJECT_EXECUTABLE_NAME} STATIC add_library(${PROJECT_EXECUTABLE_NAME} STATIC
${SRC_FILES} ${SRC_FILES}
"vendor/stb_image/stb_image.cpp" "vendor/stb_image/stb_image.cpp"
${IMGUIZMO_SRC_FILES}
) )
target_precompile_headers(${PROJECT_EXECUTABLE_NAME} PRIVATE target_precompile_headers(${PROJECT_EXECUTABLE_NAME} PRIVATE
@@ -33,6 +35,7 @@ target_include_directories(${PROJECT_EXECUTABLE_NAME} PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/include"
"/home/erris/.conan2/p/b/imguic69fe98538919/p/include" "/home/erris/.conan2/p/b/imguic69fe98538919/p/include"
"vendor/nativefiledialog-extended/src/include" "vendor/nativefiledialog-extended/src/include"
"${CMAKE_SOURCE_DIR}/vendor/ImGuizmo"
) )
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") #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 add_subdirectory(vendor/glad
./lib ./glad
) )
add_subdirectory("vendor/nativefiledialog-extended") add_subdirectory("vendor/nativefiledialog-extended")

View File

@@ -5,6 +5,7 @@
#include "open_engine/imgui/imgui_layer.hpp" #include "open_engine/imgui/imgui_layer.hpp"
#include "open_engine/events/key_event.hpp" #include "open_engine/events/key_event.hpp"
#include "open_engine/application.hpp" #include "open_engine/application.hpp"
#include "open_engine/math/math.hpp"
#include "open_engine/ref_scope.hpp" #include "open_engine/ref_scope.hpp"
#include "open_engine/logging.hpp" #include "open_engine/logging.hpp"

View File

@@ -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 <glm/glm.hpp>
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<float, float> 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

View File

@@ -1,6 +1,7 @@
#ifndef RENDERER2D_HPP #ifndef RENDERER2D_HPP
#define RENDERER2D_HPP #define RENDERER2D_HPP
#include "open_engine/renderer/editor_camera.hpp"
#include "open_engine/renderer/subtexture2d.hpp" #include "open_engine/renderer/subtexture2d.hpp"
#include "open_engine/orthographic_camera.hpp" #include "open_engine/orthographic_camera.hpp"
#include "open_engine/renderer/texture.hpp" #include "open_engine/renderer/texture.hpp"
@@ -22,8 +23,8 @@ namespace OpenEngine {
uint32_t draw_calls = 0; uint32_t draw_calls = 0;
uint32_t quad_count = 0; uint32_t quad_count = 0;
uint32_t GetToralVertexCount() { return quad_count * 4; }; uint32_t GetTotalVertexCount() { return quad_count * 4; };
uint32_t GetToralIndexCount() { return quad_count * 6; }; uint32_t GetTotalIndexCount() { return quad_count * 6; };
}; };
class Renderer2D class Renderer2D
@@ -34,6 +35,7 @@ namespace OpenEngine {
static void BeginScene(const OrthographicCamera& camera); static void BeginScene(const OrthographicCamera& camera);
static void BeginScene(const Camera& camera, const glm::mat4& transform); static void BeginScene(const Camera& camera, const glm::mat4& transform);
static void BeginScene(const EditorCamera& camera);
static void EndScene(); static void EndScene();
static void Flush(); static void Flush();
@@ -50,6 +52,9 @@ namespace OpenEngine {
private: private:
static void FlushAndReset(); static void FlushAndReset();
static void StartBatch();
static void NextBatch();
}; };
} }

View File

@@ -1,8 +1,10 @@
#ifndef SCENE_HPP #ifndef SCENE_HPP
#define SCENE_HPP #define SCENE_HPP
#include <cstdint> #include "open_engine/renderer/editor_camera.hpp"
#include <entt/entt.hpp> #include <entt/entt.hpp>
#include <cstdint>
namespace OpenEngine { namespace OpenEngine {
@@ -17,7 +19,8 @@ namespace OpenEngine {
Entity CreateEntity(const std::string& name = std::string()); Entity CreateEntity(const std::string& name = std::string());
void DeleteEntity(Entity entity); void DeleteEntity(Entity entity);
void OnUpdate(); void OnUpdateRuntime();
void OnUpdateEditor(EditorCamera& camera);
void OnViewportResize(uint32_t width, uint32_t height); void OnViewportResize(uint32_t width, uint32_t height);
entt::registry& GetRegistry() { return registry; }; entt::registry& GetRegistry() { return registry; };

View File

@@ -0,0 +1,146 @@
#include "logging.hpp"
#include <pch.hpp>
#include <renderer/editor_camera.hpp>
#include <open_engine/input/input_system.hpp>
#include <open_engine/input/keycodes.hpp>
#include <open_engine/input/mouse_codes.hpp>
#include <GLFW/glfw3.h>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/quaternion.hpp>
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<float, float> 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<MouseScrolledEvent>(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));
}
}

View File

@@ -2,7 +2,7 @@
#include "open_engine/renderer/renderer.hpp" #include "open_engine/renderer/renderer.hpp"
#include "open_engine/renderer/render_command.hpp" #include "open_engine/renderer/render_command.hpp"
#include "renderer/renderer2d.hpp" #include "open_engine/renderer/renderer2d.hpp"
#include <glad/glad.h> #include <glad/glad.h>

View File

@@ -1,3 +1,4 @@
#include "renderer/editor_camera.hpp"
#include <pch.hpp> #include <pch.hpp>
#include <renderer/render_command.hpp> #include <renderer/render_command.hpp>
@@ -130,10 +131,7 @@ namespace OpenEngine {
renderer_data.texture_shader->Bind(); renderer_data.texture_shader->Bind();
renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix()); renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
renderer_data.quad_index_count = 0; StartBatch();
renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base;
renderer_data.texture_slot_index = 1;
} }
void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& transform) 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->Bind();
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection); renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
renderer_data.quad_index_count = 0; StartBatch();
renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base; }
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() void Renderer2D::EndScene()
@@ -404,4 +411,18 @@ namespace OpenEngine {
renderer_data.texture_slot_index = 1; 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();
}
} }

View File

@@ -22,7 +22,7 @@ namespace OpenEngine {
registry.destroy(entity); registry.destroy(entity);
} }
void Scene::OnUpdate() void Scene::OnUpdateRuntime()
{ {
{ {
OE_PROFILE_SCOPE("Updating Sripts"); OE_PROFILE_SCOPE("Updating Sripts");
@@ -68,6 +68,21 @@ namespace OpenEngine {
} }
} }
void Scene::OnUpdateEditor(EditorCamera& camera)
{
Renderer2D::BeginScene(camera);
auto group = registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
for (auto entity : group)
{
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
Renderer2D::DrawQuad(transform.GetTransform(), sprite.color);
}
Renderer2D::EndScene();
}
void Scene::OnViewportResize(uint32_t width, uint32_t height) void Scene::OnViewportResize(uint32_t width, uint32_t height)
{ {
viewport_width = width; viewport_width = width;