Skip to content

Commit

Permalink
ImGui: fixed framebuffer scaling issues on MacOS
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Jun 10, 2023
1 parent e2b3d90 commit 7a820e0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 35 deletions.
4 changes: 2 additions & 2 deletions Imgui/interface/ImGuiImplMacOS.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ namespace Diligent
class ImGuiImplMacOS final : public ImGuiImplDiligent
{
public:
static std::unique_ptr<ImGuiImplMacOS> Create(const ImGuiDiligentCreateInfo& CI);
static std::unique_ptr<ImGuiImplMacOS> Create(const ImGuiDiligentCreateInfo& CI, void* _Nullable view);

ImGuiImplMacOS(const ImGuiDiligentCreateInfo& CI);
ImGuiImplMacOS(const ImGuiDiligentCreateInfo& CI, void* _Nullable view);
~ImGuiImplMacOS();

// clang-format off
Expand Down
28 changes: 16 additions & 12 deletions Imgui/src/ImGuiDiligentRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ float4 ImGuiDiligentRenderer::TransformClipRect(const ImVec2& DisplaySize, const
void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDrawData)
{
// Avoid rendering when minimized
if (pDrawData->DisplaySize.x <= 0.0f || pDrawData->DisplaySize.y <= 0.0f)
if (pDrawData->DisplaySize.x <= 0.0f || pDrawData->DisplaySize.y <= 0.0f || pDrawData->CmdListsCount == 0)
return;

// Create and grow vertex/index buffers if needed
Expand Down Expand Up @@ -907,15 +907,13 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
pCtx->SetBlendFactors(blend_factor);

Viewport vp;
vp.Width = static_cast<float>(m_RenderSurfaceWidth) * pDrawData->FramebufferScale.x;
vp.Height = static_cast<float>(m_RenderSurfaceHeight) * pDrawData->FramebufferScale.y;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = static_cast<float>(m_RenderSurfaceWidth);
vp.Height = static_cast<float>(m_RenderSurfaceHeight);
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0;
pCtx->SetViewports(1,
&vp,
static_cast<Uint32>(m_RenderSurfaceWidth * pDrawData->FramebufferScale.x),
static_cast<Uint32>(m_RenderSurfaceHeight * pDrawData->FramebufferScale.y));
pCtx->SetViewports(1, &vp, m_RenderSurfaceWidth, m_RenderSurfaceHeight);
};

SetupRenderState();
Expand Down Expand Up @@ -943,6 +941,9 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
}
else
{
if (pCmd->ElemCount == 0)
continue;

// Apply scissor/clipping rectangle
float4 ClipRect //
{
Expand All @@ -961,10 +962,13 @@ void ImGuiDiligentRenderer::RenderDrawData(IDeviceContext* pCtx, ImDrawData* pDr
static_cast<Int32>(ClipRect.z),
static_cast<Int32>(ClipRect.w) //
};
pCtx->SetScissorRects(1,
&Scissor,
static_cast<Uint32>(m_RenderSurfaceWidth * pDrawData->FramebufferScale.x),
static_cast<Uint32>(m_RenderSurfaceHeight * pDrawData->FramebufferScale.y));
Scissor.left = std::max(Scissor.left, 0);
Scissor.top = std::max(Scissor.top, 0);
Scissor.right = std::min(Scissor.right, static_cast<Int32>(m_RenderSurfaceWidth));
Scissor.bottom = std::min(Scissor.bottom, static_cast<Int32>(m_RenderSurfaceHeight));
if (!Scissor.IsValid())
continue;
pCtx->SetScissorRects(1, &Scissor, m_RenderSurfaceWidth, m_RenderSurfaceHeight);

// Bind texture
auto* pTextureView = reinterpret_cast<ITextureView*>(pCmd->TextureId);
Expand Down
21 changes: 11 additions & 10 deletions Imgui/src/ImGuiImplMacOS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,20 @@
namespace Diligent
{

std::unique_ptr<ImGuiImplMacOS> ImGuiImplMacOS::Create(const ImGuiDiligentCreateInfo& CI)
std::unique_ptr<ImGuiImplMacOS> ImGuiImplMacOS::Create(const ImGuiDiligentCreateInfo& CI, void* _Nullable view)
{
return std::make_unique<ImGuiImplMacOS>(CI);
return std::make_unique<ImGuiImplMacOS>(CI, view);
}

ImGuiImplMacOS::ImGuiImplMacOS(const ImGuiDiligentCreateInfo& CI) :
ImGuiImplMacOS::ImGuiImplMacOS(const ImGuiDiligentCreateInfo& CI, void* _Nullable view) :
ImGuiImplDiligent{CI}
{
ImGui_ImplOSX_Init();
ImGuiIO& io = ImGui::GetIO();
io.FontGlobalScale = 2;
io.BackendPlatformName = "Diligent-ImGuiImplMacOS";

const auto framebufferScale = ((NSView*)view).window.screen.backingScaleFactor ?: NSScreen.mainScreen.backingScaleFactor;;
io.DisplayFramebufferScale = ImVec2(framebufferScale, framebufferScale);
}

ImGuiImplMacOS::~ImGuiImplMacOS()
Expand All @@ -54,7 +56,7 @@
{
std::lock_guard<std::mutex> Lock(m_Mtx);
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2(RenderSurfaceWidth, RenderSurfaceHeight);
io.DisplaySize = ImVec2(RenderSurfaceWidth / io.DisplayFramebufferScale.x, RenderSurfaceHeight / io.DisplayFramebufferScale.y);
ImGui_ImplOSX_NewFrame(nil);
ImGuiImplDiligent::NewFrame(RenderSurfaceWidth, RenderSurfaceHeight, SurfacePreTransform);
}
Expand All @@ -65,11 +67,10 @@
ImGuiIO& io = ImGui::GetIO();
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged)
{
NSRect viewRectPoints = [view bounds];
NSRect viewRectPixels = [view convertRectToBacking:viewRectPoints];
NSPoint curPoint = [view convertPoint:[event locationInWindow] fromView:nil];
curPoint = [view convertPointToBacking:curPoint];
io.MousePos = ImVec2(curPoint.x, viewRectPixels.size.height-1 - curPoint.y);
NSRect viewRectPoints = [view bounds];
NSPoint curPoint = [view convertPoint:[event locationInWindow] fromView:nil];
io.MousePos.x = curPoint.x;
io.MousePos.y = viewRectPoints.size.height-1 - curPoint.y;
return io.WantCaptureMouse;
}

Expand Down
13 changes: 2 additions & 11 deletions ThirdParty/imgui_v1.85/imgui_impl_osx_v1.85.mm
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
@class ImFocusObserver;

// Data
static double g_HostClockPeriod = 0.0;
static double g_Time = 0.0;
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
static bool g_MouseCursorHidden = false;
Expand All @@ -55,16 +54,9 @@ + (id)_windowResizeNorthSouthCursor;
+ (id)_windowResizeEastWestCursor;
@end

static void InitHostClockPeriod()
static CFTimeInterval GetMachAbsoluteTimeInSeconds()
{
struct mach_timebase_info info;
mach_timebase_info(&info);
g_HostClockPeriod = 1e-9 * ((double)info.denom / (double)info.numer); // Period is the reciprocal of frequency.
}

static double GetMachAbsoluteTimeInSeconds()
{
return (double)mach_absolute_time() * g_HostClockPeriod;
return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9);;
}

static void resetKeys()
Expand Down Expand Up @@ -248,7 +240,6 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
// Setup time step
if (g_Time == 0.0)
{
InitHostClockPeriod();
g_Time = GetMachAbsoluteTimeInSeconds();
}
double current_time = GetMachAbsoluteTimeInSeconds();
Expand Down

0 comments on commit 7a820e0

Please sign in to comment.