Skip to content

[BUG] OpenGL App With Multiple Windows Doesn't Close Itself Cleanly #490

@christophercrouzet

Description

@christophercrouzet

Bug Description

Repro on Windows:

import matplotlib
import matplotlib.animation
import matplotlib.pyplot
import numpy as np
import pyglet
import warp as wp
import warp.render


BOX_POINTS = np.array(
    (
        ( 0.853553, -0.146446,  0.0     ), ( 0.146446, -0.853553,  0.0     ),
        ( 0.353553,  0.353553,  0.707106), (-0.353553, -0.353553,  0.707106),
        (-0.353553, -0.353553, -0.707106), ( 0.353553,  0.353553, -0.707106),
        (-0.853553,  0.146446,  0.0     ), (-0.146446,  0.853553,  0.0     ),
    ),
    dtype=np.float32,
)

BOX_FACE_VERTEX_INDICES = np.array(
    (
        0, 3, 1, 0, 2, 3, 4, 7, 5, 4, 6, 7, 6, 2, 7, 6, 3, 2,
        5, 1, 4, 5, 0, 1, 5, 2, 0, 5, 7, 2, 1, 6, 4, 1, 3, 6,
    ),
    dtype=np.int32,
)

SPHERE_POINTS = (
    ( 0.0     ,  0.0     , -0.5     ), ( 0.0     ,  0.28656 , -0.425325),
    ( 0.249999,  0.081230, -0.425325), ( 0.0     ,  0.447213, -0.223606),
    ( 0.249999,  0.344095, -0.262865), ( 0.425325,  0.138196, -0.223606),
    ( 0.154508, -0.212662, -0.425325), ( 0.404508, -0.131432, -0.262865),
    ( 0.262865, -0.361803, -0.223606), (-0.154508, -0.212662, -0.425325),
    ( 0.0     , -0.425325, -0.262865), (-0.262865, -0.361803, -0.223606),
    (-0.249999,  0.081230, -0.425325), (-0.404508, -0.131432, -0.262865),
    (-0.425325,  0.138196, -0.223606), (-0.249999,  0.344095, -0.262865),
    (-0.154508,  0.475528,  0.0     ), (-0.404508,  0.293892,  0.0     ),
    (-0.262865,  0.361803,  0.223606), (-0.5     ,  0.0     ,  0.0     ),
    (-0.404508, -0.293892,  0.0     ), (-0.425325, -0.138196,  0.223606),
    (-0.154508, -0.475528,  0.0     ), ( 0.154508, -0.475528,  0.0     ),
    ( 0.0     , -0.447213,  0.223606), ( 0.404508, -0.293892,  0.0     ),
    ( 0.5     ,  0.0     ,  0.0     ), ( 0.425325, -0.138196,  0.223606),
    ( 0.404508,  0.293892,  0.0     ), ( 0.154508,  0.475528,  0.0     ),
    ( 0.262865,  0.361803,  0.223606), ( 0.0     ,  0.425325,  0.262865),
    (-0.404508,  0.131432,  0.262865), (-0.249999, -0.344095,  0.262865),
    ( 0.249999, -0.344095,  0.262865), ( 0.404508,  0.131432,  0.262865),
    ( 0.0     ,  0.0     ,  0.5     ), ( 0.154508,  0.212662,  0.425325),
    (-0.154508,  0.212662,  0.425325), ( 0.249999, -0.081230,  0.425325),
    ( 0.0     , -0.262865,  0.425325), (-0.249999, -0.081230,  0.425325),
)

SPHERE_FACE_VERTEX_INDICES = (
     2,  0,  1,  4,  1,  3,  5,  2,  4,  2,  1,  4,  6,  0,  2,  7,
     2,  5,  8,  6,  7,  6,  2,  7,  9,  0,  6, 10,  6,  8, 11,  9,
    10,  9,  6, 10, 12,  0,  9, 13,  9, 11, 14, 12, 13, 12,  9, 13,
     1,  0, 12, 15, 12, 14,  3,  1, 15,  1, 12, 15, 16,  3, 15, 17,
    15, 14, 18, 16, 17, 16, 15, 17, 19, 14, 13, 20, 13, 11, 21, 19,
    20, 19, 13, 20, 22, 11, 10, 23, 10,  8, 24, 22, 23, 22, 10, 23,
    25,  8,  7, 26,  7,  5, 27, 25, 26, 25,  7, 26, 28,  5,  4, 29,
     4,  3, 30, 28, 29, 28,  4, 29, 29,  3, 16, 31, 16, 18, 30, 29,
    31, 29, 16, 31, 17, 14, 19, 32, 19, 21, 18, 17, 32, 17, 19, 32,
    20, 11, 22, 33, 22, 24, 21, 20, 33, 20, 22, 33, 23,  8, 25, 34,
    25, 27, 24, 23, 34, 23, 25, 34, 26,  5, 28, 35, 28, 30, 27, 26,
    35, 26, 28, 35, 38, 36, 37, 31, 37, 30, 18, 38, 31, 38, 37, 31,
    37, 36, 39, 35, 39, 27, 30, 37, 35, 37, 39, 35, 39, 36, 40, 34,
    40, 24, 27, 39, 34, 39, 40, 34, 40, 36, 41, 33, 41, 21, 24, 40,
    33, 40, 41, 33, 41, 36, 38, 32, 38, 18, 21, 41, 32, 41, 38, 32,
)


resolution = (512, 384)
num_frames = 48
fps = 24
camera_pos = (0.0, 2.5, 5.0)
camera_front = (0.0, -0.5, -1.0)

image = wp.empty(shape=(resolution[1], resolution[0], 3), dtype=wp.float32)

geoms = (
    (BOX_POINTS, BOX_FACE_VERTEX_INDICES),
    (SPHERE_POINTS, SPHERE_FACE_VERTEX_INDICES),
)
renderers = (
    warp.render.OpenGLRenderer(
        fps=fps,
        screen_width=resolution[0],
        screen_height=resolution[1],
        camera_pos=camera_pos,
        camera_front=camera_front,
        vsync=True,
    ),
    warp.render.OpenGLRenderer(
        fps=fps,
        screen_width=resolution[0],
        screen_height=resolution[1],
        camera_pos=camera_pos,
        camera_front=camera_front,
        vsync=True,
    ),
)
renders = ([], [])

rng = np.random.default_rng(123)
for frame in range(num_frames):
    color = wp.sin(float(frame) * 0.05) * 0.5 + 0.5

    for i in range(2):
        renderers[i].begin_frame(frame / num_frames)
        renderers[i].render_mesh(
            "box",
            geoms[i][0],
            geoms[i][1],
            colors=(color, 0.5, 0.5),
        )
        renderers[i].end_frame()
        renderers[i].get_pixels(image, split_up_tiles=False, mode="rgb")
        renders[i].append(wp.clone(image, device="cpu", pinned=True))


for i in range(2):
    plot_fig = matplotlib.pyplot.figure(figsize=resolution, dpi=1.0)
    plot_fig.subplots_adjust(left=0, bottom=0, right=1, top=1)

    plot_img = matplotlib.pyplot.imshow(renders[i][0], animated=True)
    plot_img.axes.set_axis_off()

    plot_anim = matplotlib.animation.FuncAnimation(
        plot_fig,
        lambda frame: plot_img.set_data(renders[i][frame]),
        frames=num_frames,
        interval=(1.0 / 24.0) * 1000.0,
    )

    # matplotlib.pyplot.close()
    plot_anim.save(f"anim_{i + 1}.gif")

If we proactively close the windows ourselves, then everything is fine. However, if wait a few seconds for the windows to close themselves after the 48 frames are computed, then the following exceptions occur:

Exception ignored on calling ctypes callback function: <function Win32Window._get_window_proc.<locals>.f at 0x000001657FD0CE50>
Traceback (most recent call last):
  File ".venv\lib\site-packages\pyglet\window\win32\__init__.py", line 839, in f
  File ".venv\lib\site-packages\pyglet\window\win32\__init__.py", line 1277, in _event_killfocus
  File ".venv\lib\site-packages\pyglet\window\__init__.py", line 671, in dispatch_event
  File ".venv\lib\site-packages\pyglet\event.py", line 358, in dispatch_event
AssertionError:
Exception ignored in: <function ShapeInstancer.__del__ at 0x000001655D705FC0>
Traceback (most recent call last):
  File "warp\render\render_opengl.py", line 710, in __del__
  File ".venv\lib\site-packages\pyglet\gl\lib_wgl.py", line 56, in __call__
ImportError: sys.meta_path is None, Python is likely shutting down
Exception ignored on calling ctypes callback function: <function Win32Window._get_window_proc.<locals>.f at 0x000001655D7AED40>
Traceback (most recent call last):
  File ".venv\lib\site-packages\pyglet\window\win32\__init__.py", line 839, in f
  File ".venv\lib\site-packages\pyglet\window\win32\__init__.py", line 1277, in _event_killfocus
  File ".venv\lib\site-packages\pyglet\window\__init__.py", line 671, in dispatch_event
  File ".venv\lib\site-packages\pyglet\event.py", line 358, in dispatch_event
AssertionError:
Exception ignored in: <function ShapeInstancer.__del__ at 0x000001655D705FC0>
Traceback (most recent call last):
  File "warp\render\render_opengl.py", line 710, in __del__
  File ".venv\lib\site-packages\pyglet\gl\lib_wgl.py", line 56, in __call__
ImportError: sys.meta_path is None, Python is likely shutting down

System Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions