Rendering 2D map from sprites issue

I’m still fairly new to Paradox, so apologies if I’m doing something stupid :D.

I’m using the Kenney Rouguelike/RPG pack, and for now I’m just trying to draw a really simple map (just using some grass at the moment).

I’ve got things largely working, but after every row there is a 1 pixel transparent line. I’m not sure what exactly is wrong.

Here’s what is being drawn:

And here are my assets:

Here’s my code that is doing the drawing:

using System;
using System.Threading.Tasks;
using Sellsword.Model;
using SiliconStudio.Core.Mathematics;
using SiliconStudio.Paradox.Engine;
using SiliconStudio.Paradox.Graphics;
using SiliconStudio.Paradox.Rendering;
using SiliconStudio.Paradox.Rendering.Composers;

namespace Sellsword
{
    public class TerrainScript : AsyncScript
    {
        private const int TerrainSize = 16;

        private Terrain _map;
        private SpriteBatch _spriteBatch;

        public override void Start()
        {
            base.Start();

            var virtualResolution = new Vector3(GraphicsDevice.BackBuffer.Width, GraphicsDevice.BackBuffer.Height, 20f);

            var terrainSpriteGroup = Asset.Load<SpriteGroup>("terrain_sprite");

            var sprite = terrainSpriteGroup["grass_sq_1"];
            var width = (int)Math.Round(virtualResolution.X / (double)TerrainSize);
            var height = (int)Math.Round(virtualResolution.Y / (double)TerrainSize);
            _map = new Terrain(width, height, sprite);

            // allocate the sprite batch in charge of drawing the backgrounds.
            _spriteBatch = new SpriteBatch(GraphicsDevice) { VirtualResolution = virtualResolution };
            // register the renderer in the pipeline
            var scene = SceneSystem.SceneInstance.Scene;
            var compositor = ((SceneGraphicsCompositorLayers)scene.Settings.GraphicsCompositor);
            compositor.Master.Renderers.Insert(1, new SceneDelegateRenderer(DrawBackground));
        }

        public override async Task Execute()
        {
            await Script.NextFrame();
            //while (Game.IsRunning)
            //{
            //    var elapsedTime = (float)Game.UpdateTime.Elapsed.TotalSeconds;

            //    // Update Parallax backgrounds
            //    foreach (var parallax in backgroundParallax)
            //        parallax.Update(elapsedTime);

            //    await Script.NextFrame();
            //}
        }
        
        private void DrawBackground(RenderContext context, RenderFrame frame)
        {
            _spriteBatch.Begin();

            for (int x = 0; x < _map.Width; x++)
            {
                for (int y = 0; y < _map.Height; y++)
                {
                    var sprite = _map[x, y];
                    var position = new Vector2(x * TerrainSize, y * TerrainSize);
                    var sourceRectangle = sprite.Region;

                    _spriteBatch.Draw(sprite.Texture, position, sourceRectangle, Color.White);
                }
            }

            _spriteBatch.End();
        }
    }
}

The Terrain object at the moment just returns the Sprite object passed to the constructor for all of x and y.

Any ideas of what I am doing wrong would be appreciated :).

Looks like a filtering issue try change the filtering to point.

How/where would I change the filtering? I did some googling and had a quick look around the documentation, but couldn’t find anything.

Like this:

Batch.Begin(SpriteSortMode.Deferred, NonPreMultiplied, null, null, Rasterizer); 

Where alpha mode and rasterizer are:

BlendState NonPreMultiplied = BlendState.New(this.game.GraphicsDevice, new BlendStateDescription(Blend.SourceAlpha, Blend.InverseSourceAlpha));

        Sampler = SamplerState.New(this.game.GraphicsDevice, new SamplerStateDescription(TextureFilter.Point, TextureAddressMode.Wrap));

@AlistairClark Could you check in the DrawBackground method that the GraphicsDevice.BackBuffer.Width/Height is actually the same as the one captured in the Start method? (So that the VirtualResolution doesn’t change implicitly)

Thanks,I tried changing the filtering, but that didn’t help.

Also, the GraphicsDevice.BackBuffer.Weight/Height is the same in the DrawBackground method.

I’ll keep digging around and see if I find a solution.

Hi AlistairClark,

I think that your problem comes from the fact that you are using a compressed format for the SpriteGroup. Compression algorithms work introduce error in your texture at the edges every block of pixels (4x4 on windows). In your case it just happens to match the transparency limit of your tile. Try to change the “Format” of your SpriteGroup from “Compressed” to “Color32Bits” in the property grid and see if it resolves your problem.

3 Likes

That fixed the issue, thanks very much!