[.net] [XNA] Fullscreen problems

Started by
7 comments, last by oaksystems 16 years, 8 months ago
Hey! I'm making a game and it''s coming along pretty well. So today I decided for some reason that I wanted to try it in full screen. So I set graphicsDeviceManager.IsFullScreen to true (tried .ToggleFullScreen() too, same thing) and fired it up. And it worked, until I minimized it (tabbed out) and tried to tab in again. The screen becomes all black. And then I'm unable to terminate the game the normal way (Alt+F4 etc.) or tab out once more. Is there something I'm missing here, or what? A little code, Client here derives from Game...

		public Client()
		{
			graphicsDeviceManager = new GraphicsDeviceManager(this);
			content = new ContentManager(Services);
			
			IsFixedTimeStep = false;
			IsMouseVisible = true;
			graphicsDeviceManager.PreferredBackBufferWidth = Constants.RESOLUTION_X;
			graphicsDeviceManager.PreferredBackBufferHeight = Constants.RESOLUTION_Y;
			graphicsDeviceManager.IsFullScreen = true;
			Assets.SetContentManager(content);
		}

This is the first thing that happens in the game. Am I doing something wrong? In the example given in the XNA documentation it says:
Quote:

public Game1()
    {
        graphics = new GraphicsDeviceManager( this );
        content = new ContentManager( Services );

        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 600;
        graphics.PreferMultiSampling = false;
        graphics.IsFullScreen = true;
    }
Advertisement
Not 100%, but I believe it's because leaving a fullscreen window using Alt-Tab or minimizing loses the device. You'd want to slip in some code to prevent attempting to render at this point. I believe you want to use the GraphicsDevice.GraphicsDeviceStatus property which gives you a GraphicsDeviceStatus. Try checking if the device normal before rendering anything and that might solve the problem.
In addition to Nicks advice, you also might want to make sure all unmanaged resources are being disposed and restored correctly (if you're using any ResourceManagementMode.Manual objects, make sure you handle these correctly). Aside from textures & geometry, RenderTargets and Surfaces are among the prime suspects. Setting up debug runtimes (see my sig) normally is a big help in finding out what's causing the problem.

I'm also not 100% sure, but I think XNA already behaves itself correctly when minimizing or when the device is lost/resetting.
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
Hey! Thank you for your responses.

So far it seems there is no problem with the GraphicsDeviceStatus. However, I tried to run the program from outside VC# to be able to save the output to a file (like Client.exe > text.txt). Maybe that can be done somehow from within VC#?

Anyway, then, I don't just get a black screen, but an error:
Quote:
Unhandled Exception: System.AccessViolationException: Attempted to read or write
protected memory. This is often an indication that other memory is corrupt.
at Microsoft.Xna.Framework.Graphics.RenderTarget.GetRenderTargetSurface(CubeM
apFace faceType)

at Microsoft.Xna.Framework.Graphics.GraphicsDevice.SetAbstractRenderTarget(In
t32 renderTargetIndex, RenderTarget renderTarget, CubeMapFace faceType)

at Microsoft.Xna.Framework.Graphics.GraphicsDevice.SetRenderTarget(Int32 rend
erTargetIndex, RenderTarget2D renderTarget)

at CapOrDie.Graphics.Draw(GameTime gameTime) in C:\oskar\Microsoft Visual C#Projects\CapOrDie\Client\Singletons\Graphics.cs:line 63

at CapOrDie.Client.Draw(GameTime gameTime) in C:\oskar\Microsoft Visual C#\Pr
ojects\CapOrDie\Client\Client.cs:line 112

at Microsoft.Xna.Framework.Game.DrawFrame()

at Microsoft.Xna.Framework.Game.Tick()

<some of the error removed>


So, I guess something is wrong with the render target somehow (I'm rendering to a Texture2D to be able to draw UI things on top using SpriteBatches), but...

I don't know what you are talking about, remigius. What is unmanaged resources? What is the correct way to handle them? What is ResourceManagmentMode.Manual? So basically I have no idea of what to do in order to correct this error.

And also, that "DX debug runitme" is for DX and XNA is not DX. Maybe, and probably since you mentioned it, I can use it somehow for XNA but I don't have that DirectX Control Panel thing in my Control Panel. And I'm not using DX so I don't know if I should install it.

[Edited by - tufflax on July 26, 2007 10:00:14 AM]
XNA is more or less built on top of DirectX, so any errors being generated will be bubbling up from DirectX. So yes, install it and crank up the debug level. It will show you exactly what underlying DirectX calls are failing.
OK, thanks!

But, I know it's the SetRenderTarget. I just don't know what I should be doing. I'm guessing remigius has an idea though... :)
Quote:Original post by tufflax
I don't know what you are talking about, remigius. What is unmanaged resources? What is the correct way to handle them? What is ResourceManagmentMode.Manual? So basically I have no idea of what to do in order to correct this error.


In DirectX, so on the PC, you essentially have two types of memory to worry about, RAM (internal memory) and VRAM (memory on your graphics card)1. Stuff used by the video card typically needs to be in VRAM, so your textures, vertices etc need to go from your RAM (into which it is loaded from the HD or generated by the CPU) to VRAM.

There are two common ways to go about this. One way is to use ResourceManagementMode.Automatic when loading your stuff, which will copy resources into your VRAM as needed and remove unused resources if your VRAM is filling up. Using RMM.Automatic reserves a part of your RAM to back this swapping and an advantage of that is that resources managed this way can survive device resets without any intervention from you. Another way is to use RMM.Manual, which means there's no backing RAM memory. When a device is lost (happens when minimizing, screensaver kick in, user-switch etc), Windows basically kicks your application from VRAM2, so you'll need to recreate any RMM.Manual resources yourself once the device resets, ie when your app gets it back.

There a lots of subtleties here and I'm probably only confusing you with bits of the puzzle, so my advice is to check out the XNA Docs for a more coherent description. Google (and the documentation in the DirectX SDK) can probably give you more info on handling lost devices and device resets.


Now, whatever you do, don't get discouraged! Over time, you'll come to know these properties and most of the time you don't need to worry about them too much. But now that you've got at least some vague idea what the ResourceManagementMode does, we can move on to our revelation. As it so happens, RenderTargets and the like only exist in VRAM (for performance reasons, VRAM > RAM), so basically they're using RMM.Manual. So you have to dispose them when the device is lost and recreate them when it resets.

Now, how does that help you? In the (Un)LoadGraphicsContent() methods of your game, you'll notice sections reserved for disposing/recreating RMM.Manual resources. As you might have guessed, taking care of the RenderTarget (and any other RMM.Manual) objects there should solve your problem.



1This may or may not hold true for XBox deployment, but my guess is that it does

2For simplicity's sake

Quote:And also, that "DX debug runitme" is for DX and XNA is not DX. Maybe, and probably since you mentioned it, I can use it somehow for XNA but I don't have that DirectX Control Panel thing in my Control Panel. And I'm not using DX so I don't know if I should install it.


As Moe said, XNA basically is a wrapper (yes, yes, a very fancy one and we all love it [wink]) around DirectX, on the PC that is. You'll probably need to download and install the DirectX SDK later on anyway, since the only official way to get sound to work in XNA is to use the XACT utility that comes with the SDK. Anyway, using the debug runtimes will output exactly what call into DirectX caused the error, allowing you to figure out what is wrong (resource disposed/invalid, wrong setting, unsupported operation etc).


*pfew* Hope this helps :)
Rim van Wersch [ MDXInfo ] [ XNAInfo ] [ YouTube ] - Do yourself a favor and bookmark this excellent free online D3D/shader book!
Thanks for your excellent advice remigius, I loaded the rendertarget in the loadcontent method and now it works like it's supposed to.
You've been extremely helpful and/or friendly :)
Thanks guys! You gotta love XNA, handling lost devices was such a struggle when coding DX directly. With your advice doing it in XNA is a doddle.

Dave

This topic is closed to new replies.

Advertisement