I built a very simple, okay nothing, program that just clears the render target. Eventually when I call ID3D11DeviceContext::OMSetRenderTargets() the ID3D11RenderTargetView gets removed and I can't see why. My thought is somewhere at the creating of the IDXGISwapChain1 I specified something wrong.
Once:
UINT deviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifdef _DEBUG
deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
GFX_THROW_IF_FAILED(D3D11CreateDevice(
nullptr,
D3D_DRIVER_TYPE_HARDWARE,
nullptr,
deviceFlags,
nullptr,
0u,
D3D11_SDK_VERSION,
&m_pDevice,
&m_featureLevel,
&m_pContext
));
if (m_featureLevel < D3D_FEATURE_LEVEL_11_0)
throw ExceptionMessage(__FILE__, __LINE__, "Graphics device does not support feature level 11.");
Microsoft::WRL::ComPtr<IDXGIFactory2> pFactory = {};
GFX_THROW_IF_FAILED(CreateDXGIFactory(IID_PPV_ARGS(&pFactory)));
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
scDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scDesc.SampleDesc.Count = 1u;
scDesc.SampleDesc.Quality = 0u;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.BufferCount = sc_uBufferCount;
scDesc.Scaling = DXGI_SCALING_NONE;
scDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
scDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
scDesc.Flags = 0u;
GFX_THROW_IF_FAILED(pFactory->CreateSwapChainForHwnd(
m_pDevice.Get(),
t_hWnd,
&scDesc,
nullptr,
nullptr,
&m_pSwapChain
));
m_uWindowWidth = scDesc.Width;
m_uWindowHeight = scDesc.Height;
Microsoft::WRL::ComPtr<ID3D11Resource> pBackBuffer = {};
GFX_THROW_IF_FAILED(m_pSwapChain->GetBuffer(0u, IID_PPV_ARGS(&pBackBuffer)));
GFX_THROW_IF_FAILED(m_pDevice->CreateRenderTargetView(pBackBuffer.Get(), nullptr, &m_pTarget));
and the update method:
float color[] = { (252.0f / 255.0f), (186.0f / 255.0f), (3.0f / 255.0f), 1.0f };
m_pContext->ClearRenderTargetView(m_pTarget.Get(), color);
m_pContext->OMSetRenderTargets(1u, &m_pTarget, nullptr);
if (m_pTarget.Get() == nullptr)
throw ExceptionMessage(__FILE__, __LINE__, "m_pTarget has been set to null");
GFX_THROW_IF_FAILED(m_pSwapChain->Present(1u, 0u));
CodePudding user response:
I assume that you are using Microsoft::WRL::ComPtr
to manage m_pTarget
. So when invoking m_pContext->OMSetRenderTargets(1u, &m_pTarget, nullptr);
an overloaded operator &
is being used rather than just taking an address of pointer to pass it as a pointer to first element of array containing a single pointer. Overloaded operator &
is intended to be used when passing a pointer to pointer value to some initialization function so it releases ownership of the stored pointer therefore you are getting nulls.
You should use GetAddressOf
method
m_pContext->OMSetRenderTargets(1u, m_pTarget.GetAddressOf(), nullptr);
or create a temporary array instead:
::std::array<::ID3D11RenderTargetView *> views{m_pTarget.Get()};
m_pContext->OMSetRenderTargets(views.size(), views.data(), nullptr);