Rendering/interaction issues with VTK 8.2 (Java) + JOGL on Windows

Hello Todd,

thank you for your reply.

All interactions with the scene and all painting operations are done in the EDT thread in my application.
Also, I have checked the Thread ID in the native debugger, and the calls to vtkTextureObject::Bind() are always done on the same thread, both in the cases when Bind() succeeds and in the cases when Bind() crashes.

However, I’ve made an interesting discovery. If I switch to a more “basic” orientation marker, then my program does not crash and works normally (although with a too-low update rate) even when I interact with my scene. In particular, I modified my buildOrientationMarkerWidget() method like this:

> ======================
> 
> protected void buildOrientationMarkerWidgetSimpler()
>   {
>     // Orientation marker
>     orientMarkerWidget = new vtkOrientationMarkerWidget();
> 
>     vtkAnnotatedCubeActor orientMarkerCubeProp = new vtkAnnotatedCubeActor();
>     orientMarkerCubeProp.SetXMinusFaceText("R");
>     orientMarkerCubeProp.SetXPlusFaceText("L");
>     orientMarkerCubeProp.SetYMinusFaceText("A");
>     orientMarkerCubeProp.SetYPlusFaceText("P");
>     orientMarkerCubeProp.SetZMinusFaceText("I");
>     orientMarkerCubeProp.SetZPlusFaceText("S");
> 
>     orientMarkerWidget.SetOutlineColor( 0.9300, 0.5700, 0.1300 );
>     orientMarkerWidget.SetOrientationMarker(orientMarkerCubeProp);
>     orientMarkerWidget.SetInteractor(getRenderWindowInteractor());
>     orientMarkerWidget.SetViewport(0, 0.4, 0.2, 0.6);
>     orientMarkerWidget.SetEnabled(1);
>     orientMarkerWidget.InteractiveOff();
>   }
> 
> ======================

So, maybe in my original version there is something wrong with my vtkPropAssembly, which causes issues to JOGL?

Also, the slowness / low update rate issue remains. Basically, it looks like my JOGL view only gets updated when the EDT thread is not busy. For instance, while I drag my scene, the JOGL canvas only gets updated when I move my mouse very slowly. On the other side, if I continue moving/dragging my mouse very quickly without pauses, my JOGL canvas never gets updated.

Do you have suggestions about this?

Thanks in advance for all your feedback.
Best regards,

Marco Sambin

Why did you pass a vtkPropAssembly to the orientation marker widget anyway?

Hello Todd,

using the vtkPropAssembly was a trick to be able to assign different colors to the faces of the orientation marker widget. It was a smart suggestion by a user on this list.

Do you see something wrong in how this vtkPropAssembly is built in the code?

In any case, right now my main concern is the update performance / delays. Digging in the code, I saw that the implementation of the Render() method of vtkJoglCanvasComponent finally calls repaint() on the inner GLCanvas uiComponent. As it seems, calling repaint() while dragging the mouse is actually not calling paint() until the EDT is load-free.

This is quite strange, because according to my experience calling repaint() in a mouse event handler normally results in a quite immediate redraw of the component. But this experience of mine is mostly with lightweight components, not sure if this is different with heavyweight components like GLCanvas. Or, if the lightweight + heavyweight mixture I have on my UI may still influence this behavior.

I’ve made some tests overriding the Render() call of my vtkJoglCanvasComponent-derived panel, and I replaced the call to repaint() with a direct call to paint() of uiComponent (i.e., the GLCanvas). In my tests, this has greatly improved the canvas’ refresh rate while left-dragging my scene (even though we are still far from the performance that I can obtain with vtkCanvas under Windows - is this penalty expected?), but has other side effects. I am not sure this is the right way to go with my vtkJoglCanvasComponent-derived panel…

Any comment will be greatly appreciated.

Thanks and best regards,

Marco Sambin

I think this is a threading issue.

Since you have it working with JAWT your best bet is to understand the difference between how it handles threads versus JOGAMP; particularly when updating the UI.

Hello Todd,

thanks a lot for your feedback, I appreciate.

I thought that doing repaints in the EDT was correct for both JAWT and JOGL, isn’t it?
I only manipulate my scene in the EDT, and also interaction with the scene (left-dragging with the mouse) is done on the EDT. Moreover, this isn’t something upon which I have much control. I simply use a vtkJoglCanvasComponent-derived panel, and I inherit management of mouse-based interaction from it (and my scene’s interactor).

I will try to get a more in-depth knowledge about threading best-practices with JOGL. I still need to find a good source of documentation about it, though.

Thanks and best regards,

Marco Sambin

There may well be a bug in VTK which JOGL exposes, but unless you can pinpoint the reason it isn’t encountered in JAWT I don’t think it will be resolved.

Is this relevant? https://stackoverflow.com/questions/22976815/java-opengl-draw-offscreen-buffer-to-image

Hello.
Today I’ve discovered a very interesting thing while trying to debug the issue of the low repaint/refresh rate on my vtkJoglCanvasComponent-derived panel, especially when interacting with the scene (e.g., left-dragging with my mouse).

In the initialization of my panel, I had the following method (called on the EDT):

> ======================
> public synchronized void initializeView()
>   {
>     if (! viewInited)
>     {
>       final vtkGenericRenderWindowInteractor interactor = getRenderWindowInteractor();
>       interactor.EnableRenderOff();
> 
>       ...
> 
>       // Schedule a delayed repaint of the 3D scene
>       ActionListener taskPerformer = new ActionListener() 
>       {
>         public void actionPerformed(ActionEvent evt) 
>         {
>           interactor.EnableRenderOn();
>           Render();
>         }
>       };
>       javax.swing.Timer repaintTimer = new javax.swing.Timer(250, taskPerformer);
>       repaintTimer.setRepeats(false);
>       repaintTimer.start();
>     }
> ======================

This EnableRenderOff() / EnableRenderOn() sequence was a legacy of the JAWT version of this implementation. With this code, left-dragging with my mouse on the scene results in very slow and choppy repaints of my scene.

On the other side, if I comment both those calls (EnableRenderOff() and later EnableRenderOn()) in my code, and then execute again my application, updates / repaints of my scene are very smooth and quick!

Can you guess why? Is something incorrect in those calls (wrong threads, etc.)? Both calls are done on the EDT as far as I understand.

Another little step forward today… :wink:

Thanks and best regards,

Marco

Since the timer runs only once, I cannot see how it would have an impact on the interactor. Unless you are repeatedly resetting viewInited and calling initializeView().

Hello.
New discovery: I’ve reviewed the source of vtkAbstractJoglComponent (which is the base class for my JOGL-based panel), and here is a fragment of the source code of its constructor:

================

[…]
// Make sure when VTK internally request a Render, the Render get
// properly triggered
renderWindowToUse.AddObserver(“WindowFrameEvent”, this, “Render”);
renderWindowToUse.GetInteractor().AddObserver(“RenderEvent”, this, “Render”);
renderWindowToUse.GetInteractor().SetEnableRender(false);
[…]
================

So, it basically looks like these JOGL-based components are designed to work with interactor.SetEnableRender(false).

So, my sequence of calls EnableRenderOff() / EnableRenderOn() had the final effect of changing the way interactor repainting worked with JOGL components, and probably set it to an undesirable value.

So, at least the issue related to slow repainting upon interaction with the scene with JOGL components seems to have an explanation now, and can be considered as fixed.

Regards,

Marco Sambin

Thanks Marco for your investigation and dedication. I’ll keep that in mind if someone else run into something similar.

Hello Sebastien,

now I will move on to building VTK 8.2 + Java + JOGL on macOS.
To this end, I was following this thread:

However, I miss the conclusion of this thread, i.e., which modification should be done on VTK 8.2 in order to obtain a successful and functioning build with JOGL + Java on Mac.

Have you maybe received some updates from the original poster?
If someone has already spent days in fixing some issues, I would be very happy if I could avoid spending again a lot of time in figuring out what should be modified.

Using VTK v8.2 is a must for me.

Thanks for your feedback and best regards,

Marco Sambin

I don’t have any specific and right now, I don’t have access to the old mac mini that was used to build the binaries. But I’ll do my best to help out.

Thanks,

Seb

Hi all.
I have encountered another issue with my vtkJoglCanvasComponent-derived panel.

Basically, in my application I use a “panel docking framework” which allows user to interactively drag and drop/dock panels to other locations in my window (JFrame).
While my vtkJoglCanvasComponent-derived panel cannot be dragged/redocked on its own, its container panel (also containing other children JPanels, in addition to my vtkJoglCanvasComponent-derived panel) can. While dragging/redocking the parent container panel, a “remove()” and then later “add()” calls are triggered on the container itself.

It looks like my vtkJoglCanvasComponent-derived panel reacts to the remove() calls (on the parent container) by destroying itself (glEventListener.dispose() is invoked). When add() is then invoked on the container, glEventListener.init() is invoked again, but it looks like this is not enough to restore functionality of my vtkJoglCanvasComponent-derived panel. In fact, dragging/redocking completely corrupts the functionality of my vtkJoglCanvasComponent-derived panel, which is unable to paint itself after this dragging/redocking operation.

I have already tried setting a different glEventListener, which doesn’t call Delete() in the dispose() method, but this is not enough to make it work.

Do you have suggestions about how I could fix this issue?

Thanks and best regards,

Marco Sambin

I’m confused by this. Where is viewInited set to true? Where is initializeView() called from? Is it called repeatedly?

You haven’t shown enough code to draw any meaningful conclusions.

Saving and loading the OpenGL state might be the cause of the jerky refresh rate.

void vtkGenericOpenGLRenderWindow::Render()
{
  if (this->ReadyForRendering)
  {
    this->MakeCurrent();
    if (!this->IsCurrent())
    {
      vtkLogF(TRACE, "rendering skipped since `MakeCurrent` was not successful.");
    }
    else
    {
      // Query current GL state and store them
      this->SaveGLState();

      this->Superclass::Render();

      // Restore state to previous known value
      this->RestoreGLState();
    }
  }
}

particularly the release of the current shader

void vtkOpenGLRenderWindow::RestoreGLState()
{
  // Prevent making GL calls unless we have a valid context
  if (this->Initialized)
  {
    // For now just re-store the texture unit
    this->GetState()->vtkglActiveTexture(GL_TEXTURE0 + this->GLStateIntegers["GL_ACTIVE_TEXTURE"]);

    // Unuse active shader program
    this->GetShaderCache()->ReleaseCurrentShader();
  }
}

Hello Todd,

first of all, let me clarify that the slow/jerky refresh rate issue is mainly solved, as explained in my latest posts above.

However, in order to answer your questions, my initializeView() method is called on the EDT while initializing/building my GUI. It is called only once, and the viewInited variable is set to true at the end of the initializeView() method itself, sorry for omitting this portion.
As explained in my posts above, please consider that a single interactor.EnableRenderOn() call (for instance, made during component initialization) is sufficient in order to cause the jerky refresh rate. It looks like JOGL components are not designed to work with interactor’s rendering set to ON.

Now my latest issue is different, and it is related to .remove() / .add() calls on the parent container, which cause the JOGL-based panel to stop working correctly.

I will try to assemble a self-contained test case, and hopefully come back soon.

Thanks for all your feedback and best regards,

Marco Sambin

Hello everybody.
I’ve finally come up with a simple example which shall demonstrate the issue that I am currently experiencing with my vtkJoglCanvasComponent-derived panel and the panel docking framework I am using in my Java application.
The example is based on the JoglConeRendering example, with a slight modification which adds a JButton which shall remove and then re-add the vtkJoglCanvasComponent to its container. The code is attached.

JoglConeRenderingPanelMove.java (7.5 KB)

After I press the JButton, the JOGL-based panel is completely corrupted, it becomes entirely empty (black) and the cone cannot be rendered any longer in the panel. Eventually, the application even crashes.

I am testing with VTK 8.2 + JOGAMP v2.3.2 + Java v1.8.0_151 on Windows 10 (64-bit).

Any suggestion about how to fix the situation when my JOGL panel is removed and then re-added to the container will be greatly appreciated.

Thanks and best regards,

Marco Sambin

Hello everybody.

Has anyone been able to run this test case, and confirm at least if this issue can be reproduced at your side?
I would greatly appreciate.

Thanks and best regards,

Marco Sambin

Hello Marco.
I tested your code. Yes the panel is not showing anything, after pressing the button. It did not crash.
Only difference: I am using Java 8u202.

Best,
Tom

Hello Tom,

thanks a lot for your feedback, really appreciated.

Now that I know that the issue is reproducible, I would really appreciate if someone could provide suggestions about how to fix it.

Thanks in advance.
Best regards,

Marco

Hi everybody,

I am having the same issue when running the test of @Marco
JoglConeRenderingPanelMove.java on Java 14 & VTK-9.1.0

Is there any solution/workaround to this problem?
Thanks in advance,
Regards,
/ Minh