Полноэкранное приложение Direct3D9 - искаженное отображение

Я с трудом кодирую игру на основе Direct3D9. Все прошло отлично, но я столкнулся с большой проблемой. Я создал класс, который оборачивает процесс загрузки сетки из.x файла. Я успешно загрузил куб с видимым только одним лицом. Теоретически, это лицо должно выглядеть как квадрат, но на самом деле оно отображается как прямоугольник. Я совершенно уверен, что с D3DPRESENT_PARAMETERS состав. Ниже приведены только самые важные строки инициализации моего приложения.

Первая часть, которая будет создана, это окно фокуса:

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 ответа

Решение

Если вы не установите никаких матриц преобразования, поэтому преобразование идентичности будет применено к вашей сетке, тогда грань куба будет растянута до той же формы, что и область просмотра. Если ваш видовой экран не квадратный (например, он такого же размера, как экран), то лицо вашего куба также не будет квадратным.

Вы можете использовать квадратное окно просмотра, чтобы обойти эту проблему, но это ограничит ваш рендеринг только этим квадратом на экране. Если вы хотите выполнить рендеринг на весь экран, вам нужно установить подходящую матрицу проекции. Вы можете рассчитать нормальную перспективную матрицу перспективы, используя D3DXMatrixPerspectiveFovLH, Если вам нужна ортогональная перспектива, где все одинакового размера независимо от расстояния до камеры, используйте D3DXMatrixOrthoLH рассчитать матрицу перспективы. Обратите внимание, что если вы используете ширину и высоту вашего окна просмотра с более поздней функцией, это уменьшит ваш куб. Куб единичного размера будет отображаться на экране как один пиксель. Вы можете использовать мир или просмотреть трансформацию, чтобы снова увеличить его, или использовать что-то вроде width/height а также 1 как ваши параметры ширины и высоты для D3DXMatrixOrthoLH,

Если вы идете с D3DXMatrixPerspectiveFovLH тогда вы хотите что-то вроде этого:

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

Я думаю, что ваша проблема не в параметрах D3DPP, а в вашей проективной матрице. Если вы используете D3DXMatrixPerspectiveFovLH, проверьте, чтобы соотношение сторон было 1280 / 1024 = 1.3333f.

Другие вопросы по тегам