问题
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