为什么有必要为每个帧

时间:2018-02-08 19:28:58

标签: c++ uwp directx

我正在开发一个Windows UWP应用程序,该应用程序包含在C ++中实现的DirectX 11视图(继承自Windows :: UI :: Xaml :: Controls :: SwapChainPanel)。在优化最终呈现框架的方法时,我遇到了一个我不完全理解的细微之处,而对于我的生活,却找不到任何有用的文档(无论是书籍还是在线资源)。

所以,我的渲染方法目前看起来如下

void Renderer::RenderFrame()
{
  _d3dContext->OMSetRenderTargets(1, &_renderTargetView, _depthStencilView);
  _d3dContext->ClearRenderTargetView(_renderTargetView, reinterpret_cast<const float*>(&_backgroundColor));
  _d3dContext->ClearDepthStencilView(_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
  _d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  _d3dContext->DrawIndexed(_model->GetIndicesCount(), 0, 0);
}

到目前为止一切正常,模型正确渲染,一切看起来都符合预期。在优化代码时,我认为不必为每一帧设置渲染目标,即每帧都不需要调用OMSetRenderTargets。

我的思维过程基本如下: 视图实例化渲染器并将渲染器指针传递给ID3D11RenderTargetView和ID3D11DepthStencilView。这些对象只要视图是活着的,并且我用OMSetRenderTargets方法认为我基本上告诉系统&#34;嘿,这是渲染目标视图和模板查看你必须使用&#34;。为什么我需要每帧都说出来?不应该只是&#34;嘿,使用这个渲染目标视图和模板视图,直到我告诉你使用别的东西&#34;。

我在考虑告诉它一次是足够的,这就是为什么我将调用OMSetRenderTargets调用到视图调用设置ID3D11RenderTargetView和ID3D11DepthStencilView的方法,然后如下所示:

void Renderer::SetRenderTargetView(ID3D11RenderTargetView* renderTargetView, ID3D11DepthStencilView* depthStencilView)
{
  _renderTargetView = renderTargetView;
  _depthStencilView = depthStencilView;

  _d3dContext->OMSetRenderTargets(1, &_renderTargetView, _depthStencilView);
}

RenderFrame方法如下所示:

void Renderer::RenderFrame()
{
  _d3dContext->ClearRenderTargetView(_renderTargetView, reinterpret_cast<const float*>(&_backgroundColor));
  _d3dContext->ClearDepthStencilView(_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
  _d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
  _d3dContext->DrawIndexed(_model->GetIndicesCount(), 0, 0);
}

然而,这显然是不够的,因为如果我这样做就没有任何渲染了(可能是第一帧除外,但这都是白色的,所以我并不完全确定)。 / p>

我确信它不再正确渲染的事实是由于该方法调用的移动造成的,因为这就是我在这里所做的一切。

有没有人知道为什么需要为每一帧调用OMSetRenderTargets?通过调用该方法,我还可以指示系统做什么?有人能指出我提供一些有用的文档吗?

1 个答案:

答案 0 :(得分:0)

有许多原因导致Rendertarget设置为null。我找到的主要原因是在文档中,如果您尝试从设置为write的资源中读取(如在rendertarget中)。在不知道其余设置的情况下,如果您正在使用复制资源或resolvesubresource,那么这可能会解除渲染目标中的这些纹理。

Direct X 11 - OMSetRenderTargetrs

当你使用UWP时,我会假设你正在做其中一个。因此,您将在那时取消绑定。如果要在OM中检查当前rendertarget是否存在,可以使用GetRenderTargets调用。