How to integrate VTK with OpenGL?

How to integrate VTK with OpenGL?

I have a regular VTK pipeline that works OK: I use a vtkPolyData, set it as input to a vtkXXXFilter, use a vtkPolyDataMapper, and render it in a vtkRenderWindow (using a vtkRenderer). All is OK: my scene is rendered over a white background! I do not use any OpenGL-related classes so far (or, say, I’am not sure what is used in back-end to do the rendering).

Now I need to make this VTK pipeline interact with GLFW/OpenGL: I need to retrieve a GLFWwindow consistent with OpenGL.

Replacing vtkRenderWindow with vtkOpenGLRenderWindow doesn’t compile: my understanding is that this class is not meant to be used directly. Question 1: is this correct?

Replacing vtkRenderWindow with vtkGenericOpenGLRenderWindow compiles but crashes:

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7c1dae9 in vtkOpenGLState::vtkglBlendFuncSeparate (this=0x5555555ac2e0, val1=770, val2=771, val3=1, val4=771)
    at /home/fhoussen/Downloads/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLState.cxx:873
#2  0x00007ffff7be901a in vtkOpenGLRenderWindow::Start (this=0x5555555abad0) at /home/fhoussen/Downloads/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLRenderWindow.cxx:1291
#3  0x00007ffff75ecfa1 in vtkXRenderWindowInteractor::Initialize (this=0x5555555add90) at /home/fhoussen/Downloads/VTK-9.2.6/Rendering/UI/vtkXRenderWindowInteractor.cxx:347
#1  0x00007ffff7c1dae9 in vtkOpenGLState::vtkglBlendFuncSeparate (this=0x5555555ac2e0, val1=770, val2=771, val3=1, val4=771)
    at /home/fhoussen/Downloads/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLState.cxx:873
873	    ::glBlendFuncSeparate(val1, val2, val3, val4);
(gdb) l
868	  {
869	    cs.BlendFunc[0] = val1;
870	    cs.BlendFunc[1] = val2;
871	    cs.BlendFunc[2] = val3;
872	    cs.BlendFunc[3] = val4;
873	    ::glBlendFuncSeparate(val1, val2, val3, val4);
874	  }
875	  vtkCheckOpenGLErrorsWithStack("glBlendFuncSeparate");
876	}

Question 2: how to fix/avoid this? Seems the crash occurs in ::glBlendFuncSeparate

So I tried to replace vtkRenderWindow with vtkXOpenGLRenderWindow (running on unix - I guess vtkWin32OpenGLRenderWindow is meant to be used on windows): the code compiles and run with no crash. Question 3: is there a class vtkXXXRenderWindow that can be used on both unix/windows/macOS? (I hoped this could be vtkGenericOpenGLRenderWindow)

With vtkXOpenGLRenderWindow, the code compiles but I get a black screen with no data rendered. Question 4: what is missing to get the same scene as I had initially but with OpenGL?

Hi @fghoussen

You need to use the vtkExternalOpenGLRenderWindow

OK, does vtkExternalOpenGLRenderWindow works on unix/window/macOS?

@mwestphal I have a compilation error: fatal error: vtkExternalOpenGLRenderWindow.h: No such file or directory

Is it necesseray to build VTK from source? If yes, are there options to set at configure time?

Using vtkExternalOpenGLRenderWindow, I get a crash. @mwestphal: any clue?

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7b2c289 in vtkOpenGLFramebufferObject::CreateFBO (this=0x5555555b9080) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLFramebufferObject.cxx:354
#2  0x00007ffff7b2e81a in vtkOpenGLFramebufferObject::Bind (this=0x5555555b9080, mode=36160) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLFramebufferObject.cxx:740
#3  0x00007ffff7b2e619 in vtkOpenGLFramebufferObject::Bind (this=0x5555555b9080) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLFramebufferObject.cxx:729
#4  0x00007ffff7b33559 in vtkOpenGLFramebufferObject::PopulateFramebuffer (this=0x5555555b9080, width=300, height=32767, useTextures=true, numberOfColorAttachments=1, colorDataType=3, 
    wantDepthAttachment=true, depthBitplanes=32, multisamples=0, wantStencilAttachment=false) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLFramebufferObject.cxx:1502
#5  0x00007ffff7bebe3b in vtkOpenGLRenderWindow::CreateFramebuffers (this=0x5555555b7be0, width=300, height=32767)
    at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLRenderWindow.cxx:2105
#6  0x00007ffff7f209bc in vtkExternalOpenGLRenderWindow::Start (this=0x5555555b7be0) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/External/vtkExternalOpenGLRenderWindow.cxx:57
#7  0x00007ffff7e2cfa1 in vtkXRenderWindowInteractor::Initialize (this=0x5555555ba520) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/UI/vtkXRenderWindowInteractor.cxx:347
#8  0x0000555555557b9e in createScene(unsigned int const&, bool const&) ()


(gdb) up
#1  0x00007ffff7b2c289 in vtkOpenGLFramebufferObject::CreateFBO (this=0x5555555b9080) at /home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/OpenGL2/vtkOpenGLFramebufferObject.cxx:354
354	    glGenFramebuffers(1, &temp);

(gdb) l
349	  if (!this->FBOIndex)
350	  {
351	    this->ResourceCallback->RegisterGraphicsResources(this->Context);
352	    this->FBOIndex = 0;
353	    GLuint temp;
354	    glGenFramebuffers(1, &temp);
355	    vtkOpenGLCheckErrorMacro("failed at glGenFramebuffers");
356	    this->FBOIndex = temp;
357	  }
358	}

You need to build VTK with vtkRenderingExternal. I know there is a GLUT example in the VTK source tree.

1 Like

@Jens_Munk_Hansen: I did! :slight_smile:

Here is the cmake command I used to build VTK from source cmake -DVTK_GROUP_ENABLE_Rendering=YES -DVTK_MODULE_ENABLE_VTK_RenderingExternal=YES ..: is there something missing here?

Also I use find_package(VTK COMPONENT RenderingCore RenderingExternal) to compile/link my code base to VTK.

Do you remember where is the GLUT example? Didn’t find it, will re-check…

Do you remember where is the GLUT example? Didn’t find it, will re-check…

Rendering/External/Testing/Cxx/TestGLUTRenderWindow.cxx

I took inspiration from the VTK GLUT example. Basically, I managed to add:

  // Initialize GLFW.
  glfwInit();
  GLFWwindow * window = glfwCreateWindow(800, 600, "window", NULL, NULL);
  if (!window) {
    std::cerr << "Error: can't create OpenGL window" << std::endl;
    return 1;
  }
  glfwMakeContextCurrent(window);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

And

 // Terminate GLFW.
 glfwTerminate();

Before and after the creation of the VTK pipeline

Unfortunately, I still get the same crash in glGenFramebuffers under vtkOpenGLFramebufferObject::CreateFBO?!.. @Jens_Munk_Hansen: any clue?

Try the GLUT as is. Did you very OpenGL using another application?

I created a GLFWwindow window.
I suspect I need to “set” this window into vtkExternalOpenGLRenderWindow: correct? How to do that?

when I Render() on my vtkExternalOpenGLRenderWindow instance, I get:

X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  3 (X_GetWindowAttributes)
  Resource id in failed request:  0x0
  Serial number of failed request:  8
  Current serial number in output stream:  9

When I comment the Render() call line, I get a black empty window (the GLFW one).

Seems the GLUT example doesn’t link… Can’t figure out why…

[ 83%] Linking CXX executable ../../../../bin/vtkRenderingExternalCxxTests
/usr/bin/ld: CMakeFiles/vtkRenderingExternalCxxTests.dir/TestGLUTRenderWindow.cxx.o: in function `(anonymous namespace)::MakeCurrentCallback(vtkObject*, unsigned long, void*, void*)':
/home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/External/Testing/Cxx/TestGLUTRenderWindow.cxx:75: undefined reference to `glutSetWindow'
/usr/bin/ld: CMakeFiles/vtkRenderingExternalCxxTests.dir/TestGLUTRenderWindow.cxx.o: in function `(anonymous namespace)::display()':
/home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/External/Testing/Cxx/TestGLUTRenderWindow.cxx:144: undefined reference to `glutSwapBuffers'
/usr/bin/ld: CMakeFiles/vtkRenderingExternalCxxTests.dir/TestGLUTRenderWindow.cxx.o: in function `(anonymous namespace)::handleResize(int, int)':
/home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/External/Testing/Cxx/TestGLUTRenderWindow.cxx:178: undefined reference to `glutPostRedisplay'
/usr/bin/ld: CMakeFiles/vtkRenderingExternalCxxTests.dir/TestGLUTRenderWindow.cxx.o: in function `TestGLUTRenderWindow(int, char**)':
/home/fhoussen/Downloads/VTK/VTK-9.2.6/Rendering/External/Testing/Cxx/TestGLUTRenderWindow.cxx:193: undefined reference to `glutInit'

Did you supply a valid installation path for glut when building VTK? The example still works for me.

No?!.. Isn’t CMake supposed to find GLUT (and friends) paths when expected options are ON?

What are the options you pass to cmake?

I would guess so. I usually use ccmake and search for options relevant. Sometimes I experience that it finds e.g a wrong python. It could be that the location for glut is wrong. But yes, if everything is done right things should work.

@fghoussen Chances are the crash is because glGenFrameBuffers is being called without setting
up a valid OpenGL context. When using vtkExternalOpenGLRenderWindow, it is assumed that the application provided OpenGL context is valid. To ensure that this is the case, only call Render in the draw callback of your GLFW app.

I payed attention to initialize the context before anything else! Replacing vtkExternalOpenGLRenderWindow with vtkRenderWindow doesn’t trigger the crash but I get black screen with nothing rendered in it

@fghoussen You should be using the vtkExternalOpenGLRenderWindow for sure. That is the render window sub-class that makes sure that VTK doesn’t create its own OpenGL context but hitches a ride in an externally created one. If you can, share your code that crashes - that would help get a better understanding of what’s going wrong.