Sign in to follow this  

Thread Reshash: Can't Switch from Fullscreen to Windowed

This topic is 4518 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys To start, I believe I am suffering a similar problem to the one mentioned here, but he didn't state it will and the thread derailed. Instead of resurrecting it, I'll try to state my problem more clearly here. I am having trouble getting my application to switch from fullscreen to windowed mode (Direct3D9, if it matters). I can switch from Windowed to Fullscreen just fine, but it doesn't work the other way around. I've started it up in windowed mode, saved the PresentationParameters, toggled to fullscreen, and then tried to toggle back with the saved PresentationParameters but had no luck. The BackBuffer has obviously changed to the windowed resolution, but it is still running in fullscreen. In fact, I can toggle again and get the backbuffer back to the right resolution. If anyone has any ideas I'd love to hear them. I've spent at least 5 hours of web surfing, googling, and news group reading trying to find a solution.

Share this post


Link to post
Share on other sites
Quote:
Original post by Coder
- No interesting debug output?
- Do you suffer the same problem with the samples?
- Any binary that we can try?

Thanks for the reply.

No, no exceptions are thrown and the program continues to run. The only effect is that when the resolution is dropped to the windowed res the framerate also drops a good bit, but that could easily be caused by the messed up backbuffer to frontbuffer size.

No, the samples work correctly. I tried to figure out why they work correctly, but the sample framework seems to be almost impenetrable as far as the device setup code goes. Maybe if someone has a good reference to the sample framework I could try again.

Sure, I can upload a binary in about an hour.

Share this post


Link to post
Share on other sites
How exactly do you switch from windowed to fullscreen? I use device.Reset(newPresentParams) (using managed directx) and the presentation parameters are recreated with new settings, i.e. the presentParams.windowed flag is set to true and the backbuffer settings are ignored when I switch from fullscreen to windowed mode.

Share this post


Link to post
Share on other sites
This is c++, right? Cause there are a few topics about VB having problems with windowed mode (not neccessarily the switch, but in general).

Are you setting the window handle (HWND)? Failing to do so could, I guess, give you this kind of behaviour.

Share this post


Link to post
Share on other sites
Quote:
Original post by Opwiz
How exactly do you switch from windowed to fullscreen? I use device.Reset(newPresentParams) (using managed directx) and the presentation parameters are recreated with new settings, i.e. the presentParams.windowed flag is set to true and the backbuffer settings are ignored when I switch from fullscreen to windowed mode.

I have tried a few different methods. One is copying the PresentationParameters when I first create the window in windowed mode, and then applying them when I want to switch back. This causes the resolution to drop but it is still in fullscreen, just stretched. I've also tried recreating the PresentationParameters the exact same way I did initially. This way, nothing changes. It flickers for a second and then keeps on going. Could you possibly post the code where you actually setup the PresentationParameters?

sirob: This is with Managed DirectX. When I start the program initially in Windowed mode it works correctly, so it seems that the problem isn;t so much windowed mode but the switching from Fullscreen to Windowed.

Share this post


Link to post
Share on other sites
Here is a stripped down version of my program. All it does is clear and draw an FPS counter. To Toggle Windowed and Fullscreen press F2. It will not work the second time, so you can press Escape to exit.

Here it is:http://www.savefile.com/files/3441317

Here is the source for the more important file (the rest is input/GUI code):
[source lang='c#']
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using DI = Microsoft.DirectX.DirectInput;

using GameTest;

namespace WindowTest
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form2 : System.Windows.Forms.Form
{
private Device _device;
private PresentParameters _param, _winParam;
private InputManager _input;
private System.ComponentModel.IContainer components;

long _lasttick;
FPSDisplay fps;

bool _windowed = true;
bool deviceLost = false, _closing = false;
StateBlock _restore = null;

public Form2()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

_param = new PresentParameters();
_param.SwapEffect = SwapEffect.Discard;
_param.DeviceWindow = this;
//_param.PresentationInterval = PresentInterval.Immediate;
_param.AutoDepthStencilFormat = DepthFormat.D16;
_param.EnableAutoDepthStencil = true;
_param.MultiSample = MultiSampleType.None;

if (_windowed)
{
_param.Windowed = true;
_param.BackBufferCount = 1;
_param.BackBufferHeight = 0;
_param.BackBufferWidth = 0;
_param.BackBufferFormat = Format.Unknown;
_param.DeviceWindow = this;
}
else
{
_param.Windowed = false;
_param.BackBufferCount = 1;
_param.BackBufferFormat = Manager.Adapters[0].CurrentDisplayMode.Format;
_param.BackBufferWidth = 1920;
_param.BackBufferHeight = 1200;
}
_device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, _param);
_device.DeviceResizing += new CancelEventHandler(CancelResize);
_device.DeviceLost += new EventHandler(OnDeviceLost);
_device.DeviceReset += new EventHandler(OnDeviceReset);
_winParam = _device.PresentationParameters;

_device.RenderState.SourceBlend = Blend.SourceAlpha;
_device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
_device.RenderState.ZBufferEnable = true;
_device.RenderState.ZBufferWriteEnable = true;
_device.RenderState.MultiSampleAntiAlias = false;

_device.RenderState.Lighting = false;


SetupMatrices();

_restore = new StateBlock(_device, StateBlockType.All);
_restore.Capture();

this.Show();
_input = new InputManager(this, true, new Vector2(ClientSize.Width, ClientSize.Height));
_input.KeyPress += new GameTest.Control.KeyHandler(Input_KeyPress);

fps = new FPSDisplay(_device);
fps.Size = new Vector3(150, 30, 0);
fps.Font = new Microsoft.DirectX.Direct3D.Font(_device, new System.Drawing.Font(FontFamily.GenericMonospace, 12, FontStyle.Bold, GraphicsUnit.Pixel));

}

public void SetupMatrices()
{
_device.Transform.World = Matrix.Identity;
_device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 0), new Vector3(0, -.1f, 1), new Vector3(0,1,0));
_device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, ClientSize.Width/(float)ClientSize.Height, 2f, 100.0f );
}

public void UpdateGUI()
{
long newtick = Environment.TickCount, delta = newtick-_lasttick;
_lasttick = newtick;

_input.UpdateInput();
fps.Update(delta, delta);
}

public void Render()
{

if (!deviceLost && !_closing)
{
if (_device == null)
return;

_device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.White, 1, 0);
_device.BeginScene();

RenderGUI();

_device.EndScene();
try
{
_device.Present();
}
catch (DeviceLostException e) {deviceLost = true;}
catch (DeviceNotResetException e) {deviceLost = true;}
}
else if (deviceLost) RecoverDevice();
}

private void RecoverDevice()
{
int result;
_device.CheckCooperativeLevel(out result);
if (result == (int)ResultCode.DeviceNotReset)
{
try
{
ResetDevice();
deviceLost = false;
}
catch{}
}
}

private void RenderGUI()
{
_device.SetRenderState(RenderStates.ZEnable, false);
_device.SetRenderState(RenderStates.AlphaBlendEnable, true);

_device.SetTransform(TransformType.Projection, Matrix.OrthoOffCenterLH(0, this.ClientSize.Width, this.ClientSize.Height, 0,0, 1));
_device.Transform.View = Matrix.Identity;

fps.Render();

_restore.Apply();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(632, 446);
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(640, 480);
this.MinimumSize = new System.Drawing.Size(640, 480);
this.Name = "Form1";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Hold the Button!";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
//Application.Run(new Form1());
try
{
using (Form2 frm = new Form2())
{
frm.Show();
while (frm.Created)
{
frm.UpdateGUI();
frm.Render();
Application.DoEvents();
}
}
}
catch (Exception e)
{
System.IO.StreamWriter file = new System.IO.StreamWriter("Log.txt",true);
file.WriteLine(e.ToString());
file.Close();
}
}

private void Input_KeyPress(GameTest.Control sender, GameTest.Control.KeyEventArgs e)
{
if (!e.Handled)
{
if (e.key == DI.Key.Escape)
{
Application.Exit();
_closing = true;
}
else if (e.key == DI.Key.F2)
{
_windowed=!_windowed;
ResetDevice();
}
}
}

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
fps.Dispose();
}

private void ResetDevice()
{
_restore.Dispose();

_param = _device.PresentationParameters;

if (_windowed)
{
_param = _winParam;
}
else
{
_param.Windowed = false;
_param.BackBufferCount = 1;
_param.BackBufferFormat = Manager.Adapters[0].CurrentDisplayMode.Format;
_param.BackBufferWidth = 1920;
_param.BackBufferHeight = 1200;
}
_device.Reset(_param);
}

public void CancelResize(Object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}

public void OnDeviceLost(Object sender, EventArgs e)
{
_restore.Dispose();
}

public void OnDeviceReset(Object sender, EventArgs e)
{
_device.RenderState.SourceBlend = Blend.SourceAlpha;
_device.RenderState.DestinationBlend = Blend.InvSourceAlpha;
_device.RenderState.ZBufferEnable = true;
_device.RenderState.ZBufferWriteEnable = true;
_device.RenderState.MultiSampleAntiAlias = false;

_device.RenderState.Lighting = false;


SetupMatrices();

_restore = new StateBlock(_device, StateBlockType.All);
_restore.Capture();
}

}
}





EDIT: Nevermind downloading it, as you can see in the code window I was stupid and had it hardcoded to go to 1920x1200 for resolution (my native res). I'll get a fixed version up in just a bit.

[Edited by - intrest86 on July 19, 2005 9:19:25 PM]

Share this post


Link to post
Share on other sites
I was having the exact same problem as the OP and managed to get it fixed. There were 2 things that could have been the cause in my case, so try these out if they apply:

1) when setting the params for windowed mode, I forgot to reset device.Windowed = TRUE

2) when calling SetWindowPos, I had to OR togeather the SWP_SHOWWINDOW flag with the SWP_FRAMECHANGED one...

SetWindowPos(hWnd, HWND_TOP, 0, 0, m_nWindowWidth, m_nWindowHeight, SWP_FRAMECHANGED | SWP_SHOWWINDOW);

I fixed these 2 things and it works fine now...hope it helps

-Antrim

Share this post


Link to post
Share on other sites
I'm not certain that this is the case but, I, and several other people have had a similar issue.

The problem I've found is related to the use of the events system to handle the device lost/reset. For some reason the vertex/index buffers seemed to stick around even after disposing them (this is in Pool.Default by the way, Pool.Managed seemed to work as expected, and this was a while back so I may not be remembering correctly). So, when you attempt a Reset(), with the buffers still present, it fails. You will see this when you look at the D3D debug output.

The solution? Well, the only solution I've found that works is to disable the event handlers using Device.IsUsingEventHandlers = false; and use exception handling with TestCooperativeLevel/Flip() to trap the lost/reset states. The only major thing you'll lose is the automatic handling of window resizing, and this can be countered using the NativeWindow class.

I haven't checked in the latest release (August 2005) to see if the event handlers work better or not, so that could be a better option.

Share this post


Link to post
Share on other sites

This topic is 4518 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this