渲染到纹理 - ClearRenderTargetView()可以工作,但没有任何对象渲染到纹理(渲染到屏幕工作正常)

时间:2015-08-11 00:17:54

标签: c++ directx rendering directx-11 render-to-texture

我尝试将场景渲染为纹理,然后将其显示在屏幕的一角。

我虽然我可以这样做:

  1. 渲染场景(我的Engine::render()方法将设置着色器并进行绘制调用) - 正常工作
  2. 将渲染目标更改为纹理。
  3. 再次渲染场景 - 不起作用。 context->ClearRenderTargetView(texture->getRenderTargetView(), { 1.0f, 0.0f, 0.0f, 1.0f } ) 将纹理设置为红色(步骤1中的场景。我使用不同的颜色),但 none 对象正在其上呈现。
  4. 将渲染目标更改回原始目标。
  5. 最后一次渲染场景,角落处的矩形具有我在步骤3中渲染的纹理。正常工作。我看到了场景,角落里的小矩形也是如此。问题是,它只是红色(在第3步中渲染出错了,我猜)。
  6. 结果(应该是“图像中的图像”而不是红色矩形): enter image description here

    步骤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)
    

    render()方法不会改变(它在步骤1中起作用,为什么它在渲染到纹理时不起作用?)并以swapChain->Present(0, 0)结束。

    我知道ClearRenderTargetView影响我的纹理(没有它,它不会改变颜色为红色)。但其余的渲染要么没有输出,要么还有其他问题。

    我错过了什么吗?

    我根据this tutorial创建纹理,着色器资源视图并为其渲染目标(可能我的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);
    

    深度缓冲区:

    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;
    

    这就是交换链:

    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;
    

    我以这样的方式创建默认的渲染目标视图:

    //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 个答案:

答案 0 :(得分:0)

经过一些调试,正如@Gnietschow建议的那样,我发现了一个错误:

  

D3D11错误:ID3D11DeviceContext :: OMSetRenderTargets:

     

插槽0处的RenderTargetView不兼容   DepthStencilView。 DepthStencilViews只能与。一起使用   RenderTargetViews如果视图的有效尺寸相等,   以及资源类型,多重采样计数和多重采样   质量。

     

插槽0处的RenderTargetView具有(w:1680,h:1050,as:1),而   资源是Texture2D,(mc:1,mq:0)

     

DepthStencilView有   (w:1680,h:1050,as:1),而Resource是Texture2D   的(MC:8,MQ:16)

基本上,我的渲染目标(纹理)在我的后缓冲区/深度缓冲区没有使用抗锯齿。

我必须在SampleDesc.Count1中将SampleDesc.Quality更改为0并将DXGI_SWAP_CHAIN_DESC更改为D3D11_TEXTURE2D_DESC以匹配纹理中的值我渲染。换句话说,我必须在渲染到纹理时关闭抗锯齿。

我想知道,为什么渲染到纹理不支持抗锯齿?当我将SampleDesc.CountSampleDesc.Quality设置为我的标准值(8和{对于我的纹理渲染目标,16失败并且“无效参数”(即使我在任何地方都使用相同的值),{1}},我的GPU在渲染场景时效果很好。