glfw - Toggle Fullscreen to Windowed to Fullscreen

Started by
4 comments, last by Waterlimon 8 years, 6 months ago

Does anyone know how to toggle fullscreen to windowed in GLFW? I understand that the context is lost during the transition as you have to use glfwCreateWindow, however I have passed the original context as a parameter to that method which I was under the impression shared the context resources?

I then destroy the old window and mark the new context as current


	// With GLFW we have to create a new window and destroy the old after making sure we enable the new context
	GLFWwindow* tempWindowPtr = glfwCreateWindow(
										this->renderWindow_Width,
										this->renderWindow_Height, 
										this->renderWindow_Title.c_str(), 
										this->renderWindow_Fullscreen ? this->renderWindow_DisplayMonitor : NULL,
										this->renderWindow_hWnd);
	
	if(!tempWindowPtr)
	{
		GLogManager::GetSingleton().WriteLine("Error setting new display settings.", GLogManager::Error);
		this->shouldApplyNewSettings = false;
		return GR_FAILURE;
	}

	glfwDestroyWindow(this->renderWindow_hWnd);	// destroy the old window
	this->renderWindow_hWnd = tempWindowPtr;	// swap the pointers

	glfwMakeContextCurrent(this->renderWindow_hWnd);

I then proceed to recreate my callbacks as I understand the glfw state as well as the OpenGL state is lost, but as I understood it the resources, ie textures, shaders etc won't need to be recreated?? However it seems that I just get a black screen when running the above. Running the output through gDebugger i get:

Debug String: Detected error: The debugged process asked for an extension function pointer (glActiveTexture) from one render context, but called this function pointer in another render context (context #2)

which suggests the context sharing isn't what I thought it was!!!....... anyone able to point me in the right direction here?
thanks
Jamoflaw

Advertisement

Internally glfw uses wglShareLists on windows probably.

This is what gl site says about it:

https://www.opengl.org/wiki/Platform_specifics:_Windows#wglShareLists

This means, while 'actual' resources will be shared (buffers, textures...), some other objects will not (such as VAOs) since they simply reference the actual resources, but dont really contain much data themselves.

I dont know if shaders/programs are shared, probably not (since theyre not mentioned there).

As for that error, did you reinitialize GLEW or whatever you are using to fetch the gl functions?

o3o

I didn't initially, but I did try it and got the same result.

I just added the line:


glewInit()

Straight after the last line posted above? I believe that is correct (I'm quite new to OpenGL) Got the same results though. Would I need to repopulate all the VAO's? I previously used DirectX9 so used to have a procedure for device resets which I dropped as I thought OpenGL didn't behave that way! Doh!

Are the VBO's still valid at that point? Would it just be a case of reinitialising teh VAOs with relevant VBOs?

Do you mean you still get that same error? Or you no longer get that error but it still doesnt work?

VBOs should be valid. I think you need to recreate VAOs using the same buffers.

EDIT:

looking at my own window creation, I only destroy the old window at the end (after making new context current), maybe try that.

(which is what your comment seems to say but you do the reverse...)

o3o

Ah thanks it's working now, was a case of just re-creating the VAOs.

Now Looks like:


// With GLFW we have to create a new window and destroy the old after making sure we enable the new context
	GLFWwindow* newWindowPtr = glfwCreateWindow(
										this->renderWindow_Width,
										this->renderWindow_Height, 
										this->renderWindow_Title.c_str(), 
										this->renderWindow_Fullscreen ? this->renderWindow_DisplayMonitor : NULL,
										this->renderWindow_hWnd);
	
	if(!newWindowPtr)
	{
		GLogManager::GetSingleton().WriteLine("Error setting new display settings.", GLogManager::Error);
		this->shouldApplyNewSettings = false;
		return GR_FAILURE;
	}

	GLFWwindow* origWindowPtr = this->renderWindow_hWnd;
	this->renderWindow_hWnd = newWindowPtr;	// swap the pointers

	glfwMakeContextCurrent(this->renderWindow_hWnd);
	glfwDestroyWindow(origWindowPtr);	// destroy the old window
	
	// Setup callbacks
	this->SetupRenderWindowCallbacks();
	this->SetupInputKeyboardCallbacks();
	this->SetupInputMouseCallbacks();
	glfwSetErrorCallback(&Root::OnError);


	// VAO Reset goes here...

I've changed the ordering of the delete/make current as it seems more logical this way, though it doesn't seem to make any difference and works the way it was originally! The shaders and textures all seem to work, is there any other object type which doesn't get carried or is it really just the VAOs which require the DX style reset?

IIRC glfw attempts to share as much as it can, so considering that, I would recreate anything that is easy to.

Based on the opengl site link, I would say only vbos, textures, and renderbuffers are shared... so everything else needs recreation?

o3o

This topic is closed to new replies.

Advertisement