From 8a2b46834d7fcbf04f926fb8d881a86f1dd8583a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?RAFAEL=20ARAG=C3=83O=20MORAIS?= <62299990+Raphalsk050@users.noreply.github.com> Date: Thu, 26 Jun 2025 15:19:15 -0300 Subject: [PATCH] Add modular preview scene for material editor --- ProEngine/CMakeLists.txt | 2 + .../Frame/MaterialEditor/NodeEditor.cpp | 24 +++--- .../Editor/Frame/MaterialEditor/NodeEditor.h | 4 + .../Preview/MaterialPreview.cpp | 75 +++++++++++++++++++ .../MaterialEditor/Preview/MaterialPreview.h | 36 +++++++++ 5 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.cpp create mode 100644 ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.h diff --git a/ProEngine/CMakeLists.txt b/ProEngine/CMakeLists.txt index 3b92918e9..ea8e2c9d6 100644 --- a/ProEngine/CMakeLists.txt +++ b/ProEngine/CMakeLists.txt @@ -340,6 +340,8 @@ if (PROENGINE_ENABLE_EDITOR) Core/Editor/Frame/Viewport/Viewport.cpp Core/Editor/Frame/MaterialEditor/NodeEditor.h Core/Editor/Frame/MaterialEditor/NodeEditor.cpp + Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.h + Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.cpp Core/Editor/AnimatedPopup.h Core/Editor/SimpleAnimatedPopup.h Core/Editor/CommandSystem.h diff --git a/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.cpp b/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.cpp index e16fdea9f..0c97d9536 100644 --- a/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.cpp +++ b/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.cpp @@ -7,6 +7,7 @@ #include "Core/Editor/Frame/MaterialEditor/Nodes/InputFloat.h" #include "Core/Editor/Frame/MaterialEditor/Nodes/OutputNode.h" #include "Core/Editor/Frame/MaterialEditor/Nodes/SineNode.h" +#include #include namespace ProEngine @@ -14,6 +15,7 @@ namespace ProEngine NodeEditor::NodeEditor() : root_node_id_(0), minimap_location_(0), current_time_seconds_(0), opened_(false) { + preview_ = CreateRef(preview_size_); } NodeEditor::~NodeEditor() = default; @@ -21,6 +23,7 @@ namespace ProEngine void NodeEditor::OnAttach() { Layer::OnAttach(); + preview_->OnAttach(); ImNodes::CreateContext(); ImNodesIO& imnodes_io = ImNodes::GetIO(); ImGuiIO& imgui_io = ImGui::GetIO(); @@ -40,6 +43,7 @@ namespace ProEngine { Layer::OnUpdate(ts); current_time_seconds_ = Time::GetTime(); + preview_->OnUpdate(ts); } void NodeEditor::OnImGuiRender() @@ -59,6 +63,7 @@ namespace ProEngine void NodeEditor::OnEvent(Event& event) { Layer::OnEvent(event); + preview_->OnEvent(event); EventDispatcher dispatcher(event); dispatcher.Dispatch(PENGINE_BIND_EVENT_FN(NodeEditor::OnKeyPressed)); dispatcher.Dispatch(PENGINE_BIND_EVENT_FN(NodeEditor::OnKeyReleased)); @@ -84,22 +89,21 @@ namespace ProEngine void NodeEditor::RenderNodeEditor() { ImNodes::BeginNodeEditor(); - int margin = 100; + int margin = 30; const ImU32 color = (root_node_id_ != -1) ? Evaluate(graph_, root_node_id_) : IM_COL32(255, 20, 147, 255); - ImGui::PushStyleColor(ImGuiCol_ChildBg, color); - ImGui::SetNextWindowPos(ImVec2(ImGui::GetWindowSize().x - margin * 0.85, ImGui::GetWindowSize().y - margin)); - ImGui::BeginChild("Preview", ImVec2(300, 300), true, - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse - | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBringToFrontOnFocus | - ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMouseInputs); - ImGui::SameLine(20); - ImGui::Text("Preview"); + ImVec4 color_f = ImGui::ColorConvertU32ToFloat4(color); + preview_->GetMaterial()->SetAlbedoColor(glm::vec4(color_f.x, color_f.y, color_f.z, color_f.w)); - ImGui::EndChild(); + ImGui::PushStyleColor(ImGuiCol_ChildBg, color); + ImGui::SetNextWindowPos(ImVec2(ImGui::GetWindowSize().x + ImGui::GetWindowPos().x - preview_size_.x - margin, + ImGui::GetWindowSize().y + ImGui::GetWindowPos().y - preview_size_.y - margin)); + ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 5.0f); + preview_->OnImGuiRender(); ImGui::PopStyleColor(); + ImGui::PopStyleVar(); // Pop-up de contexto const bool open_popup = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) diff --git a/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.h b/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.h index 01ea97d8c..0a4a449a4 100644 --- a/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.h +++ b/ProEngine/Core/Editor/Frame/MaterialEditor/NodeEditor.h @@ -8,6 +8,7 @@ #include "Nodes/AddNode.h" #include "Nodes/CosNode.h" #include "Nodes/MultiplyNode.h" +#include "Preview/MaterialPreview.h" namespace ProEngine @@ -191,12 +192,15 @@ namespace ProEngine bool opened_ = false; std::unordered_map key_states_; ImVec2 default_window_size_ = {400.0, 400.0}; + ImVec2 preview_size_ = {256.0f, 256.0f}; Graph graph_; std::vector nodes_; int root_node_id_; ImNodesMiniMapLocation minimap_location_; float current_time_seconds_; + Ref preview_; + private: void RenderNodeEditor(); void SetupWindow(); diff --git a/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.cpp b/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.cpp new file mode 100644 index 000000000..f0d5fdb66 --- /dev/null +++ b/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.cpp @@ -0,0 +1,75 @@ +#include "MaterialPreview.h" +#include "Core/Renderer/RenderCommand.h" +#include "Core/Renderer/Renderer3D.h" +#include "Core/Scene/SceneRenderer.h" +#include + +namespace ProEngine { + +MaterialPreview::MaterialPreview(const ImVec2& size) : size_(size) { + camera_controller_ = CreateRef(size.x / size.y, Camera3DController::ControlMode::Orbit); +} + +void MaterialPreview::OnAttach() { + FramebufferSpecification spec; + spec.Width = static_cast(size_.x); + spec.Height = static_cast(size_.y); + spec.EnableEntityIDAttachment = true; + framebuffer_ = Framebuffer::Create(spec); + camera_controller_->OnResize(spec.Width, spec.Height); + + scene_ = CreateRef(); + + sphere_entity_ = scene_->CreateEntity("PreviewSphere"); + preview_material_ = CreateRef(); + Ref sphereMesh = Mesh::CreateSphere(); + sphereMesh->SetMaterial(preview_material_); + RendererComponent rc; + rc.mesh_ptr = sphereMesh; + sphere_entity_.AddComponent(rc); +} + +void MaterialPreview::OnResize(const ImVec2& size) { + size_ = size; + framebuffer_->Resize(static_cast(size_.x), static_cast(size_.y)); + camera_controller_->OnResize(size_.x, size_.y); +} + +void MaterialPreview::OnUpdate(Timestep ts) { + camera_controller_->OnUpdate(ts); + + framebuffer_->Bind(); + int idClear = -1; + glClearBufferiv(GL_COLOR, 1, &idClear); + RenderCommand::Clear(); + Renderer3D::BeginScene(camera_controller_->GetCamera()); + Renderer3D::SetAmbientLight(glm::vec3(1.0f), 10.0); + + scene_->OnUpdate(ts); + + Renderer3D::EndScene(); + framebuffer_->Unbind(); +} + +void MaterialPreview::OnEvent(Event& e) { + camera_controller_->OnEvent(e); +} + +void MaterialPreview::OnImGuiRender() { + ImGui::BeginChild("Preview", size_, true, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoBringToFrontOnFocus | + ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMouseInputs); + ImGui::Text("Preview"); + ImVec2 avail = ImGui::GetContentRegionAvail(); + if ((uint32_t)avail.x != framebuffer_->GetSpecification().Width || + (uint32_t)avail.y != framebuffer_->GetSpecification().Height) { + OnResize(ImVec2(avail.x, avail.y)); + } + ImGui::Image((void*)(intptr_t)framebuffer_->GetColorAttachmentRendererID(), avail, ImVec2{0,1}, ImVec2{1,0}); + ImGui::EndChild(); +} + +} // namespace ProEngine + diff --git a/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.h b/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.h new file mode 100644 index 000000000..8dc3b72b1 --- /dev/null +++ b/ProEngine/Core/Editor/Frame/MaterialEditor/Preview/MaterialPreview.h @@ -0,0 +1,36 @@ +#pragma once +#include "Core/Renderer/Framebuffer.h" +#include "Core/Camera/Camera3DController.h" +#include "Core/Renderer/Material.h" +#include "Core/Scene/Scene.h" +#include "Core/Scene/EntityHandle.h" +#include "Core/Timestep.h" +#include "Core/Event/Event.h" +#include "imgui.h" + +namespace ProEngine { + +class MaterialPreview { +public: + explicit MaterialPreview(const ImVec2& size); + + void OnAttach(); + void OnUpdate(Timestep ts); + void OnEvent(Event& e); + void OnResize(const ImVec2& size); + void OnImGuiRender(); + + Ref GetMaterial() const { return preview_material_; } + Ref GetFramebuffer() const { return framebuffer_; } + +private: + ImVec2 size_; + Ref framebuffer_; + Ref scene_; + Ref camera_controller_; + EntityHandle sphere_entity_; + Ref preview_material_; +}; + +} // namespace ProEngine +