【问题标题】:OpenGL and Windows 10 per-monitor aware DPI scalingOpenGL 和 Windows 10 每显示器感知 DPI 缩放
【发布时间】:2017-11-01 06:52:44
【问题描述】:

当应用程序支持 DPI 监视器时,在 OpenGL 应用程序中处理 DPI 缩放的正确方法是什么。又名:

SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);

我在不同的设备上发现了不同的行为 - 可能与驱动程序有关,但有些机器需要像这样设置视口:

glViewport(0, 0, prc->right, prc->bottom)

而其他人需要这样的东西:

glViewport(0, 0, (int)(prc->right * 96 / dpi), (int)(prc->bottom * 96 / dpi));

(其中 prc 是客户端矩形,dpi 是窗口的当前 DPI)。

我已经整理了一个 simple demo program 来显示问题。问题发生在更改系统缩放之后,但在注销/重新登录之前。

问题包括:

  1. 以错误的比例渲染(不确定哪个驱动程序错误)
  2. 垂直移动取决于更改缩放之前与更改缩放之后标题栏高度的差异。 (在 macbook pro/bootcamp 上)

我尝试在 WM_DPICHANGED 上拆除并重新创建 wgl 上下文,但无济于事,不知道还能尝试什么。


更新:我已经更新了示例程序存储库以包含我所看到的屏幕截图,并且我已经包含了测试程序的 .exe。

请看这里:https://bitbucket.org/toptensoftware/minimalopengl/overview


更新 2 - 找到了一个可以按预期工作的 GPU Radeon RX460。更新了 repo 中的屏幕截图以显示预期内容。


更新 3 - 我现在相当有信心这是由 NVidia 和 Intel 驱动程序的问题引起的,并且已经记录了两者的错误。我猜 WHQL 合规性不包括 OpenGL 驱动程序。

仍然...如果有适当的文档或来自 Microsoft 的示例程序,说明 OpenGL 和每个显示器的 DPI 支持应该如何工作,那就太好了。

【问题讨论】:

  • 你从哪里得到prc->rightprc->bottom
  • 如前所述,它是窗口的客户端矩形(即:GetClientRect)。有关详细信息,请参阅参考的演示程序。

标签: opengl windows-10 dpi


【解决方案1】:

在 gtx 1050 上也有同样的问题。我注意到这个问题只出现在 SetThreadDpiAwarenessContext 函数中。

来自 msdn:

SetThreadDpiAwarenessContext 函数。 将当前线程的 DPI 感知设置为提供的值。

这意味着如果驱动程序创建一个或多个额外的线程来渲染 OpenGL,每个线程将具有不同的 dpi 感知级别。

所以有三种解决方案:

  1. 使用 Windows 8.1 中的旧 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) 函数并在 WM_NCCREATE 消息中调用 EnableNonClientDpiScaling(hWnd);
  2. 使用来自 Creators Update 的新 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
  3. 在应用程序清单中设置 dpi 感知级别(将应用于整个应用程序)。

这两个功能都设置了整个过程的意识级别。

【讨论】:

  • 使用 SetProcessDpiAwareness 代替 SetThreadDpiAwarenessContext https://imgur.com/wX2Gm2N的示例屏幕
  • 是的,我知道这与每个监视器线程 dpi 意识有关。这就是问题的重点——我需要用户对每个监视器的意识。
  • 您可以为整个应用程序设置每个监视器的感知,然后在不需要它的线程中调用 SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE)(或在主线程中调用 CreateWindowW 之后立即调用)
  • 不使用每个监视器的感知不是答案。这个练习的重点是更好地支持多显示器和动态变化的 DPI。我需要使用每个监视器的感知,因为一些 Windows 托管旧插件 UI(由第三方编写)并且需要正确缩放(即:插件窗口不知道,我的窗口知道)。此外,每个显示器的感知让我的窗口在不同分辨率的显示器之间移动时呈现更好的体验(即:无模糊)。
猜你喜欢
  • 2018-04-11
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 2016-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多