Rendering to texture - ClearRenderTargetView() works, but none objects are rendered to texture (rendering to screen works fine)

拜拜、爱过 提交于 2019-12-11 09:22:35

问题


I try to render the scene to texture which should be then displayed in corner of the screen.

I though that I can do that this way:

  1. Render the scene (my Engine::render() method that will set shaders and make draw calls) - works ok.
  2. Change render target to the texture.
  3. Render the scene again - does not work. The context->ClearRenderTargetView(texture->getRenderTargetView(), { 1.0f, 0.0f, 0.0f, 1.0f } ) does set my texture to red color (for scene in step 1. I use different color), but none objects are being rendered on it.
  4. Change render target back to original.
  5. Render the scene for the last time, with rectangle at corner that has the texture I've rendered in step 3. - works ok. I see the scene, the little rectangle in the corner too. The problem is, it's just red (something went wrong with rendering in step 3., I guess).

The result (there should be "image in image" instead of red rectangle):

The code for steps 2. - 4.:

context->OMSetRenderTargets(1, &textureRenderTargetView, depthStencilView); 
float bg[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
context->ClearRenderTargetView(textureRenderTargetView, bg); //backgroundColor - red, green, blue, alpha
render();
context->OMSetRenderTargets(1, &myRenderTargetView, depthStencilView); //bind  render target back to previous value (not to texture)

The render() method does not change (it works in step 1., why it doesn't work when I render to texture?) and ends with swapChain->Present(0, 0).

I know that ClearRenderTargetView affects my texture (without it, it's doesn't change color to red). But the rest of rendering either do not output to it or there's another problem.

Did I miss something?

I create the texture, shader resource view and render target for it based on this tutorial (maybe there is an error in my D3D11_TEXTURE2D_DESC?):

D3D11_TEXTURE2D_DESC textureDesc;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;

//1. create render target

ZeroMemory(&textureDesc, sizeof(textureDesc));

//setup the texture description
//we will need to have this texture bound as a render target AND a shader resource
textureDesc.Width = size.getX();
textureDesc.Height = size.getY();
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;

//create the texture
device->CreateTexture2D(&textureDesc, NULL, &textureRenderTarget);

//2. create render target view

//setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;

//create the render target view
device->CreateRenderTargetView(textureRenderTarget, &renderTargetViewDesc, &textureRenderTargetView);

//3. create shader resource view

//setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;

//create the shader resource view.
device->CreateShaderResourceView(textureRenderTarget, &shaderResourceViewDesc, &texture);

The depth buffer:

D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = sampleCount;
descDepth.SampleDesc.Quality = maxQualityLevel;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;

And here goes the swap chain:

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = numerator; //60
sd.BufferDesc.RefreshRate.Denominator = denominator; //1
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = *hwnd;
sd.SampleDesc.Count = sampleCount; //1 (and 0 for quality) to turn off multisampling
sd.SampleDesc.Quality = maxQualityLevel;
sd.Windowed = fullScreen ? FALSE : TRUE;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; //allow full-screen switchin

// Set the scan line ordering and scaling to unspecified.
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// Discard the back buffer contents after presenting.
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

I create the default render target view that way:

//create a render target view
ID3D11Texture2D* pBackBuffer = NULL;
result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
ERROR_HANDLE(SUCCEEDED(result), L"The swapChain->GetBuffer() failed.", MOD_GRAPHIC);

//Create the render target view with the back buffer pointer.
result = device->CreateRenderTargetView(pBackBuffer, NULL, &myRenderTargetView);

回答1:


After some debugging, as @Gnietschow suggested, I have found an error:

D3D11 ERROR: ID3D11DeviceContext::OMSetRenderTargets:

The RenderTargetView at slot 0 is not compatable with the DepthStencilView. DepthStencilViews may only be used with RenderTargetViews if the effective dimensions of the Views are equal, as well as the Resource types, multisample count, and multisample quality.

The RenderTargetView at slot 0 has (w:1680,h:1050,as:1), while the Resource is a Texture2D with (mc:1,mq:0).

The DepthStencilView has (w:1680,h:1050,as:1), while the Resource is a Texture2D with (mc:8,mq:16).

So basically, my render target (texture) was not using anti-aliasing while my back buffer/depth buffer do.

I had to change SampleDesc.Count to 1 and SampleDesc.Quality to 0 in both DXGI_SWAP_CHAIN_DESC and D3D11_TEXTURE2D_DESC to match the values from texture to which I render. In other words I had to turn off anti-aliasing when rendering to texture.

I wonder, why render to texture does not support anti-aliasing? When I set SampleDesc.Count and SampleDesc.Quality to my standard values (8 and 16, those works fine on my GPU when rendering the scene) for my texture render target, the device->CreateTexture2D(...) fails with "invalid parameter" (even when I use those same values everywhere).



来源:https://stackoverflow.com/questions/31931194/rendering-to-texture-clearrendertargetview-works-but-none-objects-are-rende

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!