Sprite Border

How to draw borders on a Texture2d sprite?

 public static void CreateBorder(this Texture2D texture, int borderWidth, Color borderColor)
  {
         Color[] colors = new Color[texture.Width * texture.Height];

        for (int x = 0; x < texture.Width; x++)
        {
            for (int y = 0; y < texture.Height; y++)
            {
                bool colored = false;
                for (int i = 0; i <= borderWidth; i++)
                {
                    if (x == i || y == i || x == texture.Width - 1 - i || y == texture.Height - 1 - i)
                    {
                        colors[x + y * texture.Width] = borderColor;
                        colored = true;
                        break;
                    }
                }

                if (colored == false)
                    colors[x + y * texture.Width] = Color.Transparent;
            }
        }

        texture.SetData(colors);
    }

But when using it, the loaded sprite is not visible
2021-11-04_125420
This is the result without using the CreateBorder method
2021-11-04_125446

Hello,

I think your problem is probably due to the layerdepth of your texture2D and your border being the same.
Your layerdepth can be set in the spritebatch draw method.

If you don’t mind adding extra package, you should check monogame extended. It provide additional method to the spirebatch. There is one called draw rectangle that can interest you.

2 Likes

I think this is your problem. For anything that’s not where you want to set your border, you’re resetting the colour to transparent.

If you’re interested in an alternative, you might consider just not modifying your sprite at all here. Design your border as a separate sprite, draw it, then draw your sprite (with transparency) over top. Sure it’s two draws instead of one but unless you’re drawing a tooooooon of these, it’s not really going to matter and will give you the flexibility to design your border sprite however you like.

1 Like

Thanks, I thought about it, but I was looking for a smarter way not to draw two drawings

The issue is likely that you’re expecting the call to texture.SetData to merge the color array with the existing texture, but it instead replaces the data.

If you add the following line at the top then the color array will be filled with the existing texture data first:

Color[] colors = new Color[texture.Width * texture.Height];
texture.GetData(colors);

Then if you remove the line which sets non border areas with Color.Transparent then only the border pixels will be modified.

The problem is that you are doing it ass-backwards. Why do you need to modify the texture directly? Why not just draw the border on top of that sprite? It’s gonna be faster and much easier. Even if you NEED to draw on a texture, use RenderTarget and draw on it. Direct texture data access was not made for whatever you’re trying to achieve here.

Actually this is a good point. It gives you the flexibility of having two sprites we talked about before, but also eliminates the need to have two draws (if that’s something that concerns you).

Draw both textures to a rendertarget, then use that as your texture :slight_smile: