mirror of
https://github.com/antopilo/Nuake.git
synced 2026-01-03 14:09:46 +03:00
Started editor windows refactor
This commit is contained in:
38
Editor/EditorContext.h
Normal file
38
Editor/EditorContext.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Core/MulticastDelegate.h"
|
||||
|
||||
#include "src/Actions/EditorSelection.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class Scene;
|
||||
}
|
||||
|
||||
class EditorContext
|
||||
{
|
||||
private:
|
||||
EditorSelection selection;
|
||||
Ref<Nuake::Scene> scene;
|
||||
|
||||
public:
|
||||
EditorContext() = default;
|
||||
~EditorContext() = default;
|
||||
|
||||
EditorContext(Ref<Nuake::Scene> inScene)
|
||||
: scene(inScene)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
MulticastDelegate<EditorSelection> OnSelectionChanged;
|
||||
|
||||
const EditorSelection& GetSelection() const { return selection; }
|
||||
void SetSelection(EditorSelection inSelection)
|
||||
{
|
||||
selection = selection;
|
||||
OnSelectionChanged.Broadcast(selection);
|
||||
}
|
||||
|
||||
Ref<Nuake::Scene> GetScene() const { return scene; }
|
||||
};
|
||||
17
Editor/IEditorWidget.h
Normal file
17
Editor/IEditorWidget.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
class EditorContext;
|
||||
|
||||
class IEditorWidget
|
||||
{
|
||||
protected:
|
||||
EditorContext& editorContext;
|
||||
|
||||
public:
|
||||
IEditorWidget(EditorContext& inContext) : editorContext(inContext) {}
|
||||
~IEditorWidget() {};
|
||||
|
||||
public:
|
||||
virtual void Update(float ts) = 0;
|
||||
virtual void Draw() = 0;
|
||||
};
|
||||
54
Editor/SceneEditorWindow.cpp
Normal file
54
Editor/SceneEditorWindow.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "SceneEditorWindow.h"
|
||||
|
||||
#include "SelectionPropertyWidget.h"
|
||||
#include "SceneHierarchyWidget.h"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
SceneEditorWindow::SceneEditorWindow(Ref<Scene> inScene)
|
||||
{
|
||||
editorContext = EditorContext(inScene);
|
||||
|
||||
RegisterWidget<SceneHierarchyWidget>();
|
||||
RegisterWidget<SelectionPropertyWidget>();
|
||||
}
|
||||
|
||||
void SceneEditorWindow::Update(float ts)
|
||||
{
|
||||
for (auto& widget : widgets)
|
||||
{
|
||||
widget->Update(ts);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneEditorWindow::Draw()
|
||||
{
|
||||
Ref<Scene> scene = editorContext.GetScene();
|
||||
const std::string sceneName = scene->GetName();
|
||||
|
||||
// This is to prevent other windows of other scene editors to dock
|
||||
// into this window
|
||||
ImGuiWindowClass windowClass;
|
||||
windowClass.ClassId = ImHashStr("SceneEditor");
|
||||
windowClass.DockingAllowUnclassed = false;
|
||||
ImGui::SetNextWindowClass(&windowClass);
|
||||
|
||||
if (ImGui::Begin(sceneName.c_str()))
|
||||
{
|
||||
ImGuiWindowClass localSceneEditorClass;
|
||||
localSceneEditorClass.ClassId = ImHashStr(sceneName.c_str());
|
||||
std::string dockspaceId = std::string("Dockspace##" + sceneName);
|
||||
ImGui::DockSpace(ImGui::GetID(dockspaceId.c_str()), ImGui::GetContentRegionAvail(), ImGuiDockNodeFlags_None, &localSceneEditorClass);
|
||||
|
||||
for (auto& widget : widgets)
|
||||
{
|
||||
widget->Draw();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
42
Editor/SceneEditorWindow.h
Normal file
42
Editor/SceneEditorWindow.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
|
||||
#include "IEditorWidget.h"
|
||||
#include "EditorContext.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Forward declarations
|
||||
namespace Nuake
|
||||
{
|
||||
class Scene;
|
||||
class Entity;
|
||||
}
|
||||
|
||||
class SceneHierarchyWidget;
|
||||
|
||||
class SceneEditorWindow
|
||||
{
|
||||
private:
|
||||
std::string windowID; // This is used for imgui docking
|
||||
|
||||
EditorContext editorContext;
|
||||
|
||||
std::vector<Scope<IEditorWidget>> widgets;
|
||||
public:
|
||||
SceneEditorWindow(Ref<Nuake::Scene> scene);
|
||||
~SceneEditorWindow() = default;
|
||||
|
||||
public:
|
||||
void Update(float ts);
|
||||
void Draw();
|
||||
|
||||
private:
|
||||
template<class T>
|
||||
inline void RegisterWidget()
|
||||
{
|
||||
widgets.push_back(CreateScope<T>(editorContext));
|
||||
}
|
||||
|
||||
};
|
||||
532
Editor/SceneHierarchyWidget.cpp
Normal file
532
Editor/SceneHierarchyWidget.cpp
Normal file
@@ -0,0 +1,532 @@
|
||||
#include "src/Core/Core.h"
|
||||
#include "SceneHierarchyWidget.h"
|
||||
|
||||
#include "src/UI/ImUI.h"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_internal.h>
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
#include "src/Scene/Components.h"
|
||||
|
||||
#include "SceneEditorWindow.h"
|
||||
#include <src/Core/Input.h>
|
||||
#include <src/FileSystem/FileDialog.h>
|
||||
#include "Engine.h"
|
||||
#include "src/Resource/Project.h"
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
SceneHierarchyWidget::SceneHierarchyWidget(EditorContext& inCtx) : IEditorWidget(inCtx)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::Update(float ts)
|
||||
{
|
||||
//std::string searchQuery = "";
|
||||
//
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 8, 8 });
|
||||
//ImGui::InputTextWithHint("##search", "Search entity", &searchQuery, 0, 0, 0);
|
||||
//ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::Draw()
|
||||
{
|
||||
DrawSearchBar();
|
||||
|
||||
DrawCreateEntityButton();
|
||||
|
||||
DrawEntityTree();
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::DrawSearchBar()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 8, 8 });
|
||||
ImGui::InputTextWithHint("##search", "Search entity", &searchQuery, 0, 0, 0);
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::SameLine();
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::DrawCreateEntityButton()
|
||||
{
|
||||
Ref<Scene> scene = editorContext.GetScene();
|
||||
if (UI::PrimaryButton("Add Entity", { ImGui::GetContentRegionAvail().x, 0 }))
|
||||
{
|
||||
ImGui::OpenPopup("create_entity_popup");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("create_entity_popup"))
|
||||
{
|
||||
Nuake::Entity entity;
|
||||
if (ImGui::MenuItem("Empty"))
|
||||
{
|
||||
entity = scene->CreateEntity("Empty");
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("3D"))
|
||||
{
|
||||
if (ImGui::MenuItem("Camera"))
|
||||
{
|
||||
entity = scene->CreateEntity("Camera");
|
||||
entity.AddComponent<CameraComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Model"))
|
||||
{
|
||||
entity = scene->CreateEntity("Model");
|
||||
entity.AddComponent<ModelComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Skinned Model"))
|
||||
{
|
||||
entity = scene->CreateEntity("Skinned Model");
|
||||
entity.AddComponent<SkinnedModelComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Sprite"))
|
||||
{
|
||||
entity = scene->CreateEntity("Sprite");
|
||||
entity.AddComponent<SpriteComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Particle Emitter"))
|
||||
{
|
||||
entity = scene->CreateEntity("Particle Emitter");
|
||||
entity.AddComponent<ParticleEmitterComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Light"))
|
||||
{
|
||||
entity = scene->CreateEntity("Light");
|
||||
entity.AddComponent<LightComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Quake Map"))
|
||||
{
|
||||
entity = scene->CreateEntity("Quake Map");
|
||||
entity.AddComponent<QuakeMapComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("NavMesh Volume"))
|
||||
{
|
||||
entity = scene->CreateEntity("NavMesh Volume");
|
||||
entity.AddComponent<NavMeshVolumeComponent>();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Physics"))
|
||||
{
|
||||
if (ImGui::MenuItem("Character Controller"))
|
||||
{
|
||||
entity = scene->CreateEntity("Character Controller");
|
||||
entity.AddComponent<CharacterControllerComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Rigid Body"))
|
||||
{
|
||||
entity = scene->CreateEntity("Rigid Body");
|
||||
entity.AddComponent<RigidBodyComponent>();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Colliders"))
|
||||
{
|
||||
if (ImGui::MenuItem("Box Collider"))
|
||||
{
|
||||
entity = scene->CreateEntity("Box Collider");
|
||||
entity.AddComponent<BoxColliderComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Sphere Collider"))
|
||||
{
|
||||
entity = scene->CreateEntity("Sphere Collider");
|
||||
entity.AddComponent<SphereColliderComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Capsule Collider"))
|
||||
{
|
||||
entity = scene->CreateEntity("Capsule Collider");
|
||||
entity.AddComponent<CapsuleColliderComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Cylinder Collider"))
|
||||
{
|
||||
entity = scene->CreateEntity("Cylinder Collider");
|
||||
entity.AddComponent<CylinderColliderComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Mesh Collider"))
|
||||
{
|
||||
entity = scene->CreateEntity("Mesh Collider");
|
||||
entity.AddComponent<MeshColliderComponent>();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Audio"))
|
||||
{
|
||||
if (ImGui::MenuItem("Audio Emitter"))
|
||||
{
|
||||
entity = scene->CreateEntity("Audio Emitter");
|
||||
entity.AddComponent<AudioEmitterComponent>();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (entity.IsValid())
|
||||
{
|
||||
EditorSelection selection = editorContext.GetSelection();
|
||||
if (selection.Type == EditorSelectionType::Entity && selection.Entity.IsValid())
|
||||
{
|
||||
selection.Entity.AddChild(entity);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& camera = editorContext.GetScene()->m_EditorCamera;
|
||||
Vector3 newEntityPos = camera->Translation + camera->Direction;
|
||||
entity.GetComponent<TransformComponent>().SetLocalPosition(newEntityPos);
|
||||
}
|
||||
|
||||
editorContext.SetSelection(EditorSelection(entity));
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::DrawEntityTree()
|
||||
{
|
||||
Ref<Scene> scene = editorContext.GetScene();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(26.f / 255.0f, 26.f / 255.0f, 26.f / 255.0f, 1));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4, 4 });
|
||||
if (ImGui::BeginChild("Scene tree", ImGui::GetContentRegionAvail(), false))
|
||||
{
|
||||
if (ImGui::BeginTable("entity_table", 4, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp))
|
||||
{
|
||||
ImGui::TableSetupColumn(" Label", ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Script", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("Visibility ", ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_IndentDisable | ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
|
||||
|
||||
std::vector<Nuake::Entity> entitiesToDisplay;
|
||||
if (searchQuery.empty())
|
||||
{
|
||||
entitiesToDisplay = scene->GetAllEntities();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto view = scene->m_Registry.view<NameComponent>();
|
||||
for (auto& e : view)
|
||||
{
|
||||
auto& nameComponent = view.get<NameComponent>(e);
|
||||
if (String::RemoveWhiteSpace(String::ToUpper(nameComponent.Name)).find(String::RemoveWhiteSpace(String::ToUpper(searchQuery))) != std::string::npos)
|
||||
{
|
||||
entitiesToDisplay.push_back({ e, scene.get() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display valid entities
|
||||
for (Nuake::Entity e : entitiesToDisplay)
|
||||
{
|
||||
// Draw all entity without parents.
|
||||
bool displayAllHierarchy = searchQuery.empty();
|
||||
if ((displayAllHierarchy && !e.GetComponent<ParentComponent>().HasParent) || !displayAllHierarchy)
|
||||
{
|
||||
// TODO(antopilo): Add font regular font
|
||||
// ImGui::PushFont(normalFont);
|
||||
|
||||
// Recursively draw childrens if not searching
|
||||
DrawEntity(e, displayAllHierarchy);
|
||||
|
||||
// ImGui::PopFont();
|
||||
}
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if(ImGui::BeginDragDropTarget()) // Drag n drop new prefab file into scene tree
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Prefab"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
std::string relPath = FileSystem::AbsoluteToRelative(fullPath);
|
||||
auto newPrefabInstance = Prefab::New(relPath);
|
||||
newPrefabInstance->Root.GetComponent<PrefabComponent>().SetPrefab(newPrefabInstance);
|
||||
newPrefabInstance->Root.GetComponent<NameComponent>().IsPrefab = true;
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
if (deletionQueue.GetHandle() != -1)
|
||||
{
|
||||
scene->DestroyEntity(deletionQueue);
|
||||
|
||||
// Unselect
|
||||
editorContext.SetSelection(EditorSelection());
|
||||
|
||||
deletionQueue = Nuake::Entity{ (entt::entity)-1, scene.get() };
|
||||
}
|
||||
}
|
||||
|
||||
void SceneHierarchyWidget::DrawEntity(Nuake::Entity entity, bool drawChildrens)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{ 0.0f, 0.0f });
|
||||
ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_FramePadding | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
|
||||
NameComponent& nameComponent = entity.GetComponent<NameComponent>();
|
||||
std::string name = nameComponent.Name;
|
||||
|
||||
ParentComponent& parent = entity.GetComponent<ParentComponent>();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Draw first column Name
|
||||
|
||||
// Highlight if the entity is currently selected
|
||||
auto selection = editorContext.GetSelection();
|
||||
if (selection.Type == EditorSelectionType::Entity && selection.Entity == entity)
|
||||
{
|
||||
base_flags |= ImGuiTreeNodeFlags_Selected;
|
||||
}
|
||||
|
||||
// Display arrow if it has children
|
||||
bool isPrefab = entity.HasComponent<PrefabComponent>();
|
||||
if (parent.Children.size() == 0 || isPrefab || !drawChildrens)
|
||||
{
|
||||
base_flags |= ImGuiTreeNodeFlags_Leaf;
|
||||
}
|
||||
|
||||
// Hightlight if the entity is a prefab or BSP
|
||||
if (nameComponent.IsPrefab && entity.HasComponent<PrefabComponent>())
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 255, 0, 255));
|
||||
}
|
||||
else if (entity.HasComponent<BSPBrushComponent>())
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 120));
|
||||
}
|
||||
|
||||
// TODO(antopilo) unfolding when mouse picking
|
||||
|
||||
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
ImVec2 cursorPosition = ImGui::GetCursorScreenPos();
|
||||
const auto& cleanName = String::RemoveWhiteSpace(String::ToUpper(name));
|
||||
const size_t searchIt = cleanName.find(String::RemoveWhiteSpace(String::ToUpper(searchQuery)));
|
||||
|
||||
ImGui::SetNextItemAllowOverlap();
|
||||
bool open = ImGui::TreeNodeEx(name.c_str(), base_flags);
|
||||
|
||||
if (!searchQuery.empty() && searchIt != std::string::npos)
|
||||
{
|
||||
int firstLetterFoundIndex = static_cast<int>(searchIt);
|
||||
|
||||
const auto foundStr = name.substr(0, firstLetterFoundIndex + searchQuery.size());
|
||||
auto highlightBeginPos = ImGui::CalcTextSize(foundStr.c_str());
|
||||
auto highlightEndPos = ImGui::CalcTextSize(searchQuery.c_str());
|
||||
|
||||
auto fg = ImGui::GetForegroundDrawList();
|
||||
auto color = Engine::GetProject()->Settings.PrimaryColor;
|
||||
auto rgbColor = IM_COL32(color.r * 255.0f, color.g * 255.0f, color.b * 255.0f, std::min(color.a, 0.2f) * 255.0f);
|
||||
|
||||
fg->AddRectFilled(ImVec2(cursorPosition.x + 20.0f, cursorPosition.y + 4.0f), ImVec2(cursorPosition.x + highlightEndPos.x + 26.0f, cursorPosition.y + highlightEndPos.y + 6.0f), rgbColor, 4.0f);
|
||||
}
|
||||
|
||||
// Renaming behavior
|
||||
if (isRenaming)
|
||||
{
|
||||
if (selection.Type == EditorSelectionType::Entity && selection.Entity == entity)
|
||||
{
|
||||
ImGui::SetCursorPosY(cursorPos.y);
|
||||
ImGui::Indent();
|
||||
ImGui::InputText("##renamingEntity", &name);
|
||||
ImGui::Unindent();
|
||||
if (Nuake::Input::IsKeyDown(Key::ENTER))
|
||||
{
|
||||
nameComponent.Name = name;
|
||||
isRenaming = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drag and drop behavior
|
||||
bool isDragging = false;
|
||||
if (nameComponent.IsPrefab && entity.HasComponent<PrefabComponent>() || entity.HasComponent<BSPBrushComponent>())
|
||||
{
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
else if (!isRenaming && ImGui::BeginDragDropSource())
|
||||
{
|
||||
ImGui::SetDragDropPayload("ENTITYPrefab", (void*)&entity, sizeof(Nuake::Entity));
|
||||
ImGui::Text(name.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITYPrefab"))
|
||||
{
|
||||
Nuake::Entity payload_entity = *(const Nuake::Entity*)payload->Data;
|
||||
|
||||
// Check if entity is already parent.
|
||||
ParentComponent& parentPayload = payload_entity.GetComponent<ParentComponent>();
|
||||
if (!payload_entity.EntityContainsItself(payload_entity, entity) && parentPayload.Parent != entity && std::count(parent.Children.begin(), parent.Children.end(), payload_entity) == 0)
|
||||
{
|
||||
if (parentPayload.HasParent)
|
||||
{
|
||||
// Erase remove idiom.
|
||||
ParentComponent& childOfParent = parentPayload.Parent.GetComponent<ParentComponent>();
|
||||
childOfParent.Children.erase(std::remove(childOfParent.Children.begin(), childOfParent.Children.end(), payload_entity), childOfParent.Children.end());
|
||||
}
|
||||
|
||||
parentPayload.Parent = entity;
|
||||
parentPayload.HasParent = true;
|
||||
parent.Children.push_back(payload_entity);
|
||||
}
|
||||
}
|
||||
else if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_NetScript"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
|
||||
std::string fullPath = std::string(file, 512);
|
||||
std::string path = Nuake::FileSystem::AbsoluteToRelative(std::move(fullPath));
|
||||
|
||||
if (entity.HasComponent<NetScriptComponent>())
|
||||
{
|
||||
entity.GetComponent<NetScriptComponent>().ScriptPath = path;
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.AddComponent<NetScriptComponent>().ScriptPath = path;
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
if (!isDragging && ImGui::IsItemHovered() && ImGui::IsMouseReleased(0))
|
||||
{
|
||||
// We selected another another that we werent renaming
|
||||
if (selection.Entity != entity)
|
||||
{
|
||||
isRenaming = false;
|
||||
}
|
||||
|
||||
editorContext.SetSelection(EditorSelection(entity));
|
||||
}
|
||||
|
||||
if (!isDragging && (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) || Input::IsKeyPressed(Key::F2))
|
||||
{
|
||||
isRenaming = true;
|
||||
}
|
||||
|
||||
if (!isRenaming && selection.Type == EditorSelectionType::Entity && Input::IsKeyPressed(Key::DELETE_KEY))
|
||||
{
|
||||
this->deletionQueue = selection.Entity;
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
editorContext.SetSelection(EditorSelection(entity));
|
||||
|
||||
Nuake::Entity entity = selection.Entity;
|
||||
if (entity.HasComponent<CameraComponent>())
|
||||
{
|
||||
// Moves the editor camera to the camera position and direction.
|
||||
if (ImGui::Selectable("Focus camera"))
|
||||
{
|
||||
Ref<EditorCamera> editorCam = editorContext.GetScene()->m_EditorCamera;
|
||||
Vector3 camDirection = entity.GetComponent<CameraComponent>().CameraInstance->GetDirection();
|
||||
camDirection.z *= -1.0f;
|
||||
editorCam->SetTransform(glm::inverse(entity.GetComponent<TransformComponent>().GetGlobalTransform()));
|
||||
}
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
if (ImGui::Selectable("Remove"))
|
||||
{
|
||||
deletionQueue = entity;
|
||||
}
|
||||
|
||||
if (entity.GetComponent<ParentComponent>().HasParent && ImGui::Selectable("Move to root"))
|
||||
{
|
||||
auto& parentComp = selection.Entity.GetComponent<ParentComponent>();
|
||||
if (parentComp.HasParent)
|
||||
{
|
||||
auto& parentParentComp = parentComp.Parent.GetComponent<ParentComponent>();
|
||||
parentParentComp.RemoveChildren(entity);
|
||||
parentComp.HasParent = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Selectable("Save entity as a new prefab"))
|
||||
{
|
||||
Ref<Prefab> newPrefab = Prefab::CreatePrefabFromEntity(selection.Entity);
|
||||
std::string savePath = Nuake::FileDialog::SaveFile("*.prefab");
|
||||
if (!String::EndsWith(savePath, ".prefab"))
|
||||
{
|
||||
savePath += ".prefab";
|
||||
}
|
||||
|
||||
if (!savePath.empty())
|
||||
{
|
||||
newPrefab->SaveAs(savePath);
|
||||
selection.Entity.AddComponent<PrefabComponent>().PrefabInstance = newPrefab;
|
||||
}
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TextColored(ImVec4(0.5, 0.5, 0.5, 1.0), "");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
{
|
||||
bool hasScript = entity.HasComponent<NetScriptComponent>();
|
||||
if (hasScript)
|
||||
{
|
||||
std::string scrollIcon = std::string(ICON_FA_SCROLL) + "##" + name;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
|
||||
if (ImGui::Button(scrollIcon.c_str(), { 40, 0 }))
|
||||
{
|
||||
auto& scriptComponent = entity.GetComponent<NetScriptComponent>();
|
||||
if (!scriptComponent.ScriptPath.empty() && FileSystem::FileExists(scriptComponent.ScriptPath))
|
||||
{
|
||||
OS::OpenIn(FileSystem::RelativeToAbsolute(scriptComponent.ScriptPath));
|
||||
}
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
bool& isVisible = entity.GetComponent<VisibilityComponent>().Visible;
|
||||
std::string visibilityIcon = isVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH;
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
|
||||
if (ImGui::Button(visibilityIcon.c_str(), { 40, 0 }))
|
||||
{
|
||||
isVisible = !isVisible;
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
if (open)
|
||||
{
|
||||
if (drawChildrens && !isPrefab)
|
||||
{
|
||||
// Caching list to prevent deletion while iterating.
|
||||
std::vector<Nuake::Entity> childrens = parent.Children;
|
||||
for (auto& e : childrens)
|
||||
{
|
||||
DrawEntity(e);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
28
Editor/SceneHierarchyWidget.h
Normal file
28
Editor/SceneHierarchyWidget.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include "IEditorWidget.h"
|
||||
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
|
||||
class EditorContext;
|
||||
|
||||
class SceneHierarchyWidget : public IEditorWidget
|
||||
{
|
||||
public:
|
||||
SceneHierarchyWidget(EditorContext& inCtx);
|
||||
~SceneHierarchyWidget() = default;
|
||||
|
||||
public:
|
||||
void Update(float ts) override;
|
||||
void Draw() override;
|
||||
|
||||
private:
|
||||
std::string searchQuery;
|
||||
bool isRenaming;
|
||||
Nuake::Entity deletionQueue;
|
||||
|
||||
void DrawSearchBar();
|
||||
void DrawCreateEntityButton();
|
||||
|
||||
void DrawEntityTree();
|
||||
void DrawEntity(Nuake::Entity entity, bool drawChildrens = true);
|
||||
};
|
||||
17
Editor/SelectionPropertyWidget.cpp
Normal file
17
Editor/SelectionPropertyWidget.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "SelectionPropertyWidget.h"
|
||||
|
||||
SelectionPropertyWidget::SelectionPropertyWidget(EditorContext& inCtx)
|
||||
: IEditorWidget(inCtx)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SelectionPropertyWidget::Update(float ts)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SelectionPropertyWidget::Draw()
|
||||
{
|
||||
|
||||
}
|
||||
18
Editor/SelectionPropertyWidget.h
Normal file
18
Editor/SelectionPropertyWidget.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "IEditorWidget.h"
|
||||
|
||||
class EditorContext;
|
||||
|
||||
class SelectionPropertyWidget : public IEditorWidget
|
||||
{
|
||||
public:
|
||||
SelectionPropertyWidget(EditorContext& inCtx);
|
||||
~SelectionPropertyWidget() = default;
|
||||
|
||||
public:
|
||||
void Update(float ts) override;
|
||||
void Draw() override;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <volk/volk.h>
|
||||
|
||||
#include "src/Rendering/Vulkan/SceneRenderPipeline.h"
|
||||
#include <src/Rendering/Vulkan/DebugCmd.h>
|
||||
|
||||
namespace Nuake {
|
||||
|
||||
@@ -182,7 +183,7 @@ namespace Nuake {
|
||||
// Title bar drag area
|
||||
// On Windows we hook into the GLFW win32 window internals
|
||||
ImGui::SetCursorPos(ImVec2(windowPadding.x, windowPadding.y + titlebarVerticalOffset)); // Reset cursor pos
|
||||
|
||||
|
||||
const auto titleBarDragSize = ImVec2(w - buttonsAreaWidth, titlebarHeight);
|
||||
|
||||
if (Window::Get()->IsMaximized())
|
||||
@@ -191,7 +192,7 @@ namespace Nuake {
|
||||
if (windowMousePosY >= 0.0f && windowMousePosY <= 5.0f)
|
||||
m_TitleBarHovered = true; // Account for the top-most pixels which don't register
|
||||
}
|
||||
|
||||
|
||||
auto curPos = ImGui::GetCursorPos();
|
||||
bool isOnMenu = false;
|
||||
{
|
||||
@@ -204,7 +205,7 @@ namespace Nuake {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
// Centered Window title
|
||||
@@ -236,12 +237,12 @@ namespace Nuake {
|
||||
{
|
||||
int iconWidth = std::max(MinimizeTexture->GetWidth(), 24);
|
||||
int iconHeight = std::max(MinimizeTexture->GetHeight(), 24);
|
||||
|
||||
|
||||
if (ImGui::InvisibleButton("Minimize", ImVec2(buttonWidth, buttonHeight)))
|
||||
{
|
||||
glfwIconifyWindow(Window::Get()->GetHandle());
|
||||
}
|
||||
|
||||
|
||||
auto rect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||
UI::DrawButtonImage(MinimizeTexture, buttonColN, buttonColH, buttonColP, rect);
|
||||
}
|
||||
@@ -280,19 +281,38 @@ namespace Nuake {
|
||||
{
|
||||
glfwSetWindowShouldClose(Window::Get()->GetHandle(), true);
|
||||
}
|
||||
|
||||
|
||||
UI::DrawButtonImage(CloseIconTexture, UI::TextCol, UI::TextCol, buttonColP);
|
||||
}
|
||||
|
||||
// Second bar with play stop pause etc
|
||||
ImGui::SetCursorPosX(windowPadding.x);
|
||||
ImGui::SetCursorPosX(windowPadding.x + NuakeTexture->GetSize().x);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 2.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 2));
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 0));
|
||||
|
||||
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, ImGui::GetStyle().WindowPadding.y));
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_TabBarBorderSize, 0);
|
||||
//
|
||||
//ImGui::SetNextWindowSize({ 300.0f, 25.0f });
|
||||
//if (ImGui::BeginTabBar("SceneTabsBar", ImGuiTabBarFlags_None))
|
||||
//{
|
||||
// ImGui::BeginTabItem("Scene 1");
|
||||
// ImGui::BeginTabItem("Scene 2");
|
||||
// ImGui::BeginTabItem("Scene 3");
|
||||
// ImGui::EndTabItem();
|
||||
//
|
||||
// ImGui::EndTabBar();
|
||||
//}
|
||||
//
|
||||
//ImGui::PopStyleVar(2);
|
||||
//
|
||||
//
|
||||
//ImGui::SameLine();
|
||||
ImGui::Dummy({ ImGui::GetContentRegionAvail().x / 2.0f - (76.0f / 2.0f), 8.0f });
|
||||
ImGui::SameLine();
|
||||
//ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 6.0f);
|
||||
|
||||
|
||||
if (Engine::IsPlayMode() && Engine::GetTimeScale() != 0.0f)
|
||||
{
|
||||
@@ -607,8 +627,8 @@ namespace Nuake {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
std::string name = ICON_FA_GAMEPAD + std::string(" Scene");
|
||||
ImGuiWindowClass window_class;
|
||||
window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
|
||||
ImGui::SetNextWindowClass(&window_class);
|
||||
//window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
|
||||
//ImGui::SetNextWindowClass(&window_class);
|
||||
|
||||
if (ImGui::Begin(name.c_str(), 0, ImGuiWindowFlags_NoDecoration))
|
||||
{
|
||||
@@ -1471,8 +1491,6 @@ namespace Nuake {
|
||||
// Recursively draw childrens if not searching
|
||||
const std::string entityName = e.GetComponent<NameComponent>().Name;
|
||||
|
||||
|
||||
|
||||
DrawEntityTree(e, displayAllHierarchy);
|
||||
|
||||
ImGui::PopFont();
|
||||
@@ -2107,6 +2125,19 @@ namespace Nuake {
|
||||
prefabEditors.push_back(CreateRef<PrefabEditorWindow>(newPrefab));
|
||||
}
|
||||
|
||||
void EditorInterface::OpenSceneWindow(const std::string& scenePath)
|
||||
{
|
||||
if (!FileSystem::FileExists(scenePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Scene> newScene = Scene::New();
|
||||
newScene->Path = scenePath;
|
||||
newScene->Deserialize(json::parse(FileSystem::ReadFile(scenePath)));
|
||||
sceneEditors.push_back(CreateRef<SceneEditorWindow>(newScene));
|
||||
}
|
||||
|
||||
void NewProject()
|
||||
{
|
||||
if (Engine::GetProject() && Engine::GetProject()->FileExist())
|
||||
@@ -2442,9 +2473,11 @@ namespace Nuake {
|
||||
VkRenderer::Get().SceneRenderer->sceneRenderPipeline->OnDebugDraw().AddRaw(this, &EditorInterface::OnDebugDraw);
|
||||
}
|
||||
|
||||
void EditorInterface::OnDebugDraw()
|
||||
void EditorInterface::OnDebugDraw(DebugCmd& cmd)
|
||||
{
|
||||
Logger::Log("On debug draw");
|
||||
|
||||
//cmd.DrawLine({ 0, 0, 0 }, { 10, 10, 10 }, { 1, 0, 0, 1 });
|
||||
//cmd.DrawCube({ 0, 0, 0 }, { 1, 1, 1 }, { 0, 1, 0, 1 });
|
||||
}
|
||||
|
||||
bool isLoadingProject = false;
|
||||
@@ -2699,12 +2732,40 @@ namespace Nuake {
|
||||
float titleBarHeight;
|
||||
DrawTitlebar(titleBarHeight);
|
||||
ImGui::SetCursorPosY(titleBarHeight);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
float minWinSizeX = style.WindowMinSize.x;
|
||||
style.WindowMinSize.x = 370.0f;
|
||||
ImGui::DockSpace(ImGui::GetID("MyDockspace"));
|
||||
|
||||
ImGuiWindowClass top_level_class;
|
||||
top_level_class.ClassId = ImHashStr("SceneEditor");
|
||||
top_level_class.DockingAllowUnclassed = false;
|
||||
|
||||
ImGui::DockSpace(ImGui::GetID("SceneEditorDockSpace"), {0, 0}, 0, &top_level_class);
|
||||
style.WindowMinSize.x = minWinSizeX;
|
||||
ImGuiDockNode* node = (ImGuiDockNode*)GImGui->DockContext.Nodes.GetVoidPtr(ImGui::GetID("SceneEditorDockSpace"));
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 64);
|
||||
if(ImGui::DockNodeBeginAmendTabBar(node))
|
||||
{
|
||||
ImGui::SetNextItemWidth(48);
|
||||
if (ImGui::BeginTabItem("##logoPadding", 0, ImGuiTabItemFlags_Leading))
|
||||
{
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::DockNodeEndAmendTabBar();
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowClass(&top_level_class);
|
||||
ImGui::Begin("SceneEditor");
|
||||
{
|
||||
ImGuiWindowClass inside_document_class;
|
||||
inside_document_class.ClassId = ImHashStr("SceneEditor1");
|
||||
ImGui::DockSpace(ImGui::GetID("SceneEditorWindowDockspace"), ImGui::GetContentRegionAvail(), ImGuiDockNodeFlags_None, &inside_document_class);
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
ImGui::End();
|
||||
//DrawMenuBar();
|
||||
//DrawMenuBars();
|
||||
@@ -2721,6 +2782,12 @@ namespace Nuake {
|
||||
{
|
||||
prefabEditors->Draw();
|
||||
}
|
||||
|
||||
for (auto& sceneEditor : sceneEditors)
|
||||
{
|
||||
sceneEditor->Draw();
|
||||
}
|
||||
|
||||
//pInterface.DrawEntitySettings();
|
||||
DrawViewport();
|
||||
DrawSceneTree();
|
||||
@@ -2813,6 +2880,7 @@ namespace Nuake {
|
||||
{
|
||||
std::string entityTypeName = "";
|
||||
|
||||
|
||||
if (entity.HasComponent<LightComponent>())
|
||||
{
|
||||
entityTypeName = "Light";
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <src/Scripting/ScriptingEngineNet.h>
|
||||
#include "ProjectSettings/ProjectSettingsWindow.h"
|
||||
#include "PrefabEditor/PrefabEditorWindow.h"
|
||||
#include "../../SceneEditorWindow.h"
|
||||
|
||||
|
||||
using namespace NuakeEditor;
|
||||
@@ -28,6 +29,7 @@ namespace Nuake
|
||||
class Material;
|
||||
class FileSystemUI;
|
||||
class VulkanImage;
|
||||
class DebugCmd;
|
||||
|
||||
class EditorInterface
|
||||
{
|
||||
@@ -35,6 +37,8 @@ namespace Nuake
|
||||
bool m_TitleBarHovered = false;
|
||||
std::vector<CompilationError> errors;
|
||||
std::vector<Ref<PrefabEditorWindow>> prefabEditors;
|
||||
std::vector<Ref<SceneEditorWindow>> sceneEditors;
|
||||
|
||||
Ref<Scene> SceneSnapshot;
|
||||
static NuakeEditor::CommandBuffer* mCommandBuffer;
|
||||
|
||||
@@ -103,7 +107,7 @@ namespace Nuake
|
||||
void EndMenubar();
|
||||
|
||||
void OnSceneLoaded(Ref<Scene> scene);
|
||||
void OnDebugDraw();
|
||||
void OnDebugDraw(Nuake::DebugCmd& cmd);
|
||||
|
||||
void SetStatusMessage(const std::string& msg, const Color& color = Color(0.08f, 0.08f, 0.08f, 1.0f)) { m_StatusMessage = msg; m_StatusBarColor = color; }
|
||||
void DrawViewport();
|
||||
@@ -116,6 +120,8 @@ namespace Nuake
|
||||
void Overlay();
|
||||
|
||||
void OpenPrefabWindow(const std::string& prefabPath);
|
||||
void OpenSceneWindow(const std::string& scenePath);
|
||||
|
||||
bool ShouldDrawAxis() const { return m_DrawAxis; }
|
||||
bool ShouldDrawShapes() const { return m_DrawShapes; }
|
||||
bool ShouldDrawGizmos() const { return m_DrawGizmos; }
|
||||
|
||||
26
Nuake/src/Rendering/Vulkan/DebugCmd.cpp
Normal file
26
Nuake/src/Rendering/Vulkan/DebugCmd.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include "DebugCmd.h"
|
||||
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
DebugCmd::DebugCmd(Cmd& inCmd) :
|
||||
cmd(inCmd)
|
||||
{
|
||||
}
|
||||
|
||||
void DebugCmd::DrawLine(const Vector3& start, const Vector3& end, const Color& color) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DebugCmd::DrawSphere(const Vector2& position, float radius, const Color& color) const
|
||||
{
|
||||
}
|
||||
|
||||
void DebugCmd::DrawCube(const Vector3& position, const Vector3& size, const Color& color) const
|
||||
{
|
||||
}
|
||||
|
||||
void DebugCmd::DrawAABB(const Vector3& min, const Vector3& max, const Color& color) const
|
||||
{
|
||||
}
|
||||
23
Nuake/src/Rendering/Vulkan/DebugCmd.h
Normal file
23
Nuake/src/Rendering/Vulkan/DebugCmd.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "Cmd.h"
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
// This is the API to render anything debugging related
|
||||
// Like lines, shapes, gizmos, etc.
|
||||
class DebugCmd
|
||||
{
|
||||
private:
|
||||
Cmd& cmd;
|
||||
|
||||
public:
|
||||
DebugCmd(Cmd& inCmd);
|
||||
~DebugCmd() = default;
|
||||
|
||||
public:
|
||||
void DrawLine(const Vector3& start, const Vector3& end, const Color& color) const;
|
||||
void DrawSphere(const Vector2& position, float radius, const Color& color) const;
|
||||
void DrawCube(const Vector3& position, const Vector3& size, const Color& color) const;
|
||||
void DrawAABB(const Vector3& min, const Vector3& max, const Color& color) const;
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "src/Scene/Components/ModelComponent.h"
|
||||
|
||||
#include <Tracy.hpp>
|
||||
#include "DebugCmd.h"
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
@@ -280,8 +281,8 @@ void SceneRenderPipeline::Render(PassRenderContext& ctx)
|
||||
GBufferPipeline.Execute(ctx, pipelineInputs);
|
||||
|
||||
// Debug drawing
|
||||
// Get delegate
|
||||
OnDebugDraw().Broadcast();
|
||||
DebugCmd debugCmd = DebugCmd(ctx.commandBuffer);
|
||||
OnDebugDraw().Broadcast(debugCmd);
|
||||
}
|
||||
|
||||
Ref<VulkanImage> SceneRenderPipeline::ResizeImage(Ref<VulkanImage> image, const Vector2& size)
|
||||
|
||||
@@ -62,6 +62,8 @@ namespace Nuake
|
||||
int BlurDirection;
|
||||
};
|
||||
|
||||
class DebugCmd;
|
||||
|
||||
// This class handles all the rendering of the scene
|
||||
class SceneRenderPipeline
|
||||
{
|
||||
@@ -98,7 +100,7 @@ namespace Nuake
|
||||
static RenderPipeline GBufferPipeline;
|
||||
|
||||
// Delegates
|
||||
MulticastDelegate<> DebugDrawDelegate;
|
||||
MulticastDelegate<DebugCmd&> DebugDrawDelegate;
|
||||
|
||||
public:
|
||||
SceneRenderPipeline();
|
||||
@@ -108,7 +110,7 @@ namespace Nuake
|
||||
void Render(PassRenderContext& ctx);
|
||||
Ref<VulkanImage> GetOutput() { return TonemappedOutput; }
|
||||
|
||||
MulticastDelegate<>& OnDebugDraw() { return DebugDrawDelegate; }
|
||||
MulticastDelegate<DebugCmd&>& OnDebugDraw() { return DebugDrawDelegate; }
|
||||
|
||||
private:
|
||||
Ref<VulkanImage> ResizeImage(Ref<VulkanImage> image, const Vector2& size);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_internal.h"
|
||||
#include "../../../Editor/src/Misc/InterfaceFonts.h"
|
||||
|
||||
#include "imgui/imgui_stdlib.h"
|
||||
#include "src/Resource/FontAwesome5.h"
|
||||
#include "src/Rendering/Textures/Texture.h"
|
||||
#include <src/Rendering/Vulkan/VulkanImage/VulkanImage.h>
|
||||
|
||||
Reference in New Issue
Block a user