Не создается девайс DirectX
Учу DirectX и столкнулся с проблемой. Не создается девайс в функции InitDevice(). Привожу код:
#include <Windows.h>
#include <d3d11.h>
#include <d3d11_1.h>
#include <d3d11_2.h>
#include <d3d11_3.h>
#include <d3d11_4.h>
#define ERROR_WINDOW MessageBox(NULL, L"Ошибка: Не создалось окно!", L"Ошибка", MB_ICONEXCLAMATION | MB_OK)
#define ERROR_DEVICE MessageBox(NULL, L"Ошибка: Не создался девайс!", L"Ошибка", MB_ICONEXCLAMATION | MB_OK)
HINSTANCE application = NULL;
HWND window = NULL;
D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL featureType = D3D_FEATURE_LEVEL_11_1;
ID3D11Device* Device = NULL; // Создает ресуры
ID3D11DeviceContext* Context = NULL; // Вывод ресурсов
IDXGISwapChain* SwapChain = NULL;
ID3D11RenderTargetView* RenderTargetView = NULL;
typedef TCHAR string;
string Class[] = L"Class";
string Title[] = L"Windows API + DirectX";
MSG msg;
HRESULT hr = S_OK;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT InitWindow(HINSTANCE application, HWND window, int mode);
HRESULT InitDevice();
void Render();
void CleanupDevice();
int WINAPI WinMain(HINSTANCE app, HINSTANCE hPrev, LPSTR lpCmdShow, int mode)
{
UNREFERENCED_PARAMETER(hPrev);
UNREFERENCED_PARAMETER(lpCmdShow);
if (FAILED(InitWindow(app, window, mode)))
{
ERROR_WINDOW;
return NULL;
}
if (FAILED(InitDevice()))
{
ERROR_DEVICE;
CleanupDevice();
return NULL;
}
while (WM_QUIT != msg.message)
{
if (GetMessage(&msg, window, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
Render();
}
CleanupDevice();
return msg.wParam;
}
HRESULT InitWindow(HINSTANCE application, HWND window, int mode)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.cbWndExtra = 0;
wc.cbClsExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hIcon = LoadIcon(application, IDI_WINLOGO);
wc.hIconSm = LoadIcon(application, IDI_WINLOGO);
wc.hCursor = LoadCursor(application, IDC_ARROW);
wc.hInstance = application;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = Class;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClassEx(&wc))
return E_FAIL;
window = CreateWindow(
Class,
Title,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
application,
NULL
);
if (!window)
return E_FAIL;
ShowWindow(window, mode);
UpdateWindow(window);
return S_OK;
}
HRESULT InitDevice()
{
RECT rc;
GetClientRect(window, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED;
D3D_DRIVER_TYPE driverTypes[] = {
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
UINT numFeatureLeves = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 75;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = window;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
// Вот тут и неработает
for (UINT i = 0; i < numDriverTypes; i++)
{
driverType = driverTypes[i];
// Возвращает что-то не то
hr = D3D11CreateDeviceAndSwapChain(NULL, driverType, NULL, createDeviceFlags, featureLevels, numFeatureLeves,
D3D11_SDK_VERSION, &sd, &SwapChain, &Device, &featureType, &Context);
// По этому это не работает
if (SUCCEEDED(hr))
break;
}
// И происходит это
if (FAILED(hr))
return hr;
ID3D11Texture2D* BackBuffer = NULL;
hr = SwapChain->GetBuffer(NULL, __uuidof(ID3D11Texture2D), (LPVOID*)&BackBuffer);
if (FAILED(hr))
return hr;
hr = Device->CreateRenderTargetView(BackBuffer, NULL, &RenderTargetView);
BackBuffer->Release();
if (FAILED(hr))
return hr;
Context->OMSetRenderTargets(1, &RenderTargetView, NULL);
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
// Подключаем вьюпорт к контексту устройства
Context->RSSetViewports(1, &vp);
return S_OK;
}
void CleanupDevice()
{
if (Context)
Context->ClearState();
if (RenderTargetView)
RenderTargetView->Release();
if (SwapChain)
SwapChain->Release();
if (Context)
Context->Release();
if (Device)
Device->Release();
}
void Render()
{
float ClearColor[4] = {
0.0f,
0.0f,
1.0f,
1.0f
};
Context->ClearRenderTargetView(RenderTargetView, ClearColor);
SwapChain->Present(0, 0);
}
LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(NULL);
break;
default:
return DefWindowProc(window, message, wParam, lParam);
}
return NULL;
}
Программа просто для открытия окна