在IOS和Android下的纵向和横向模式之间切换时遇到问题。
我可以同时使用人像和风景模式。
我正在使用SDL处理任何方向更改,正在设置相机的新纵横比,并使用新分辨率调用glViewport。在我的情况下,Portrait是640x1136,Landscape是相反的1136x640。
这是我的最终结果,在“肖像”中,模型比“风景”更大。



这是代码的相关部分。

float width = displayMode.w;

float height = displayMode.h;


float aspect = width/height;
m_pCamera->SetAspect(aspect);

glViewport(0, 0, width, height);

while(game->running)
{
     while (SDL_PollEvent(&event)) {
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED)
            {
                width = event.window.data1;
                height = event.window.data2;

                aspect = width/height;
                m_pCamera->SetAspect(aspect);

                glViewport(0, 0, width, height);
            }
}

最佳答案

透视投影矩阵的常用计算保持了沿y轴显示的几何范围。这正是您的图片所显示的,因此这是标准透视图的预期行为。

为了得到您想要的东西,您需要稍微调整透视矩阵的计算。您可以将与较大屏幕尺寸相对应的轴的范围保持恒定,而不是将y轴上的范围保持恒定。使用此功能,旋转设备时,对象的大小将保持不变。

保持y范围恒定的透视矩阵是这样计算的,tanAng2是一半视场的tanaspRat是长宽比:

[ 1 / (aspRat * tanAng2)       0                0                  0           ]
[           0             1 / tanAng2           0                  0           ]
[           0                  0        (n + f) / (n - f)  2 * n * f / (n - f) ]
[           0                  0               -1                  0           ]

在这种情况下,有趣的矩阵元素是m00m11,因为它们确定xy的缩放比例。关注这两个,并用width / height替换aspRat:
m00 = height / (width * tanAng2)
m11 = 1 / tanAng2

为了使x范围保持不变,这些矩阵元素的计算公式为:
m00 = 1 / tanAng2
m11 = width / (height * tanAng2)

使用这些值,视野将直接应用于x方向,以前是y方向。此外,m11 / m00仍然是aspRat,这对于避免渲染的几何图形失真是必需的。

剩下的就是根据widthheight是否更大在两者之间进行选择:
if (height > width) {
    m00 = height / (width * tanAng2)
    m11 = 1 / tanAng2
} else {
    m00 = 1 / tanAng2
    m11 = width / (height * tanAng2)
}

所有剩余的矩阵元素保持不变,与上面显示的完整矩阵一样。

09-08 03:34