gpt4 book ai didi

c++ - 为什么需要为每一帧调用 OMSetRenderTargets DirectX 方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:41:42 30 4
gpt4 key购买 nike

我正在开发一个 Windows UWP 应用程序,它包含一个用 C++ 实现的 DirectX 11 View (继承自 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。

我的思路大致是这样的: View 实例化渲染器并将渲染器指针传递给 ID3D11RenderTargetView 和 ID3D11DepthStencilView。这些对象只要 View 存在就一直存在,我认为使用 OMSetRenderTargets 方法我基本上是在告诉系统“嘿,这是您必须使用的渲染目标 View 和模板 View ”。为什么我需要每一帧都告诉它这个?不应该只是“嘿,使用这个渲染目标 View 和模板 View ,直到我告诉你使用其他东西”。

我认为告诉它一次就足够了,这就是为什么我将对 OMSetRenderTargets 的调用移动到 View 调用以设置 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);
}

然而,这显然是不够的,因为如果我那样做,就不会再渲染任何东西(可能除了第一帧,但那是全白的,所以我不完全确定)。

我确信它不再正确呈现的事实是由该方法调用的移动引起的,因为这就是我在这里所做的全部更改。

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

最佳答案

有很多原因会导致 Rendertarget 被设置为 null。我发现的主要原因是在文档中,如果您试图从设置为写入的资源中读取(如在渲染目标中)。在不知道其余设置的情况下,如果您正在使用复制资源或 resolvesubresource,那么这可能会解除这些纹理与渲染目标的绑定(bind)。

Direct X 11 - OMSetRenderTargetrs

当您使用 UWP 时,我假设您正在做其中之一。因此,您将在那时解除约束。如果您想检查 OM 中是否存在当前渲染目标,您可以使用 GetRenderTargets 调用。

关于c++ - 为什么需要为每一帧调用 OMSetRenderTargets DirectX 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48693344/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com