Тест глубины Directx 11 не работает - PullRequest
0 голосов
/ 25 декабря 2011

Я не могу заставить свою программу правильно выбирать, какие модели размещать впереди.Я точно следовал коду MSDN.Кажется, мой код правильно рисует все многоугольники в конкретном вызове DrawIndexed, но каждый последующий вызов, кажется, заставляет модели рисоваться в том порядке, в котором они нарисованы, не основываясь на том, находятся ли они ближе к экрану.Вот мой код для инициализации Direct3d:

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 = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 4;
sd.SampleDesc.Quality = 0;
sd.Windowed = !fullScreen;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
D3D_FEATURE_LEVEL  FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
UINT               numFeatureLevelsRequested = 1;
D3D_FEATURE_LEVEL  FeatureLevelsSupported;
HRESULT hr;
if( FAILED (hr = D3D11CreateDeviceAndSwapChain( adapters[0], 
    D3D_DRIVER_TYPE_UNKNOWN, 
    NULL, 
    NULL,
    NULL, 
    NULL, 
    D3D11_SDK_VERSION, 
    &sd, 
    &swapchain, 
    &dev, 
    &FeatureLevelsSupported,
    &devcon )))
{
    //return;
}
ID3D11Texture2D *pBack = NULL;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBack);

// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBack, NULL, &backbuffer);
pBack->Release();

// set the render target as the back buffer
// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format =DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = 4;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;

hr = dev->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil);
if(FAILED(hr))
    exit(hr);

// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory(&descDSV, sizeof(descDSV));

descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;;  
//descDSV.Texture2DMS.UnusedField_NothingToDefine = 0;  

hr = dev->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView);
if(FAILED(hr))
    exit(hr);
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));

viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = width;
viewport.Height = height;

devcon->RSSetViewports(1, &viewport);

Это мой код для рендеринга:

void Direct3DRenderer::Render()
{

    devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
    devcon->ClearDepthStencilView(g_pDepthStencilView,  D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0 );
    camera.location = simulation->GetWorld()->GetCameraCoordinates();
    camera.direction = simulation->GetWorld()->GetCameraLookAt();
    //camera.up = simulation->GetWorld()->GetCameraOrientation();
    Vec3d lookAt = camera.location + camera.direction;
    XMVECTOR eye = XMVectorSet((float)camera.location[0], (float)camera.location[1], (float)camera.location[2], 0.f);
    XMVECTOR look = XMVectorSet(lookAt[0], lookAt[1], lookAt[2], 0);
    XMVECTOR up = XMVectorSet(camera.up[0], camera.up[1], camera.up[2], 0);
    g_View = XMMatrixLookAtLH(eye, look, up);

    ConstantBuffer oncePerFrame;
    oncePerFrame.matrix = XMMatrixTranspose(g_View);
    devcon->UpdateSubresource(oncePerFrameBuffer, 0, NULL, &oncePerFrame, 0, 0);

    UINT stride = sizeof(VERTEX);
    UINT offset = 0;

    const std::vector<Graphical*> graphicalList = simulation->GetWorld()->GetGraphicalList();

    for(int ind = 0; ind < graphicalList.size(); ++ind)
    {
        switch(graphicalList[ind]->GetModelType())
        {
            case 1:  //Sphere
                {
                    ConstantBuffer oncePerModel2;
                    oncePerModel2.matrix = XMMatrixTranspose(XMMatrixScalingFromVector(graphicalList[ind]->GetScaleX()) * XMMatrixTranslationFromVector(graphicalList[ind]->GetTranslationX()));
                    devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel2, 0, 0);
                    devcon->IASetVertexBuffers(0, 1, &(sphereModel.vertexBuffer), &stride, &offset);
                    devcon->IASetIndexBuffer(sphereModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
                    devcon->DrawIndexed(sphereModel.indexCount, 0, 0);
                }
                break;
        }
    }
    ConstantBuffer oncePerModel;
    oncePerModel.matrix = XMMatrixTranspose(g_World);
    devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel, 0, 0);

    devcon->IASetVertexBuffers(0, 1, &terrainModel.vertexBuffer, &stride, &offset);
    devcon->IASetIndexBuffer(terrainModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
    devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    devcon->DrawIndexed(terrainModel.indexCount, 0, 0);

    swapchain->Present(0, 0);
}

Я много пробовал искать и следовал всем учебникам, которые мог найти.Ничто не исправляет это.

В случае с сферами глубина представляется правильной, если смотреть с одной стороны, но не с другой.

Любая помощь будет принята с благодарностью.Спасибо.

Ответы [ 3 ]

1 голос
/ 24 января 2017

Из комментария ОП:

Проблема оказалась намного проще.Я не установил минимальную и максимальную глубину для объекта области просмотра.Это сработало, как только я это сделал.

У меня была такая же проблема, теперь она работает:

D3D11_VIEWPORT screenViewport;
/* ... */
screenViewport.MinDepth = 0;
screenViewport.MaxDepth = 1;
/* ... */
context->RSSetViewports(1, &screenViewport);
0 голосов
/ 03 января 2012

Была похожая проблема в DirectX10, похоже, это был код инициализации, я не уверен насчет CreateDevice и SwapChain для UNKNOWN типа драйвера, так как я не использовал это раньше.

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

например:

// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;

// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;

В любом случае, вот рабочий пример DirectX10, я уверен, что вы можете быстро адаптировать его для DirectX11.

logger->debug("initD3D: Calling D3D10CreateDeviceAndSwapChain.\n");

SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
srand((unsigned int)sysTime.wMilliseconds);
logger->debug("in initD3D.\n");
shutdownXX = false;

count = 1;
quality = 0;

//Create the back buffer desc.
ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

swapDesc.BufferCount = 1;
swapDesc.BufferDesc.Width = width;
swapDesc.BufferDesc.Height = height;

swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

swapDesc.BufferDesc.RefreshRate.Numerator = 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.OutputWindow = hwnd;
swapDesc.SampleDesc.Count = count;
swapDesc.SampleDesc.Quality = quality;
swapDesc.Windowed = FALSE;


swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

//Create the device.
HRESULT hr = D3D10CreateDeviceAndSwapChain(
        NULL, 
        D3D10_DRIVER_TYPE_HARDWARE, 
        NULL, 
        0, 
        D3D10_SDK_VERSION, 
        &swapDesc, 
        &swapChain, 
        &device);
if (!chk(hr, TEXT("Could not create D3D Device D3D10CreateDeviceAndSwapChain failed.")))
    return false;

ID3D10Texture2D *buffer;

logger->debug("initD3D: Calling swapChain->GetBuffer.\n");
hr = swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &buffer);
if (!chk(hr, TEXT("Could not create D3D Device: swapChain->GetBuffer failed.")))
    return false;

D3D10_TEXTURE2D_DESC BBDesc;
ZeroMemory(&BBDesc, sizeof(D3D10_TEXTURE2D_DESC));
buffer->GetDesc( &BBDesc );

D3D10_RENDER_TARGET_VIEW_DESC RTVDesc;
ZeroMemory(&RTVDesc, sizeof(D3D10_RENDER_TARGET_VIEW_DESC));
RTVDesc.Format = BBDesc.Format;
//RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DMS;
RTVDesc.Texture2D.MipSlice = 0;

logger->debug("initD3D: Calling device->CreateRenderTargetView.\n");
hr = device->CreateRenderTargetView(buffer, &RTVDesc, &renderTView);
buffer->Release();

if (!chk(hr, TEXT("Could not create D3D Device: device->CreateRenderTargetView failed.")))
    return false;


ZeroMemory(&descDepth, sizeof(D3D10_TEXTURE2D_DESC));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
//descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = count;
descDepth.SampleDesc.Quality = quality;
descDepth.Usage = D3D10_USAGE_DEFAULT;
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;

hr = device->CreateTexture2D(&descDepth, NULL, &stencil);
if (!chk(hr, TEXT("device->device->CreateTexture2D Failed\n")))
    return false;

// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D10_COMPARISON_LESS;

// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;

// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;

// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;


hr = device->CreateDepthStencilState(&dsDesc, &pDSState);
if (!chk(hr, TEXT("device->device->CreateDepthStencilState Failed\n")))
    return false;
device->OMSetDepthStencilState(pDSState, 1);

ZeroMemory(&descDSV, sizeof(D3D10_DEPTH_STENCIL_VIEW_DESC));
descDSV.Format = descDepth.Format;
//descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;

hr = device->CreateDepthStencilView(stencil, &descDSV, &depthStencil);
if (!chk(hr, TEXT("device->device->CreateDepthStencilView Failed\n")))
    return false;

device->OMSetRenderTargets(1, &renderTView, depthStencil);

resizeD3D10Window(width, height);

return true;
0 голосов
/ 27 декабря 2011

Существует три основных шага к Z-буферизации.

  1. Установка соответствующих параметров представления
  2. Включение Z-буферизации
  3. Очистка Z-буфера

1) Установка соответствующих параметров представления

D3DPRESENT_PARAMETERS d3dpp;
//...
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

EnableAutoDepthStencil

По правде говоря, z-буферизация может быть сложной.Установка этого значения в TRUE указывает Direct3D автоматически создавать z-буфер и устанавливать его наиболее часто используемым способом.Конечно, есть способы использования сложного метода, но пока мы будем придерживаться простого.Мы расскажем, как сложный метод может быть полезен позже в этом уроке.

AutoDepthStencilFormat

Это формат для каждого пикселя в z-буфере.Мы не используем обычный формат пикселей, определенный в параметрах презентации.Вместо этого мы используем специальный формат для z-буферов.Этот формат D3DFMT_D16.Это означает, что каждый пиксель является 16-битным.Существуют и другие форматы, но они нам не понадобятся в рамках данного урока.

2) Включение Z-буферизации

// d3ddev is your Direct3D device - a variable of type LPDIRECT3DDEVICE9
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);

3) Очистка Z-буфера

d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

Кстати, это работает в DirectX 9.0c.Я не уверен, что он совместим с DirectX 11.

...