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

glfwTerminate() called in the Visualizer destructor #4960

Closed
3 tasks done
bchretien opened this issue Mar 31, 2022 · 4 comments · Fixed by #6559
Closed
3 tasks done

glfwTerminate() called in the Visualizer destructor #4960

bchretien opened this issue Mar 31, 2022 · 4 comments · Fixed by #6559
Labels
bug Not a build issue, this is likely a bug.

Comments

@bchretien
Copy link
Contributor

bchretien commented Mar 31, 2022

Checklist

Describe the issue

While testing headless rendering, I got rendering issues with a lot of warnings like this one:

[Open3D WARNING] GLFW Error: The GLFW library is not initialized

This has been brought up in some other issues (e.g. #599, #2006, #3489), but apparently the root cause has not been addressed. After looking at the code, I've seen that glfwTerminate() is called in a singleton handling initialization/deinitialization of GLFW (as expected), but also in Visualizer's destructor (see here), which I don't understand. The official documentation of that function is clear:

This function destroys all remaining windows and cursors, restores any modified gamma ramps and frees any other allocated resources. Once this function is called, you must again call glfwInit successfully before you will be able to use most GLFW functions.
If GLFW has been successfully initialized, this function should be called before the application exits. If initialization fails, there is no need to call this function, as it is called by glfwInit before it returns failure.

So why is that terminate call needed here?

Steps to reproduce the bug

# Example taken and adapted from #2006

import open3d as o3d
import time

o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug)
sample_data = o3d.data.DemoCustomVisualization()

for i in range(3):
    # Read Pointcloud
    pcd = o3d.io.read_point_cloud(sample_data.point_cloud_path)

    # Visualize Point Cloud
    vis = o3d.visualization.Visualizer()
    vis.create_window(width=960, height=540, visible=True)
    vis.add_geometry(pcd)

    # View Control
    ctr = vis.get_view_control()
    ctr.set_front([0,1,0])
    ctr.set_up([0,0,1])
    ctr.set_zoom(1.5)

    # Updates
    vis.update_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()

    # Capture image
    time.sleep(1)
    vis.capture_screen_image("{}.png".format(i))

    # Close
    vis.destroy_window()

Error message

[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] Global colormap init.
[Open3D DEBUG] [Visualizer] Screen capture to 0.png
[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D DEBUG] [Visualizer] Screen capture to 1.png
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D WARNING] GLFW Error: The GLFW library is not initialized
[Open3D DEBUG] [Visualizer] Screen capture to 2.png
[Open3D WARNING] GLFW Error: The GLFW library is not initialized

Expected behavior

We should be able to create and destroy Visualizer without breaking GLFW.

Open3D, Python and System information

- Operating system: Debian 10
- Python version: Python 3.9.12
- Open3D version: 0.15.2+7938858c
- System architecture: x86-64
- Is this a remote workstation?: yes
- How did you install Open3D?: build from source
- Compiler version (if built from source): gcc 8.3.0

Additional information

No response

@bchretien bchretien added the bug Not a build issue, this is likely a bug. label Mar 31, 2022
@bchretien
Copy link
Contributor Author

bchretien commented Mar 31, 2022

I just made a test where I remove that glfwTerminate() call, and everything works as expected:

[Open3D INFO] Downloading https://github.com/isl-org/open3d_downloads/releases/download/20220301-data/DemoCustomVisualization.zip
[Open3D INFO] Downloaded to /root/open3d_data/download/DemoCustomVisualization/DemoCustomVisualization.zip
[Open3D INFO] Extracting /root/open3d_data/download/DemoCustomVisualization/DemoCustomVisualization.zip.
[Open3D DEBUG]  Extracting: camera_trajectory.json
[Open3D DEBUG]  Extracting: fragment.ply
[Open3D DEBUG]  Extracting: renderoption.json
[Open3D INFO] Extracted to /root/open3d_data/extract/DemoCustomVisualization.
[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] Global colormap init.
[Open3D DEBUG] [Visualizer] Screen capture to 0.png
[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] [Visualizer] Screen capture to 1.png
[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] [Visualizer] Screen capture to 2.png

I'll open a PR as soon as my other one is merged.

@bchretien bchretien changed the title glfwTerminate() called on every Visualizer destructor glfwTerminate() called in the Visualizer destructor Apr 1, 2022
@bchretien
Copy link
Contributor Author

bchretien commented Apr 1, 2022

⚠️ With the removal, the warning is gone but the 2nd and 3rd rendered images are blank, so there is still something going on. I'll investigate as soon as I have some time.

bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
bchretien added a commit to Outflier/Open3D that referenced this issue Apr 1, 2022
@bchretien
Copy link
Contributor Author

bchretien commented Apr 1, 2022

⚠️ I improved the GLTF context handling, but I still need to delete the Visualizer and the associated ViewControl at the end of each iteration if I create the visualizer in the loop, as suggested in comments of the linked issues. So the #4963 PR improves the situation, but there is one more fix needed to have something more flexible (I don't have the time to work on this though).

With my PR and this code, everything is fine:

import time

import numpy as np
import open3d as o3d

o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug)
sample_data = o3d.data.DemoCustomVisualization()

# Read Pointcloud
pcd = o3d.io.read_point_cloud(sample_data.point_cloud_path)

for i in range(3):
    # Create Visualizer
    vis = o3d.visualization.Visualizer()
    vis.create_window(width=960, height=540, visible=True)
    vis.add_geometry(pcd)

    # View Control
    ctr = vis.get_view_control()
    ctr.set_front([0,1,0])
    ctr.set_up([0,0,1])
    ctr.set_zoom(1.5)

    # Updates
    vis.update_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()

    # Capture image
    time.sleep(1)
    image = np.array(vis.capture_screen_float_buffer())
    assert np.amin(image) < np.amax(image)

    # WARNING: this is still needed, unsure why
    del ctr
    del vis

Output:

[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] [Visualizer] Creating window.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] Global colormap init.
[Open3D DEBUG] [Visualizer] Destroying window.
[Open3D DEBUG] GLFW destruct.
[Open3D DEBUG] [Visualizer] Creating window.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] [Visualizer] Destroying window.
[Open3D DEBUG] GLFW destruct.
[Open3D DEBUG] [Visualizer] Creating window.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] [Visualizer] Destroying window.
[Open3D DEBUG] GLFW destruct.

With the visualizer outside the loop, it's fine too:

import time

import numpy as np
import open3d as o3d

o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Debug)
sample_data = o3d.data.DemoCustomVisualization()

# Read Pointcloud
pcd = o3d.io.read_point_cloud(sample_data.point_cloud_path)

# Create Visualizer
vis = o3d.visualization.Visualizer()
vis.create_window(width=960, height=540, visible=True)
vis.add_geometry(pcd)

for i in range(3):
    # View Control
    ctr = vis.get_view_control()
    ctr.set_front([0,1,0])
    ctr.set_up([0,0,1])
    ctr.set_zoom(1.5)

    # Updates
    vis.update_geometry(pcd)
    vis.poll_events()
    vis.update_renderer()

    # Capture image
    time.sleep(1)
    image = np.array(vis.capture_screen_float_buffer())
    assert np.amin(image) < np.amax(image)
    
    del ctr

del vis

Output:

[Open3D DEBUG] Format auto File /root/open3d_data/extract/DemoCustomVisualization/fragment.ply
[Open3D DEBUG] Read geometry::PointCloud: 196133 vertices.
[Open3D DEBUG] [Visualizer] Creating window.
[Open3D DEBUG] GLFW init.
[Open3D DEBUG] Add geometry and update bounding box to [(0.5586, 0.8320, 0.5666) - (3.9661, 2.4275, 2.5586)]
[Open3D DEBUG] Global colormap init.
[Open3D DEBUG] [Visualizer] Destroying window.
[Open3D DEBUG] GLFW destruct.

@shyu216
Copy link

shyu216 commented Oct 9, 2022

thanks for your work, after adding

    # WARNING: this is still needed, unsure why
    del ctr
    del vis

,my loop can work.

ssheorey added a commit that referenced this issue Dec 29, 2023
…(See PR #4963) [Author: @bchretien] (#6559)

* examples: fix headless_rendering.py
* ViewControl.cpp: relax floating-point comparison in ConvertFromPinholeCameraParameters()
* Visualizer: improve GLTF context handling (fix #4960)
---------
Authored-by: Benjamin Chrétien <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not a build issue, this is likely a bug.
Projects
None yet
2 participants