Sign in to follow this  
Tuom Larsen

GLFW: Resize callback stall

Recommended Posts

Tuom Larsen    104

Hi!

I'm trying to use GLFW to display a simple triangle and it works! However, the problem is that when I resize the window by dragging the lower-right corner nothing happens (not even the redrawing, i.e. various artifacts show up) during the dragging, until I release the mouse button. I'm on MacOS X and using GLFW 3.0.4.

I set up the "glfwSetWindowSizeCallback()" handler and it gets called, like this:

    static void window_size_callback(GLFWwindow *window, int width, int height) {
        glViewport(0, 0, width, height);
        printf("was called\n");
    }

I read that it is caused by the OS event loop and I verified the included GLFW examples, all of which exhibit the said behavior.

Please, how do I make it "live" resize? Are there any examples of this?

Share this post


Link to post
Share on other sites
swiftcoder    18437

Please, how do I make it "live" resize?

You don't.

 

GLFW has had this limitation for quite some time (as does SDL), and it's actually become quite tricky to accomplish even when implementing a native Mac application. Ever since Apple detached OpenGL rendering from the main thread, it is bloody hard to get the window resize event to sync with your application's render loop...

 

If you are interested in the underlying issues, it's worth reading this MacRumors thread.

Edited by swiftcoder

Share this post


Link to post
Share on other sites
Tuom Larsen    104

But there has to be some way..? I hope!

 

I checked with SDL and yes, it has the same issue.

 

On the other hand, I tried to subclass NSOpenGLView and it works, contrary to what the link says. And I also tried the linked GLEssentials, and those work, too.

 

Do you perhaps know, what do I have to do in order to redraw the view immediately? Multi-threading? Custom event loop? I'm asking because I find it difficult to believe that someone at all is using GLFW or SDL if such basic a feature is impossible to accomplish. I mean, Valve is reportedly using SDL and they surely wouldn't if they could not resize the window properly. Just guessing, thou...

 

In any case thanks!

Share this post


Link to post
Share on other sites
swiftcoder    18437

I'm asking because I find it difficult to believe that someone at all is using GLFW or SDL if such basic a feature is impossible to accomplish. I mean, Valve is reportedly using SDL and they surely wouldn't if they could not resize the window properly

 

It's worth noting that an awful lot of games don't support live resize. There are exceptions, of course, but the default approach seems to be to support most common resolutions, and allow the user to choose whether the game should be fullscreen or windowed.

 

 

And I also tried the linked GLEssentials, and those work, too.

 

Interesting. Having just pulled the GLEssentials code, I see that they applied a fix for this issue in a recent update.

 

If you look in [GLEssentialsGLView reshape], you'll note that they now manually lock the context, and then render an additional frame synchronously on the main thread.

 

It might not be a particularly elegant solution, but if it works, it works.

Share this post


Link to post
Share on other sites
Tuom Larsen    104

In my NSOpenGLView subclass I only do:

 

- reshape(void) {

    NSSize size = [self.window.contentView frame].size;

    glViewport(0, 0, size.width, size.height);

}

 

and it seems to work as well...

Edited by Tuom Larsen

Share this post


Link to post
Share on other sites
Tuom Larsen    104

but are you rendering off-thread?

Hm, to be honest, I know know how it works, probably not. I mean, I simply subclassed NSOpenGLView, drew a triangle in `drawRect:` method and reshaped as above. So I would guess no, it renderers in the same thread, I certainly didn't create one.

 

Does it mean that when I render from UI threat, it just works? And the problem happens only when there is an extra rendering thread?

 

To put it differently, I thought GLFW uses just one thread so why doesn't it work as well? And if it is using another thread for rendering, isn't it possible to somehow force it to render in the main thread?

Edited by Tuom Larsen

Share this post


Link to post
Share on other sites
swiftcoder    18437

Does it mean that when I render from UI threat, it just works? And the problem happens only when there is an extra rendering thread?

Most of the time, yes. Strictly speaking this occurs whenever you don't immediately render a frame following [NSOpenGLView reshape]. One way for this to occur is off-thread rendering.

To put it differently, I thought GLFW uses just one thread so why doesn't it work as well?

GLFW doesn't manage window resize from the [NSOpenGLView reshape] callback. Due to intricacies in the way they manage the window, they resize from [NSWindow windowDidResize:] instead, and it looks like that call doesn't arrive in the right order with respect to the NSOpenGLView deciding to redraw.
 
It's certainly solvable, but will require some non-trivial changes to GLFW's Cocoa implementation - you might consider raising the issue on the glfw-dev mailing list.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this