XNA Windowed Mode Resizing Problem

Started by
12 comments, last by MJP 15 years, 1 month ago
Hello I'm creating a windowed application that uses an XNA-enabled custom control. The presentation parameters are as follows: presentationParameters.BackBufferCount = 1; presentationParameters.IsFullScreen = false; presentationParameters.DeviceWindowHandle = this.renderControl.Handle; presentationParameters.BackBufferWidth = 0;// this.renderControl.Width; presentationParameters.BackBufferHeight = this.renderControl.Height; presentationParameters.SwapEffect = SwapEffect.Discard; presentationParameters.AutoDepthStencilFormat = DepthFormat.Depth24Stencil8; presentationParameters.EnableAutoDepthStencil = true; presentationParameters.PresentationInterval = PresentInterval.Default; presentationParameters.BackBufferFormat = SurfaceFormat.Unknown; presentationParameters.MultiSampleType = MultiSampleType.None; //presentParams.MultiSampleType = MultiSampleType.TwoSamples; /* This does not run on Intel? */ //presentParams.MultiSampleQuality = 1; presentationParameters.RenderTargetUsage = RenderTargetUsage.PreserveContents; graphicsDevice = new GraphicsDevice( GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.renderControl.Handle, presentationParameters ); Upon resizing the control: renderer.graphicsDevice.PresentationParameters.BackBufferWidth = w; renderer.graphicsDevice.PresentationParameters.BackBufferHeight = h; //Viewport vp = new Viewport(); //vp.X = 0; //vp.Y = 0; //vp.Width = w; //vp.Height = h; //renderer.graphicsDevice.Viewport = vp; renderer.graphicsDevice.Reset(); float aspectRation = renderer.graphicsDevice.Viewport.AspectRatio; renderer.projMatrix = Matrix.CreatePerspectiveFieldOfView( (float) Math.PI / 4, aspectRation, 4.0f, 40000.0f ); However, after resetting the device, the backbuffer dimensions are set back to the creation time width and height which is incorrect. What's wrong? Thanks.
Advertisement
Quote:Original post by Sambori
However, after resetting the device, the backbuffer dimensions are set back to the creation time width and height which is incorrect.

What's wrong?
You're telling it to reset the backbuffer width and height.

When you reset the device, you pass it a full set of presentation parameters, which is the new state you want to reset to. The device won't retain any state at all, and won't care what you set it up with. You'll want to make doubly and triply sure that you're passing in the correct width and height.
Quote:Original post by Evil Steve
Quote:Original post by Sambori
However, after resetting the device, the backbuffer dimensions are set back to the creation time width and height which is incorrect.

What's wrong?
You're telling it to reset the backbuffer width and height.

When you reset the device, you pass it a full set of presentation parameters, which is the new state you want to reset to. The device won't retain any state at all, and won't care what you set it up with. You'll want to make doubly and triply sure that you're passing in the correct width and height.


Well the XNA GraphicsDevice does keep your settings around, it just doesn't use them when you call Rest (which is what's confusing the OP). Like you said you need to pass it a new set of PresentationParameters. If he wanted, he could copy all the settings from the PresentationParameters Property first to get all the old state, and then send it all to the Reset method.

BTW....why aren't you at the MVP summit? :(

I used Reset(PresentParams) where I re-initialize the present. params upon window resizing. That worked great whether I'm using a new instance of params or the current graphics device's. The problem is that all the params are preserved as they are passed to Reset except for the unknown or the ones set to be figured out internally such as the width, height and the back buffer format, in case of windowed mode. But anyway I could work around the width and height by reading the current viewport dimensions, but still need to figure out the buffer format.
is there anyway to read it from the device or query about it?
Just copy the existing params.

PresentationParameters newParams = renderer.graphicsDevice.PresentationParameters;newParams.BackBufferWidth = w;newParams.BackBufferHeight = h;renderer.graphicsDevice.Reset(newParams);
Here's what I use, it may help you. It sets to either full or windowed mode. It also checks if the video card supports that resolution. If it doesn't, it defaults to a fixed resolution. Got this from some tutorial somewhere ...

//----------------------------------------------------------------// InitGraphicsMode() - set resolution//----------------------------------------------------------------public bool InitGraphicsMode(int iWidth, int iHeight, bool bFullScreen, GraphicsDeviceManager graphicsDevMgr){    // If we aren't using a full screen mode, the height and width of the window can    // be set to anything equal to or smaller than the actual screen size.    if (bFullScreen == false)    {        if ((iWidth <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width)        && (iHeight <= GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height))        {            graphicsDevMgr.PreferredBackBufferWidth = iWidth;            graphicsDevMgr.PreferredBackBufferHeight = iHeight;            graphicsDevMgr.IsFullScreen = bFullScreen;            graphicsDevMgr.ApplyChanges();            return true;        }    }    else    {        // If we are using full screen mode, we should check to make sure that the display        // adapter can handle the video mode we are trying to set. To do this, we will        // iterate thorugh the display modes supported by the adapter and check them against        // the mode we want to set.        foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)        {            // Check the width and height of each mode against the passed values            if ((dm.Width == iWidth) && (dm.Height == iHeight))            {                // The mode is supported, so set the buffer formats, apply changes and return                graphicsDevMgr.PreferredBackBufferWidth = iWidth;                graphicsDevMgr.PreferredBackBufferHeight = iHeight;                graphicsDevMgr.IsFullScreen = bFullScreen;                graphicsDevMgr.ApplyChanges();                return true;            }        }    }    // The mode was not supported, so set defaulth width and height    graphicsDevMgr.PreferredBackBufferWidth = 1024;    graphicsDevMgr.PreferredBackBufferHeight = 768;    graphicsDevMgr.IsFullScreen = false;    graphicsDevMgr.ApplyChanges();    return false;}
Quote:Original post by MJP
BTW....why aren't you at the MVP summit? :(
Work :(
But I still cannot read the framebuffer format. It's in windowed mode which means it has the same format as the desktop's. how can I read it back from the device?
Quote:Original post by Sambori
But I still cannot read the framebuffer format. It's in windowed mode which means it has the same format as the desktop's. how can I read it back from the device?


GraphicsAdapter.CurrentDisplayMode will give you that.
Excellent! That worked! Thanks mates!

This topic is closed to new replies.

Advertisement