【问题标题】:XNA - Drawing Quads (and primitives) in right orderXNA - 以正确的顺序绘制四边形(和基元)
【发布时间】:2010-06-22 13:14:14
【问题描述】:

我对 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;

而且它有效。我的四边形画得很好,我很高兴。但是有一个小问题。如果一个四边形在另一个四边形或常规模型之后,则确定在顶部绘制哪个四边形的方式是我绘制它们的顺序。

假设我在四边形 B 之前绘制四边形 A,然后 B 将显示在四边形 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) 如果这不正常,可能是什么原因以及什么是调试错误的解决方案/好方法。

如果能帮我解决这个问题,我将不胜感激! :)

【问题讨论】:

  • 顺便说一下,您不必在对 DrawUserIndexedPrimitives 的调用中指定泛型类型 。编译器可以从您传递给函数的参数中判断您想要哪种类型。

标签: c# xna drawing primitive


【解决方案1】:

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

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

GraphicsDevice.RenderState.DepthBufferEnable = true;

相关链接:

有关深度缓冲区(或“Z 缓冲区”)的说明,您可以查看wikipedia article

简要描述深度缓冲区:它基本上是场景的位图图像,用于存储每个像素“进入”屏幕的距离(深度)。当你去绘制你的第二个对象时,它会首先计算它要绘制的每个像素的“深度” - 并且在已经有一个对象“前面”的区域(深度值更接近的像素)在深度缓冲区,它只会跳过那些像素的绘制。

(您的常规网格没有问题的原因可能是由于backface-culling 并且您的网格没有以从后到前的顺序绘制的任何“重叠位”。)

至于调试这种错误的好方法(奇怪的深度缓冲区问题、错误的渲染状态以及大多数其他情况下您的渲染输出不是您所期望的),我强烈建议安装 DirectX SDK 和 @987654327 @。

【讨论】:

  • 首先,感谢您提供的丰富信息。我很感激!其次,你是对的。是我的 spritebatch 把事情搞砸了!但是再次打开深度缓冲区解决了问题。非常感谢! :)
【解决方案2】:

感谢您回答这个问题!只是对任何想知道这个答案的人的跟进。在 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    相关资源
    最近更新 更多