When resuming my MonoGame Android game, it crashes.
I have these errors:
No reply here either in six days. Not a single reply.
don’t know much of android, but did you recreate your renderTargets after resume?
Thanks for the reply.
I don’t know how to do that really, I do know that the game crashes at the bloomcomponent and at something like rendertargets, but I don’t really know much about any of that. I could try to recreate them if I knew how to, do you know?
just subscribe to GravicsDevice.DeviceReset event and create a new renderTarget.
I don’t really understand what you mean there, I never code with “renderTarget”, the bloom-code was copied from a sample. I have just learned how to program the game itself like in XNA and I have then started making XNA games in MonoGame for Android, I am not familiar with any advanced programming outside of the usual game programming such as player movement and such…
I’m not familiar with the term subscribe in this context either, but I guess you mean that I should have a function that gets called when the GraphicsDevice is reset, and in that function create a new renderTarget (which I do not know how), or have I misunderstood? Thanks for the help anyway, it’s not easy trying to code to Android ^^
Is that the NeonShooter from MG-Samples?
ttps://github.com/Mono-Game/MonoGame.Samples/tree/develop/NeonShooter ?
That bug will cause WP to crash as well.
See the lines 104/116/117
https://github.com/LinusNeuman/NeonShooter/blob/master/NeonShooter/BloomComponent.cs#L104
that’s where it creates 3 rendertargets.
When the game resume on devices like WP & android all GPU resources are freed to save RAM. ContentManager is smart enough to reload all assets for you but doesn’t know about render targets and things you create manually.
inside “LoadContent()” create an event listener to GraphicsDevice.ResetDevice += GraphicsDevice_ResetDevice(…)
and inside that new method recreate the renderTargets, some thing like
sceneRenderTarget = new RenderTarget2D(GraphicsDevice, width, height, false, format, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
116 renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
I believe that will work.
It’s my own game but the bloom parts have been taken directly from an old XNA sample and I have ported it over to MonoGame without any problems.
Alright, thanks. I have never coded with events or event listeners, I read about them now and learned a bit about delegates and such, but I can still not really understand how I would use it here. Sorry for that but I have as said never coded with events… Probably time that I start with that. I can ask my programming teacher if he could teach me about events, but in the mean time maybe you could explain briefly what I am supposed to do? I understand the concept but I don’t know how to put it to code, I need to learn about events.
Thanks again for your help
I experimented and came up with this:
Am I on to something here? By the way the error is for “The name ‘GraphicsDevice_DeviceReset’ does not exist in the current context”
Almost there.
Here is the code, i can’t compile your android sample right now, you have to fix any mispell, case errors, etc
If you are using Visual studio type “GraphicsDevice.DeviceReset +=” , by the time you press ‘=’ a pop up will appear. press ‘tab’ twice and visual studio will auto-generate the method for you!
public void LoadContent()
{
…
GraphicsDevice.DeviceReset += GraphicsDevice_DeviceReset;
}
void GraphicsDevice_DeviceReset(object sender, EventArgs e)
{
sceneRenderTarget = new RenderTarget2D(GraphicsDevice, width, height, false, format, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
}
The eventHandler you read about is still there, it’s just that recent C# compiler add this for you behind the scene.
Thank you!
I have tried it and ended up with this:
void GraphicsDevice_DeviceReset(object sender, EventArgs e)
{
PresentationParameters pp = GraphicsDevice.PresentationParameters;
int width = pp.BackBufferWidth;
int height = pp.BackBufferHeight;
SurfaceFormat format = pp.BackBufferFormat;
sceneRenderTarget = new RenderTarget2D(GraphicsDevice, width, height, false, format, pp.DepthStencilFormat, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
width /= 2;
height /= 2;
renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
}
/// <summary>
/// Load your graphics content.
/// </summary>
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
GraphicsDevice.DeviceReset += GraphicsDevice_DeviceReset;
bloomExtractEffect = Game.Content.Load<Effect>("FX/BloomExtract");
bloomCombineEffect = Game.Content.Load<Effect>("FX/BloomCombine");
gaussianBlurEffect = Game.Content.Load<Effect>("FX/GaussianBlur");
// Look up the resolution and format of our main backbuffer.
PresentationParameters pp = GraphicsDevice.PresentationParameters;
int width = pp.BackBufferWidth;
int height = pp.BackBufferHeight;
SurfaceFormat format = pp.BackBufferFormat;
// Create a texture for rendering the main scene, prior to applying bloom.
sceneRenderTarget = new RenderTarget2D(GraphicsDevice, width, height, false,
format, pp.DepthStencilFormat, pp.MultiSampleCount,
RenderTargetUsage.DiscardContents);
// Create two rendertargets for the bloom processing. These are half the
// size of the backbuffer, in order to minimize fillrate costs. Reducing
// the resolution in this way doesn't hurt quality, because we are going
// to be blurring the bloom images in any case.
width /= 2;
height /= 2;
renderTarget1 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
renderTarget2 = new RenderTarget2D(GraphicsDevice, width, height, false, format, DepthFormat.None);
}
It still crashes though… Framebuffer incomplete. What do I do wrong?
Screenshot:
Your code looks good. It has to be an issue with android. There is an older post with the same problem.
Change all RenderTargets to DepthFormat.None to verify if this is the same bug.
If your game depends of Depth testing the screen would look corrupted but check anyway to see if it crash or not.
When changing all RenderTargets to DepthFormat.None I got this error instead:
System.InvalidOperationException: Not all framebuffer attachment points are framebuffer attachment complete.
maybe that is related?
Maybe but that was from 2014, that fix should already be implemented?
I have no idea.
Somebody with more experience on android could help?
Yeah probably, but it’s hard to find help here. I have started a lot of threads for my problems but this one is the only one with replies…
Thanks for your help though