我对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
<VertexPositionNormalTexture>(
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<VertexPositionColor>(
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)如果这不正常,可能是什么原因以及调试错误的解决方案/好方法。
我很感激有任何帮助来解决这个问题! :)
答案 0 :(得分:6)
听起来你已经关闭了深度缓冲区。也许你手绘精灵? (使用SpriteBatch将改变正常3D绘图所需的各种渲染状态。)
在绘制任何3D对象之前尝试添加此行代码:
GraphicsDevice.RenderState.DepthBufferEnable = true;
相关链接:
对于深度缓冲区(或“Z缓冲区”)的解释,您可以查看wikipedia article。
简要描述深度缓冲区:它基本上是场景的位图图像,用于存储每个像素“进入”屏幕的深度(深度)。当您去绘制第二个对象时,它将首先计算它将要绘制的每个像素的“深度” - 并且在已经存在“前面”对象的区域(深度值更近的像素)中深度缓冲区,它将简单地跳过这些像素的绘图。
(你的常规网格没有问题的原因可能归功于backface-culling并且你的网格没有按照从前到后的顺序绘制任何“重叠位”。)
至于调试这种错误的好方法(奇怪的深度缓冲问题,错误的渲染状态,以及大多数其他渲染输出不符合预期的情况),我强烈建议安装DirectX SDK和learning to use PIX
答案 1 :(得分:4)
感谢您回答这个问题!只是对任何想知道这个答案的人进行跟进。在xna 4.0中,它已经发生了一些变化。
某些3D图块对象对其他3D对象是透明的。这是因为删除了:
GraphicsDevice.RenderState.DepthBufferEnable = true;
在XNA 4中,它被替换为:
DepthStencilState depthBufferState = new DepthStencilState();
depthBufferState.DepthBufferEnable = true;
GraphicsDevice.DepthStencilState = depthBufferState;