Meatgortex

So I'm doing a 3D version of a boardgame and I've having trouble getting my tiles to draw correctly. I've got a class that is handling what should be drawn on screen during the phases of a players turn. Something along the lines of:

GameBoardBackground.Draw(...)

Foreach PlacedTile
Tile.Draw(...)

HUD.Draw(...)

The tiles draw on top of the gameboard, and the HUD draws on top of the tiles which is what I'd expect. Unfortunately the tiles are drawn in the order that they occur in the foreach loop, so I end up with a bunch of sorting issues.

My assumption is that I need to let the graphics device know I want that entire foreach loop drawn using z-buffer sorting and not explicitly sorted by order of draw call, but how do I do that

Thanks



Re: XNA Game Studio Express Z-sorting trouble

dczraptor

Did you set the depth buffer

graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;

graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

If you want to manually sort the tiles, you can do something like:

Tile : IComparer

{

int override CompareTo(object obj)

{

// return the negation so that the tiles farthest away are rendered last.

return -(camera.Position - this.position).Length().CompareTo((((Tile)obj).position-camera.Position).Length());
}
}

Then call tiles.Sort();






Re: XNA Game Studio Express Z-sorting trouble

Peter D.

If your tiles are drawn using spritebatch, then you can simply set the level for the sprite to draw at and this should enforce your drawing order for you.





Re: XNA Game Studio Express Z-sorting trouble

Meatgortex

The tiles are 3D objects not sprites, so I'm afraid that won't help.

WRT the depth buffer:

I never explicitely turned the depth buffer off, and assumed it was on by default. Regardless setting it to true didn't help me.

Currently I'm specifically calling my own render() call in each Tile so that I can control draw order, but I may switch to using the Draw() override and then controlling things using the DrawableGameComponent.DrawOrder. Hopefully if I set all the tiles to the same value it will draw them together.

Ultimately I don't think this the the RightWay(TM) to be doing things. All of these Tiles share textures for the bottom and sides and it seems like from my limited understanding of 3D performance that I'd want to draw the bottoms of all tiles at once, then the sides of all tiles, and finally the tops based on texture and not position. But if the model is associated with the Tile class as it currently is I have no idea how I would do that. I'm not drawing enough stuff on screen for performance to be an issue so I'm going to tinker around a bit more trying to get what I have to work correctly.





Re: XNA Game Studio Express Z-sorting trouble

B1narySh0t

If you are drawing quads that are textured as your tiles (which I would assume you are), then, have the depth buffer enabled, and making sure that the Z coordinate (if you are drawing in the XY plane) are the same. For the HUD, you could increase/decrease the Z coordinate (moving it closer, farther away in the view depth).

I am unsure how you are storing your tiles, but most of what you are asking should be handled automatically. Perhaps post some code regarding your tiles, such as their structure and the draw routine.





Re: XNA Game Studio Express Z-sorting trouble

Meatgortex

Not drawing flat quads but full 3d tiles with sides, bottom, and a beveled top.

Here is an example, and many will probably recognize the board game:

http://farm1.static.flickr.com/171/366338065_9bfe9dc80b.jpg

You can see the tile on the upper right is drawing over the one below it, and that tile is drawing over the top of the bent road tile in the middle.

All the tiles and the gameboard in the background inherit my ModelHandler class which in turn inherits DrawableGameComponent. I got this ModelHandler from a tutorial somewhere but it seems pretty basic, just cycling through all the meshes and effects in a model and then drawing the model. I'm not using the gameTime for anything and the WorldTransformMatrix is currently always (0,0,0).

    public virtual void Render(GameTime gameTime, Matrix projection, Matrix view)
    {
      foreach (ModelMesh mesh in Model3D.Meshes)
      {
        foreach (BasicEffect effect in mesh.Effects)
        {
          effect.View = view;
          effect.Projection = projection;
          effect.World = BoneTransforms[mesh.ParentBone.Index] * WorldTransformMatrix;
        }
        mesh.Draw();
      }
    }

The code that is calling this Render() shown in the screenshot above looks like this:

    void Draw_DisplayBoard(GameTime gametime)
    {
      this.GraphicsDevice.Clear(Color.Black);
      gBoard.Render(gametime, camera.projection, camera.view);

      foreach (Tile t in gBoard.boardPositions)
      {
        if (t != null)
        {
          t.Render(gametime, camera.projection, camera.view);
        }
      }

      base.Draw(gametime);
    }

So it's basically doing exactly what I'm telling it to do, draw all these things in order. I just want it to draw them together as one batch and sort them correctly.

 

EDIT: Not sure why they are appearing out of order, but the second post above fixed my issue. My response to that post is somehow showing up in the chain above this one, issue resolved.





Re: XNA Game Studio Express Z-sorting trouble

Meatgortex

dczraptor wrote:

Did you set the depth buffer

graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;

graphics.GraphicsDevice.RenderState.DepthBufferWriteEnable = true;

My mistake dczraptor your comment above fixed the issue.

I just tried this again after looking through the SpaceWar code. When I first added those lines I was doing it in the main game initialization not in my rendering code. All is well now that I put it at the top of my render function.

Thanks.