add imgui & set main viewport
This commit is contained in:
parent
6c7dc30711
commit
1bbddd1c7d
2
engine/3rdparty/xmake.lua
vendored
2
engine/3rdparty/xmake.lua
vendored
@ -1,6 +1,6 @@
|
|||||||
add_requires("spdlog", "vulkansdk","shaderc","spirv","spirv-cross","stb")
|
add_requires("spdlog", "vulkansdk","shaderc","spirv","spirv-cross","stb")
|
||||||
add_requires("mimalloc", {configs = {shared = true, debug = true, copy = true}})
|
add_requires("mimalloc", {configs = {shared = true, debug = true, copy = true}})
|
||||||
--add_requires("imgui",{configs = {shared = true, debug = true, copy = true}})
|
add_requires("imgui",{configs = {shared = true, debug = true, copy = true}})
|
||||||
add_requires("noesis",{configs = {shared = true, copy = true}})
|
add_requires("noesis",{configs = {shared = true, copy = true}})
|
||||||
add_requires("libsdl",{configs = {shared = true}})
|
add_requires("libsdl",{configs = {shared = true}})
|
||||||
includes("*/xmake.lua")
|
includes("*/xmake.lua")
|
||||||
50
engine/include/editor/editor_system.h
Normal file
50
engine/include/editor/editor_system.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "render/graph/frame_graph.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
namespace api {
|
||||||
|
class EditorSystem;
|
||||||
|
struct RenderEditorContext {
|
||||||
|
EditorSystem* editor;
|
||||||
|
uint32_t frame;
|
||||||
|
uint32_t frameCount;
|
||||||
|
EditorSystem* operator->() {
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class EditorPanel {
|
||||||
|
public:
|
||||||
|
EditorPanel() = default;
|
||||||
|
~EditorPanel() = default;
|
||||||
|
virtual void DrawPanel(FrameGraph& graph, RenderEditorContext& ctx) = 0;
|
||||||
|
};
|
||||||
|
class EditorWindow {
|
||||||
|
protected:
|
||||||
|
std::vector<EditorPanel*> mPanels;
|
||||||
|
public:
|
||||||
|
EditorWindow() = default;
|
||||||
|
~EditorWindow() = default;
|
||||||
|
virtual void Draw(FrameGraph& graph, RenderEditorContext& ctx) = 0;
|
||||||
|
template<typename T, typename ... Args>
|
||||||
|
T* AddPanel(Args&&... args) {
|
||||||
|
T* ptr = new (GlobalPool()) T(std::forward<Args>(args)...);
|
||||||
|
mPanels.push_back(ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class EDITOR_API EditorSystem : public ISystem
|
||||||
|
{
|
||||||
|
SINGLETON_IMPL(EditorSystem)
|
||||||
|
protected:
|
||||||
|
std::vector<EditorWindow*> mWindows;
|
||||||
|
public:
|
||||||
|
EditorSystem();
|
||||||
|
template<typename T, typename ... Args>
|
||||||
|
T* AddWindow(Args&&... args) {
|
||||||
|
T* ptr = new (GlobalPool()) T(std::forward<Args>(args)...);
|
||||||
|
mWindows.push_back(ptr);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
ImTextureID AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler sampler);
|
||||||
|
virtual ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
namespace api {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "render/editor_system.h"
|
|
||||||
namespace api {
|
|
||||||
class MenuBarPanel : public EditorPanel {
|
|
||||||
public:
|
|
||||||
void DrawPanel(FrameGraph& graph, RenderEditorContext& context) override;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,10 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "editor/editor_system.h"
|
||||||
#include "ui/ui_window.h"
|
#include "ui/ui_window.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
class EditorMainWindow : public UIWindow {
|
class EditorMainUIWindow : public UIWindow {
|
||||||
public:
|
public:
|
||||||
using UIWindow::UIWindow;
|
using UIWindow::UIWindow;
|
||||||
void InitializeComponent() override;
|
void InitializeComponent() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
class EditorMainWindow : public EditorWindow {
|
||||||
|
public:
|
||||||
|
Noesis::Ptr<Noesis::IView> mView;
|
||||||
|
public:
|
||||||
|
EditorMainWindow();
|
||||||
|
void Draw(FrameGraph& graph, RenderEditorContext& ctx) override;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ namespace api {
|
|||||||
table<TextureSampler, void*> mTextureSamplerPool;
|
table<TextureSampler, void*> mTextureSamplerPool;
|
||||||
table<Tag, uint32_t> mTextureTagMap;
|
table<Tag, uint32_t> mTextureTagMap;
|
||||||
table<TextureKey, std::vector<TextureID>> mTextureKeyMap;//一张图不够用了
|
table<TextureKey, std::vector<TextureID>> mTextureKeyMap;//一张图不够用了
|
||||||
std::vector<TextureDesc> mTexturePool;
|
pmr::vector<TextureDesc> mTexturePool{GlobalPool()};
|
||||||
table<TextureViewKey, ImageViewPtr> mTextureViewPool;
|
table<TextureViewKey, ImageViewPtr> mTextureViewPool;
|
||||||
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
|
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
|
||||||
RenderPassNode* mFirstInputNode{ nullptr };
|
RenderPassNode* mFirstInputNode{ nullptr };
|
||||||
|
|||||||
@ -56,7 +56,7 @@ namespace api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (outputNodes.size() > 1) {
|
if (outputNodes.size() > 1) {
|
||||||
std::sort(outputNodes.begin(), outputNodes.end(), [](RenderPassNode* a, RenderPassNode* b) {
|
std::sort(outputNodes.begin(), outputNodes.end(), [](const RenderPassNode* a, const RenderPassNode* b) {
|
||||||
if (a->type != b->type) {
|
if (a->type != b->type) {
|
||||||
return a->type < b->type;
|
return a->type < b->type;
|
||||||
}
|
}
|
||||||
@ -105,6 +105,12 @@ namespace api {
|
|||||||
result.clear();
|
result.clear();
|
||||||
seenNodes.clear();
|
seenNodes.clear();
|
||||||
}
|
}
|
||||||
|
std::sort(mNodes.begin(), mNodes.end(), [](const FrameGraphNodePtr& a, const FrameGraphNodePtr& b) {
|
||||||
|
if (a->type != b->type) {
|
||||||
|
return a->type < b->type;
|
||||||
|
}
|
||||||
|
return a < b;
|
||||||
|
});
|
||||||
if (mLastOutputNode) {
|
if (mLastOutputNode) {
|
||||||
mFirstInputNode->flag |= RenderPassNodeFlag::FirstInput;
|
mFirstInputNode->flag |= RenderPassNodeFlag::FirstInput;
|
||||||
mLastOutputNode->flag |= RenderPassNodeFlag::LastOutput;
|
mLastOutputNode->flag |= RenderPassNodeFlag::LastOutput;
|
||||||
|
|||||||
@ -43,7 +43,8 @@ namespace api {
|
|||||||
void UIRenderDevice::UpdateTexture(Noesis::Texture* texture, uint32_t level, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
|
void UIRenderDevice::UpdateTexture(Noesis::Texture* texture, uint32_t level, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data)
|
||||||
{
|
{
|
||||||
UITexture* uiTex = (UITexture*)texture;
|
UITexture* uiTex = (UITexture*)texture;
|
||||||
|
TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .data = data};
|
||||||
|
mApi->UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST);
|
||||||
}
|
}
|
||||||
void UIRenderDevice::BeginOffscreenRender()
|
void UIRenderDevice::BeginOffscreenRender()
|
||||||
{
|
{
|
||||||
|
|||||||
1206
engine/modules/engine/ui/include/imgui/imgui_impl_sdl2.cpp
Normal file
1206
engine/modules/engine/ui/include/imgui/imgui_impl_sdl2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
50
engine/modules/engine/ui/include/imgui/imgui_impl_sdl2.h
Normal file
50
engine/modules/engine/ui/include/imgui/imgui_impl_sdl2.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// dear imgui: Platform Backend for SDL2
|
||||||
|
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||||
|
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Clipboard support.
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
|
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
|
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
// Issues:
|
||||||
|
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||||
|
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
|
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct SDL_Window;
|
||||||
|
struct SDL_Renderer;
|
||||||
|
struct _SDL_GameController;
|
||||||
|
typedef union SDL_Event SDL_Event;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOther(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||||
|
|
||||||
|
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||||
|
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||||
|
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
@ -3,3 +3,7 @@ static_component("ui","engine")
|
|||||||
add_files("src/**.cpp")
|
add_files("src/**.cpp")
|
||||||
add_deps("core", "asset", "zlib", "render")
|
add_deps("core", "asset", "zlib", "render")
|
||||||
add_packages("noesis", "stb", {public = true})
|
add_packages("noesis", "stb", {public = true})
|
||||||
|
if WITH_EDITOR then
|
||||||
|
add_files("include/imgui/*.cpp")
|
||||||
|
add_packages("imgui", {public = true})
|
||||||
|
end
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "editor/editor_system.h"
|
||||||
|
#include "render/graph/frame_graph.h"
|
||||||
|
#include "vkn/vulkan_api.h"
|
||||||
|
namespace vkn {
|
||||||
|
using api::FrameGraph;
|
||||||
|
using api::RenderPassContext;
|
||||||
|
using api::RenderPassBuilder;
|
||||||
|
using api::RenderEditorContext;
|
||||||
|
class VulkanImguiEditor : public api::EditorSystem {
|
||||||
|
public:
|
||||||
|
void Initialize() override;
|
||||||
|
void Finalize() override;
|
||||||
|
|
||||||
|
ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) override;
|
||||||
|
|
||||||
|
void Render(FrameGraph& graph, RenderEditorContext& ctx);
|
||||||
|
void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame);
|
||||||
|
static VulkanImguiEditor* Ptr() {
|
||||||
|
return (VulkanImguiEditor*)api::EditorSystem::Ptr();
|
||||||
|
};
|
||||||
|
static void Setup(FrameGraph& graph, RenderPassBuilder& builder);
|
||||||
|
static void Execute(FrameGraph&, RenderPassContext&);
|
||||||
|
};
|
||||||
|
}
|
||||||
1960
engine/modules/render/vulkan/src/imgui/imgui_impl_vulkan.cpp
Normal file
1960
engine/modules/render/vulkan/src/imgui/imgui_impl_vulkan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
engine/modules/render/vulkan/src/imgui/imgui_impl_vulkan.h
Normal file
211
engine/modules/render/vulkan/src/imgui/imgui_impl_vulkan.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
// dear imgui: Renderer Backend for Vulkan
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||||
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
|
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||||
|
|
||||||
|
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||||
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
|
||||||
|
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
|
||||||
|
// You will use those if you want to use this rendering backend in your engine/app.
|
||||||
|
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
|
||||||
|
// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
|
||||||
|
// Read comments in imgui_impl_vulkan.h.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
|
||||||
|
// [Configuration] in order to use a custom Vulkan function loader:
|
||||||
|
// (1) You'll need to disable default Vulkan function prototypes.
|
||||||
|
// We provide a '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' convenience configuration flag.
|
||||||
|
// In order to make sure this is visible from the imgui_impl_vulkan.cpp compilation unit:
|
||||||
|
// - Add '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' in your imconfig.h file
|
||||||
|
// - Or as a compilation flag in your build system
|
||||||
|
// - Or uncomment here (not recommended because you'd be modifying imgui sources!)
|
||||||
|
// - Do not simply add it in a .cpp file!
|
||||||
|
// (2) Call ImGui_ImplVulkan_LoadFunctions() before ImGui_ImplVulkan_Init() with your custom function.
|
||||||
|
// If you have no idea what this is, leave it alone!
|
||||||
|
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||||
|
|
||||||
|
// Convenience support for Volk
|
||||||
|
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
|
||||||
|
//#define IMGUI_IMPL_VULKAN_USE_VOLK
|
||||||
|
|
||||||
|
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||||
|
#define VK_NO_PROTOTYPES
|
||||||
|
#endif
|
||||||
|
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||||
|
#define NOMINMAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Vulkan includes
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||||
|
#include <volk.h>
|
||||||
|
#else
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#endif
|
||||||
|
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||||
|
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||||
|
// [Please zero-clear before use!]
|
||||||
|
// - About descriptor pool:
|
||||||
|
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||||
|
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
|
||||||
|
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||||
|
// - Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||||
|
// - It is expected that as early as Q1 2025 the backend will use a few more descriptors, so aim at 10 + number of desierd calls to ImGui_ImplVulkan_AddTexture().
|
||||||
|
// - About dynamic rendering:
|
||||||
|
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||||
|
struct ImGui_ImplVulkan_InitInfo
|
||||||
|
{
|
||||||
|
VkInstance Instance;
|
||||||
|
VkPhysicalDevice PhysicalDevice;
|
||||||
|
VkDevice Device;
|
||||||
|
uint32_t QueueFamily;
|
||||||
|
VkQueue Queue;
|
||||||
|
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||||
|
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||||
|
uint32_t MinImageCount; // >= 2
|
||||||
|
uint32_t ImageCount; // >= MinImageCount
|
||||||
|
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||||
|
|
||||||
|
// (Optional)
|
||||||
|
VkPipelineCache PipelineCache;
|
||||||
|
uint32_t Subpass;
|
||||||
|
|
||||||
|
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||||
|
uint32_t DescriptorPoolSize;
|
||||||
|
|
||||||
|
// (Optional) Dynamic Rendering
|
||||||
|
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||||
|
bool UseDynamicRendering;
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
|
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// (Optional) Allocation, Debugging
|
||||||
|
const VkAllocationCallbacks* Allocator;
|
||||||
|
void (*CheckVkResultFn)(VkResult err);
|
||||||
|
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||||
|
|
||||||
|
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||||
|
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||||
|
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||||
|
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||||
|
|
||||||
|
// Optional: load Vulkan functions with a custom function loader
|
||||||
|
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplVulkan_RenderState
|
||||||
|
{
|
||||||
|
VkCommandBuffer CommandBuffer;
|
||||||
|
VkPipeline Pipeline;
|
||||||
|
VkPipelineLayout PipelineLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Internal / Miscellaneous Vulkan Helpers
|
||||||
|
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// You probably do NOT need to use or care about those functions.
|
||||||
|
// Those functions only exist because:
|
||||||
|
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||||
|
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||||
|
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||||
|
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||||
|
//
|
||||||
|
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||||
|
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||||
|
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct ImGui_ImplVulkanH_Frame;
|
||||||
|
struct ImGui_ImplVulkanH_Window;
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
||||||
|
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||||
|
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||||
|
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||||
|
|
||||||
|
// Helper structure to hold the data needed by one rendering frame
|
||||||
|
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||||
|
// [Please zero-clear before use!]
|
||||||
|
struct ImGui_ImplVulkanH_Frame
|
||||||
|
{
|
||||||
|
VkCommandPool CommandPool;
|
||||||
|
VkCommandBuffer CommandBuffer;
|
||||||
|
VkFence Fence;
|
||||||
|
VkImage Backbuffer;
|
||||||
|
VkImageView BackbufferView;
|
||||||
|
VkFramebuffer Framebuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImGui_ImplVulkanH_FrameSemaphores
|
||||||
|
{
|
||||||
|
VkSemaphore ImageAcquiredSemaphore;
|
||||||
|
VkSemaphore RenderCompleteSemaphore;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper structure to hold the data needed by one rendering context into one OS window
|
||||||
|
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||||
|
struct ImGui_ImplVulkanH_Window
|
||||||
|
{
|
||||||
|
int Width;
|
||||||
|
int Height;
|
||||||
|
VkSwapchainKHR Swapchain;
|
||||||
|
VkSurfaceKHR Surface;
|
||||||
|
VkSurfaceFormatKHR SurfaceFormat;
|
||||||
|
VkPresentModeKHR PresentMode;
|
||||||
|
VkRenderPass RenderPass;
|
||||||
|
bool UseDynamicRendering;
|
||||||
|
bool ClearEnable;
|
||||||
|
VkClearValue ClearValue;
|
||||||
|
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||||
|
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||||
|
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||||
|
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||||
|
ImGui_ImplVulkanH_Frame* Frames;
|
||||||
|
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||||
|
|
||||||
|
ImGui_ImplVulkanH_Window()
|
||||||
|
{
|
||||||
|
memset((void*)this, 0, sizeof(*this));
|
||||||
|
PresentMode = (VkPresentModeKHR)~0; // Ensure we get an error if user doesn't set this.
|
||||||
|
ClearEnable = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
168
engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp
Normal file
168
engine/modules/render/vulkan/src/vulkan_imgui_editor.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#include "vkn/vulkan_imgui_editor.h"
|
||||||
|
#include "vkn/vulkan_window.h"
|
||||||
|
#include "vkn/vulkan_api_help.h"
|
||||||
|
#include "vkn/backend.h"
|
||||||
|
#include "vkn/wrapper/device.h"
|
||||||
|
#include "vkn/wrapper/instance.h"
|
||||||
|
#include "vkn/wrapper/queue.h"
|
||||||
|
#include "imgui/imgui_impl_vulkan.h"
|
||||||
|
#include "imgui/imgui_impl_sdl2.h"
|
||||||
|
#include "data/global.h"
|
||||||
|
#include "event/event_system.h"
|
||||||
|
#include "tinyimageformat/tinyimageformat_apis.h"
|
||||||
|
namespace vkn {
|
||||||
|
using namespace api;
|
||||||
|
static Name ImguiPassName{"ImguiPass"};
|
||||||
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
|
// Vulkan的ImGui接入比较麻烦,参考教程: https://frguthmann.github.io/posts/vulkan_imgui/
|
||||||
|
VkDescriptorPool CreateDescriptorPool(VkDevice device) {
|
||||||
|
VkDescriptorPoolSize pool_sizes[] =
|
||||||
|
{
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
||||||
|
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 }
|
||||||
|
};
|
||||||
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
|
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
|
||||||
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||||
|
pool_info.pPoolSizes = pool_sizes;
|
||||||
|
VkDescriptorPool descriptorPool;
|
||||||
|
vkCreateDescriptorPool(device, &pool_info, VK_NULL_HANDLE, &descriptorPool);
|
||||||
|
return descriptorPool;
|
||||||
|
}
|
||||||
|
VkRenderPass CreateRenderPass(TinyImageFormat format, VkDevice device) {
|
||||||
|
VkAttachmentDescription colorAttachment = {};
|
||||||
|
colorAttachment.format = (VkFormat)TinyImageFormat_ToVkFormat(format);
|
||||||
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
|
VkAttachmentReference colorAttachmentRef = {};
|
||||||
|
colorAttachmentRef.attachment = 0;
|
||||||
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpass = {};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
|
|
||||||
|
VkSubpassDependency dependency = {};
|
||||||
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||||
|
dependency.dstSubpass = 0;
|
||||||
|
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo info = {};
|
||||||
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
info.attachmentCount = 1;
|
||||||
|
info.pAttachments = &colorAttachment;
|
||||||
|
info.subpassCount = 1;
|
||||||
|
info.pSubpasses = &subpass;
|
||||||
|
info.dependencyCount = 1;
|
||||||
|
info.pDependencies = &dependency;
|
||||||
|
VkRenderPass renderPass;
|
||||||
|
if (vkCreateRenderPass(device, &info, VK_NULL_HANDLE, &renderPass) != VK_SUCCESS)
|
||||||
|
throw std::runtime_error("Could not create Dear ImGui's render pass");
|
||||||
|
return renderPass;
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::Initialize()
|
||||||
|
{
|
||||||
|
VulkanAPI* API = VulkanAPI::Ptr();
|
||||||
|
VulkanWindow* window = VulkanWindow::Ptr();
|
||||||
|
Backend& backend = API->GetBackend();
|
||||||
|
Queue* pQueue = backend.GetDevice().GetQueue(Queue::RenderQueue);
|
||||||
|
VkDescriptorPool descriptorPool = CreateDescriptorPool(backend.GetDevice().Ptr());
|
||||||
|
TextureDesc surface = API->context.surface;
|
||||||
|
VkRenderPass renderPass = CreateRenderPass(surface.format, backend.GetDevice().Ptr());
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||||
|
init_info.Instance = backend.GetInstance().Ptr();
|
||||||
|
init_info.PhysicalDevice = backend.GetDevice().GetPhysical();
|
||||||
|
init_info.Device = backend.GetDevice().Ptr();
|
||||||
|
init_info.QueueFamily = pQueue->QueueFamilyIndex();
|
||||||
|
init_info.Queue = pQueue->Ptr();
|
||||||
|
init_info.DescriptorPool = descriptorPool;
|
||||||
|
init_info.MinImageCount = 2;
|
||||||
|
init_info.ImageCount = API->context.frameCount;
|
||||||
|
init_info.RenderPass = renderPass;
|
||||||
|
init_info.PipelineCache = VK_NULL_HANDLE;
|
||||||
|
init_info.Subpass = 0;
|
||||||
|
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
init_info.Allocator = VK_NULL_HANDLE;
|
||||||
|
ImGui_ImplVulkan_Init(&init_info);
|
||||||
|
API->SetRenderPassInfo(ImguiPassName, renderPass);
|
||||||
|
EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanImguiEditor::OnBeginRenderFrame, this);
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::Finalize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ImTextureID VulkanImguiEditor::AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state)
|
||||||
|
{
|
||||||
|
VkDescriptorSet descriptorSet = ImGui_ImplVulkan_AddTexture((VkSampler)sampler, (VkImageView)imageview, vkApiGetImageLayout(state));
|
||||||
|
return reinterpret_cast<ImTextureID>(descriptorSet);
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::Render(FrameGraph& graph, RenderEditorContext& ctx)
|
||||||
|
{
|
||||||
|
for (auto win : mWindows)
|
||||||
|
{
|
||||||
|
win->Draw(graph, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame)
|
||||||
|
{
|
||||||
|
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
||||||
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
|
graph.mEditorSurfaceID = graph.mSurfaceID;
|
||||||
|
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
||||||
|
}
|
||||||
|
graph.AddRenderPass<VulkanImguiEditor>();
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
||||||
|
{
|
||||||
|
builder.Name(ImguiPassName)
|
||||||
|
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
||||||
|
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT);
|
||||||
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
|
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context)
|
||||||
|
{
|
||||||
|
graph.GetRenderSurface().state = ResourceState::PRESENT;
|
||||||
|
ImGui_ImplVulkan_NewFrame();
|
||||||
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
VulkanImguiEditor* editor = VulkanImguiEditor::Ptr();
|
||||||
|
RenderEditorContext editorContext{.editor = editor, .frame = context->frame, .frameCount = context->frameCount };
|
||||||
|
editor->Render(graph, editorContext);
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
VulkanContext& ctx = *(VulkanContext*)context.parent;
|
||||||
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), ctx.command);
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
// 更新并渲染平台窗口
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
|
{
|
||||||
|
ImGui::UpdatePlatformWindows();
|
||||||
|
ImGui::RenderPlatformWindowsDefault(nullptr, ctx.command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,10 +2,17 @@
|
|||||||
#include "vkn/vulkan_module.h"
|
#include "vkn/vulkan_module.h"
|
||||||
#include "vkn/loader/vulkan_glsl_loader.h"
|
#include "vkn/loader/vulkan_glsl_loader.h"
|
||||||
#include "pmr/frame_allocator.h"
|
#include "pmr/frame_allocator.h"
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
#include "vkn/vulkan_imgui_editor.h"
|
||||||
|
#endif // WITH_EDITOR
|
||||||
using namespace vkn;
|
using namespace vkn;
|
||||||
void VulkanModule::OnLoad(int argc, char** argv)
|
void VulkanModule::OnLoad(int argc, char** argv)
|
||||||
{
|
{
|
||||||
VulkanGlslLoader::Init();
|
VulkanGlslLoader::Init();
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
AddSystem<VulkanImguiEditor>();
|
||||||
|
#endif // WITH_EDITOR
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanModule::OnUnload()
|
void VulkanModule::OnUnload()
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
shared_module("vulkan","engine")
|
shared_module("vulkan","engine")
|
||||||
add_headerfiles("include/**.h")
|
add_headerfiles("include/**.h")
|
||||||
add_files("src/**.cpp", "include/volk/volk.c")
|
|
||||||
add_packages("vulkansdk", {public = true})
|
add_packages("vulkansdk", {public = true})
|
||||||
add_dependency("engine", {public = true})
|
add_dependency("engine", {public = true})
|
||||||
|
if WITH_EDITOR then
|
||||||
|
add_deps("editor")
|
||||||
|
add_headerfiles("src/imgui/*.h")
|
||||||
|
add_files("src/**.cpp", "include/volk/volk.c")
|
||||||
|
else
|
||||||
|
add_files("src/**.cpp|imgui/*|vulkan_imgui_editor.cpp", "include/volk/volk.c")
|
||||||
|
end
|
||||||
on_load(function (target)
|
on_load(function (target)
|
||||||
if is_plat("windows") then
|
if is_plat("windows") then
|
||||||
target:add("defines", "VK_USE_PLATFORM_WIN32_KHR=1")
|
target:add("defines", "VK_USE_PLATFORM_WIN32_KHR=1")
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
#include "editor/editor.h"
|
#include "editor/editor.h"
|
||||||
#include "editor/window/editor_main_window.h"
|
#include "editor/window/editor_main_window.h"
|
||||||
#include "ui/ui_render_device.h"
|
|
||||||
#include "event/event_system.h"
|
|
||||||
#include "os/file_manager.h"
|
#include "os/file_manager.h"
|
||||||
#include <NoesisPCH.h>
|
#include "imgui.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
using namespace Noesis;
|
|
||||||
Ptr<IView> mView;
|
|
||||||
void EditorModule::OnLoad(int argc, char** argv)
|
void EditorModule::OnLoad(int argc, char** argv)
|
||||||
{
|
{
|
||||||
PackagePath editor_noesis{"/engine/assets/noesis"};
|
PackagePath editor_noesis{"/engine/assets/noesis"};
|
||||||
FileManager::Ptr()->Mount("editor_noesis", editor_noesis.RealPath().c_str());
|
FileManager::Ptr()->Mount("editor_noesis", editor_noesis.RealPath().c_str());
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // 可选:启用键盘导航
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // 可选:启用Docking
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // 可选:启用多视口
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorModule::OnUnload()
|
void EditorModule::OnUnload()
|
||||||
@ -18,17 +21,7 @@ namespace api {
|
|||||||
}
|
}
|
||||||
void EditorModule::Initialize(void)
|
void EditorModule::Initialize(void)
|
||||||
{
|
{
|
||||||
Ptr<FrameworkElement> xaml = GUI::LoadXaml<FrameworkElement>("/editor_noesis/Menu.xaml");
|
EditorSystem* Editor = EditorSystem::Ptr();
|
||||||
mView = GUI::CreateView(xaml);
|
Editor->AddWindow<EditorMainWindow>();
|
||||||
mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD);
|
|
||||||
mView->SetSize(1024, 768);
|
|
||||||
//mView->GetRenderer()->Init(UIRenderDevice::Ptr());
|
|
||||||
EventSystem::Ptr()->BeginRenderFrame.Subscribe(mInfo.name, [](FrameGraph& graph, int32_t frame) {
|
|
||||||
//mView->Update(0.033);
|
|
||||||
//IRenderer* renderer = mView->GetRenderer();
|
|
||||||
//renderer->UpdateRenderTree();
|
|
||||||
//renderer->RenderOffscreen();
|
|
||||||
//renderer->Render();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
engine/src/editor/editor_system.cpp
Normal file
14
engine/src/editor/editor_system.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "editor/editor_system.h"
|
||||||
|
namespace api {
|
||||||
|
SINGLETON_DEFINE(EditorSystem)
|
||||||
|
EditorSystem::EditorSystem()
|
||||||
|
{
|
||||||
|
SINGLETON_PTR();
|
||||||
|
}
|
||||||
|
ImTextureID EditorSystem::AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler key)
|
||||||
|
{
|
||||||
|
ImageViewPtr imageview = graph.ResolveTextureView(desc);
|
||||||
|
SamplerPtr sampler = graph.ResolveTextureSampler(key);
|
||||||
|
return AddTexture(imageview, sampler, desc.state);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,88 @@
|
|||||||
#include "editor/window/editor_main_window.h"
|
#include "editor/window/editor_main_window.h"
|
||||||
|
#include "ui/ui_render_device.h"
|
||||||
|
#include "event/event_system.h"
|
||||||
|
#include "data/global.h"
|
||||||
|
#include <NoesisPCH.h>
|
||||||
namespace api {
|
namespace api {
|
||||||
void EditorMainWindow::InitializeComponent()
|
using namespace Noesis;
|
||||||
|
void EditorMainUIWindow::InitializeComponent()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
int j = 1;
|
int j = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EditorMainWindow::EditorMainWindow()
|
||||||
|
{
|
||||||
|
Ptr<FrameworkElement> xaml = GUI::LoadXaml<FrameworkElement>("/editor_noesis/Menu.xaml");
|
||||||
|
mView = GUI::CreateView(xaml);
|
||||||
|
mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD);
|
||||||
|
mView->SetSize(1024, 768);
|
||||||
|
mView->GetRenderer()->Init(UIRenderDevice::Ptr());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
TextureSampler sampler{
|
||||||
|
.filterMag = SamplerMagFilter::LINEAR,
|
||||||
|
.filterMin = SamplerMinFilter::LINEAR,
|
||||||
|
.wrapS = SamplerWrapMode::CLAMP_TO_EDGE,
|
||||||
|
.wrapT = SamplerWrapMode::CLAMP_TO_EDGE,
|
||||||
|
.wrapR = SamplerWrapMode::CLAMP_TO_EDGE,
|
||||||
|
.compareMode = SamplerCompareMode::COMPARE_TO_TEXTURE,
|
||||||
|
.compareFunc = SamplerCompareFunc::GE,
|
||||||
|
};
|
||||||
|
ImTextureID TextureIDList[10] = {};
|
||||||
|
void InitRenderSurface(FrameGraph& graph, uint32_t frameCount) {
|
||||||
|
static bool sInit = false;
|
||||||
|
if (sInit)
|
||||||
|
return;
|
||||||
|
sInit = true;
|
||||||
|
TextureDesc desc{};
|
||||||
|
desc.width = 512;
|
||||||
|
desc.height = 512;
|
||||||
|
desc.format = TinyImageFormat_B8G8R8A8_SRGB;
|
||||||
|
desc.state = ResourceState::UNDEFINED;
|
||||||
|
desc.sampleCount = SampleCount::SAMPLE_COUNT_1;
|
||||||
|
desc.arraySize = 1;
|
||||||
|
desc.mipLevel = 1;
|
||||||
|
desc.depth = 1;
|
||||||
|
desc.dimension = TextureDimension::TEX_2D;
|
||||||
|
desc.usage = TextureUsage::COLOR_ATTACHMENT | TextureUsage::SAMPLEABLE;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < frameCount; i++) {
|
||||||
|
graph.SetResourceTexture(desc, FrameGraph::NameEditorSurface, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void EditorMainWindow::Draw(FrameGraph& graph, RenderEditorContext& ctx)
|
||||||
|
{
|
||||||
|
static float my_float = 0.5f;
|
||||||
|
TextureDesc renderSurface = graph.GetRenderSurface();
|
||||||
|
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
|
// 设置窗口的大小为屏幕的分辨率
|
||||||
|
ImGui::SetNextWindowSize(ImVec2(renderSurface.width, renderSurface.height));
|
||||||
|
// 设置窗口位置为左上角
|
||||||
|
ImGui::SetNextWindowPos(viewport->Pos);
|
||||||
|
|
||||||
|
ImGui::Begin("MainWindow", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||||
|
ImGui::Text("This is some useful text.");
|
||||||
|
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
||||||
|
if (gEngineConfig.IsRenderEditorSurface) {
|
||||||
|
TextureDesc surface = graph.GetSurface();
|
||||||
|
if (!TextureIDList[ctx.frame]) {
|
||||||
|
TextureIDList[ctx.frame] = ctx->AddTexture(graph, surface, sampler);
|
||||||
|
}
|
||||||
|
// 每帧渲染时都可以通过 ImTextureID 使用
|
||||||
|
ImGui::Image(TextureIDList[ctx.frame], ImVec2(surface.width, surface.height));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gEngineConfig.IsRenderEditorSurface = true;
|
||||||
|
InitRenderSurface(graph, ctx.frameCount);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
//mView->Update(0.033);
|
||||||
|
//IRenderer* renderer = mView->GetRenderer();
|
||||||
|
//renderer->UpdateRenderTree();
|
||||||
|
//renderer->RenderOffscreen();
|
||||||
|
//renderer->Render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -3,15 +3,18 @@
|
|||||||
#include "ui/ui_render_device.h"
|
#include "ui/ui_render_device.h"
|
||||||
#include "xmalloc_new_delete.h"
|
#include "xmalloc_new_delete.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
class ENGINE_API EngineModule : public api::IDynamicModule
|
class ENGINE_API EngineModule : public IDynamicModule
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void OnLoad(int argc, char** argv) override {
|
void OnLoad(int argc, char** argv) override {
|
||||||
#ifdef ENGINE_ROOT
|
#ifdef ENGINE_ROOT
|
||||||
api::FileManager::Ptr()->Mount("engine", TOSTRING(ENGINE_ROOT));
|
api::FileManager::Ptr()->Mount("engine", TOSTRING(ENGINE_ROOT));
|
||||||
#endif
|
#endif
|
||||||
new UIRenderDevice(RenderAPI::Ptr());
|
|
||||||
};
|
};
|
||||||
|
void Initialize() override {
|
||||||
|
IDynamicModule::Initialize();
|
||||||
|
new UIRenderDevice(RenderAPI::Ptr());
|
||||||
|
}
|
||||||
void OnUnload() override {
|
void OnUnload() override {
|
||||||
};
|
};
|
||||||
void InitMetaData(void) override {
|
void InitMetaData(void) override {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ target("engine")
|
|||||||
set_group("Engine")
|
set_group("Engine")
|
||||||
add_rules("engine.api")
|
add_rules("engine.api")
|
||||||
add_files("src/engine/**.cpp")
|
add_files("src/engine/**.cpp")
|
||||||
add_packages("noesis")
|
|
||||||
target("editor")
|
target("editor")
|
||||||
set_kind("shared")
|
set_kind("shared")
|
||||||
set_group("Engine")
|
set_group("Engine")
|
||||||
|
|||||||
@ -10,8 +10,19 @@ Size=191,71
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][MainWindow]
|
[Window][MainWindow]
|
||||||
Pos=163,77
|
Pos=0,0
|
||||||
Size=695,351
|
Size=1080,720
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][ChildWindow]
|
||||||
|
ViewportPos=0,0
|
||||||
|
ViewportId=0x4CE55A22
|
||||||
|
Size=1080,720
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Debug]
|
||||||
|
Pos=101,134
|
||||||
|
Size=545,504
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
|
|||||||
@ -5,6 +5,9 @@
|
|||||||
#include "vkn/vulkan_window.h"
|
#include "vkn/vulkan_window.h"
|
||||||
#include "vkn/vulkan_api.h"
|
#include "vkn/vulkan_api.h"
|
||||||
#include "render/pass/demo_pass.h"
|
#include "render/pass/demo_pass.h"
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
#include "imgui/imgui_impl_sdl2.h"
|
||||||
|
#endif
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace api;
|
using namespace api;
|
||||||
RenderAPI* API;
|
RenderAPI* API;
|
||||||
@ -20,6 +23,9 @@ void ZWorldModule::OnLoad(int argc, char** argv)
|
|||||||
window->CreateRender(args);
|
window->CreateRender(args);
|
||||||
API->Init();
|
API->Init();
|
||||||
API->context.views.push_back({});
|
API->context.views.push_back({});
|
||||||
|
#ifdef WITH_EDITOR //绑定窗口交互
|
||||||
|
ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void ZWorldModule::InitMetaData()
|
void ZWorldModule::InitMetaData()
|
||||||
{
|
{
|
||||||
@ -47,6 +53,9 @@ void ZWorldModule::MainLoop()
|
|||||||
while (running) {
|
while (running) {
|
||||||
// 处理事件
|
// 处理事件
|
||||||
while (SDL_PollEvent(&event_)) {
|
while (SDL_PollEvent(&event_)) {
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
ImGui_ImplSDL2_ProcessEvent(&event_);
|
||||||
|
#endif // WITH_EDITOR
|
||||||
if (event_.type == SDL_QUIT) {
|
if (event_.type == SDL_QUIT) {
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user