C++ 中的 DirectX 10 HUD
我正在尝试在 DirectX 10 中制作自定义 HUD 系统。我当前的攻击方法是简单地使用网格树来表示不同级别的菜单。
我相信,通过禁用深度测试,我可以制作一个网格,将其粘贴到背景中我的 3d 世界的其余部分之上。为了实现此目的,我尝试使用 D3D10_DEPTH_STENCIL_DESC,其中我将 DepthEnable 选项设置为 false。然后,我将此 D3D10_DEPTH_STENCIL_DESC 绑定到模板状态,然后在绘制网格之前激活该状态。到目前为止,这给我留下了一个缺失的网格。
我的问题实际上可以归结为:我是否走在正确的轨道上,或者我是否需要重新思考这个问题?另外,如果这是解决这个问题的一个很好的计划,那么我是否忘记考虑什么?
下面是我尝试获取此 HUD 的代码位
创建 D3D10_DEPTH_STENCIL_DESC:
//HUD Elements
D3D10_DEPTH_STENCIL_DESC dsDesc;
//Depth Settings
dsDesc.DepthEnable = false;
dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
//Stencil settings
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xff;
dsDesc.StencilWriteMask = 0xff;
//Always pass the stencil test, and replace the current stencil value with
// the stencil reference value 1
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// We are not rendering backfacing polygons, so these settings do not matter.
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
//Bind HUD to a stencil
HR(md3dDevice->CreateDepthStencilState(&dsDesc,&hud));
为了绘制,我只需执行以下操作:
md3dDevice->OMSetDepthStencilState(hud, 1);
menu.draw(mVP);
I'm attempting to make a custom HUD system in DirectX 10. My current method of attack is to simply use a tree of meshes to represent different levels of the menu.
I believe that by disabling the Depth Test I can make a mesh which is pasted up above the rest of my 3d world in the background. To achieve this I've attempted to use a D3D10_DEPTH_STENCIL_DESC whereby I set DepthEnable option to false. I then bind this D3D10_DEPTH_STENCIL_DESC to a stencil state which I then activate just before I draw my mesh. This thus far has left me with a missing mesh.
My question really boils down to : Am I on the right track with this, Or do I need to re-think this altogether? Additionally if this is a good plan of attack on this problem, is there anything that I am forgetting to take into consideration?
Below are the bits of code where I attempt to get this HUD
Creating the D3D10_DEPTH_STENCIL_DESC:
//HUD Elements
D3D10_DEPTH_STENCIL_DESC dsDesc;
//Depth Settings
dsDesc.DepthEnable = false;
dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
//Stencil settings
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xff;
dsDesc.StencilWriteMask = 0xff;
//Always pass the stencil test, and replace the current stencil value with
// the stencil reference value 1
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// We are not rendering backfacing polygons, so these settings do not matter.
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_REPLACE;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
//Bind HUD to a stencil
HR(md3dDevice->CreateDepthStencilState(&dsDesc,&hud));
To Draw I simply do:
md3dDevice->OMSetDepthStencilState(hud, 1);
menu.draw(mVP);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,你找对了树。但要记住的是,如果您的菜单系统是分层的,那么您必须从后到前绘制,因为 Z 缓冲区无法帮助您。这将意味着相当多的透支。
另一种解决方案允许您通过使用 Z 缓冲区(尤其是使用早期 Z 拒绝硬件支持)和从前到后绘制来限制透支量。然而,你会遇到它与场景交互的问题。只需在渲染菜单之前清除 Z 缓冲区即可轻松解决此问题。
老实说,您最好使用 Z 缓冲区清除方法,因为这意味着您可以更有效地批量处理绘制调用。即,不断映射和填充 ID3D10Buffer 会比执行一次然后不断重新绘制它要慢。当然,当状态发生变化时,您可能需要编辑缓冲区,但您可以限制编辑的缓冲区量,并且当没有状态变化时,您不会不必要地消耗 CPU。
Yeah you are barking up the right tree. Something to bear in mind though is that if your menu system is layered then you HAVE to draw back to front as the Z-buffer can't help you. This will mean quite a bit of overdraw.
Another solution allows you to limit the amount of overdraw by using a Z-Buffer (and especially using the early Z rejects the hardware supports) and drawing front to back. However you then have the problem of it interacting with your scene. This can easily be fixed by simply clearing the Z-Buffer before rendering your menu.
TBH though you'd be best off using the Z-Buffer clearing method as it means you can batch together draw calls far more efficiently. ie Constantly mapping and filling an ID3D10Buffer will be slower than doing it once and then continually re-drawing it. Sure when the state changes you may need to edit the buffer but you can limit how much of the buffer you edit AND when there is no state change you aren't chewing through the CPU unnecessarily.