fury icon indicating copy to clipboard operation
fury copied to clipboard

Fine-tuning of the OpenGL state

Open devmessias opened this issue 4 years ago • 2 comments

VTK it’s powerful, but sometimes we need to get more control about how OpenGL will render the actors. For example, enforcing deep-test to keep disabled during a draw call of a specific actor. This can be useful when we need to increasse the performance or create specific visualization effects in order to understand a certain data, like to enhance the visualization of clusters in a network. Because I need to have this kind of control to draw my networks I send some messages to @filipinascimento asking him if there is a way to perform that with FURY.

Unfortunately, It seem's that VTK doesn't expose the opengl context. @filipinascimento and I dived in the Vtk documentation and we found some ways to achieve the opengl state control.

VTK wraps a lot of opengl context methods through the GetState from a vtkXOpenGLRenderWindow objectclassvtkOpenGLState Therefore, we can control the opengl state globally using vtkglEnable for each variable. I belive one exception it's depth-test state. It looks like VTK always enable depth-test before the draw calls, Rendering/OpenGL2/vtkOpenGLRenderer.cxx#L743

One approach to achieve the control of the opengl state, including depth-test. Essentially, it's to use shader callbacks and render callbacks to enforce a specific opengl state in VTK. I couldn't find any performance issue related to this approach.

Here is my branch with the gl_set functions https://github.com/devmessias/fury/blob/b4ec148e049dac09bcc8392aa2528c453d2a0fcb/fury/window.py#L1170-L1211

with the following example https://github.com/devmessias/fury/blob/opengl_context_state/docs/examples/viz_fine_tuning_gl_context.py

The behavior it's very simple and doesn't change any other functions inside FURY

#fury/window.py
def gl_disable_depth(window):
    '''This it will disable any gl behavior which has no
    function for opaque objects. This has the benefit of
    speeding up the rendering of the image.

    See more
    --------
    [1] https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glFrontFace.xhtml
    '''
    glState = window.GetState()
    glState.ResetGLBlendEquationState()
    glState.ResetGLBlendFuncState()

    glState.vtkglDisable(_GL['GL_BLEND'])
    glState.vtkglDisable(_GL['GL_DEPTH_TEST'])
# how to use 
def callback(
       _caller, _event, calldata=None,
       gl_set_func=None, window_obj=None):
   program = calldata
   if program is not None:
       gl_set_func(window_obj)
id_observer_normal = add_shader_callback(
       actors, partial(
           callback, gl_set_func=window.gl_disable_depth,
           window_obj=showm.window))

Using this, we can control the state for each actor image It's also possible to get some effects using cheap additive blending effects

image

I don't know if there is a better way to achieve this;

If the FURY team agrees I can send a pull-request (at least for the example) or add extra effects using that.

Thanks!

devmessias avatar Apr 30 '21 02:04 devmessias

Yes, please make a PR @devmessias. But also experiment with actors that are not using billboards. Try with some of our standard geometry based actors.

Garyfallidis avatar Apr 30 '21 20:04 Garyfallidis

That's great! Yes please, make a PR.

skoudoro avatar May 01 '21 23:05 skoudoro