C++ 为什么DirectXToolkit会破坏我的深度测试
我确信我只是错过了一些简单的步骤,到目前为止我太盲目而没有注意到,但我似乎根本无法让深度测试发挥作用。这是与DirectX 11 应该设置所有这些的代码:C++ 为什么DirectXToolkit会破坏我的深度测试,c++,graphics,directx,depth-testing,directxtk,C++,Graphics,Directx,Depth Testing,Directxtk,我确信我只是错过了一些简单的步骤,到目前为止我太盲目而没有注意到,但我似乎根本无法让深度测试发挥作用。这是与DirectX 11 应该设置所有这些的代码: DXGI\u SWAP\u CHAIN\u DESC swapDesc={}; swapDesc.BufferDesc.Width=0; swapDesc.BufferDesc.Height=0; swapDesc.BufferDesc.Format=DXGI_Format_B8G8R8A8_UNORM; swapDesc.BufferDes
DXGI\u SWAP\u CHAIN\u DESC swapDesc={};
swapDesc.BufferDesc.Width=0;
swapDesc.BufferDesc.Height=0;
swapDesc.BufferDesc.Format=DXGI_Format_B8G8R8A8_UNORM;
swapDesc.BufferDesc.RefreshRate.Numerator=0;
swapDesc.BufferDesc.RefreshRate.Denominor=1;
swapDesc.BufferDesc.Scaling=DXGI_MODE_Scaling_未指定;
swapDesc.BufferDesc.ScanlineOrdering=DXGI\u MODE\u SCANLINE\u ORDER\u未指定;
swapDesc.SampleDesc.Count=1;
swapDesc.SampleDesc.Quality=0;
swapDesc.BufferUsage=DXGI\u USAGE\u RENDER\u TARGET\u输出;
swapDesc.BufferCount=1;
swapDesc.OutputWindow=hwnd;
swapDesc.Windowed=TRUE;
swapDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD;
swapDesc.Flags=0;
UINT flg=0;
#如果MAGE_调试
flg |=D3D11_创建_设备_调试;
#恩迪夫
GFX_-THROW_-INFO(D3D11CreateDeviceAndSwapChain(nullptr、D3D_-DRIVER_-TYPE_-HARDWARE、nullptr、,
flg,
nullptr,0,
D3D11_SDK_版本、&swapDesc、&mSwap、&mDevice、nullptr、,
&mContext);
COMptr backBuffer;
GFX_THROW_INFO(mSwap->GetBuffer(0,uidof(ID3D11Resource),&backBuffer));
GFX_THROW_INFO(mDevice->CreateRenderTargetView(backBuffer.Get()、nullptr和mTarget));
日志信息(“设置深度模具尺寸({},{})”,宽度,高度);
COMptr深度模板;
D3D11_TEXTURE2D_DESC texDesc={};
texDesc.Width=宽度;
texDesc.Height=高度;
texDesc.MipLevels=1;
texDesc.ArraySize=1;
texDesc.Format=DXGI_Format_D32_FLOAT;
texDesc.SampleDesc.Count=1;
texDesc.SampleDesc.Quality=0;
texDesc.Usage=D3D11_Usage_默认值;
texDesc.BindFlags=D3D11_BIND_DEPTH_模具;
GFX_抛出_信息(mDevice->CreateTexture2D(&texDesc、nullptr和depthStencil));
D3D11_DEPTH_STENCIL_DESC DEPTH={};
depth.deptenable=TRUE;
depth.DepthWriteMask=D3D11_depth_WRITE_MASK_ALL;
depth.DepthFunc=D3D11\u小于;
COMptr深度状态;
GFX_抛出_信息(mDevice->CreateDepthStencilState(&depth,&depthState));
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc={};
dsvDesc.Format=DXGI_Format_D32_FLOAT;
dsvDesc.ViewDimension=D3D11\u DSV\u DIMENSION\u纹理2D;
dsvDesc.Texture2D.mipsicle=0;
GFX_THROW_INFO(mDevice->CreateDepthStencilView(depthStencil.Get(),&dsvDesc,&mDepthStencilView));
mContext->OMSetDepthStencilState(depthState.Get(),1);
mContext->OMSetRenderTargets(1,mTarget.GetAddressOf(),mDepthStencilView.Get());
日志信息(“设置视口尺寸({},{})”,宽度,高度;
D3D11_视口vp;
vp.Width=(浮动)宽度;
vp.高度=(浮动)高度;
vp.MinDepth=0.0f;
vp.MaxDepth=1.0f;
vp.TopLeftX=0.0f;
vp.TopLeftY=0.0f;
mContext->rsset视口(1,&vp);
当然,在每一帧之前,我称之为:
mContext->ClearRenderTargetView(mTarget.Get(), color);
mContext->ClearDepthStencilView(mDepthStencilView.Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
但不幸的是,结果是这样的(请注意,crysis纳米电路模型位于地精头部的后面),我相信这也可能是地精模型渲染错误的原因,即使是单独渲染,但还没有弄清楚这一点
从一个角度看,只有地精
如果有人能帮我找出它为什么不起作用,我将不胜感激
编辑
在一些更令人沮丧的测试之后,我发现深度测试被破坏了,因为我正在使用DirectX工具包的SpriteBatch和SpriteFont类进行一些测试文本渲染。以前有人遇到过这个问题吗?除了文本渲染和加载dds纹理之外,我真的不想/需要该工具包,所以我希望如果我想使用这些类,我不需要大幅更改现有代码?DirectX工具包不像传统的D3DX9/D3DX10 sprite那样“捕获/恢复”状态。这是低效的,并且依赖一些黑客后门功能来捕获Direct3D 10+的“状态块”。在大多数情况下,您已经将常用状态的大部分设置为下一个draw调用
相反,我已经完整地记录了每个类影响的所有状态。在DirectX工具包对象呈现后,您需要更改所有必需的状态。例如,文档说明:
SpriteBatch
使用以下状态:
- 混合状态
- 恒定缓冲区(顶点着色器阶段,插槽0)
- 深度状态
- 索引缓冲区
- 输入布局
- 像素着色器
- 本原拓扑
- 光栅化状态
- 采样状态(像素着色器阶段,插槽0)
- 着色器资源(像素着色器阶段,插槽0)
- 顶点缓冲区(插槽0)
- 顶点着色器
SpriteBatch::End
后将DepthStencilState设置为您想要使用的
作为状态管理的一般习惯,您应该设置每个框架所依赖的所有状态。在Direct3D 11中,调用Present
时的“最后状态”在下一帧开始时仍然存在,但在DirectX 12中并非如此。因此,您应该养成在新帧开始时设置所有内容的习惯,如当前渲染目标、视口、整个场景的渲染状态等
例如,大多数“HUD”渲染最后完成,因此SpriteBatch的状态更改通常会在下一帧开始时重置——同样,假设您在帧开始时设置了所需的状态,而不是假设它在许多帧上保持不变
TL;DR:清除渲染目标后,将此代码移动到每帧:
mContext->OMSetDepthStencilState(depthState.Get(), 1);
mContext->OMSetRenderTargets(1, mTarget.GetAddressOf(), mDepthStencilView.Get());
D3D11_VIEWPORT vp = { 0.f, 0.f, float(width), float(height), D3D11_MIN_DEPTH, D3D11_MAX_DEPTH };
mContext->RSSetViewports(1, &vp);
非常感谢!添加
RSSetViewports
,OMSetDepthStencilState