Hello all, again.
So, I’ve recently been trying to change the window size while running the game, and subsequently scale everything using a Camera2D view matrix.
Now, everything works when I set the PreferredBackBufferWidth and whatnot during Initialize, and all dimensions work great, the ScalingViewportAdapter works great and then the Camera works great, but the trouble is doing this in game.
The main problem is that while my input manager scales (clickable elements, etc) accurately, the actual graphics do not. Say I have the initial width and height set to 1280x720, and then I hit a button that changes it to 1600x900.
graphics.PreferredBackBufferWidth = 1600;
graphics.PreferredBackBufferHeight = 900;
The actual rendered image stays the same fidelity and size, and position, the window simply expands outward and draws black anywhere outside the original 1280x720 area. Again, input is scaled correctly for the mouse and things.
I don’t exactly know what the problem is, but I have a feeling it’s something to do with my Camera view matrix.
Things I’ve tried so far is re-initializing my ScalingViewportAdapter and then re-initializing my Camera2D object, theoretically remaking it’s view matrix. I’ve also tried not doing these things, both attempts ended with the same result: no change from what I described above. I’ve also tried going fullscreen with graphics.ToggleFullscreen(); but that stretches the original resolution out to fill the screen, and input is completely broke.
Anything I physically draw to the screen is modified by the transformMatrix: camera.GetViewMatrix().
Did you maybe forget to scale your rendertargets? (If you do 3D)
I’m in 2D, but no, I’m not scaling my rendertargets. Do I need to be even if I’m calling spriteBatch.Begin(transformMatrix: camera.GetViewMatrix()); ?
I made a testing game1 class a long while ago to perform tests on monogame under fullscreen mode, changing windowing, and all sorts of things it basically tracks all the changes that occur.
You might be to use it to figure out what you need to do or tweek it to give you more info.
Its basically just a game1 class but you will need to turn on your console output.
Make a new project copy paste this over the game1 class change the namespace (nothing in it but monogame calls).
To turn on your console to see all the output,.under VS -> Debug-> properties -> Application -> Output type (click the dropdown change it from application to console, it will run the game window as well as a console) you may wish to after you run it once change the console windows buffer by right clicking it on the top left and make it bigger.
How it works.
If you let it run automatically it will perform screen tests after about 20seconds your screen will flash minimize maximize ect… it may even flash to black and back like the old dxdialog.
You can manually perform tests with the F keys. Then look at the code as well as the output to see everything that is changing in the console from what it was to what it is. As well as look thru the code maybe the old mode switch attempts i did in it work still.
i cant remember which one was newer
top center is the download arrow.
I guess I can’t say what I should be looking for here, the process looks similar to what I’m trying to do. The window is re-sizing properly, however the actual content isn’t. Here is a a quick gif example of what’s going on. https://gfycat.com/UniqueHeavenlyConey I hit a button to change the buffer width and height, then apply; however it just expands into nothing, not re-sizing the content. It should be since all graphics have a transform matrix applied to it from the camera view, which relies on the the viewport, which is being changed.
The camera stuff is probably where I’m running into trouble since I still don’t know a great deal about Extended workings.
I think the problem might be something to do with the
GraphicsDevice.Viewport property not being set to the right size when you change the preferred back buffer size.
Try doing something like this:
GraphicsDevice.Viewport = new Viewport(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height);
If that doesn’t work I’d be happy to take a closer look if you can do up a reproduction of the issue.
I must admit, the viewport adapters could do with some love in this area. They where not really designed with in-game resolution changes in mind, but I realize now that was a bit silly since almost all games require this.
No difference with that code, input is still scaling, graphics are not.
What do you mean do up a reproduction? Pretty much I’m drawing content at the starting resolution fine, then take input to change the resolution and ideally the camera view matrix updates scaling the drawn content appropriately (which is not the case).
Make sure the window.clientbounds is actually correct to say its width height has changed as well to the backbuffer size your trying to set. If its not you may need to manually set it.
The view matrix shouldn’t have anything to do with it unless you are manually setting the matrix elements yourself to scale e.g m11 =.5f; m22 =.5f ect… but note that mode switching and fullscreen to windowed in monogame is still a little wonky.
You can use the RecordDiff class at the bottom of that game1.cs file i posted up, to see what is or is not changing as for the window and graphics device, copy out the bottom class RecordDiff from my posted .cs file. Paste it below your game1 class or at the end as a inner class.
Record the changes just before you fire your resize code in your method.
new RecordDiff(gdm, gd, window);
passing in your GraphicsDeviceManager GraphicsDevice and Window as parameters
Then execute your resize code, and call it again to record what happened after.
new RecordDiff(gdm, gd, window);
Then see just what is changing by calling the below.
Make sure you have your application set to temporarily show a console window as described in my previous post. If you cant immediately see the problem after that. Post up the console text output on here.
Are you able to send me a simple project that does the same thing? Don’t send me your entire game code, just try to re-create the important bits for this particular problem. If you want a starting point you can use some of the sample code out of MonoGame.Extended.
I’ve raised a bug to investigate this further. When I get time I’ll try and re-create the issue myself. I just thought it might be quicker if you could provide the required code to reproduce it.
You know what, I think I fixed it. I was going through the motions of recreating it, unable to, and then I checked for key differences in the recreation and my actual game. I wasn’t resetting my main render target, as at the beginning of every main Draw() the render target is set to a sceneContents RenderTarget2D, which I initially just set once in LoadContent().
Since LoadContent() is only called once, it stayed the same. So now, whenever I change the resolution I must call
sceneContents = new RenderTarget2D(GraphicsDevice, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
again for the main thing to scale properly to the new window size.
Seems to be working now!