C++ 长宽比-如何进行?(D3D视口设置)

C++ 长宽比-如何进行?(D3D视口设置),c++,math,graphics,aspect-ratio,direct3d,C++,Math,Graphics,Aspect Ratio,Direct3d,好吧,看来我的问题和我的脑袋一样模糊。让我们再试一次 为D3D设备配置视口时,我有3个属性: -设备运行的分辨率(全屏)。 -监视器的物理纵横比(分数和浮子:1,例如4:3和1.33)。 -源分辨率的纵横比(源分辨率本身是一种模拟,告诉我们的仅仅是渲染所需的纵横比和理想的运行分辨率) 然后我们遇到了这样的情况: // -- figure out aspect ratio adjusted VPs -- m_nativeVP.Width = xRes; m_nativeVP.Height =

好吧,看来我的问题和我的脑袋一样模糊。让我们再试一次

为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;
/--计算纵横比调整后的VP--
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;
修好我//这不包括所有的基础--修好!
uint xResAdj,yResAdj;
如果(g_displaySpectratio.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分辨率,硬件拉伸),就需要另一个步骤进行补偿,我很难弄清楚到底是如何补偿的


(还有,我在原子类型上使用C样式强制转换,与之共存:-)

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

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

viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio;
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;
在您描述的拉伸情况下(例如,在16:10屏幕上拉伸4:3图像),像素不再是正方形,您必须在相机纵横比中考虑这一点:

viewport_aspect_ratio = viewport_res_x / viewport_res_y;
camera_aspect_ratio = viewport_aspect_ratio;
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\u size\u x
screen\u size\u y
是监视器实际大小的倍数(例如16:10)

但是,您应该简单地假设为方形像素(除非您有特定的拒绝理由),因为监视器可能会向系统报告不正确的物理大小信息,或者根本没有任何信息。此外,显示器并不总是拉伸,例如,我的显示器保持1:1像素的纵横比,并为较低的分辨率添加黑色边框

编辑

如果要将视口调整为某个纵横比,并使其适合任意分辨率,则可以执行以下操作:

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;

我不明白你到底想做什么。谢谢你的回答。你的假设在一定程度上是正确的,但我应该补充一点,我也希望在2D合成中保持一定的纵横比(或屏幕格式),就像宽屏电影一样。与游戏不同的是,我没有评估过创作视觉效果的选项,这两种比例看起来都不错。你的提示是不用担心非正方形像素,这很让人放心(我一直在想),但是考虑到像素比率是一个很好的提示。编辑了答案,添加了“任意屏幕分辨率上的任意视口纵横比”的内容。这就是代码现在所做的(我意识到我没有粘贴任何关于我如何处理投影纵横比的代码,这可能会有所帮助,因为这已经很好了):)但是很公平,谢谢!对不起,我不明白你的问题是什么。“[…]补偿还需要另一个步骤,我很难弄清楚具体的补偿方式。”:定义“补偿”。在这段代码中,有一行代码:screen\u aspect\u ratio=screen\u res\u x/screen\u res\y。这与第2条有关。现在,如果屏幕的纵横比是任意的,描述了显示器的物理比率,该怎么办?(例如,在硬件拉伸的情况下)(尽管如此,我越是讨论这个问题,我就越想知道为什么我甚至想要这个…-我想这很好)