299 lines
9.9 KiB
C++
Executable File
299 lines
9.9 KiB
C++
Executable File
#ifndef EDITOR_HPP
|
|
#define EDITOR_HPP
|
|
|
|
#include "open_engine/ref_scope.hpp"
|
|
#include "panels/scene_hierarchy.hpp"
|
|
#include <open_engine.hpp>
|
|
|
|
#include <glm/ext/matrix_transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <glm/matrix.hpp>
|
|
#include <entt/entt.hpp>
|
|
#include <glad/glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <cstdint>
|
|
#include <imgui.h>
|
|
|
|
namespace OpenEngine {
|
|
|
|
class CameraController : public NativeScriptableEntity
|
|
{
|
|
public:
|
|
void OnCreate()
|
|
{
|
|
};
|
|
|
|
void OnUpdate()
|
|
{
|
|
auto delta = Time::DeltaTime();
|
|
|
|
auto& position = GetComponent<TransformComponent>().translation;
|
|
|
|
if (Input::IsKeyPressed(KeyCode::Up))
|
|
position.y += 5.0 * delta;
|
|
if (Input::IsKeyPressed(KeyCode::Down))
|
|
position.y -= 5.0 * delta;
|
|
if (Input::IsKeyPressed(KeyCode::Right))
|
|
position.x += 5.0 * delta;
|
|
if (Input::IsKeyPressed(KeyCode::Left))
|
|
position.x -= 5.0 * delta;
|
|
};
|
|
|
|
void OnDestroy()
|
|
{
|
|
};
|
|
};
|
|
|
|
class EditorLayer : public Layer
|
|
{
|
|
public:
|
|
EditorLayer()
|
|
: Layer("editor_layer")/*,
|
|
camera((float)Application::Get().GetWindow().GetWidth() /
|
|
Application::Get().GetWindow().GetHeight(), 1.0f)
|
|
*/
|
|
{
|
|
}
|
|
~EditorLayer() {};
|
|
|
|
entt::registry registry;
|
|
|
|
void OnAttach() override
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
FramebufferSpecification specs;
|
|
specs.width = 1280;
|
|
specs.height = 720;
|
|
|
|
framebuffer = FrameBuffer::Create(specs);
|
|
|
|
scene = CreateRef<Scene>();
|
|
|
|
sq_entity = scene->CreateEntity("square");
|
|
|
|
sq_entity.AddComponents<TransformComponent>();
|
|
sq_entity.AddComponents<SpriteRendererComponent>(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
|
|
|
camera_bis = scene->CreateEntity("Main camera");
|
|
camera_bis.AddComponents<TransformComponent>();
|
|
camera_bis.AddComponents<CameraComponent>();
|
|
camera_bis.AddComponents<NativeScriptComponent>().Bind<CameraController>();
|
|
|
|
scene_hierarchy.SetContext(scene);
|
|
}
|
|
|
|
void OnDetach() override
|
|
{
|
|
}
|
|
|
|
void OnUpdate() override
|
|
{
|
|
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);
|
|
//camera.OnResize(viewport_size.x, viewport_size.y);
|
|
}
|
|
|
|
{
|
|
OE_PROFILE_SCOPE("Setting up Rendering");
|
|
//camera.OnUpdate();
|
|
framebuffer->Bind();
|
|
|
|
scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
|
|
}
|
|
|
|
Renderer2D::ResetStats();
|
|
RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
|
|
RenderCommand::Clear();
|
|
|
|
//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};
|
|
Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color);
|
|
}
|
|
}
|
|
|
|
Transform tr5 = {
|
|
glm::vec3(world_pos_cursor.x, world_pos_cursor.y, 0.9f),
|
|
glm::vec3(0.1f, 0.1f, 0.0f), 0.0f};
|
|
|
|
Renderer2D::DrawQuad(tr5, {1, 1, 1, 1});
|
|
*/
|
|
|
|
scene->OnUpdate();
|
|
|
|
//Renderer2D::EndScene();
|
|
|
|
framebuffer->Unbind();
|
|
}
|
|
|
|
void OnEvent(Event& event) override
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
//camera.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 DrawViewport()
|
|
{
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0, 0 });
|
|
|
|
ImGui::Begin("Viewport");
|
|
bool focused = ImGui::IsWindowFocused();
|
|
bool hovered = ImGui::IsWindowHovered();
|
|
Application::Get().GetImGuiLayer()->SetBlockEvents(!focused || !hovered);
|
|
|
|
ImVec2 viewport_panel_size = ImGui::GetContentRegionAvail();
|
|
|
|
viewport_size = { viewport_panel_size.x, viewport_panel_size.y };
|
|
|
|
ImVec2 imgui_cursor_position = ImGui::GetCursorScreenPos();
|
|
auto pair_position = 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 (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 });
|
|
|
|
ImGui::End();
|
|
ImGui::PopStyleVar();
|
|
};
|
|
|
|
void DrawStats()
|
|
{
|
|
auto stats = Renderer2D::GetStats();
|
|
static float time = 0;
|
|
|
|
time += Time::DeltaTime();
|
|
|
|
if (time >= 1) {
|
|
time = 0;
|
|
}
|
|
|
|
ImGui::Begin("Statistics");
|
|
ImGui::Text("FPS: %0.0f", 1 / Time::DeltaTime());
|
|
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());
|
|
|
|
/*
|
|
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();
|
|
};
|
|
|
|
void OnImGuiRender() override
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
ImGui::DockSpaceOverViewport();
|
|
|
|
DrawStats();
|
|
scene_hierarchy.OnImGuiRender();
|
|
DrawViewport();
|
|
|
|
ImGui::ShowDemoWindow();
|
|
};
|
|
|
|
private:
|
|
std::vector<Time::ProfilingResult> profiling_results;
|
|
|
|
glm::vec2 world_pos_cursor = { 0.0f, 0.0f };
|
|
|
|
glm::vec2 viewport_size = { 0.0f, 0.0f };
|
|
Ref<OpenEngine::FrameBuffer> framebuffer;
|
|
SceneHierarchy scene_hierarchy;
|
|
//OrthographicCameraController camera;
|
|
|
|
Entity camera_bis;
|
|
|
|
Ref<Scene> scene;
|
|
Entity sq_entity;
|
|
};
|
|
}
|
|
|
|
class EditorApp : public OpenEngine::Application
|
|
{
|
|
public:
|
|
EditorApp();
|
|
~EditorApp();
|
|
};
|
|
|
|
#endif // EDITOR_HPP
|