VTK-9.5.0: what is the correct way to use vtkGenericOpenGLRenderWindow with glad?

VTK-9.5.0: what is the correct way to use vtkGenericOpenGLRenderWindow with glad?

I have a application that build from source VTK for an application using vtkGenericOpenGLRenderWindow.

Before VTK-9.5.0: glew was used. The application needed to use the same glew than VTK used.

From VTK-9.5.0: glew seems to have been replaced by glad. Seems there is no vtk_glad.h, nor VTK_MODULE_ENABLE_VTK_glew. Also seems VTK uses glad1 but not glad2 (which is the default AFAIU - the glad repo generates glad2 by default => no way to compile with VTK for now). Also seems VTK uses glad1: is this correct (OpenGL pointers are different from glad1)?

For illustration:

I try to compile:

+bool initGladFromVTK() {
+  // Trigger fake VTK render: make sure the OpenGL context has been created.
+  vtkNew<vtkGenericOpenGLRenderWindow> window;
+  window->Render(); // Ensure the OpenGL context exists.
+  vtkOpenGLRenderWindow* glWin = vtkOpenGLRenderWindow::SafeDownCast(window);
+  if (!glWin) {
+    std::cerr << "Error: window is not an OpenGL render window" << std::endl;
+    return false;
+  }
+
+  // Initialize GLAD using VTK's OpenGL context.
+  if (!gladLoadGL((GLADloadproc) (glWin->GetProcAddress()))) {
+    std::cerr << "Error: failed to initialize GLAD using VTK's context" << std::endl;
+    return false;
+  }
+
+  return true;
+}

And get:

error: ‘GLADloadfunc’ was not declared in this scope; did you mean ‘GLADloadproc’?
  103 |   if (!gladLoadGL((GLADloadfunc) (glWin->GetProcAddress))) {
      |                    ^~~~~~~~~~~~
      |                    GLADloadproc

glad1 (which seems to be used by VTK now?) needs GLADloadfunc but the glad repo generated glad2 (with GLADloadproc).

Is there a doc on how to use vtkGenericOpenGLRenderWindow From VTK-9.5.0? This https://vtk.org/doc/nightly/html/c2_vtk_e_0.html#c2_vtk_e_vtkGenericOpenGLRenderWindow doesn’t help: these example are built from inside the VTK tree AFAIU. I am outside of it.

It seems VTK already defines an internal glad target (CMake doesn’t allow to define the same target twice) so external application can not define there own glad target (needed to gather glfw + the app using vtkGenericOpenGLRenderWindow): is it possible to rename this internal target as vtk_glad1 to allow external app to use an easy/natural glad target and pinpoint VTK uses glad1 but not glad2?

This seems to confirm that VTK uses glad1. Why using glad1? Why not glad2 (using GLADloadproc)?
> git grep gladLoadGL
ThirdParty/glad/vtkglad/src/gl.c:int gladLoadGL( GLADloadfunc load) {

My understanding is that vtk_glad is not exposed: is this correct? Any reason for this?

To ask the question differently, before 9.5.0 I was doing #include “vtk_glew.h” and I called glewInit() defined from inside the header: from 9.5.0, what am I supposed to do to get the same behavior?

I’ve never used glad with vtkGenericOpenGLWindow, but I’m almost certain that VTK’s glad is exported and is glad 2. I’m guessing that the main issue is that cmake isn’t linking to VTK::glad during your build.

The vtk_glad.h header exists, but it’s a generated header, so it’s in the build tree rather than the source tree. As long as your CMakeLists.txt has target_link_libraries(... VTK::glad), then your build should be able to find it while compiling your source files.

OK, indeed, I found vtk_glad.h in the build tree. These ir no gladInit() function: how to load GL (like the following try to do)?

// Trigger fake VTK render: make sure the OpenGL context has been created.
vtkNew window;
window->Render(); // Ensure the OpenGL context exists.
vtkOpenGLRenderWindow* glWin = vtkOpenGLRenderWindow::SafeDownCast(window);
if (!glWin) {
  std::cerr << “Error: window is not an OpenGL render window” << std::endl;
  return false;
}

// Initialize GLAD using VTK’s OpenGL context.
if (!gladLoadGL((GLADloadproc) (glWin->GetProcAddress()))) {
  std::cerr << “Error: failed to initialize GLAD using VTK’s context” << std::endl;
  return false;
}

how to get gladLoadGL()? How to get the argument (GL context) to pass to gladLoadGL()?

Note: my understanding is that VKT uses glad1

>> git grep gladLoadGL
ThirdParty/glad/vtkglad/include/glad/gl.h:GLAD_API_CALL int gladLoadGL( GLADloadfunc load);

glad2 defines GLADloadproc not GLADloadfunc.
Why not using the upstream glad2? Is this planned? If yes, when?

Are you sure? I see GLADloadfunc in the upstream glad2 branch. For example,
in github.com/Dav1dde/glad/blob/glad2/glad/generator/c/templates/gl.h:

GLAD_API_CALL int gladLoad{{ api|api }}{{ 'Context' if options.mx }}({{ template_utils.context_arg(',') }} GLADloadfunc load);

OK VTK::glad can indeed be used from outside of the VTK build tree (I didn’t expect that). I load OpenGL using gladLoaderLoadGL from vtk_glad.h after glfw init (like usual with regular glad).

Now the application starts and seems to run fine, but, it crashes at the end (GUI close)… The patch has only glad-related stuffs. Calling gladLoaderUnloadGL() at the end crashes too: crash append in destructors of vtk objects (like vtkCameraOrientationWidget) called at the end of the main scope?!.. I get a stack like

#1  0x00007ffff7579297 in vtkOpenGLBufferObject::~vtkOpenGLBufferObject
...
#21 0x00007ffff4a77c6e in vtkObjectBase::Delete
#22 0x0000555555587950 in vtkNew<vtkCameraOrientationWidget>::Reset
#23 0x0000555555585d08 in vtkNew<vtkCameraOrientationWidget>::~vtkNew
#26 0x00005555555811b5 in main ()

Is this a known problem? How to fix this?

Are you sure? I see GLADloadfunc in the upstream glad2 branch.

Mostly yes. GLAD 1 = GLADloadfunc and GLAD 2 = GLADloadproc such that VTK seems to use glad2 (see git-grep above) + the glad repo / file ships only one version of glad (glad2 for v2.x and master, or, glad1 for previous tagged commit v1.x or v0.x)

OK. For this to work, you need:

  • compile / link to VTK::glad
  • include vtk_glad.h
  • call gladLoaderLoadGL at the very beginning (after glfw init)
  • call Finalize on your vtkGenericOpenGLRenderWindow at the end (before glfw terminate)

Would be glad (putting it mildly) there is a VTK module for glad someday (like there was one for glew - would make integration easier)…

@dgobbi : I tried to start a discussion about glad here https://gitlab.kitware.com/vtk/vtk/-/issues/19838

@fghoussen
VTK uses glad2. The website link used to generate the glad sources are documented in https://gitlab.kitware.com/vtk/vtk/-/blob/master/ThirdParty/glad/README.md?ref_type=heads. Those links take you to glad2 generator.

FWIW, the VTK_MODULE_ENABLE_VTK_glad variable exists in CMakeCache.txt.

Also, another way to confirm glad2 was used is just check the top of the gl.h header.

https://gitlab.kitware.com/vtk/vtk/-/blob/v9.5.0/ThirdParty/glad/vtkglad/include/glad/gl.h?ref_type=tags#L2

/**
 * Loader generated by glad 2.0.6 on Fri Aug  2 19:25:11 2024
 * ...
 */