如何缩放类似于 Imgui 的图元?

How to scale primitives similar to Imgui?

我希望我的渲染器的行为类似于 imgui。 无论 imgui 应用程序有多大,imgui 小部件 window 大小都不会改变。

这就是 imgui 在分辨率为 1280x720 时的样子

enter image description here

这就是分辨率为 1920x1017 时的样子

enter image description here

基元的大小始终相同

在我的应用程序中调整一个window导致不同的边是不同的厚度或不愉快的现象。

我的应用未填充矩形 1280x720

enter image description here

我的应用程序相同的矩形 1920x1017

enter image description here

如您所见,在这种情况下,更高的分辨率会导致未填充矩形的底部与另一侧的厚度不同(照片中可能不会显示,但在屏幕中会显示,这很烦人).

imgui 没有遇到这个问题。我的应用程序渲染器几乎相同(没有几个高级选项)。

我该如何实现?为什么它会这样工作? 我问过 imgui 的创建者,但他告诉我这与 imgui 无关,他也无能为力。

总的来说,不管怎样,您绘制的任何图元最终都会出现在剪辑 space 中,然后归一化设备坐标。您可以将一些矩阵变换应用于输入位置或诸如此类的东西,但根据定义,顶点着色器输出 clip-space 坐标。然后将这些剪辑space 坐标投影到规范化的设备坐标。

在标准化设备坐标 (NDC) 中,您的视口(您的 "screen")在 x 和 y 方向上从 -1 延伸到 1(因此 "normalized")。 NDC 与您的视口相关。这意味着,如果您指定基元的顶点,使其在 NDC 中的位置 (-0.5, 0.25) 处结束,则意味着它将沿 x 方向为屏幕全宽的 1/4,沿 y 方向为 5/8:

如果您想将基元放置在视口内的特定像素位置,则必须计算它们的坐标,以便它们最终位于相应的 NDC 坐标处。例如,假设您有一个 800×600 的视口,并且您想要在像素坐标 (50, 40) 处放置一个顶点。在这种情况下,您希望顶点坐标最终成为

x_NDC = 2 * (50 + 0.5) / 800 - 1
y_NDC = 2 * (40 + 0.5) / 600 - 1

+ 0.5 是为了说明 OpenGL 中的样本位置位于像素网格的中心:

一般来说,要在近平面的像素坐标 (x, y) 处放置一个顶点,您希望顶点着色器 return 坐标

x_clip = 2.0f * (x + 0.5f) / W - 1
y_clip = 2.0f * (y + 0.5f) / H - 1
z_clip = 0
w_clip = 1

其中 WH 是视口的宽度和高度,假设像素坐标的原点是左下角。