XNA - Drawing Quads (and primitives) in right order

﹥>﹥吖頭↗ 提交于 2019-12-06 11:04:03

问题


I'm fairly new to 3D-stuff in XNA and unfortunately I have encountered a problem I can't find the solution for. (Don't even know what the problem is).

To cut it short: I am drawing quads in my game using:

        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();

My effect also has these properties:

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

And it works. My quad is drawn nicely and me is happy. However there is one slight problem. If one quad is behind another quad or regular model the way that determines which is drawn on top is the order that I draw them in.

Lets say I draw Quad A before Quad B, then B will be shown as on top of Quad A even if it is 40 units lesser in the Z-axis. Looks very confusing I must say! ;)

Now I haven't had any problem like this with my regular meshes, it is when primitives are involved things get this messy. The very same problem goes for drawing regular lines:

            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

So what I'm asking really is:

A) Is this normal? Should I build a special engine which decides when to draw what? I can easily work around this in my project by drawing stuff at the right time but I can imagine a game where I could not. A fps for example couldn't draw its billboards all over the place! ;)

B) If this is not normal, what could be the cause and what would be a solution/good way to debug the error.

I would appreciate any help to sort this out! :)


回答1:


It sounds like you've got the depth buffer turned off. Perhaps you are drawing sprites before hand? (Using SpriteBatch will change various render states needed for normal 3D drawing.)

Try adding this line of code before you draw any 3D objects:

GraphicsDevice.RenderState.DepthBufferEnable = true;

Related Links:

  • SpriteBatch and renderstates (for XNA 3.1)
  • SpriteBatch and renderstates in XNA Game Studio 4.0
  • RenderState.DepthBufferEnable Property

For an explaination of the depth buffer (or "Z-buffer"), you could check the wikipedia article.

To describe the depth buffer briefly: It is basically a bitmap image of your scene that stores how far "into" the screen each pixel is (the depth). When you go to draw your second object, it will first calculate the "depth" of each pixel it is about to draw - and in the areas where there is already an object "in front" (pixels with a closer depth value) in the depth buffer, it will simply skip drawing for those pixels.

(The reason you don't have problems with your regular meshes is probably thanks to backface-culling and your meshes not having any "overlapping bits" being drawn in a back-to-front order.)

As for a good way to debug this kind of error (weird depth buffer problems, wrong render states, and most other cases where your rendered output is not what you expect), I strongly recommend installing the DirectX SDK and learning to use PIX.




回答2:


Thanks for answering this question! Just a follow up for anybody else who wants to know about this answer. In xna 4.0, it has changed a little bit.

Some 3D tile objects were transparent to other 3D objects. This was due to the removal of:

GraphicsDevice.RenderState.DepthBufferEnable = true;

In XNA 4 this was replaced by:

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

Taken from this source: http://www.hexworld.co.uk/blog/?cat=9



来源:https://stackoverflow.com/questions/3093405/xna-drawing-quads-and-primitives-in-right-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!