Direct3D9全屏应用程序 - 变形渲染

时间:2014-08-22 17:41:45

标签: directx fullscreen direct3d direct3d9

我几乎没有编写基于Direct3D9的游戏。一切都很好,我遇到了一个大问题。我创建了一个包装从.x文件加载网格的过程的类。我成功加载了一个只有一个面可见的立方体。理论上,该面应该看起来像一个正方形,但实际上它呈现为一个矩形。我很确定D3DPRESENT_PARAMETERS结构有问题。 Down bellow只是我应用程序初始化中最重要的一行。

要创建的第一部分是焦点窗口:

HWND hWnd = CreateWindowEx(0UL, L"NewFrontiers3DWindowClass", Title.c_str(), WS_POPUP | WS_EX_TOPMOST, 0, 0, 1280, 1024, nullptr, (HMENU)false, hInstance, nullptr);

然后我填写D3DPRESENT_PARAMETERS结构。

D3DDISPLAYMODE D3DMM;
SecureZeroMemory(&D3DMM, sizeof(D3DDISPLAYMODE));
if(FAILED(hr = Direct3D9->GetAdapterDisplayMode(Adapter, &D3DMM)))
{
    // Error is processed here
}

PresP.BackBufferWidth = D3DMM.Width;
PresP.BackBufferHeight = D3DMM.Height;
PresP.BackBufferFormat = BackBufferFormat;
PresP.BackBufferCount = 1U;
PresP.MultiSampleType = D3DMULTISAMPLE_NONE;
PresP.MultiSampleQuality = 0UL;
PresP.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresP.hDeviceWindow = hWnd;
PresP.Windowed = false;
PresP.EnableAutoDepthStencil = EnableAutoDepthStencil;
PresP.AutoDepthStencilFormat = AutoDepthStencilFormat;
PresP.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
PresP.FullScreen_RefreshRateInHz = D3DMM.RefreshRate;
PresP.PresentationInterval = PresentationInterval;

然后创建Direct3D9设备,然后是SetRenderState函数。

接下来,分配视口。

D3DVIEWPORT9 D3D9Viewport;
SecureZeroMemory(&D3D9Viewport, sizeof(D3DVIEWPORT9));
    D3D9Viewport.X = 0UL;
    D3D9Viewport.Y = 0UL;
    D3D9Viewport.Width = (DWORD)D3DMM.Width;
    D3D9Viewport.Height = (DWORD)D3DMM.Height;
    D3D9Viewport.MinZ = 0.0f;
    D3D9Viewport.MaxZ = 1.0f;
if(FAILED(Direct3D9Device->SetViewport(&D3D9Viewport)))
{
    // Error is processed here
}

在初始化之后,我全局声明一些将在以后使用的参数。

D3DXVECTOR3 EyePt(0.0f, 0.0f, -5.0f), Up(0.0f, 1.0f, 0.0f), LookAt(0.0f, 0.0f, 0.0f);
D3DXMATRIX View, Proj, World;

更新功能如下所示:

Mesh.Render(Direct3D9Device);

D3DXMatrixLookAtLH(&View, &EyePt, &LookAt, &Up);
Direct3D9Device->SetTransform(D3DTS_VIEW, &View);

D3DXMatrixPerspectiveFovLH(&Proj, D3DX_PI/4, 1.0f, 1.0f, 1000.f);
Direct3D9Device->SetTransform(D3DTS_PROJECTION, &Proj);

D3DXMatrixTranslation(&World, 0.0f, 0.0f, 0.0f);
Direct3D9Device->SetTransform(D3DTS_WORLD, &World);

设备不是空指针。

我最近意识到声明和设置视口并没有区别。

如果有人能指出正确的答案,请帮我解决这个恼人的问题。

2 个答案:

答案 0 :(得分:0)

我认为你的问题不在D3DPP参数中,而在你的投影矩阵中。如果使用D3DXMatrixPerspectiveFovLH,请检查纵横比为1280/1024 = 1.3333f

答案 1 :(得分:0)

如果您没有设置任何转换矩阵,那么身份转换将应用于您的网格,然后立方体的面将被拉伸到视口的相同形状。如果您的视口不是正方形(例如,它与屏幕的大小相同),那么您的立方体的脸也不会是正方形。

您可以使用方形视口来解决此问题,但这会将渲染限制在屏幕上的那个方块上。如果要渲染到整个屏幕,则需要设置合适的投影矩阵。您可以使用D3DXMatrixPerspectiveFovLH计算普通透视透视矩阵。如果您想要一个正交透视图,无论与相机的距离如何,所有内容的大小都相同,请使用D3DXMatrixOrthoLH计算透视矩阵。请注意,如果您使用视口的宽度和高度与后一个函数一起使用,它将缩小您的多维数据集。单位大小的立方体将在屏幕上呈现为单个像素。您可以使用世界或视图变换再次进行缩放,也可以使用width/height1之类的宽度和高度参数作为D3DXMatrixOrthoLH

如果你选择D3DXMatrixPerspectiveFovLH,那么你需要这样的东西:

D3DXMatrixPerspectiveFovLH(&Proj, D3DX_PI/4, (double) D3DMM.Width / D3DMM.Height,
                           1.0f, 1000.f);