#graphics #3d #depth-buffer #direct3d11
#графика #3D #глубина-буфер #direct3d11
Вопрос:
Я экспериментирую с Direct3D 11 API и не очень хорошо знаком с D3D. У меня всегда есть OpenGL для моих проектов. До сих пор мне удавалось нарисовать простой треугольник. Теперь я хочу нарисовать несколько более сложных объектов, но есть проблема. Я не знаю, как включить глубинный тест (или он использует совершенно другую концепцию?). Я получаю что-то вроде этого:
Я инициализирую D3D следующим образом:
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(amp;swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.Windowed = true;
HRESULT result = D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE,
NULL,
0,
NULL,
0,
D3D11_SDK_VERSION,
amp;swapChainDesc,
amp;SwapChain,
amp;Device,
NULL,
amp;DeviceContext);
if (result != S_OK)
throw "Direct3D initialization error";
ID3D11Texture2D *backBufferTexture;
result = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)amp;backBufferTexture);
if (result != S_OK)
{
[error handling here]
}
result = Device->CreateRenderTargetView(backBufferTexture, NULL, amp;BackBuffer);
backBufferTexture->Release();
if (result != S_OK)
{
[error handling here]
}
DeviceContext->OMSetRenderTargets(1, amp;BackBuffer, NULL);
После этого происходит загрузка шейдера, настройка матрицы, инициализация вершинного и индексного буферов. Бьюсь об заклад, здесь чего-то не хватает, но я не знаю чего.
Комментарии:
1. В вашем вопросе больше пуха, чем кода. Вставьте свой код.
2. Я нашел, в чем проблема. Буфер глубины необходимо создавать отдельно (но пока я не могу опубликовать полный ответ).
Ответ №1:
Хорошо, я выяснил, чего не хватало. Буфер глубины должен быть создан явно. Что интересно, буферы глубины и трафарета объединены в один буфер.
D3D11_TEXTURE2D_DESC depthTextureDesc;
ZeroMemory(amp;depthTextureDesc, sizeof(depthTextureDesc));
depthTextureDesc.Width = width;
depthTextureDesc.Height = height;
depthTextureDesc.MipLevels = 1;
depthTextureDesc.ArraySize = 1;
depthTextureDesc.SampleDesc.Count = 1;
depthTextureDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D *DepthStencilTexture;
result = Device->CreateTexture2D(amp;depthTextureDesc, NULL, amp;DepthStencilTexture);
if (result != S_OK) [error handling code]
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
ZeroMemory(amp;dsvDesc, sizeof(dsvDesc));
dsvDesc.Format = depthTextureDesc.Format;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
result = Device->CreateDepthStencilView(DepthStencilTexture, amp;dsvDesc, amp;DepthBuffer);
DepthStencilTexture->Release();
if (result != S_OK) [error handling code]
DeviceContext->OMSetRenderTargets(1, amp;BackBuffer, DepthBuffer);
Конечно, очистка этого буфера требуется каждый кадр.
DeviceContext->ClearDepthStencilView(DepthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
Комментарии:
1. На самом деле они представляют собой один буфер.