Comments (35)
Assuming you're using MonoGame.Framework.SDL2.csproj?
If you can provide me with a complete history of what SDL2_GameWindow::EndScreenDeviceChange is going through throughout your program (print the full set of variables and their values each time the device change occurs), that'll tell me what's wrong with the application. Otherwise, best I can say is "I dunno, lol", since I recently added code to ensure that GraphicsDeviceManager preferences were usable by the time you hit Game::Initialize. Though, I also haven't seen ToggleFullscreen in a while, so maybe there's something to be investigated there.
A test case will also help, if you've got one.
from fna-mghistory.
Hm, here's something: keep an eye on _wantFullScreen
in GraphicsDeviceManager.cs as well. Wondering if messing with ToggleFullscreen and GraphicsDeviceManager preferences too much causes some inconsistencies.
from fna-mghistory.
Bummer that it wasn't just "oh, I hardcoded that to be on" ;)
Thanks for the pointers, I'll debug at the points you mentioned.
from fna-mghistory.
This is a little strange... when the app starts, every time SDL2_GameWindow::EndScreenDeviceChange() is called, when we get to the SDL_SetWindowFullscreen call, both of these tests always returns 0:
(INTERNAL_sdlWindowFlags_Next & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN)
// as well as
(INTERNAL_sdlWindowFlags_Next & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP)
and _wantFullScreen is set to false.
That gets called 3 times during startup and then the window appears fullscreen. If I let my loading-screen and splash-screens run, then my game is sitting idle. If I then hit F11, the ToggleFullscreen code gets called but the state in SDL_Window seems to not match the actual stae of the window... so _wantFullScreen gets switched from false to true. Resultingly, a test of:
(INTERNAL_sdlWindowFlags_Next & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN)
// as well as
(INTERNAL_sdlWindowFlags_Next & SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP)
Shows that SDL_WINDOW_FULLSCREEN flag and SDL_WINDOW_FULLSCREEN_DESKTOP are now set. Although my game ran past this point, when I'm debugging it always dies right afterwards by running out of memory at the next Draw() call in the game loop.
What code might be capable of setting the window fullscreen against _wantFullScreen's wishes?
from fna-mghistory.
It miiight be possible that ToggleFullscreen() is changing IsFullscreen without consulting _wantFullscreen first? I don't know what behavior could change here, but maybe before the IsFullscreen = !IsFullscreen;
bit we need _wantFullscreen = !IsFullscreen
as well? _wantFullscreen is a weird, weird variable...
Of course, this probably means that BeginScreenDeviceChange is getting false
each time, so SDL2_GamePlatform::BeginScreenDeviceChange is always being told to stay windowed. That'd be another place to look for issues.
You might be able to set a breakpoint at SDL_SetWindowFullscreen or spam SDL_GetWindowFlags to check its info, but the part where it runs out of memory is really interesting. The Mono profiler might be able to shed some light on that (I think)?
Is there any use of System.Windows.Forms going on? That's the only other thing I can think of that might try to change the window state (it really, really shouldn't); SDL2 does the rest... and I don't think 2.0.0 has had any reports regarding fullscreen for any particular OS.
from fna-mghistory.
IsFullscreen
is just wrapping _wantFullscreen
basically, and it does appear to be getting set correctly inToggleFullScreen
.
I set a breakpoint at all the calls to SDL_SetWindowFullscreen inside of BeginScreenDeviceChange and it doesn't gets either of those FULLSCREEN flags being set during the initial startup. Also, since the app gets focus gained/lost because of my debugging, I put a breakpoint where SDL_SetWindowFullscreen is called in INTERNAL_RunLoop and the flags aren't set there either. The flags only get set when I hit F11.
No use of System.Windows.Forms in our project.
...hmm... I realized that I could restore-down my Visual Studio window and actually watch when it goes fullscreen (because it's a smaller window during initialization, before it goes fullscreen).
It's on this specific line:
SDL.SDL_SetWindowPosition(
INTERNAL_sdlWindow,
x + ((INTERNAL_glFramebufferWidth - clientWidth) / 2),
y + ((INTERNAL_glFramebufferHeight - clientHeight) / 2)
);
This is... strange.
from fna-mghistory.
Ah, now that might be something:
https://github.com/flibitijibibo/MonoGame/blob/monogame-sdl2/MonoGame.Framework/SDL2/SDL2_GameWindow.cs#L354
https://github.com/flibitijibibo/MonoGame/blob/monogame-sdl2/MonoGame.Framework/SDL2/SDL2_GameWindow.cs#L363
These two lines, take 'em out. Wondering if we screwed something up early on for when handling window events. Even though the focus isn't getting touched (er, well, it shouldn't), it may still mess with the flags.
This may also be why window state is getting wonky on seemingly unrelated SDL window calls, but I don't know if that's our fault or SDL2 doing something internally.
from fna-mghistory.
Took those two lines out & it didn't appear to have any effect.
Why is it that .SDL_SetWindowPosition()
is making it go fullscreen? Does that just mean that something else set the flags to make it fullscreen prior to that call, and that call happens to be Applying Changes?
(Not sure if it's relevant but the position it's setting the window to is (0, 0)).
from fna-mghistory.
Does removing that block of code to center the window fix it?
Here's the SetWindowPosition in SDL... not sure if tracing this will lead to anything interesting:
http://hg.libsdl.org/SDL/file/cf99258f905c/src/video/SDL_video.c#l1524
from fna-mghistory.
Removing the SetWindowPosition call, DOES prevent it from going fullscreen on startup. Pretty cool :)
Then, if I hit F11, it goes fullscreen. However, subsequent F11s only make it flicker, and it stays fullscreen. That's gotta be another hint... so I'll debug more of that (might hop over and do the Ludum Dare now, though - if it's an interesting theme).
from fna-mghistory.
Another wrinkle is that despite having "Window.AllowUserResizing = true;" Window resizing is not being allowed.
from fna-mghistory.
I actually don't think I ever bothered to implement that. Look into the resizable window flag and resize events, then submit the patch. None of my games use that, so I have nothing to test with.
from fna-mghistory.
Ok sounds good. We'll take a peek. Thanks!
from fna-mghistory.
Ah, now I remember why I didn't bother implementing it: this little gem:
For some reason, SDL2 never had a SetWindowResizable, so it can only be set before SDL_CreateWindow. So, if you need this variable, just change this line manually:
I'll need to add this as a remark in the SDL2_GameWindow's documentation. The window should at least be resizable after that, but I don't think the viewport is modified, just the mouse scaling:
It might be worth asking the SDL mailing list why a SetWindowResizable was never made... I can't really think of a reason, unless it affects the GL context.
from fna-mghistory.
Those changes seemed to have worked. Just needed to add this into the SDL event handling as well for it to behave the same way XNA does.
if(evt.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
OnClientSizeChanged();
The only issue I see now is when we switch to fullscreen the graphics get stretched (since we force our viewport to 16:9. I think thats due to the SDL window forcing the render to cover the whole window, but I'll explore it a bit more. Let me know if you might have any insight. Thanks a ton for your help!
from fna-mghistory.
Compare it to XNA4 and let me know what you get. As far as I know it should work if you set the backbuffer preferences to the actual display mode, then adjust the Viewport accordingly (this is what we do for FEZ).
Also, I've added in the resizable window changes:
The resizability for the SDL2_GameWindow is now configurable via #define
. This should be particularly nice when merging branches that change things in this file.
from fna-mghistory.
Thanks! You actually need to put another check in there to check to make sure it is specifically a resize event, otherwise you'll get an infinite loop in my experience.
Good work on the define. Good idea!
I have it on the same codebase with MonoSDL2 and XNA4. Everything works the same except the fullscreen on Mono is stretched vertically. In XNA4 it automatically letterboxes the rendering. I'm setting the Viewport to be 16:9 as well as the preferredbackbufferwidth/height. You are saying the preferredbackbuffer stuff should be to the actual display resolution rather than the viewport size?
from fna-mghistory.
Hmmm. Actually on my fullscreen code, I'm not doing the 16:9 fixing properly. Let me explore. XNA must be doing something extra under the covers that is fixing my mistake.
from fna-mghistory.
If you're using Window.ClientBounds to check the display size, change it to the GraphicsDevice/GraphicsAdapter information instead. For fullscreen on SDL2, the ClientBounds will always be the native screen resolution, so if the intended resolution ends up being lower than the native res, the info will be wrong. I'm hoping to fix this internally, but the MonoGame core implementation uses the ClientBounds in too many places, so I have to stick with it until we get the core library using the INTERNAL_backbufferWidth/Height.
I'll split up the resize events, now that I look at it it would probably cause an infinite loop inside ApplyChanges... my bad.
from fna-mghistory.
Ended up just splitting those two window events:
from fna-mghistory.
Those changes look good.
I am using the GraphicsDevice width and height already. And I changed my code to force a 16:9 PreferredWidth/Height and I get the same results. So it seems like XNA is doing something on its own to center the viewport rather than stretching it. I'll dig around some more tomorrow.
from fna-mghistory.
Hmmm. So the more I look at this, the more it looks "correct" (in that I'm rendering properly to a 1280x720 canvas). I'm pushing our game to fullscreen at 1280x720. Both XNA and Monogame agree that that is a valid DisplayMode for my monitor. As best I can tell, XNA actually changes my monitors resolution to that, causing a letterboxing effect (presumably done via the driver). SDL appears to be doing a "fake" fullscreen though, where it isn't actually changing my resolution. So instead of letting my graphics driver do the letterboxing for it, Mono is just stretching everything to fit as if the resolution was actually 1280x720. FYI, my screen is 1680x1050. I've tried changing SDL2 to use "actual" fullscreen where it changes my display mode, but that is just resulting in a black screen.
It seems like this is just what SDL does: http://forums.libsdl.org/viewtopic.php?t=4373&sid=d8fd7fcc8a2e16e71a1df6edf1949080
If you switch to a resolution that your driver supports but isn't the same aspect ratio as your monitor you'll get the stretching in SDL in fake fullscreen mode. Although I guess theoretically if your driving doesn't do letterboxing automatically this could be a problem in real fullscreen mode as well. Looks like rendering to a texture and scaling that up and letterboxing on my own is the way to go. Fortunately I just switched things to render the whole scene to texture yesterday for another reason.
Thanks for you help on this one. Let me know if you have another idea, I think this is the correct route though.
from fna-mghistory.
I had to make this change in GraphicsAdapter.CurrentDisplayMode within the SDL2 define:
SDL2.SDL.SDL_DisplayMode dm;
SDL2.SDL.SDL_GetCurrentDisplayMode(0, out dm);
return new DisplayMode(
dm.w,
dm.h,
dm.refresh_rate,
SurfaceFormat.Color
);
I think that is probably the correct way to do it. Short of maybe caching the value. Although, that probably isn't necessary. It allowed me to actually get the display resolution and do the letterboxing myself. Worked like a charm. Only problem I have now is when I come out of fullscreen the Mono version of the code doesn't restore the old resolution. Probably something easy I'd guess.
from fna-mghistory.
Indeed, that is what we do in the SDL2_GameWindow, as I mentioned earlier in the thread.
Odds are it's the monitor that's able to letterbox when the aspect ratio is off. Not yet aware of any driver that'll handle that.
If you need the "intended" resolution, grab the CurrentDisplayMode. If you want the actual resolution, grab Window.ClientBounds. That should give you the info needed to letterbox on the right aspect ratios.
from fna-mghistory.
Committed some changes from Darthdurden's window tweaks:
SeanColombo@e5f5c07
Due to my github n00bery, I'm not sure how to do a pull request for that because we have another pull request from the same branch that's waiting to get merged (so it's trying to pick up all of those changes too).
from fna-mghistory.
You'll need to create a new git branch and then push that branch to your origin.
However, I don't know if I want those changes. This breaks the ability to get the fullscreen FBO resolution when you can get the "real" resolution from Window.ClientBounds.
from fna-mghistory.
The change darthdurden made, makes it analogous to how XNA does it.
Can't you just get the values you're looking for from GraphicsDevice.PresentationParameters?
from fna-mghistory.
I'm largely doing this for the sake of XNA4 accuracy. The original XNA API behavior needs to be 100% accurate to the original, and the SDL display mode will not be the same in every case. The platform extensions, however, I am willing to let by, since calls like Game.Window.ClientBounds
can have different behavior on varying platforms.
I don't think I ever got a test case, anyone have one?
from fna-mghistory.
Yea I actually made this change to make it accurate to XNA4. The DisplayMode property returns the current DisplayMode of display you are using, regardless of your backbuffer size when you are in XNA. When I want the backbuffer size, I just query GraphicsDevice.PresentationParameters. The test cause is just making a non-fullscreen window and checking all of those parameters.
I guess the way you have it implemented will work if you are in fullscreen since the backbuffer and screen resolution are the same, but basically this fixes things for windowed mode as well. Any reason you wouldn't want to just query PresenationParameters if you want backbuffer info?
from fna-mghistory.
It's less about what I'd do, but rather what the client did when writing their XNA4 game. This is how they ended up writing their code, and it bugs out on MG-SDL2.
That said, I just looked at the original code I had in there before using the FBO dims:
So maybe that code will work? Let me run it through AVNT real quick, as that's the game that queries this value.
I'll just push this myself if it does work, as there are some other things I need to change in the GameWindow as a result.
from fna-mghistory.
http://www.flibitijibibo.com/avntMode.zip
The AVNT code works in XNA4, but with that DisplayMode change it causes ^ in MG-SDL2.
from fna-mghistory.
So I think this is the problem:
Lets say you have a 1920x1080 display for this example and want to run your game at 1280x720.
In SDL2 "Fullscreen Mode" isn't really fullscreen in the current code. If you run in fullscreen it is making the window the same size as the screens resolution (so 1080p). So you have a 1920x1080 window taking up the whole screen but with a backbuffer of only 720p size, but scaled up so that it looks like your actual resolution has switched to 720p. So my guess is that is why you want the DisplayMode to return the backbuffer size, since in XNA, those would be the same since it goes into real fullscreen mode and actually changes the screen display resolution.
So really that DisplayMode code should return what you are proposing if we're in fullscreen mode, but when in windowed mode, it should be return what I'm proposing. I think.
But long story short, I think my code is technically correct, except that fullscreen isn't done the same way it is done in XNA. So either we fix that somehow (which probably isn't worth it), or just change the way DisplayMode works depending on if we are in Fullscreen or not.
Does that make sense to you?
from fna-mghistory.
In windowed mode, the FBO dimensions will be the same as the window dimensions, so in windowed mode it would not matter which is queried. Only in fullscreen mode will the two values vary, and only when the intended resolution is different.
Basically, make it correct in XNA first, then fix the MonoGame bugs (and for platform code such as direct use of GameWindow, be prepared to def things for XNA4 and MonoGame). That is rule #1 of the MG-SDL2 project.
If that's the idea you have in mind, go for it. It really does sound like you just want to render your game solely in 720p regardless of the resolution, with black borders around the viewport. AVNT actually does the same thing, and the way that is done is by allowing any resolution, but making the viewport 1280x720 inside that resolution. You cannot assume that a 720p fullscreen window will magically have borders around the viewport; this is only ever done by the monitor rather than the OS display manager. I would even suggest changing your OS display mode just to be sure that the monitor is doing the work rather than the OS.
In fact, here's my desktop at 1152x864, with my monitor set to letterbox, as an example of this:
http://www.flibitijibibo.com/monitorboxing.jpg
It's also worth noting that forcing your viewport to a resolution when you have the option to avoid it (read: you're not doing a port from the 360) is pretty much asking for PC gamers to hate you.
from fna-mghistory.
I agree that the window and FBO dimensions would be the same in windowed mode. I'm interested in getting the current display mode though (ie. the actual resolution that the OS is outputting to determine what we want to display to the user when they go to fullscreen mode).
I suppose I could possible switch the code around to put it into fullscreen first and then query the DisplayMode to get the resolution. The only problem with that is that in XNA the DisplayMode actually changes (to match the viewport as best I can tell) so you'll get essentially the backbuffer size. SO XNA and Mono will disagree on what to do at that point.
As for forcing 720, that isn't what we're planning on doing. Right now we are rendering to a 720 backbuffer on a RenderTarget in fullscreen mode, but we scale it up to fill the screen. It probably won't stay that way and we'll most likely render to as big of a 16:9 area as we can based on the width/height of your monitor with letterboxing (done on our end) where appropriate.
Anyway, I get what you're saying about the defines, I can probably figure something out. I'll look at the spots where we are getting DisplayMode and see if they can do it some other way when in Mono. Or we'll just fork that file if all else fails. ;)
from fna-mghistory.
Someone else figured this one out for you:
The faulty behavior was also in GraphicsDevice, not just GraphicsAdapter.
This should now be resolved.
from fna-mghistory.
Related Issues (20)
- shader normalmap not work HOT 3
- Can't run on machine without audio device HOT 9
- [OpenGL] VMware/VBox Support? HOT 7
- [MojoShader] MOJOSHADER_glSetVertexAttribDivisor causes 'System.AccessViolationException' on some computers HOT 3
- [Keyboard] Proposal for Keyboard.GetLayoutEXT() HOT 1
- Microsoft.Xna.Framework.Input.GamePad.INTERNAL_AddInstance throws "An element with the same key already exists in the dictionary" HOT 2
- Triangle color is wrong with fairly simple shader + access violation exception HOT 7
- Unable to load a texture (.PNG) from stream HOT 9
- Initialization order mishap HOT 3
- GraphicsDeviceManager never set in Game HOT 1
- GL Object Disposal Wrappers are not thread-safe HOT 3
- DynamicSoundEffectInstance behavior incompatible with XNA4 HOT 8
- OpenGL 3.2+ Core Profile support HOT 4
- Starting game in full screen bug HOT 8
- Null reference when disposing sound effect after checking sound device exists HOT 5
- [QUESTIONS] learning, using FNA HOT 3
- More spec-compliant Touch Support HOT 34
- FNA Binary Release HOT 1
- RasterizerState.MultiSampleAntiAlias not implemented HOT 8
- Set Render Target to Another Window HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fna-mghistory.