Fix ImGui sometimes not respecting the viewport resolution in-Editor
ImguiAtomSystemComponent isn't guaranteed to initialize before ImGuiManager, which caused some issues. Additionally, because we allow the user to configure ImGui's render resolution, I've refactored the window size override into a new OverrideRenderWindowSize API in ImGuiManager to decouple it from the target render resolution.
This commit is contained in:
@@ -59,14 +59,8 @@ namespace AZ
|
||||
const AZ::Name contextName = atomViewportRequests->GetDefaultViewportContextName();
|
||||
AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(contextName);
|
||||
|
||||
#if defined(IMGUI_ENABLED)
|
||||
ImGui::ImGuiManagerListenerBus::Broadcast(&ImGui::IImGuiManagerListener::SetResolutionMode, ImGui::ImGuiResolutionMode::LockToResolution);
|
||||
auto defaultViewportContext = atomViewportRequests->GetDefaultViewportContext();
|
||||
if (defaultViewportContext)
|
||||
{
|
||||
OnViewportSizeChanged(defaultViewportContext->GetViewportSize());
|
||||
}
|
||||
#endif
|
||||
m_initialized = false;
|
||||
InitializeViewportSizeIfNeeded();
|
||||
}
|
||||
|
||||
void ImguiAtomSystemComponent::Deactivate()
|
||||
@@ -75,6 +69,23 @@ namespace AZ
|
||||
AZ::RPI::ViewportContextNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ImguiAtomSystemComponent::InitializeViewportSizeIfNeeded()
|
||||
{
|
||||
#if defined(IMGUI_ENABLED)
|
||||
if (m_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
auto defaultViewportContext = atomViewportRequests->GetDefaultViewportContext();
|
||||
if (defaultViewportContext)
|
||||
{
|
||||
// If this succeeds, m_initialized will be set to true.
|
||||
OnViewportSizeChanged(defaultViewportContext->GetViewportSize());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImguiAtomSystemComponent::RenderImGuiBuffers(const ImDrawData& drawData)
|
||||
{
|
||||
Render::ImGuiSystemRequestBus::Broadcast(&Render::ImGuiSystemRequests::RenderImGuiBuffersToCurrentViewport, drawData);
|
||||
@@ -83,6 +94,7 @@ namespace AZ
|
||||
void ImguiAtomSystemComponent::OnRenderTick()
|
||||
{
|
||||
#if defined(IMGUI_ENABLED)
|
||||
InitializeViewportSizeIfNeeded();
|
||||
ImGui::ImGuiManagerListenerBus::Broadcast(&ImGui::IImGuiManagerListener::Render);
|
||||
#endif
|
||||
}
|
||||
@@ -90,7 +102,17 @@ namespace AZ
|
||||
void ImguiAtomSystemComponent::OnViewportSizeChanged(AzFramework::WindowSize size)
|
||||
{
|
||||
#if defined(IMGUI_ENABLED)
|
||||
ImGui::ImGuiManagerListenerBus::Broadcast(&ImGui::IImGuiManagerListener::SetImGuiRenderResolution, ImVec2{aznumeric_cast<float>(size.m_width), aznumeric_cast<float>(size.m_height)});
|
||||
ImGui::ImGuiManagerListenerBus::Broadcast([this, size](ImGui::ImGuiManagerListenerBus::Events* imgui)
|
||||
{
|
||||
imgui->OverrideRenderWindowSize(size.m_width, size.m_height);
|
||||
// ImGuiManagerListenerBus may not have been connected when this system component is activated
|
||||
// as ImGuiManager is not part of a system component we can require and instead just listens for ESYSTEM_EVENT_GAME_POST_INIT.
|
||||
// Let our ImguiAtomSystemComponent know once we successfully connect and update the viewport size.
|
||||
if (!m_initialized)
|
||||
{
|
||||
m_initialized = true;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace AZ
|
||||
void Deactivate() override;
|
||||
|
||||
private:
|
||||
void InitializeViewportSizeIfNeeded();
|
||||
|
||||
// OtherActiveImGuiRequestBus overrides ...
|
||||
void RenderImGuiBuffers(const ImDrawData& drawData) override;
|
||||
@@ -57,6 +58,7 @@ namespace AZ
|
||||
void OnViewportSizeChanged(AzFramework::WindowSize size) override;
|
||||
|
||||
DebugConsole m_debugConsole;
|
||||
bool m_initialized = false;
|
||||
};
|
||||
} // namespace LYIntegration
|
||||
} // namespace AZ
|
||||
|
||||
@@ -90,6 +90,8 @@ namespace ImGui
|
||||
virtual void SetResolutionMode(ImGuiResolutionMode state) = 0;
|
||||
virtual const ImVec2& GetImGuiRenderResolution() const = 0;
|
||||
virtual void SetImGuiRenderResolution(const ImVec2& res) = 0;
|
||||
virtual void OverrideRenderWindowSize(uint32_t width, uint32_t height) = 0;
|
||||
virtual void RestoreRenderWindowSizeToDefault() = 0;
|
||||
virtual void Render() = 0;
|
||||
};
|
||||
typedef AZ::EBus<IImGuiManagerListener> ImGuiManagerListenerBus;
|
||||
|
||||
@@ -262,6 +262,21 @@ void ImGuiManager::Shutdown()
|
||||
ImGui::DestroyContext(m_imguiContext);
|
||||
}
|
||||
|
||||
void ImGui::ImGuiManager::OverrideRenderWindowSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
m_windowSize.m_width = width;
|
||||
m_windowSize.m_height = height;
|
||||
m_overridingWindowSize = true;
|
||||
// Don't listen for window updates if our window size is being overridden
|
||||
AzFramework::WindowNotificationBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void ImGui::ImGuiManager::RestoreRenderWindowSizeToDefault()
|
||||
{
|
||||
m_overridingWindowSize = false;
|
||||
InitWindowSize();
|
||||
}
|
||||
|
||||
void ImGuiManager::Render()
|
||||
{
|
||||
if (m_clientMenuBarState == DisplayState::Hidden && m_editorWindowState == DisplayState::Hidden)
|
||||
@@ -757,7 +772,7 @@ void ImGuiManager::InitWindowSize()
|
||||
{
|
||||
// We only need to initialize the window size by querying the window the first time.
|
||||
// After that we will get OnWindowResize notifications
|
||||
if (!AzFramework::WindowNotificationBus::Handler::BusIsConnected())
|
||||
if (!m_overridingWindowSize && !AzFramework::WindowNotificationBus::Handler::BusIsConnected())
|
||||
{
|
||||
AzFramework::NativeWindowHandle windowHandle = nullptr;
|
||||
AzFramework::WindowSystemRequestBus::BroadcastResult(windowHandle, &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
|
||||
|
||||
@@ -60,6 +60,8 @@ namespace ImGui
|
||||
void SetResolutionMode(ImGuiResolutionMode mode) override { m_resolutionMode = mode; }
|
||||
const ImVec2& GetImGuiRenderResolution() const override { return m_renderResolution; }
|
||||
void SetImGuiRenderResolution(const ImVec2& res) override { m_renderResolution = res; }
|
||||
void OverrideRenderWindowSize(uint32_t width, uint32_t height) override;
|
||||
void RestoreRenderWindowSizeToDefault() override;
|
||||
void Render() override;
|
||||
// -- ImGuiManagerListenerBus Interface -------------------------------------------------------------------
|
||||
|
||||
@@ -89,6 +91,7 @@ namespace ImGui
|
||||
ImVec2 m_renderResolution = ImVec2(1920.0f, 1080.0f);
|
||||
ImVec2 m_lastRenderResolution;
|
||||
AzFramework::WindowSize m_windowSize = AzFramework::WindowSize(1920, 1080);
|
||||
bool m_overridingWindowSize = false;
|
||||
|
||||
// Rendering buffers
|
||||
std::vector<SVF_P3F_C4B_T2F> m_vertBuffer;
|
||||
|
||||
Reference in New Issue
Block a user