XNA – 以正确的顺序绘制四边形(和基元)

我对XNA中的3D内容很新,不幸的是我遇到了一个问题我无法找到解决方案。 (甚至不知道问题是什么)。

简而言之:我在游戏中使用以下方法绘制四边形:

effect.World = Matrix.Identity * Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateTranslation(Position); // Apply camera-matrixes effect.View = viewMatrix; effect.Projection = projectionMatrix; graphics.VertexDeclaration = vertDec; // Begin effect drawing effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); graphics.DrawUserIndexedPrimitives ( PrimitiveType.TriangleList, quad.Vertices, 0, 4, quad.Indexes, 0, 2); pass.End(); } effect.End(); 

我的效果也有这些属性:

  this.effect.TextureEnabled = true; this.effect.Texture = texture; 

它有效。 我的四边形绘制得很好,我很高兴。 但是有一个小问题。 如果一个四边形位于另一个四边形或常规模型后面,那么确定在顶部绘制的四边形的方式就是我绘制它们的顺序。

假设我在Quad B之前绘制了Quad A,那么B将显示在Quad A的顶部,即使它在Z轴上小于40个单位。 我必须说,看起来很混乱! ;)

现在我的常规网格没有像这样的任何问题,当涉及原语时,事情会变得混乱。 绘制常规线也是同样的问题:

  graphics.DrawUserIndexedPrimitives( PrimitiveType.LineStrip, pointList, 0, // vertex buffer offset to add to each element of the index buffer 6, // number of vertices in pointList new short[] { 0, 1 }, // the index buffer 0, // first index element to read 1 // number of primitives to draw 

所以我真正要问的是:

A)这是正常的吗? 我应该建立一个特殊的引擎,决定何时绘制什么? 我可以通过在合适的时间绘制内容轻松地在我的项目中解决这个问题,但我可以想象一个我无法想象的游戏。 例如,fps无法在整个地方绘制广告牌! ;)

B)如果这不正常,可能是什么原因以及调试错误的解决方案/好方法。

我很感激任何帮助来解决这个问题! 🙂

听起来你已经关闭了深度缓冲区。 也许你手头上画的是精灵? (使用SpriteBatch将改变正常3D绘图所需的各种渲染状态。)

在绘制任何3D对象之前尝试添加此行代码:

 GraphicsDevice.RenderState.DepthBufferEnable = true; 

相关链接:

  • SpriteBatch和renderstates(适用于XNA 3.1)
  • XNA Game Studio 4.0中的SpriteBatch和渲染
  • RenderState.DepthBufferEnable属性

有关深度缓冲区(或“Z缓冲区”)的说明,您可以查看维基百科文章 。

简要描述深度缓冲区:它基本上是场景的位图图像,用于存储每个像素“进入”屏幕的深度(深度)。 当你去绘制你的第二个物体时,它将首先计算它将要绘制的每个像素的“深度” – 并且在已经有一个物体“前面”(深度值更近的像素)的区域中深度缓冲区,它将简单地跳过这些像素的绘图。

(你的常规网格没有问题的原因可能是由于背面剔除和你的网格没有任何“重叠位”按照从前到后的顺序绘制。)

至于调试这种错误的好方法(奇怪的深度缓冲区问题,错误的渲染状态,以及大多数其他渲染输出不符合预期的情况),我强烈建议安装DirectX SDK并学习使用PIX 。

谢谢你回答这个问题! 只是对任何想知道这个答案的人进行跟进。 在xna 4.0中,它已经发生了一些变化。

某些3D图块对象对其他3D对象是透明的。 这是由于删除:

 GraphicsDevice.RenderState.DepthBufferEnable = true; 

在XNA 4中,这被替换为:

 DepthStencilState depthBufferState = new DepthStencilState(); depthBufferState.DepthBufferEnable = true; GraphicsDevice.DepthStencilState = depthBufferState; 

取自此来源: http : //www.hexworld.co.uk/blog/? cat = 9