Advertisement

GLFW freeze when holding window's titilebar

Started by January 05, 2020 05:45 PM
2 comments, last by Shaarigan 4 years, 10 months ago

I fixed window resizing and moving freezes

but when I hold down mouse left click on window's title bar, <glfwPollEvents()> stops the main thread.

I searched the web; people said you should move render loop to an other thread.

I tried multi threaded way, but the screen, goes crazy!

Can anyone help me fix that?

this is single threaded code:

Visual Studio 2019 (v142)

my project properties>Linker>system>subsystem in on <Windows (/SUBSYSTEM:WINDOWS)>

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <Windows.h>
#include <iostream>
#include <conio.h>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void pos_callback(GLFWwindow* window, int x, int y);
void f_callback(GLFWwindow* window);
void processInput(GLFWwindow* window);
void onTerminate();

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

void draw(GLFWwindow* window) {

	// render
	// ------
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
	// -------------------------------------------------------------------------------
	glfwSwapBuffers(window);
}

int main()
{
	// glfw: initialize and configure
	// ------------------------------
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif

	// glfw window creation
	// --------------------
	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Scene", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
	glfwSetWindowPosCallback(window, pos_callback);
	glfwSetWindowRefreshCallback(window, f_callback);

	// glad: load all OpenGL function pointers
	// ---------------------------------------
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// render loop
	// -----------
	while (!glfwWindowShouldClose(window))
	{
		// input
		// -----
		processInput(window);

		// render
		// ------
		//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		//glClear(GL_COLOR_BUFFER_BIT);

		// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
		// -------------------------------------------------------------------------------
		//glfwSwapBuffers(window);
		draw(window);
		glfwPollEvents();
	}

	onTerminate();
	
	return 0;
}



// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	// make sure the viewport matches the new window dimensions; note that width and 
	// height will be significantly larger than specified on retina displays.
	glViewport(10, 10, width-10, height-10);
	draw(window);
}

void pos_callback(GLFWwindow* window, int x, int y)
{
	draw(window);
}

void f_callback(GLFWwindow* window)
{
	draw(window);
}

void onTerminate()
{
	// glfw: terminate, clearing all previously allocated GLFW resources.
	// -----------------------------------------------------------------
	glfwTerminate();
}

int CALLBACK WinMain(
	__in  HINSTANCE hInstance,
	__in  HINSTANCE hPrevInstance,
	__in  LPSTR lpCmdLine,
	__in  int nCmdShow
) {
	return main();
}

Lock the mouse to the window region so it can't get to the title bar.

Press ESC to pause the game to allow mousing outside window.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Advertisement

The problem that occures here is that the event loop is flooded with OS specific events that tells the Window that it's position has changed. If you are on Windows for example you will always stay in the

while(true)
{
    if(PeekMessage)
    {
        TranslateMessage;
        DispatchMessage;
    }
    
    //call to the game loop
}

if clause and translate those “important” messages until you stop moving your window.

I don't know how GLFW is written but you should try to move the glfwMakeContextCurrent(window); call into your thread if you want to render multithreaded. OpenGL is used to stay single-threaded only and so only one thread can own the render context. If another thread tries to modify something, GL will prevent this but it allows to share contexts between threads with defined roles, for example a loader thread that has data access while the render thread well … renders

This topic is closed to new replies.

Advertisement