From 4a95a79926715528bf4ca7466d5b382c0aa00c6f Mon Sep 17 00:00:00 2001 From: Gary Talent <gary@drinkingtea.net> Date: Sat, 11 Mar 2023 18:45:35 -0600 Subject: [PATCH] [nostalgia/scene] ACTUALLY add Scene Studio module --- src/nostalgia/scene/studio/CMakeLists.txt | 25 ++++++++ src/nostalgia/scene/studio/module.cpp | 32 ++++++++++ src/nostalgia/scene/studio/module.hpp | 17 ++++++ .../scene/studio/sceneeditor-imgui.cpp | 59 +++++++++++++++++++ .../scene/studio/sceneeditor-imgui.hpp | 43 ++++++++++++++ src/nostalgia/scene/studio/sceneeditor.cpp | 15 +++++ src/nostalgia/scene/studio/sceneeditor.hpp | 33 +++++++++++ .../scene/studio/sceneeditorview.cpp | 37 ++++++++++++ .../scene/studio/sceneeditorview.hpp | 33 +++++++++++ 9 files changed, 294 insertions(+) create mode 100644 src/nostalgia/scene/studio/CMakeLists.txt create mode 100644 src/nostalgia/scene/studio/module.cpp create mode 100644 src/nostalgia/scene/studio/module.hpp create mode 100644 src/nostalgia/scene/studio/sceneeditor-imgui.cpp create mode 100644 src/nostalgia/scene/studio/sceneeditor-imgui.hpp create mode 100644 src/nostalgia/scene/studio/sceneeditor.cpp create mode 100644 src/nostalgia/scene/studio/sceneeditor.hpp create mode 100644 src/nostalgia/scene/studio/sceneeditorview.cpp create mode 100644 src/nostalgia/scene/studio/sceneeditorview.hpp diff --git a/src/nostalgia/scene/studio/CMakeLists.txt b/src/nostalgia/scene/studio/CMakeLists.txt new file mode 100644 index 00000000..1aa7d323 --- /dev/null +++ b/src/nostalgia/scene/studio/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library( + NostalgiaScene-Studio OBJECT + module.cpp + sceneeditor-imgui.cpp + sceneeditor.cpp + sceneeditorview.cpp +) + +if(NOT MSVC) + target_compile_options(NostalgiaScene-Studio PRIVATE -Wsign-conversion) +endif() + +target_link_libraries( + NostalgiaScene-Studio PUBLIC + NostalgiaGlUtils + NostalgiaStudio + NostalgiaScene +) + +install( + TARGETS + NostalgiaScene-Studio + LIBRARY DESTINATION + ${NOSTALGIA_DIST_MODULE} +) diff --git a/src/nostalgia/scene/studio/module.cpp b/src/nostalgia/scene/studio/module.cpp new file mode 100644 index 00000000..6a794aca --- /dev/null +++ b/src/nostalgia/scene/studio/module.cpp @@ -0,0 +1,32 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#include <ox/std/memory.hpp> + +#include "sceneeditor-imgui.hpp" +#include "module.hpp" + +namespace nostalgia::scene { + +ox::Vector<studio::EditorMaker> StudioModule::editors(core::Context *ctx) noexcept { + return { + { + {"nscn"}, + [ctx](ox::CRStringView path) -> ox::Result<studio::BaseEditor*> { + try { + return ox::make<SceneEditorImGui>(ctx, path); + } catch (const ox::Exception &ex) { + return ex.toError(); + } + } + }, + }; +} + +ox::Vector<ox::UPtr<studio::ItemMaker>> StudioModule::itemMakers(core::Context*) noexcept { + ox::Vector<ox::UPtr<studio::ItemMaker>> out; + return out; +} + +} diff --git a/src/nostalgia/scene/studio/module.hpp b/src/nostalgia/scene/studio/module.hpp new file mode 100644 index 00000000..bd0b14a5 --- /dev/null +++ b/src/nostalgia/scene/studio/module.hpp @@ -0,0 +1,17 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include <nostalgia/studio/studio.hpp> + +namespace nostalgia::scene { + +class StudioModule: public studio::Module { + public: + ox::Vector<studio::EditorMaker> editors(core::Context *ctx) noexcept override; + ox::Vector<ox::UPtr<studio::ItemMaker>> itemMakers(core::Context*) noexcept override; +}; + +} diff --git a/src/nostalgia/scene/studio/sceneeditor-imgui.cpp b/src/nostalgia/scene/studio/sceneeditor-imgui.cpp new file mode 100644 index 00000000..fb4e205f --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditor-imgui.cpp @@ -0,0 +1,59 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#include <imgui.h> + +#include <nostalgia/core/gfx.hpp> +#include <nostalgia/foundation/media.hpp> +#include <ox/std/memory.hpp> + +#include "sceneeditor-imgui.hpp" + +namespace nostalgia::scene { + +SceneEditorImGui::SceneEditorImGui(core::Context *ctx, ox::CRStringView path): + m_editor(ctx, path), + m_view(ctx, m_editor.scene()) { + m_ctx = ctx; + m_itemPath = path; + const auto lastSlash = std::find(m_itemPath.rbegin(), m_itemPath.rend(), '/').offset(); + m_itemName = m_itemPath.substr(lastSlash + 1); + setRequiresConstantRefresh(false); +} + +ox::CRString SceneEditorImGui::itemName() const noexcept { + return m_itemPath; +} + +ox::CRString SceneEditorImGui::itemDisplayName() const noexcept { + return m_itemName; +} + +void SceneEditorImGui::draw(core::Context*) noexcept { + const auto paneSize = ImGui::GetContentRegionAvail(); + const geo::Size fbSize{ + static_cast<int>(paneSize.x), + static_cast<int>(paneSize.y)}; + m_view.draw(fbSize.width, fbSize.height); + auto &fb = m_view.framebuffer(); + const uintptr_t buffId = fb.color.id; + ImGui::Image( + reinterpret_cast<void*>(buffId), + paneSize, + ImVec2(0, 1), + ImVec2(1, 0)); +} + +void SceneEditorImGui::onActivated() noexcept { + m_view.setupScene(); +} + +ox::Error SceneEditorImGui::saveItem() noexcept { + const auto sctx = applicationData<studio::StudioContext>(m_ctx); + oxReturnError(sctx->project->writeObj(m_itemPath, &m_editor.scene())); + oxReturnError(m_ctx->assetManager.setAsset(m_itemPath, m_editor.scene())); + return {}; +} + +} diff --git a/src/nostalgia/scene/studio/sceneeditor-imgui.hpp b/src/nostalgia/scene/studio/sceneeditor-imgui.hpp new file mode 100644 index 00000000..8fb2c817 --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditor-imgui.hpp @@ -0,0 +1,43 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include <nostalgia/core/gfx.hpp> +#include <nostalgia/studio/studio.hpp> + +#include "sceneeditor.hpp" +#include "sceneeditorview.hpp" + +namespace nostalgia::scene { + +class SceneEditorImGui: public studio::Editor { + + private: + core::Context *m_ctx = nullptr; + ox::String m_itemName; + ox::String m_itemPath; + SceneEditor m_editor; + SceneEditorView m_view; + + public: + SceneEditorImGui(core::Context *ctx, ox::CRStringView path); + + /** + * Returns the name of item being edited. + */ + ox::CRString itemName() const noexcept final; + + ox::CRString itemDisplayName() const noexcept final; + + void draw(core::Context*) noexcept final; + + void onActivated() noexcept override; + + protected: + ox::Error saveItem() noexcept final; + +}; + +} diff --git a/src/nostalgia/scene/studio/sceneeditor.cpp b/src/nostalgia/scene/studio/sceneeditor.cpp new file mode 100644 index 00000000..b5a28bf4 --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditor.cpp @@ -0,0 +1,15 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#include "sceneeditor.hpp" + +namespace nostalgia::scene { + +SceneEditor::SceneEditor(core::Context *ctx, ox::CRStringView path) { + m_ctx = ctx; + oxRequireT(scn, foundation::readObj<SceneStatic>(m_ctx, path)); + m_scene = *scn; +} + +} diff --git a/src/nostalgia/scene/studio/sceneeditor.hpp b/src/nostalgia/scene/studio/sceneeditor.hpp new file mode 100644 index 00000000..8ee29c59 --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditor.hpp @@ -0,0 +1,33 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include <nostalgia/core/gfx.hpp> +#include <nostalgia/studio/studio.hpp> +#include <nostalgia/scene/scene.hpp> + +namespace nostalgia::scene { + +class SceneEditor { + + private: + core::Context *m_ctx = nullptr; + ox::String m_itemName; + ox::String m_itemPath; + SceneStatic m_scene; + + public: + SceneEditor(core::Context *ctx, ox::CRStringView path); + + const SceneStatic &scene() noexcept { + return m_scene; + } + + protected: + ox::Error saveItem() noexcept; + +}; + +} diff --git a/src/nostalgia/scene/studio/sceneeditorview.cpp b/src/nostalgia/scene/studio/sceneeditorview.cpp new file mode 100644 index 00000000..bea6b23e --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditorview.cpp @@ -0,0 +1,37 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#include "sceneeditorview.hpp" + +namespace nostalgia::scene { + +SceneEditorView::SceneEditorView(core::Context *ctx, const SceneStatic &sceneStatic) noexcept: + m_ctx(*ctx), + m_sceneStatic(sceneStatic), + m_scene(m_sceneStatic) { +} + +void SceneEditorView::setupScene() noexcept { + oxIgnoreError(m_scene.setupDisplay(&m_ctx)); +} + +void SceneEditorView::draw(int width, int height) noexcept { + if (width != m_frameBuffer.width || height != m_frameBuffer.height) { + glutils::resizeInitFrameBuffer(&m_frameBuffer, width, height); + core::gl::setRenderSize(&m_ctx, width, height); + oxIgnoreError(m_scene.setupDisplay(&m_ctx)); + } + glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer); + glViewport(0, 0, m_frameBuffer.width, m_frameBuffer.height); + // draw begin + core::gl::drawMainView(&m_ctx); + // draw end + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +const glutils::FrameBuffer &SceneEditorView::framebuffer() const noexcept { + return m_frameBuffer; +} + +} diff --git a/src/nostalgia/scene/studio/sceneeditorview.hpp b/src/nostalgia/scene/studio/sceneeditorview.hpp new file mode 100644 index 00000000..a3072d95 --- /dev/null +++ b/src/nostalgia/scene/studio/sceneeditorview.hpp @@ -0,0 +1,33 @@ +/* + * Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved. + */ + +#pragma once + +#include <nostalgia/core/gfx.hpp> +#include <nostalgia/glutils/glutils.hpp> +#include <nostalgia/scene/scene.hpp> + +namespace nostalgia::scene { + +class SceneEditorView { + + private: + core::Context &m_ctx; + const SceneStatic &m_sceneStatic; + Scene m_scene; + glutils::FrameBuffer m_frameBuffer; + + public: + SceneEditorView(core::Context *ctx, const SceneStatic &sceneStatic) noexcept; + + void setupScene() noexcept; + + void draw(int width, int height) noexcept; + + [[nodiscard]] + const glutils::FrameBuffer &framebuffer() const noexcept; + +}; + +}