MonoGame.Extended icon indicating copy to clipboard operation
MonoGame.Extended copied to clipboard

[Tiled] Objects render order

Open davidbezdek opened this issue 7 years ago • 7 comments

Hi i have this for map render:

var viewMatrix = ScreenManager.Instance.Camera.GetViewMatrix();
            var projectionMatrix = Matrix.CreateOrthographicOffCenter(0, ScreenManager.Instance.GraphicsDevice.Viewport.Width, ScreenManager.Instance.GraphicsDevice.Viewport.Height, 0, 0f, -1f);

            #region Under object layers
            mapRenderer.Draw(mapTiles.GetLayer("Ground"), ref viewMatrix, ref projectionMatrix);
            mapRenderer.Draw(mapTiles.GetLayer("Layer1"), ref viewMatrix, ref projectionMatrix);
            mapRenderer.Draw(mapTiles.GetLayer("Layer2"), ref viewMatrix, ref projectionMatrix);
            mapRenderer.Draw(mapTiles.GetLayer("Layer3"), ref viewMatrix, ref projectionMatrix);
            #endregion

            foreach (DynamicEntity entity in Entities.Values)
                entity.Draw(spriteBatch);

            #region Above objects layers
            mapRenderer.Draw(mapTiles.GetLayer("TopLayer1"), ref viewMatrix, ref projectionMatrix);
            mapRenderer.Draw(mapTiles.GetLayer("TopLayer2"), ref viewMatrix, ref projectionMatrix);
            mapRenderer.Draw(mapTiles.GetLayer("TopLayer3"), ref viewMatrix, ref projectionMatrix);
            #endregion

Camera follow player it works great but all dynamic entities are above TopLayers and above gui mouse. Can you please advise how to force spritebatch to keep the order?

davidbezdek avatar Feb 09 '18 23:02 davidbezdek

The API around this stuff is quite complicated unfortunately. If I remember correctly you'll need to play with the depth value on the SpriteBatch.

The plan is to improve and clean up the Tiled API in the 2.0 branch to make this kind of stuff easier.

If you could provide a project that reproduces the problem I'll look into it further.

craftworkgames avatar Feb 14 '18 00:02 craftworkgames

What I do in my code is draw all my "Gound level" layers, SpriteBatch.Begin(), draw your entities, SpriteBatch.End(), draw all "upper level" layers.

From my understanding of the TiledMapRenderer system in the API before the 2.0 changes, mapRenderer.Draw() writes "directly" to the graphics card. SpriteBatch is rendered to the graphics card when SpriteBatch.End() is called. Your entity.Draw() calls are just queuing up the rendering, then the upper layers are drawn (i.e. behind the character) before the characters are actually drawn.

stefanrbk avatar Feb 21 '18 05:02 stefanrbk

@stefanrbk Thank you i did this and now it works perfect ;)

davidbezdek avatar Feb 21 '18 09:02 davidbezdek

@davidbezdek no worries! Since you are also working with TiledMaps, have you been noticing any graphics glitches like what I posted in #476?

stefanrbk avatar Feb 22 '18 18:02 stefanrbk

So, I have been putting some thought into how we could make this rendering a little easier without having to break it down per layer now that we can use group layers, etc. We could do an Action-based delegate or event in the TiledMapRenderer or TiledMapLayer for SpriteBatch-related processing, or have the ability to pass in a pre-made ECS system to link to the renderer, or something else even. What do you guys think?

stefanrbk avatar Jul 09 '18 19:07 stefanrbk

Can't just add a couple of methods to the renderer that will take an array of strings or a range and render them in order?

My own renderer still has the layers similar to that, but each layer has a bunch of tiles, their depth gets calculated and they are added to my ECS and drawn automatically.

EReeves avatar Jul 10 '18 04:07 EReeves

Our renderer for Tiled maps allows you to pass in a TiledMap to render the whole map or a TiledMapLayer to render just that layer. I have 2-4 layers which need to be rendered under the ECS entities and at least 1 layer to render above. We currently don't have a way to change the depth of the render/not sure if we could change the depth of the render for the maps as they are rendered with models directly on the graphics card. The map renderer and the ECS run completely separately, so that is what i'm trying to figure out how we would want to link them together.

Edit: I'm wrong, there is a depth setting for the layer draw functions. I'm gonna look at that quickly...

stefanrbk avatar Jul 10 '18 19:07 stefanrbk