长宽比 - 如何处理它们? (D3D 视口设置)
好吧——看来我的问题和我的头脑一样模糊。 让我们再试一次。
在为 D3D 设备配置视口时,我有 3 个属性: - 设备运行时的分辨率(全屏)。 - 显示器的物理纵横比(分数和浮点数:1,例如 4:3 和 1.33)。 - 源分辨率的宽高比(源分辨率本身没有任何意义,它只告诉我们渲染所需的宽高比以及最适合运行的分辨率类型)。
然后我们遇到这个:
// -- figure out aspect ratio adjusted VPs --
m_nativeVP.Width = xRes;
m_nativeVP.Height = yRes;
m_nativeVP.X = 0;
m_nativeVP.Y = 0;
m_nativeVP.MaxZ = 1.f;
m_nativeVP.MinZ = 0.f;
FIX_ME // this does not cover all bases -- fix!
uint xResAdj, yResAdj;
if (g_displayAspectRatio.Get() < g_renderAspectRatio.Get())
{
xResAdj = xRes;
yResAdj = (uint) ((float) xRes / g_renderAspectRatio.Get());
}
else if (g_displayAspectRatio.Get() > g_renderAspectRatio.Get())
{
xResAdj = (uint) ((float) yRes * g_renderAspectRatio.Get());
yResAdj = yRes;
}
else // ==
{
xResAdj = xRes;
yResAdj = yRes;
}
m_fullVP.Width = xResAdj;
m_fullVP.Height = yResAdj;
m_fullVP.X = (xRes - xResAdj) >> 1;
m_fullVP.Y = (yRes - yResAdj) >> 1;
m_fullVP.MaxZ = 1.f;
m_fullVP.MinZ = 0.f;
现在只要 g_displayAspectRatio 等于 xRes/yRes 的比率(= 根据设备分辨率调整),一切都很好,并且此代码将执行预期的操作。 但是一旦这两个值不再相关(例如,有人在 16:10 的屏幕上运行 4:3 的分辨率,硬件拉伸),就需要另一个步骤来补偿,而且我很难弄清楚到底如何。
(ps我在原子类型上使用C风格的转换,接受它:-))
Allright - seems my question was as cloudy as my head. Lets try again.
I have 3 properties while configuring viewports for a D3D device:
- The resolution the device is running in (full-screen).
- The physical aspect ratio of the monitor (as fraction and float:1, so for ex. 4:3 & 1.33).
- The aspect ratio of the source resolution (source resolution itself is kind of moot and tells us little more than the aspect ratio the rendering wants and the kind of resolution that would be ideal to run in).
Then we run into this:
// -- figure out aspect ratio adjusted VPs --
m_nativeVP.Width = xRes;
m_nativeVP.Height = yRes;
m_nativeVP.X = 0;
m_nativeVP.Y = 0;
m_nativeVP.MaxZ = 1.f;
m_nativeVP.MinZ = 0.f;
FIX_ME // this does not cover all bases -- fix!
uint xResAdj, yResAdj;
if (g_displayAspectRatio.Get() < g_renderAspectRatio.Get())
{
xResAdj = xRes;
yResAdj = (uint) ((float) xRes / g_renderAspectRatio.Get());
}
else if (g_displayAspectRatio.Get() > g_renderAspectRatio.Get())
{
xResAdj = (uint) ((float) yRes * g_renderAspectRatio.Get());
yResAdj = yRes;
}
else // ==
{
xResAdj = xRes;
yResAdj = yRes;
}
m_fullVP.Width = xResAdj;
m_fullVP.Height = yResAdj;
m_fullVP.X = (xRes - xResAdj) >> 1;
m_fullVP.Y = (yRes - yResAdj) >> 1;
m_fullVP.MaxZ = 1.f;
m_fullVP.MinZ = 0.f;
Now as long as g_displayAspectRatio equals the ratio of xRes/yRes (= adapted from device resolution), all is well and this code will do what's expected of it. But as soon as those 2 values are no longer related (for example, someone runs a 4:3 resolution on a 16:10 screen, hardware-stretched) another step is required to compensate, and I've got trouble figuring out how exactly.
(and p.s I use C-style casts on atomic types, live with it :-) )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设您想要实现的是“方形”投影,例如,当您绘制圆形时,您希望它看起来像圆形而不是椭圆形。
您唯一应该考虑的是您的投影(相机)纵横比。 在正常情况下,显示器保持像素正方形,您所要做的就是将相机宽高比设置为等于视口的宽高比:
在您描述的拉伸情况下(例如,在 16:10 屏幕上拉伸 4:3 图像),像素不再是方形的,您必须在相机宽高比中考虑到这一点:
其中
screen_size_x
和screen_size_y
是显示器实际尺寸的倍数(例如 16:10 )。但是,您应该简单地假设正方形像素(除非您有特定的理由不这样做),因为显示器可能会向系统报告不正确的物理尺寸信息,或者根本不报告任何信息。 此外,显示器并不总是会拉伸,例如我的显示器保持 1:1 像素长宽比,并为较低的分辨率添加黑色边框。
编辑
如果您想将视口调整为某种纵横比并使其适应任意分辨率,那么您可以这样做:
I'm assuming what you want to achieve is a "square" projection, e.g. when you draw a circle you want it to look like a circle rather than an ellipse.
The only thing you should play with is your projection (camera) aspect ratio. In normal cases, monitors keep pixels square and all you have to do is set your camera aspect ratio equal to your viewport's aspect ratio:
In the stretched case you describe (4:3 image stretched on a 16:10 screen for example), pixels are not square anymore and you have to take that into account in your camera aspect ratio:
Where
screen_size_x
andscreen_size_y
are multiples of the real size of the monitor (e.g. 16:10).However, you should simply assume square pixels (unless you have a specific reason no to), as the monitor may report incorrect physical size informations to the system, or no informations at all. Also monitors don't always stretch, mine for example keeps 1:1 pixels aspect ratio and adds black borders for lower resolutions.
Edit
If you want to adjust your viewport to some aspect ratio and fit it on an arbitrary resolution then you could do like that :