Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ DirectX使用多个渲染目标作为彼此的输入_C++_Directx_Directx 11 - Fatal编程技术网

C++ DirectX使用多个渲染目标作为彼此的输入

C++ DirectX使用多个渲染目标作为彼此的输入,c++,directx,directx-11,C++,Directx,Directx 11,我有一个相当简单的DirectX 11框架设置,我想用于各种2D模拟。我目前正在尝试在GPU上实现2D波动方程。它要求我将模拟的网格状态保持在前两个时间步,以便计算新的时间步 我是这样做的-我有一个名为FrameBuffer的类,它有以下公共方法: bool Initialize(D3DGraphicsObject* graphicsObject, int width, int height); void BeginRender(float clearRed, float clearGreen

我有一个相当简单的DirectX 11框架设置,我想用于各种2D模拟。我目前正在尝试在GPU上实现2D波动方程。它要求我将模拟的网格状态保持在前两个时间步,以便计算新的时间步

我是这样做的-我有一个名为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渲染目标的效果如何,以及是否每一帧都画错了

编辑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作为渲染目标,而它仍然绑定到着色器中的像素阶段。在使用wave着色器渲染后,我通过将着色器资源设置为NULL修复了该问题,但问题仍然存在-实际上没有运行或更新任何内容。我从这里获取了渲染目标代码,并对其进行了轻微修改,如果有帮助的话:

好的,正如我所理解的,您需要对纹理进行多通道渲染

基本上就像我在这里描述的那样:

  • 您可以使用
    D3D11_BIND_SHADER_RESOURCE
    D3D11_BIND_RENDER_TARGET
    BIND标志创建SRV
  • 可以从纹理渲染目标
  • 将第一个纹理设置为输入(
    *SetShaderResources()
    ),将第二个纹理设置为输出(
    OMSetRenderTargets()
  • 您可以
    Draw()*
  • 然后绑定第二个纹理作为输入,第三个作为输出
  • Draw()*
  • 等等
其他建议:

  • 如果您的目标GPU能够从非计算着色器写入无人机,您可以使用它。它更简单,更不容易出错
  • 如果你的目标GPU适合,考虑使用计算着色器。这是我的荣幸
  • 不要忘记启用DirectX调试层。有时我们会出现明显的错误,调试输出可能会指向这些错误
  • 在每次绘制调用后,使用图形调试器查看纹理
  • 编辑1:

    如我所见,您只调用一次
    BeginRender
    OMSetRenderTargets
    ,因此,所有渲染都进入
    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()
    设计,使资源绑定更清晰可见


    快乐编码!=)

    对不起,这不是我正在做的吗?My FrameBuffer BeginRender函数绑定其中的资源以进行绘图,GetTextureResource检索该资源。也是的-我想试试计算着色器,但我想先让它工作起来,以我自己的知识。可能吧,但我不知道你的
    BeginRender
    函数做什么。如果您确信您的代码编写正确,只需使用图形调试器查看错误。我们帮不了你多少忙。顺便说一句,我看不出你在哪里绑定渲染目标。大家好,这里不是我链接更多代码的地方,而是我基于帧缓冲区类的地方:在那里你可以看到他是如何创建和使用它的,这与我想做的有点不同。你使用过任何图形调试器吗?