Как мне включить проверку глубины в Direct3D 11?

#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. На самом деле они представляют собой один буфер.