2013-10-11 54 views
4

我有一些使用OpenGL編寫的渲染代碼。我使用模板緩存來實現裁剪:將OpenGL模板功能移植到DirectX 11


    //Let's assume this is done in render loop. 

    if(!already_created()) 
    { 
     create_stencil_attachment_and_bind_to_FB_as_depth_stencil_attachment(); 
    } 

    glEnable(GL_STENCIL_TEST); 
    glColorMask(0,0,0,0); 
    glDepthMask(0); 
    glClearStencil(0); 
    glClear(GL_STENCIL_BUFFER_BIT); 
    glStencilFunc(GL_ALWAYS,1,1); 
    glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE); 

    render_to_stencil(); 

    glColorMask(1,1,1,1); 
    glDepthMask(1); 
    glStencilFunc(GL_EQUAL,1,1); 
    glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); 

    render_with_clipping(); 

    glDisable(GL_STENCIL_TEST); 

現在的問題是,我需要移植此代碼DX11。我看到了MSDN上的例子和一些很好的教程。我結束了這樣的邏輯:

 
1. Create ID3D11Texture2D with format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT. 
2. Create ID3D11DepthStencilState for rendering to stencil: //Let's call it DS_RENDER 
    - For both front and back faces: 
    - op = D3D11_STENCIL_OP_REPLACE for all 3 cases 
    - func = D3D11_COMPARISON_ALWAYS 
    - DepthEnable = FALSE 
    - StencilEnable = TRUE 
    - StencilReadMask = 0xFF 
    - StencilWriteMask = 0xFF 
3. Create ID3D11DepthStencilView for state and texture created before. //Let's call it DSV 
4. Create ID3D11DepthStencilState for using stencil as 'input': //Let's call it DS_CLIP 
    - For both front and back faces: 
    - op = D3D11_STENCIL_OP_KEEP for all 3 cases 
    - func = D3D11_COMPARISON_EQUAL 
    - DepthEnable = FALSE 
    - StencilEnable = TRUE 
    - StencilReadMask = 0xFF 
    - StencilWriteMask = 0xFF 

現在,我不知道我該怎麼辦設置模板作爲目標或輸入。

MSDN說:

`pDevice->OMSetDepthStencilState(pDSState, 1);`

`pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, pDSV);`

如果我正確理解這些要求,第1臺模板狀態,而第二個結合pDSV作爲額外的「附件」來渲染目標。那是對的嗎?

如果是這樣,這個工作是否符合我的預期?



    pDevice->OMSetDepthStencilState(DS_RENDER, 1); 
    pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV); 

    render_geometry_to_stencil_buffer(); 

    pDevice->OMSetDepthStencilState(DS_CLIP, 1); 

    render_geometry_with_clipping(); 

    pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); //Does this disable stencil testing? 

預先感謝每一個幫助或提供有用的線索。

回答

1

如果你想渲染只模板,使用(設置你的狀態寫入):

pd3dDeviceContext->OMSetRenderTargets(0, NULL, DSV); 

你不需要渲染顏色緩衝區,因此無需綁定。

然後呈現給你的目標和實現模板測試,使用方法:

pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV); 

當你使用模板作爲輸入,一個很簡單的事情也設置StencilWriteMask = 0; 所以它永遠不會寫入它(這是你想渲染修剪後的幾何圖形)。

如果你使用:

pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); 

你確實會禁止任何形式的深度/模板測試的(沒有更深入的約束,所以DepthStencilState不會有任何影響的話)。

此外,我會使用DXGI_FORMAT_D24_UNORM_S8_UINT深度格式(個人喜好壽),它會完美地適合您的使用情況,並消耗更少的內存。

希望有所幫助。

+0

我沒有機會測試這個解決方案,但它確實看起來一致,並且與我記得關於DX中模具的這些片段相匹配:)我會盡快提供反饋。 –