DirectX 9 Triangle List通过自身绘制,如何设置深度缓冲区?

时间:2013-07-24 02:32:41

标签: c# directx-9

我无法分解我在DirectX 9应用程序中看到的错误。我正在使用顶点缓冲区渲染一个三角形列表,没有剔除(错误显示出来)。当我从某个方向观察渲染的三角形条带时,条带的底部(最远的部分)将绘制应该在其上方的部分。用文字解释有点困难,所以我会尝试通过图像来展示正在发生的事情。

Expected drawing

以上是我期望看到的,锥体的尖端呈现在黑色底座上方。当朝这个方向看时它起作用。

Why is the base drawing ontop of the cone!?

以上是我从坏方向看的时候得到的。注意黑色底座如何在锥体的中间绘制。这太可怕了,根本不是我想要发生的事情。

enter image description here

有趣的是,如果你走到另一边看坏方向,那么当基座应该是绘制的时候,就是在基座上方绘制的圆锥(如上所示)。如果使用反向剔除(CounterClockwise),则不会出现这种情况。我希望这可以给一些有更多经验的人找出错误的帮助。

无论如何,我甚至不知道从哪里开始跟踪这个bug,因为我对DirectX还不熟悉。我认为可能有很多原因:

  • 深度缓冲区太不精确
  • 我没有正确设置深度缓冲
  • 我没有按照正确的顺序定义我的顶点
  • 我没有正确绘制顶点缓冲区
  • ...

在此应用程序中,没有照明设置,我正在使用CustomVertex.PositionTextured作为顶点。我希望有人可以帮助我缩小这个问题的范围,因为我认为(希望)它是一个相当简单的问题,但我已经坚持了好几个小时了。

修改

我的猜测是深度缓冲区尚未初始化。事实上,我还没有这样做。我用于初始化Device的代码是:

 presentParameters.SwapEffect = SwapEffect.Copy;

 device = new Device(0, DeviceType.Reference, this, CreateFlags.SoftwareVertexProcessing, presentParameters);

当然,这并没有设置深度缓冲区。但它至少显示了我所展示的内容。我尝试了以下代码来尝试设置深度缓冲区:

presentParameters.SwapEffect = SwapEffect.Copy;
presentParameters.EnableAutoDepthStencil = true;
presentParameters.AutoDepthStencilFormat = DepthFormat.D16;

device = new Device(0, DeviceType.Reference, this, CreateFlags.SoftwareVertexProcessing, presentParameters);
device.RenderState.ZBufferEnable = true;

现在模型根本不显示。这是我清理和绘制场景的方式:

device.Clear(ClearFlags.Target, Color.SlateGray, 1.0f, 0);

SetupCamera();
SetupTransformations();

//Begin scene
device.BeginScene();

Draw();

device.EndScene();
device.Present();

在设置深度缓冲区时我做错了什么?

EDIT2

我注意到设备创建后我的设备有错误:

+       RasterStatus    'device.RasterStatus' threw an exception of type 'Microsoft.DirectX.Direct3D.InvalidCallException'  Microsoft.DirectX.Direct3D.RasterStatus {Microsoft.DirectX.Direct3D.InvalidCallException}

这两种情况都会发生。我应该提到的一件事是我在表格上画这个。我有另一个应用程序,我正在寻求帮助,将其绘制到自定义用户控件,它没有此错误。无论如何,我不知道如何解码这个错误,谷歌一直没有帮助。

切换到DeviceType.Hardware时不会发生这种情况。我仍在使用表格,这会是一个问题吗?

1 个答案:

答案 0 :(得分:0)

问题是我忘了清除设备中的zbuffer。清除呼叫:

device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SlateGray, 1.0f, 0);

现在它有效!