Hi. I’m trying to write a settings menu for my game giving the player the option to set the resolution and if the game is full screen or not. I’ve got it mostly working but sometime when I change resolution I get a graphicsModeException with the error
Device Primary: {X=0,Y=0,Width=1920,Height=1080} (387 modes available): Failed to change resolution to {X=0,Y=0,Width=1600,Height=1024}x32@30Hz.
This only happens when I go fullscreen BTW and not all resolutions. I’m getting a list of available resolutions using GraphicsAdapter.DefaultAdapter.SupportedDisplayModes but I think I might be getting a few unavailable resolutions due to my slightly odd monitor setup (primary monitor going though a HDMI splitter to a tv and the monitor). Does anyone know how to fix this problem? I’m hoping it’ll just involve sanity checking the available resolutions when filling out the list
Edit this is really old test code for xna not mono-game
now im not gonna redo it as a example or explain why its static.
but hopefully it will help.
the gdm here is the graphics device manager itself
note this line
GraphicsAdapter.DefaultAdapter.SupportedDisplayModes
you should be able to see how i was changing modes
xna could override your choice as well and would if
there was a problem with the pixel format or something else.
i dunno if this works in mono-game but it worked in xna
public static void NextDisplayMode()
{
// If we are using full screen mode
// todo test under mono game
if (Gdm.IsFullScreen == true)
{
// we should find the current display mode then switch to the next one
int thisdisplaymode = 0;
int nextdisplaymode = 0;
int counter = 0;
int w = Gdm.GraphicsDevice.DisplayMode.Width;
int h = Gdm.GraphicsDevice.DisplayMode.Height;
float aspectratio = Gdm.GraphicsDevice.DisplayMode.AspectRatio;
SurfaceFormat f = Gdm.GraphicsDevice.DisplayMode.Format;
//
List<DisplayMode> dmlist = new List<DisplayMode>();
foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
dmlist.Add(dm);
}
// loop and find the current display mode
for (int i = 0; i < dmlist.Count; i++)
{
DisplayMode d = dmlist[i];
// find the matching display mode;
if ((d.Width == w) && (d.Height == h))
{
thisdisplaymode = counter;
nextdisplaymode = counter + 1;
if (dmlist.Count == nextdisplaymode)
{
nextdisplaymode = 0;
}
}
counter++;
}
// The mode is supported, so set the buffer formats, apply changes, show it and return
if (nextdisplaymode != thisdisplaymode)
{
w = dmlist[nextdisplaymode].Width;
h = dmlist[nextdisplaymode].Height;
f = dmlist[nextdisplaymode].Format;
aspectratio = dmlist[nextdisplaymode].AspectRatio;
//
Gdm.PreferredBackBufferWidth = w;
Gdm.PreferredBackBufferHeight = h;
Gdm.PreferredBackBufferFormat = f;
Gdm.ApplyChanges(); // apply the changes
// make sure we note them
client_screen_width = Gdm.GraphicsDevice.DisplayMode.Width; w = client_screen_width;
client_screen_height = Gdm.GraphicsDevice.DisplayMode.Height; h = client_screen_height;
aspectratio = Gdm.GraphicsDevice.DisplayMode.AspectRatio;
f = Gdm.GraphicsDevice.DisplayMode.Format;
//
Console.WriteLine("\n .. \n Display mode[" + nextdisplaymode.ToString() + "] now is WH(" + w.ToString() + "," + h.ToString() + ") aspectratio " + aspectratio.ToString() + " format " + f.ToString());
Console.WriteLine(" Fire_clientSizeChange_CallBacks() \n");
fire_All_Added_OnResize_Callbacks();
}
}
}
Thanks for that. Looking identical to how I’m changing my resolution. By the looks of things the problem is the refresh rate. If I only change it to resolutions that support the same refresh rate the game is currently running in then there’s no problem. My setup is a bit iffy with refresh rates since I started using a HDMI splitter it tries to default to 30hz I have to force it to 59hz. The more I look the more it looks like an annoying edge case todo with HDMI splitters which have screwed up a few games
Is there a safe way to change the refresh rate from monogame?
that is weird
to change it the only thing i know of that you can do to attempt to set it thru the api is …
gdm.SynchronizeWithVerticalRetrace = true;
but i would think that is set by default
here is a old xna post were someone was having a similar problem xna post old
maybe tom or one of the monogame guys can take a look and comment on this
Hi quick update on this in case some people are having the same problem. Looks like it was changing the refresh rate that did. When I limited the available resolutions to only ones that support the current monitors refresh rate it stopped crashing on res change.
It still doesn’t quite work correctly though. Now when I change resolution the game appears part way down the screen with a white bar on top. Anyone seen this before?