How to get vtkShaderProgram* of an actor?

Hi teams,

I have already know

void TestShaderCallback::Execute(vtkObject *, unsigned long, void *cbo){
    auto cellBO = reinterpret_cast<vtkShaderProgram*>(cbo);
    float diffuseColor[3]{1,0.2,0.6};
    cellBO->SetUniform3f("border_color_outside", diffuseColor);
}

is the right way to change uniform data in vtkshader,
But how can I access it by myself?
Because I can not find the object “cbo” belongs to which part of an actor.

I checked the source code in github for a really long time, but I could not get the result, please help me.

Thank you!

Best regards.

Hello,

vtkShaderProgram has three methods to access its component vtkShader objects: GetVertexShader(), GetFragmentShader() and GetGeometryShader(). https://vtk.org/doc/nightly/html/classvtkShaderProgram.html.

regards,

Paulo

But I do not know how to get vtkShaderProgram object of an actor or a mapper.
How Can I access it?

Do you set custom shaders in the program?

yes, I used vtkOpenGLMapper->SetxxxShadercode(), but where to get the ShaderProgram?

and the ShaderProgram object belongs to which part? the mapper or the actor? or even the renderer?

What class are you using? I can’t find any vtkOpenGLMapper.

Are you using vtkOpenGLPolyDataMapper?

Thank you, and sorry, it names vtkOpenGLPolyDataMapper actually.

it has the function in 9.0 version, and the function is removed in the lastest version, but the question is the same; despite the way of setting shaders is different, I can not find a easy way to get vtkProgram objects.

Well, I’d add bookkeeping code to the program. Whenever you create a vtkActor/vtkMapper alongside a vtkShader in your scene-building code, you could add the two objects to some indexed STL container (using the vtkShader pointers as key). So, when you get a vtkShader via GetVertexShader(), GetFragmentShader() or GetGeometryShader() via vtkShaderProgram in your callback, simply query the index to find the corresponding vtkActor/vtkMapper. I know it’s dirty, but I couldn’t think of a better way to do what you want.

Edit: It’s not Python, it’s C++.

Alternatively, you could subclass the vtkShader you are using and add setter/getter to add a pointer to whatever object you need to recover in the callback. This is a bit cleaner than bookkeeping.

Thank you! I will try both of them

You may also want to look at vtkShaderProperty which is on Actor. It supports all sorts of shader manipulation and is already tied to the actor and honored by the mapper. Note that OpenGLPolyDataMapper uses multiple shader programs when rendering (one for lines, another for surfaces, another for edges, and they can be changed by picking/opacity/etc so they tend to be changing based on user input (if the user has that level of control).

1 Like