2013-10-07 41 views
2

我有一個相當簡單的DirectX 11框架設置,我想用於各種2D模擬。我目前正試圖在GPU上實現二維波動方程。它要求我保持模擬的網格狀態爲前兩個時間步長,以計算新的時間步長。DirectX使用多個渲染目標作爲對方的輸入

我如何去這件事是這樣的 - 我有一個叫FrameBuffer的類,它具有以下公共方法:

bool Initialize(D3DGraphicsObject* graphicsObject, int width, int height); 

void BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const; 
void EndRender() const; 

// Return a pointer to the underlying texture resource 
const ID3D11ShaderResourceView* GetTextureResource() const; 

在我的正選賽循環我有這些緩衝區的3數組。每個循環我都使用前兩個緩衝區的紋理作爲下一個幀緩衝區的輸入,並且還繪製任何用戶輸入以更改模擬狀態。然後我畫出結果。

int nextStep = simStep+1; 
    if (nextStep > 2) 
     nextStep = 0; 

    mFrameArray[nextStep]->BeginRender(0.0f,0.0f,0.0f,1.0f); 
    { 
     mGraphicsObj->SetZBufferState(false); 
     mQuad->GetRenderer()->RenderBuffers(d3dGraphicsObj->GetDeviceContext()); 
     ID3D11ShaderResourceView* texArray[2] = { mFrameArray[simStep]->GetTextureResource(), 
                mFrameArray[prevStep]->GetTextureResource() }; 
     result = mWaveShader->Render(d3dGraphicsObj, mQuad->GetRenderer()->GetIndexCount(), texArray); 
     if (!result) 
      return false; 
     // perform any extra input 
     I_InputSystem *inputSystem = ServiceProvider::Instance().GetInputSystem(); 
     if (inputSystem->IsMouseLeftDown()) { 
      int x,y; 
      inputSystem->GetMousePos(x,y); 
      int width,height; 
      mGraphicsObj->GetScreenDimensions(width,height); 
      float xPos = MapValue((float)x,0.0f,(float)width,-1.0f,1.0f); 
      float yPos = MapValue((float)y,0.0f,(float)height,-1.0f,1.0f); 
      mColorQuad->mTransform.position = Vector3f(xPos,-yPos,0); 
      result = mColorQuad->Render(&viewMatrix,&orthoMatrix); 
      if (!result) 
       return false; 
     } 
     mGraphicsObj->SetZBufferState(true); 
    } 
    mFrameArray[nextStep]->EndRender(); 

    prevStep = simStep; 
    simStep = nextStep; 

    ID3D11ShaderResourceView* currTexture = mFrameArray[nextStep]->GetTextureResource(); 

    // Render texture to screen 
    mGraphicsObj->SetZBufferState(false); 
    mQuad->SetTexture(currTexture); 
    result = mQuad->Render(&viewMatrix,&orthoMatrix); 
    if (!result) 
     return false; 
    mGraphicsObj->SetZBufferState(true); 

問題是什麼都沒有發生。無論我畫的是什麼,都會出現在屏幕上(我使用一個小的四邊形繪製),但模擬的任何部分實際上都沒有運行。如果需要,我可以提供着色器代碼,但是我確定它可以工作,因爲我之前在CPU上使用相同的算法實現了這一點。我只是不確定D3D渲染目標的工作效果如何,以及我是否每幀畫出錯誤。

EDIT 1: 下面是開始和結束呈現幀緩衝器的功能的代碼:

void D3DFrameBuffer::BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const { 

    ID3D11DeviceContext *context = pD3dGraphicsObject->GetDeviceContext(); 

context->OMSetRenderTargets(1, &(mRenderTargetView._Myptr), pD3dGraphicsObject->GetDepthStencilView()); 

float color[4]; 

// Setup the color to clear the buffer to. 
color[0] = clearRed; 
color[1] = clearGreen; 
color[2] = clearBlue; 
color[3] = clearAlpha; 

// Clear the back buffer. 
context->ClearRenderTargetView(mRenderTargetView.get(), color); 

// Clear the depth buffer. 
context->ClearDepthStencilView(pD3dGraphicsObject->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0); 

void D3DFrameBuffer::EndRender() const { 
    pD3dGraphicsObject->SetBackBufferRenderTarget(); 
} 

編輯2好的,我在我建立我發現我了DirectX調試層使用SRV作爲渲染目標,而它仍然在着色器中綁定到像素階段。我在使用波形着色器進行渲染後,通過將着色器資源設置爲NULL來解決此問題,但問題仍然存在 - 實際上沒有任何操作或更新。我從這裏拿到了渲染目標代碼,並稍加修改,如果有任何幫助的話:http://rastertek.com/dx11tut22.html

回答

2

好吧,據我所知,正確的你需要一個多遍渲染紋理。

Basiacally你做它像我這裏描述的:link

  • 您創造既D3D11_BIND_SHADER_RESOURCED3D11_BIND_RENDER_TARGET綁定標誌SRVs。
  • 您ctreating從紋理
  • 您可以設置第一個紋理作爲輸入(*SetShaderResources())和第二個紋理作爲輸出渲染目標(OMSetRenderTargets()
  • Draw()*
  • 那麼你綁定第二個紋理作爲輸入,第三作爲輸出
  • Draw()*

附加建議:

  1. 如果您的目標GPU能夠從非計算着色器寫入無人機,則可以使用它。它更簡單,更不容易出錯。
  2. 如果您的目標GPU合適,請考慮使用計算着色器。我很樂意不客氣。
  3. 不要忘記啓用DirectX調試圖層。有時我們會犯明顯的錯誤,調試輸出可能會指向它們。
  4. 使用圖形調試器在每次繪製調用後檢查紋理。

編輯1:

依我之見,你叫BeginRenderOMSetRenderTargets只有一次,所以,所有的渲染進入mRenderTargetView。但你需要的是交錯:

SetSRV(texture1); 
SetRT(texture2); 
Draw(); 
SetSRV(texture2); 
SetRT(texture3); 
Draw(); 
SetSRV(texture3); 
SetRT(backBuffer); 
Draw(); 

此外,我們不知道什麼是mRenderTargetView呢。

所以,前

result = mColorQuad->Render(&viewMatrix,&orthoMatrix); 

地方必須OMSetRenderTargets

可能最好查看您的Begin()/End()設計,使資源綁定更清晰可見。

快樂編碼! =)

+0

對不起,但不是我已經在做什麼?我的FrameBuffer BeginRender函數綁定其中的資源進行繪製,並由GetTextureResource檢索它。另外耶 - 我想嘗試計算着色器,但是我想首先根據自己的知識來完成這項工作。可能是 – Valentin

+0

,但我不知道你的'BeginRender'函數是幹什麼的。如果你確信你的代碼編寫正確,只需使用圖形調試器來查看出了什麼問題。我們沒有太多可以幫助你。 – Drop

+0

順便說一句,我沒有看到你綁定渲染目標的地方。 – Drop