好吧-似乎我的问题就像我的头一样浑浊。让我们再试一次。

在为D3D设备配置视口(viewport)时,我具有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的屏幕上以硬件拉伸(stretch)的方式在4:3的分辨率下运行),则需要采取另一步骤进行补偿,而我很难弄清楚。

(请注意,我对原子类型使用C风格的强制转换,忍受它:-))

最佳答案

我假设您要实现的是“正方形”投影,例如当您画一个圆时,您希望它看起来像一个圆而不是一个椭圆。

您唯一要玩的是投影(相机)纵横比。在正常情况下,监视器使像素保持正方形,而您要做的就是将相机的纵横比设置为等于视口(viewport)的纵横比:

viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio;

在您描述的拉伸(stretch)情况下(例如在16:10屏幕上拉伸(stretch)的4:3图像),像素不再是正方形,因此您必须在相机的宽高比中考虑到这一点:
stretch_factor_x = screen_size_x / viewport_res_x;
stretch_factor_y = screen_size_y / viewport_res_y;
pixel_aspect_ratio = stretch_factor_x / stretch_factor_y;
viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio * pixel_aspect_ratio;

其中screen_size_xscreen_size_y是监视器实际大小的倍数(例如16:10)。

但是,您应该仅假设正方形像素(除非有特殊原因,否则),因为监视器可能会向系统报告错误的物理尺寸信息,或者根本不报告任何信息。监视器也不总是拉伸(stretch),例如我的显示器保持1:1像素的宽高比,并添加黑色边框以降低分辨率。

编辑

如果您想将视口(viewport)调整为某个宽高比并将其调整为任意分辨率,则可以这样做:
viewport_aspect_ratio = 16.0 / 10.0; // The aspect ratio you want your viewport to have
screen_aspect_ratio = screen_res_x / screen_res_y;

if (viewport_aspect_ratio > screen_aspect_ratio) {
    // Viewport is wider than screen, fit on X
    viewport_res_x = screen_res_x;
    viewport_res_y = viewport_res_x / viewport_aspect_ratio;
} else {
    // Screen is wider than viewport, fit on Y
    viewport_res_y = screen_res_y;
    viewport_res_x = viewport_res_y * viewport_aspect_ratio;
}

camera_aspect_ratio = viewport_res_x / viewport_res_y;

关于c++ - 宽高比-如何计算? (D3D视口(viewport)设置),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1222340/

10-09 04:04