2012-10-29 82 views
4

我有一個DirectX10 + C++問題。Depth stencil not working - DirectX 10 C++

基本上我們處於渲染的早期階段,由於某種原因,我們的深度模具似乎無法理解我們的模型。基本上,這裏的一切,我們正在做的:

  1. 負載着色器,模型和紋理
  2. 初始化的DirectX
  3. 繪製

模型,着色以及紋理的所有負荷和正常工作,但是(如下面的截圖所示),深度模板顯然沒有完成它的工作,並且着色器被用在錯誤的地方。我還包括了我們的初始化方法,以防您需要將其計算出來。我們相信我們已經嘗試了幾乎所有的東西,但是我們知道我們的運氣可能遺漏了1行重要代碼^。^

我們也看到別人有同樣的問題,但是他們的修復程序沒有工作(他們的問題是他們已經將近剪裁平面設置爲0.0,但是我們不是0.0,所以這不是問題)

在此先感謝!

Problem screenshot

void GraphicsDeviceDirectX::InitGraphicsDevice(HWND hWnd) 
{ 
    DXGI_SWAP_CHAIN_DESC scd; // create a struct to hold various swap chain information 

    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); // clear out the struct for use 

    scd.BufferCount = 2; // create two buffers, one for the front, one for the back 
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color 
    scd.BufferDesc.Height = 600; 
    scd.BufferDesc.Width = 600; 
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // tell how the chain is to be used 
    scd.OutputWindow = hWnd; // set the window to be used by Direct3D 
    scd.SampleDesc.Count = 1; // set the level of multi-sampling 
    scd.SampleDesc.Quality = 0; // set the quality of multi-sampling 
    scd.Windowed = true; // set to windowed or full-screen mode 

    //set scan line ordering and scaling 
    scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; 
    scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; 

    //discard back buffer dontents 
    scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 

    //dont set advanced flags 
    scd.Flags = 0; 

    // create a device class and swap chain class using the information in the scd struct 
    if(FAILED(D3D10CreateDeviceAndSwapChain(NULL, 
            D3D10_DRIVER_TYPE_HARDWARE, 
            NULL, 
            D3D10_CREATE_DEVICE_DEBUG, 
            D3D10_SDK_VERSION, 
            &scd, 
            &swapchain, 
            &device))) 
    { 
     throw EngineException("Error creating graphics device"); 
    } 

    //Push graphics device to Persistant Object Manager 
    //PerObjMan::Push(device); 
    //Push swapchain to Peristant Object Manager 
    PerObjMan::Push(swapchain); 

    // get the address of the back buffer and use it to create the render target 
    ID3D10Texture2D* pBackBuffer; 
    swapchain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); 
    device->CreateRenderTargetView(pBackBuffer, NULL, &rtv); 

    /*D3D10_TEXTURE2D_DESC descBack; 
    pBackBuffer->GetDesc(&descBack);*/ 
    pBackBuffer->Release(); 
    pBackBuffer = NULL; 

    //Push graphics device to Persistant Object Manager 
    PerObjMan::Push(rtv); 

    ID3D10Texture2D* pDepthStencil = NULL; 
    D3D10_TEXTURE2D_DESC descDepth; 

    ZeroMemory(&descDepth, sizeof(descDepth)); 

    descDepth.Width = 600; 
    descDepth.Height = 600; 
    descDepth.MipLevels = 1; 
    descDepth.ArraySize = 1; 
    descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 
    descDepth.SampleDesc.Count = 1; 
    descDepth.SampleDesc.Quality = 0; 
    descDepth.Usage = D3D10_USAGE_DEFAULT; 
    descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL; 
    descDepth.CPUAccessFlags = 0; 
    descDepth.MiscFlags = 0; 
    HRESULT hr; 
    hr = GetGraphicsDevice()->CreateTexture2D(&descDepth, NULL, &pDepthStencil); 
    if(FAILED(hr)) 
     throw EngineException("FAIL"); 

    PerObjMan::Push(pDepthStencil); 

    D3D10_DEPTH_STENCIL_DESC dsDesc; 

    ZeroMemory(&dsDesc, sizeof(dsDesc)); 
    // Depth test parameters 
    dsDesc.DepthEnable = true; 
    dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK::D3D10_DEPTH_WRITE_MASK_ALL; 
    dsDesc.DepthFunc = D3D10_COMPARISON_FUNC::D3D10_COMPARISON_LESS; 

    // Stencil test parameters 
    dsDesc.StencilEnable = false; 
    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;  

    // Create depth stencil state 
    hr = device->CreateDepthStencilState(&dsDesc, &dss); 
    if(FAILED(hr)) 
     throw EngineException("FAIL"); 

    // Bind depth stencil state 
    device->OMSetDepthStencilState(dss, 1); 


    PerObjMan::Push(dss); 

    D3D10_DEPTH_STENCIL_VIEW_DESC descDSV; 

    ZeroMemory(&descDSV, sizeof(descDSV)); 

    descDSV.Format = descDepth.Format; 
    descDSV.ViewDimension = D3D10_DSV_DIMENSION::D3D10_DSV_DIMENSION_TEXTURE2D; 
    descDSV.Texture2D.MipSlice = 0; 

    // Create the depth stencil view 
    hr = device->CreateDepthStencilView(pDepthStencil, // Depth stencil texture 
             &descDSV, // Depth stencil desc 
             &dsv); // [out] Depth stencil view 

    if(FAILED(hr)) 
     throw EngineException("FAIL"); 

    PerObjMan::Push(dsv); 

    // Bind the depth stencil view 
    device->OMSetRenderTargets(1,   // One rendertarget view 
           &rtv,  // Render target view, created earlier 
           dsv);  // Depth stencil view for the render target 


    D3D10_VIEWPORT viewport; // create a struct to hold the viewport data 

    ZeroMemory(&viewport, sizeof(D3D10_VIEWPORT)); // clear out the struct for use 

    GameToImplement::GameInfo::Info info = GameToImplement::GameInfo::GetGameInfo(); 

    RECT rect; 
    int width = 0; 
    int height = 0; 
    if(GetClientRect(hWnd, &rect)) 
    { 
     width = rect.right - rect.left; 
     height = rect.bottom - rect.top; 
    } 
    else 
    { 
     throw EngineException(""); 
    } 

    viewport.TopLeftX = 0; // set the left to 0 
    viewport.TopLeftY = 0; // set the top to 0 
    viewport.Width = 600; // set the width to the window's width 
    viewport.Height = 600; // set the height to the window's height 
    viewport.MinDepth = 0.0f; 
    viewport.MaxDepth = 1.0f; 

    device->RSSetViewports(1, &viewport); // set the viewport 

}
+1

你還試過設置光柵器狀態嗎?嘗試不同的剔除模式,可能來自那裏。 – catflier

+0

你的代碼似乎沒問題。你看過PIX嗎?該工具可以顯示深度緩衝區。檢查是否寫入了正確的值。 –

+0

@catflier謝謝,事實證明我們過早釋放光柵器狀態。現在它正在工作! – Zantom07

回答

1

我固定它,這要歸功於在正確的方向catflier點頭。事實上,我實際上是在釋放光柵器狀態,以便使用深度模板。

我會在這裏給任何有同樣問題的人留下這個答案。