简体   繁体   English

深度模板不工作 - DirectX 10 C ++

[英]Depth stencil not working - DirectX 10 C++

I have a DirectX10 + C++ problem. 我有一个DirectX10 + C ++问题。

Basically we're at the early stages of rendering, and for some reason our depth stencil seems to be failing to understand our model. 基本上我们处于渲染的早期阶段,由于某种原因,我们的深度模板似乎无法理解我们的模型。 Basically, here is everything we are doing: 基本上,这是我们正在做的一切:

  1. Load shader, model and texture 加载着色器,模型和纹理
  2. Initialize DirectX 初始化DirectX
  3. Draw

The model, shader and texture all load and work correctly, however (as shown in the screenshot below), the depth stencil is clearly not doing its job and the shader is being used in the wrong places. 模型,着色器和纹理都可以正确加载和工作(但如下面的屏幕截图所示),深度模板显然无法正常工作,并且着色器正在错误的位置使用。 I have also included our initialization method in case you need it to figure it out. 我还包括了我们的初始化方法,以防你需要它来解决它。 We believe we have tried almost everything but knowing our luck we have probably missed out 1 line of important code ^.^ 我们相信我们已经尝试了几乎所有的东西,但是知道我们的运气,我们可能错过了一行重要代码^。^

We also saw that someone else had the same problem, however their fix didn't work (their problem was that they had set the near clipping plane to 0.0, however ours is not 0.0 so that is not the problem) 我们还看到其他人有同样的问题,但是他们的修复无效(他们的问题是他们已经将近剪裁平面设置为0.0,但是我们的不是0.0因此不是问题)

Thanks in advance! 提前致谢!

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

}

I fixed it, thanks to catflier's nod in the right direction. 我修好了,感谢catflier正朝着正确的方向点头。 Turns out I was actually releasing the rasterizer state too early for the depth stencil to be used. 事实证明,我实际上太早地发布了光栅化器状态,​​无法使用深度模板。

I'll leave this answer here for anyone who has the same problem. 对于遇到同样问题的人,我会在这里留下这个答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM