1
votes

So I'm working on a project, where I have a 3d cube-based world. I got all of that to work, and I'm starting the user interface, and the moment I start using spritebatch to draw a cursor texture I have, I discovered that XNA doesn't layer all the models correctly, some of the models that are further away will be drawn first, instead of behind a model. When I take out all the spritebatch code, which is just this:

        spriteBatch.Begin();
        cursor.draw(spriteBatch);
        spriteBatch.End();

I find that the problem is fixed immediately. The cursor is an object, the draw method is just using spriteBatch.draw();

The way I see it, there are two solutions, I could find a way to draw my cursor and other interfaces without using SpriteBatch, or maybe there is a parameter in spriteBatch.Begin() that I could plug in to fix the issue? I'm not sure how to do either of these, anyone else encounter this problem and know how to fix it?

Thanks in advance.

2
I am not positive but can't you just enable the normal mouse cursor and then if you want to change the way it looks I think there are windows api calls that do that. But I don't know that for sure.Alexander Van Atta
I'm just using the mouse to start, I'm going to add some HUD later for gameplay. So if I find a way to draw the mouse while keeping the models drawn correctly, then I can continue with the interface.Glen654

2 Answers

4
votes

This does not answer the question!

I'm not sure if you could (or should) draw 2D without a spritebatch, however I've had the same problem with 3D model rendering when using 2D spritebatch, and the solution on solution I've found on GameDev helped me solve this:

Your device states are probably wrong. This often happens when mixing 2D and 3D (for example the overload for SpriteBatch.Begin() which takes no arguments sets some device states that are incompatible with 3D rendering. No worries though, all you have to do is to make sure that the following device states are set the way you want them:

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

Basically, you first call the SpriteBatch methods for 2D draws, then the above code (which should ensure proper 3D rendering), and then draw your 3D models. In fact, I only used the first two lines - BlendState and DepthStencilState and it worked as it should.

2
votes

Have you had a look at this overload?

You can use the last parameter, layerDepth, to control in what order sprites are drawn. If you use that, make sure to check out the sprite sort mode (in the SpriteBatch.Begin(...) call) as well. Does this cover what you need to do?

Edit: Also note that this implies using the correct perspective matrix, drawing in 2D (I'm assuming you want your cursor to display in 2D on top of everything else), and after all the 3D stuff (it's quite possible to draw sprites at Z=0 for example, making objects in front of that obstruct the sprite).