flickering sprites problem

I have a MonoGame C# game that I have been working on for several years. Recently, I decided to upgrade it to C#8, and as part of following the instructions to set it up, I also upgraded to a more recent version of MonoGame.

Now the sprites flicker. I’ve stripped away all but the absolute basics (e.g. there’s nothing in the Update loop), and determined that any sprite that’s drawn exactly once flickers:

int already = 0;
        protected override void Draw(GameTime gameTime)
        {            
            sprites.Begin();
            if (already<1)
            {
                sprites.Draw(myImage, Vector2.Zero, Color.White);
                already += 1;
            }            
            sprites.End();
            base.Draw(gameTime);
        }

If I change that code so that it checks (already<2) rather than (already<1), i.e. it draws the sprite twice rather than once, the flickering stops. The flickering also stops if I click and hold anywhere on the title bar of the window; sometimes it’ll stop with the image visible, sometimes with the image invisible. Any idea what’s going on here?

Are any of the objects using an alpha < 1?

If so, I’ve run into a bug where anything on the same layer will flicker if one of the two objects has an alpha < 1.

My work around was to assign each object a drawing layer and add .00001 to each object (and increment that object).

So:
Object A would be on Layer 0.0001
Object B would be on Layer 0.0002
Object C would be on Layer 0.0003

Etc…

Seems like a bug in MonoGame, but I haven’t had time to put together a demo app of this to report it as a bug yet. It’s on my long TODO list :slight_smile:

1 Like

Hey, is this your main game, or a sub class?

I notice that a clear call is missing to GraphicsDevice.Clear(…), and I wonder if that might be the cause of some issues. I believe the core MonoGame setup is immediate mode drawing. If you’re trying to do some kind of retained mode drawing, those systems aren’t built directly in so you’d probably have to do something using a RenderTarget2D and clever logic.

If the above is not at all what you’re trying to do, just put GraphicsDevice.Clear(Color.Black) at the top of your Draw statement and see what happens :smiley: Change the colour to whatever you like.

I have the exact same problem and I did the exact same solution, but I didn’t like it. In my case I have a lot of sprites and to manage each different layer depth is a bit confusing.

The only thing different that I see about your code is that your already int might not be set to 0 every time you call it?

The alpha is 1, so it’s not the same bug. After talking to some people on Reddit, I think it’s not really a significant bug in MonoGame, but rather a mishandling of sprites on my part - sprites in general should be redrawn in every frame. So whether it’s a bug or not, using sprites in the intended way fixes the problem.

I tried including the GraphicsDevice.Clear(…) call and it didn’t fix the problem. However, someone on Reddit explained to me that my mental model of how sprite drawing should work was wrong; the engine assumes I should be redrawing the sprites every frame. When I refactored the code to do that, it worked just fine. So possibly it’s a “bug”, but one that only comes up when using the tools in unintended ways.

How did you rewrite the code you wrote above?
I didn’t understand what is your fix! Because I have the same problem if I draw two sprites with the same depth, even if I clear the graphics device on each draw cycle.
Thansk!

If I applied the change to the original example, it would be to simply remove the conditional like so, such that the image gets drawn every cycle.

protected override void Draw(GameTime gameTime)
{
      sprites.Begin();
      sprites.Draw(myImage, Vector2.Zero, Color.White); 
      sprites.End();
      base.Draw(gameTime);
}
1 Like

Thanks! :smiley: