Change Screen Mode in GLFW

Monkey Forums/User Modules/Change Screen Mode in GLFW

Skn3(Posted 2013) [#1]
Here is some code to allow screen mode changing in GLFW.

Please note that you must discard all images before changing screen mode and then you must reload them after.

You MUST discard images using image.Discard()

You MUST discard and reloads images used by 3rd party modules such as the mojo default font.

This isn't exactly a clean solution yet but I think in the new Monkey (v67) it will be far easier to implement this using a system similar to blitzmax where the image data is kept in ram as well as video memory. Reloads can then be automated. There is also a DiscardImages() event in the new monkeygame interface which could help.

Would anyone like to implement this code on other targets?

modules/skn3/screenmode.monkey


modules/skn3/screenmode/native/screenmode.glfw.cpp



Skn3(Posted 2013) [#2]
Example



EdzUp(Posted 2013) [#3]
Excellent stuff :D


therevills(Posted 2013) [#4]
Skn3 what did I miss when I first looked into this? Looking at your code and what I originally did looks very similar... apart from the bits bit.


Skn3(Posted 2013) [#5]
Simply you and everyone else had missed the image.discard()Ii spent ages reading the posts on that thread, reading stack overflow and examining how monkey works under the hood. I had no idea monkey had picked up a command to manually discard().

So basically the reason it appeared to work once was just a coincidence. The images were referencing gl surfaces that had lost the context they belonged to when the window was closed.


Chroma(Posted 2013) [#6]
Yep, good job man!

Just test it...works as advertised.


John McCubbin(Posted 2013) [#7]
Good work, now if only we had it for XNA too :P


dopeyrulz(Posted 2013) [#8]
Skn3,

Hi been using your module in v66, but haven't yet managed to get it going in v68 with all the internal changes - having some trouble trying to get the callbacks referenced.

Did you have any plans for upgrading to v68 and beyond?


therevills(Posted 2013) [#9]
Try adding:
extern gxtkGraphics *bb_graphics_device;

To the top of the C++.

Then change:
	//modify the dimensions of the app
	app->graphics->width = width;
	app->graphics->height = height;

to:
	//modify the dimensions of the app
	bb_graphics_device->width = width;
	bb_graphics_device->height = height;


Not tested ;)


dopeyrulz(Posted 2013) [#10]
@therevills
Thanks for your help - that's about where I got to!

It's the stuff referencing the glfw callbacks I can't get working as the keys etc stop working)
	glfwSetKeyCallback(gxtkApp::OnKey);
	glfwSetCharCallback(gxtkApp::OnChar);
	glfwSetWindowSizeCallback(gxtkApp::OnWindowSize);
	glfwSetWindowRefreshCallback(gxtkApp::OnWindowRefresh);
	glfwSetMouseButtonCallback(gxtkApp::OnMouseButton);


Also noted these callbacks are slightly changed in v68.

As the App setup stuff now appears to be Monkey code rather than native it can't seen to see how I can get access.

I've created a launch frontend for my Donkey Kong arcade cabinet that I've recently been building. Annoyingly when I launch Mame (via Execute) it sort-of turns the full-screen window into an almost full-screen window (it appears to size it without considering the window frame leaving the right/bottom part of the desktop visible) which I need to refresh to return back to full-screen. This code has been a lifesaver in allowing me to continue in monkey.


therevills(Posted 2013) [#11]
Ah, I didn't see those, sorry...

Try:
glfwSetKeyCallback(BBGlfwGame::OnKey);


Or looking at the code (I hate C++ BTW), try getting the static reference of GlfwGame:
class BBGlfwGame : public BBGame{
public:
	BBGlfwGame();

	static BBGlfwGame *GlfwGame(){ return _glfwGame; }



Skn3(Posted 2013) [#12]
Hey cheers for the fixes, Let me know if the fix works for now. I'll have another look into this soon and see if it can be improved with the new v68 stuff.


dopeyrulz(Posted 2013) [#13]
@therevills
No probs mate - nice of you to take a look. Yeah c++ not my thing either, but i'll have a play around - certainly maybe what we want is not publically exposed.


Trion(Posted 2013) [#14]
Hi! Did anyone test it on v70? And I want to know - can it use a current desktop user resolution? Does It hard to add this?

/sorry I am a newbie :) But I remember when I release my first game on BigFishGames (On BLitz3D)- change resolutions and other resolution stuff was a real hard issue. And I want to get it clear on Monkey GLFW...


SLotman(Posted 2013) [#15]
Alternating from windowed to fullscreen in Monkey is a pain. I've got it working on v70f - but a lot of changes had to be made, which I posted about here


jjsonick(Posted 2013) [#16]
SLotman, are you saying you made changes in Skn3's code to get it working in v70f/g? If so, could you post the changes (I didn't code or a link to code in the thread you mention)?


Skn3(Posted 2013) [#17]
Yeah if anyone has a definitive solution to this I could put it on a repo or update the code snippets in the first post?


SLotman(Posted 2013) [#18]
Not on Skn3's code - I code it myself, the changes I've made I posted on Monkey.70f thread. You need to expose a bunch of calls from monkeygame (the calls to read keys, mouse, etc) since they're private.

Then you destroy the glfw window, create a new one, discard all images and load them again.


ImmutableOctet(SKNG)(Posted 2013) [#19]
SLotman, I've messed with this sort of thing in the past, and I REALLY don't feel like doing it again. If you have working code, can you please just post it? If you've already done the work, there's no point in having every single one of us do it from scratch. I've already edited the GLFWGame code, so I shouldn't have any problems.


Why0Why(Posted 2013) [#20]
I REALLY think that being able to change screen res on the fly in GLFW should be an absolute priority. I was also disappointed that in the aforementioned thread that Mark didn't address that at all when Slot listed some relatively easy changes that would help.


ImmutableOctet(SKNG)(Posted 2013) [#21]

Why0Why: I REALLY think that being able to change screen res on the fly in GLFW should be an absolute priority. I was also disappointed that in the aforementioned thread that Mark didn't address that at all when Slot listed some relatively easy changes that would help.


Believe it or not, I was going to post about the same thing, but the post became huge and somewhat irrelevant, so I moved it to here.


SLotman(Posted 2013) [#22]
Actually, I don't have a screen *resolution* change. I set on config.target width and height to zero, and my code only switches from fullscreen to windowed mode and vice-versa.

With width/height set as 0 game starts at desktop resolution, and that's all I need.

This is the routine I call to create the windowed mode, should be all needed:
void setWindowed(int w, int h)
{
      glfwCloseWindow();
      while(glfwGetWindowParam(GLFW_OPENED)) { glfwPollEvents(); }      

	GLFWvidmode desktopMode;
	glfwGetDesktopMode( &desktopMode );

	glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, GL_FALSE);
	if (w==0 && h==0)
	{
	  if (CFG_GLFW_WINDOW_WIDTH==0) { w = desktopMode.Width; }
	  if (CFG_GLFW_WINDOW_HEIGHT==0){ h = desktopMode.Height; }
	  glfwOpenWindow(w,h, 0, 0, 0, 0, 0, 0, GLFW_WINDOW );
	} else {
	  glfwOpenWindow(w, h, 0, 0, 0, 0, 0, 0, GLFW_WINDOW );
        }
      while(!glfwGetWindowParam(GLFW_OPENED)) { glfwPollEvents(); }      

	   glfwSetWindowTitle(_STRINGIZE(CFG_GLFW_WINDOW_TITLE));

		glfwEnable(GLFW_KEY_REPEAT);
		glfwDisable(GLFW_AUTO_POLL_EVENTS);

		glfwSetKeyCallback(BBGlfwGame::OnKey);
		glfwSetCharCallback(BBGlfwGame::OnChar);
		glfwSetMouseButtonCallback(BBGlfwGame::OnMouseButton);
		glfwSetMousePosCallback(BBGlfwGame::OnMousePos);
		glfwSetWindowCloseCallback(BBGlfwGame::OnWindowClose);

#if INIT_GL_EXTS
	Init_GL_Exts();
#endif

}



As you can see, it's pretty simple and almost the same code you see on glfw code. I don't see what's the big fuzz of 'not posting the code' is all about.


ImmutableOctet(SKNG)(Posted 2013) [#23]
So, I finally got around to modifying your code SLotman, and here's the result:



Here's the "Extern" code for Monkey:



I think I went a bit overboard, and the transition option was done as a proof of concept, but regardless, that should all work.

I've tested all of this with V70e, I'll get around to testing it with V71 at some point. This should also work with Linux and Mac OS X, but I haven't tested it.

Please note that this was designed with 'OnCreate' in mind, so you generally should be calling 'ResizeWindow' there. And obviously, you shouldn't do anything graphics related with Mojo before using 'ResizeWindow' (Unless you want to reload/reset everything).

Also note that this requires the same edits to the 'BBGlfwGame' class, which can be located in "targets/glfw/modules/native/glfwgame.cpp".

I can't guarantee that this will work in the future; however, I may end up updating it if there's a problem with a future version of Monkey/Mojo. I'll be using this for my own project, so I'll at the very least have a working version.