我尝试将场景渲染为纹理,然后将其显示在屏幕的一角。
我虽然我可以这样做:
Engine::render()
方法将设置着色器并进行绘制调用) - 正常工作。context->ClearRenderTargetView(texture->getRenderTargetView(), { 1.0f, 0.0f, 0.0f, 1.0f } )
将纹理设置为红色(步骤1中的场景。我使用不同的颜色),但 none 对象正在其上呈现。步骤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);
答案 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.Count
和1
中将SampleDesc.Quality
更改为0
并将DXGI_SWAP_CHAIN_DESC
更改为D3D11_TEXTURE2D_DESC
以匹配纹理中的值我渲染。换句话说,我必须在渲染到纹理时关闭抗锯齿。
我想知道,为什么渲染到纹理不支持抗锯齿?当我将SampleDesc.Count
和SampleDesc.Quality
设置为我的标准值(8
和{对于我的纹理渲染目标,16
失败并且“无效参数”(即使我在任何地方都使用相同的值),{1}},我的GPU在渲染场景时效果很好。