Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to update the window while resizing or dragging the window #3016

Open
eXpl0it3r opened this issue May 16, 2024 · 1 comment
Open

Unable to update the window while resizing or dragging the window #3016

eXpl0it3r opened this issue May 16, 2024 · 1 comment

Comments

@eXpl0it3r
Copy link
Member

eXpl0it3r commented May 16, 2024

Describe your issue here

On Windows, while a window is being resized or dragged, it's currently not possible to refresh the window's content and thus you may get odd smearing effects or black rectangles.

The root cause is the way events are processed on Windows, which never gives control back to the main loop. More specifically, DispatchMessageW doesn't return until the resize is finished.

It's important to note, that if you application gets out of sync or disconnects, while resizing the window, it's really considered an issue in your code. Blocked CPU time can happen in other cases as well, which should be properly handled in your application.

I currently see four possibilities:

  • Callback
  • Threading
  • Parent-Child Window
  • WM_SYSCOMMAND + Custom Resize Handler

Also check the solution design for a more in-depth discussion: https://github.com/SFML/SFML/wiki/SD:-Render-while-Resizing

SDL has addressed this issue not to long ago in libsdl-org/SDL#1059 for SDL 2 (libsdl-org/SDL@509c70c) and SDL 3 (libsdl-org/SDL@02f3564). The linked issue also shows a few alternative approaches and discusses why some are better than others. Maybe it can serve as an inspiration for a solution within SFML.

Allegro seems to choose the approach of using a separate thread to handle the resize events. I haven't fully understood when this thread is launched and how it gives control back to the main event loop.

This issue is related to #1601, #1604, #1397, and many more discussion on the forum and Discord

Your Environment

  • OS / distro / window manager: Windows
  • SFML version: 2.x / 3.x

Steps to reproduce

  1. Display something dynamic on the window
  2. Resize the window

Expected behavior

The dynamic rendering continues rendering and slowly adjusts in size as the window get larger or smaller

Actual behavior

The rendering stops completely, as well as the application update handling.

@MarioLiebisch
Copy link
Member

So finally had some time the other day to look into this and this kind of clashes a bit with SFML's classic approach of handling the main loop.

Overall, the implementation is rather trivial, but it essentially requires a callback that can be called. Ignoring events for now, getting this done with the Window example could look a bit like this:

const auto draw = [&]() {
    // Clear the color and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Apply some transformations to rotate the cube
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.f, 0.f, -200.f);
    glRotatef(clock.getElapsedTime().asSeconds() * 50, 1.f, 0.f, 0.f);
    glRotatef(clock.getElapsedTime().asSeconds() * 30, 0.f, 1.f, 0.f);
    glRotatef(clock.getElapsedTime().asSeconds() * 90, 0.f, 0.f, 1.f);

    // Draw the cube
    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Finally, display the rendered frame on screen
    window.display();
};

window.setUnblockedDrawing(draw);    

// Start the game loop
while (window.isOpen)
{
    // Process events
    ...
    
    draw();
}
2024-06-07.12-06-43_edit.mp4

However, maybe it might be a better idea to do a different approach and call DispatchMessage() in a second thread? Not sure that's allowed or possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants