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

Vec*_*vox 2 c# primitive xna drawing

我对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();
Run Code Online (Sandbox Code Playgroud)

我的效果也有这些属性:

        this.effect.TextureEnabled = true;
        this.effect.Texture = texture;
Run Code Online (Sandbox Code Playgroud)

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

假设我在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
Run Code Online (Sandbox Code Playgroud)

所以我真正要问的是:

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

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

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

And*_*ell 6

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

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

GraphicsDevice.RenderState.DepthBufferEnable = true;
Run Code Online (Sandbox Code Playgroud)

相关链接:

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

简要描述深度缓冲区:它基本上是场景的位图图像,用于存储每个像素"进入"屏幕的深度(深度).当您去绘制第二个对象时,它将首先计算它将要绘制的每个像素的"深度" - 并且在已经存在"前面"对象的区域(深度值更近的像素)中深度缓冲区,它将简单地跳过那些像素的绘图.

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

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


Boj*_*ojo 5

感谢您回答这个问题!只是对其他想要了解此答案的人进行跟进。在 xna 4.0 中,它发生了一些变化。

一些 3D 平铺对象对其他 3D 对象是透明的。这是由于删除了:

GraphicsDevice.RenderState.DepthBufferEnable = true;
Run Code Online (Sandbox Code Playgroud)

在 XNA 4 中,这被替换为:

DepthStencilState depthBufferState = new DepthStencilState(); 
depthBufferState.DepthBufferEnable = true;
GraphicsDevice.DepthStencilState = depthBufferState;
Run Code Online (Sandbox Code Playgroud)

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