我几乎没有编写基于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);
设备不是空指针。
我最近意识到声明和设置视口并没有区别。
如果有人能指出正确的答案,请帮我解决这个恼人的问题。
答案 0 :(得分:0)
我认为你的问题不在D3DPP参数中,而在你的投影矩阵中。如果使用D3DXMatrixPerspectiveFovLH,请检查纵横比为1280/1024 = 1.3333f
答案 1 :(得分:0)
如果您没有设置任何转换矩阵,那么身份转换将应用于您的网格,然后立方体的面将被拉伸到视口的相同形状。如果您的视口不是正方形(例如,它与屏幕的大小相同),那么您的立方体的脸也不会是正方形。
您可以使用方形视口来解决此问题,但这会将渲染限制在屏幕上的那个方块上。如果要渲染到整个屏幕,则需要设置合适的投影矩阵。您可以使用D3DXMatrixPerspectiveFovLH
计算普通透视透视矩阵。如果您想要一个正交透视图,无论与相机的距离如何,所有内容的大小都相同,请使用D3DXMatrixOrthoLH
计算透视矩阵。请注意,如果您使用视口的宽度和高度与后一个函数一起使用,它将缩小您的多维数据集。单位大小的立方体将在屏幕上呈现为单个像素。您可以使用世界或视图变换再次进行缩放,也可以使用width/height
和1
之类的宽度和高度参数作为D3DXMatrixOrthoLH
。
如果你选择D3DXMatrixPerspectiveFovLH
,那么你需要这样的东西:
D3DXMatrixPerspectiveFovLH(&Proj, D3DX_PI/4, (double) D3DMM.Width / D3DMM.Height,
1.0f, 1000.f);