Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么DirectXToolkit会破坏我的深度测试_C++_Graphics_Directx_Depth Testing_Directxtk - Fatal编程技术网

C++ 为什么DirectXToolkit会破坏我的深度测试

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

我确信我只是错过了一些简单的步骤,到目前为止我太盲目而没有注意到,但我似乎根本无法让深度测试发挥作用。这是与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.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