# Inheriting from vtkActor for custom OpenGL rendering

**URL:** https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358
**Category:** Support
**Created:** [May 2, 2023, 10:28pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358 "2023-05-02T22:28:41Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![mohaya](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/m/dbc845/32.png) [@mohaya](https://discourse.vtk.org/u/mohaya)
#### Post date: [May 2, 2023, 10:28pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/1 "2023-05-02T22:28:42Z")

</div>

Hello. I created a `CustomActor` class which inherits from `vtkOpenGLActor` and overrides the common rendering methods. The idea is to use OpenGL calls directly within these methods to render with custom shaders.

I managed to get the code below compiling and running. The issue is: GLEW fails to initialize and throws an error from `vtkOpenGLRenderWindow::OpenGLInit()`. Trying to call any OpenGL functions result in a segmentation fault because of that.

```auto
ERR| vtkXOpenGLRenderWindow (0x5623a0c95ee0): GLEW could not be initialized: Missing GL version

```

Despite the error, the program runs flawlessly and renders the transparent objects (with the logs from the overridden methods), but I’m **unable** to write OpenGL code for rendering. Any advice on this?

I’m on VTK 9.0.3, built from source on Ubuntu 20.04 LTS.

Result is correct:

 ![vtk-custom-actor](https://discourse.vtk.org/uploads/default/original/2X/1/1c318f0dd17bb2f179b9bfca0d3db251ab88211a.png)

`hpp` file:

```cpp
#include <vtkOpenGLActor.h>
#include <vtkObjectFactory.h>

#include <iostream>

class CustomActor : public vtkOpenGLActor
{
public:
  static CustomActor *New();
  vtkTypeMacro(CustomActor, vtkOpenGLActor);
  virtual void PrintSelf(ostream& os, vtkIndent indent);

  // Override standard render methods.
  int RenderOverlay(vtkViewport *viewport);
  int RenderOpaqueGeometry(vtkViewport *viewport);
  int HasTranslucentPolygonalGeometry();
  int RenderTranslucentPolygonalGeometry(vtkViewport* viewport);

protected:
  CustomActor();
  ~CustomActor();

private:
  // Not implemented.
  CustomActor(const CustomActor&);  
  void operator=(const CustomActor&);

};

```

`cpp` file:

```cpp
#include "custom_actor.hpp"

#include <vtk_glew.h>

#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkInteractorObserver.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkOpenGLRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>

/* --- CustomActor implementation --- */

vtkStandardNewMacro(CustomActor);

CustomActor::CustomActor() {}

CustomActor::~CustomActor() {}

void CustomActor::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
};

int CustomActor::RenderOverlay(vtkViewport *viewport)
{
  std::cout << "CustomActor::RenderOverlay" << std::endl;
  return this->Superclass::RenderOverlay(viewport);
}

int CustomActor::RenderOpaqueGeometry(vtkViewport *viewport)
{
  std::cout << "CustomActor::RenderOpaqueGeometry" << std::endl;
  return this->Superclass::RenderOpaqueGeometry(viewport);
}

int CustomActor::HasTranslucentPolygonalGeometry()
{
  std::cout << "CustomActor::HasTranslucentPolygonalGeometry" << std::endl;
  return this->Superclass::HasTranslucentPolygonalGeometry();
}

int CustomActor::RenderTranslucentPolygonalGeometry(vtkViewport* viewport)
{
  std::cout << "CustomActor::RenderTranslucentPolygonalGeometry" << std::endl;
  return this->Superclass::RenderTranslucentPolygonalGeometry(viewport);
}

// Setup custom actors.
void _setupCubeActor(CustomActor* cube_actor);
void _setupConeActor(CustomActor* cone_actor);

// Main
int main(int argc, char* argv[])
{
  vtkNew<CustomActor> cubeActor;
  _setupCubeActor(cubeActor);
  vtkNew<CustomActor> coneActor;
  _setupConeActor(coneActor);

  // Create renderer, render window and an OpenGL context.
  vtkNew<vtkRenderer> renderer;
  vtkNew<vtkRenderWindow> renWin;
  vtkOpenGLRenderWindow* context = vtkOpenGLRenderWindow::SafeDownCast(renWin);
  // vtkOpenGLRenderWindow::OpenGLInit() calls glewInit(), which fails:
  // ERROR: vtkOpenGLRenderWindow.c:569 ERR| vtkXOpenGLRenderWindow (0x5623a0c95ee0): GLEW could not be initialized: Missing GL version
  context->OpenGLInit();
  context->MakeCurrent();
  context->AddRenderer(renderer);
  context->SetSize(800, 800);

  unsigned int vao;
  //glGenVertexArrays(1, &vao); // -> Segmantation fault!

  vtkNew<vtkNamedColors> colors;
  renderer->SetBackground(colors->GetColor3d("MidnightBlue").GetData());
  renderer->AddActor(cubeActor);
  renderer->AddActor(coneActor);

  // Setup interactor.
  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow(context);

  context->Render();
  context->SetWindowName("Transparent Objects");

  // Interact with the data
  iren->Start();

  return EXIT_SUCCESS;
}

void _setupCubeActor(CustomActor* cube_actor)
{
  vtkNew<vtkNamedColors> colors;

  // Cube object.
  vtkNew<vtkCubeSource> cubeSource;
  cubeSource->SetXLength(4.0);
  cubeSource->SetYLength(9.0);
  cubeSource->SetZLength(1.0);
  cubeSource->SetCenter(0.0, 0.0, -6.0);

  vtkNew<vtkPolyDataMapper> cubeMapper;
  cubeMapper->SetInputConnection(cubeSource->GetOutputPort());

  cube_actor->GetProperty()->SetDiffuseColor(
      colors->GetColor3d("DarkGreen").GetData()
  );
  cube_actor->GetProperty()->SetOpacity(0.5);
  cube_actor->SetMapper(cubeMapper);
}

void _setupConeActor(CustomActor* cone_actor)
{
  vtkNew<vtkNamedColors> colors;

  // Cone object.
  vtkNew<vtkConeSource> coneSource;
  coneSource->SetCenter(0.0, 0.0, 0.0);
  coneSource->SetHeight(4.0);
  coneSource->SetRadius(2.0);
  coneSource->SetDirection(0.0, 1.0, 0.0);
  coneSource->SetResolution(60);
  coneSource->CappingOn();

  vtkNew<vtkPolyDataMapper> coneMapper;
  coneMapper->SetInputConnection(coneSource->GetOutputPort());

  cone_actor->GetProperty()->SetDiffuseColor(
      colors->GetColor3d("DarkTurquoise").GetData()
  );
  cone_actor->GetProperty()->SetOpacity(0.5);
  cone_actor->SetMapper(coneMapper);
}

```

---

<div class="post-metadata">

### Author: ![sankhesh](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sankhesh/32/73_2.png) [@sankhesh](https://discourse.vtk.org/u/sankhesh)
#### Post date: [May 5, 2023, 3:29pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/2 "2023-05-05T15:29:48Z")

</div>

All of the OpenGL shader logic is handled by mappers in VTK. For polydata, check the code for `vtkOpenGLPolyDataMapper`.

---

<div class="post-metadata">

### Author: ![mohaya](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/m/dbc845/32.png) [@mohaya](https://discourse.vtk.org/u/mohaya)
#### Post date: [May 5, 2023, 8:35pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/3 "2023-05-05T20:35:10Z")

</div>

@sankhesh Thanks for the pointer. In my program, I would like to render only a specific type of actor with custom OpenGL calls, that’s why I implemented it as a subclass of `vtkActor` and reimplemented its render methods.  
Would you say this is not advised? It did not seem risky to me, as it’s still drawing with OpenGL. I never used VTK’s way of injecting custom shaders, so I’m not sure how restrictive it can be.

---

<div class="post-metadata">

### Author: ![sankhesh](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sankhesh/32/73_2.png) [@sankhesh](https://discourse.vtk.org/u/sankhesh)
#### Post date: [May 5, 2023, 9:15pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/4 "2023-05-05T21:15:07Z")

</div>

> [@mohaya](#):
>
> Thanks for the pointer. In my program, I would like to render only a specific type of actor with custom OpenGL calls

Could you please elaborate on what you’re trying to do?

> [@mohaya](#):
>
> Would you say this is not advised? It did not seem risky to me, as it’s still drawing with OpenGL

Depends on what you’re trying to do. The vtkOpenGLActor doesn’t do much except call `Render` on its mapper. So, if you’d really like to do custom OpenGL, mapper is where you’d do it.

---

<div class="post-metadata">

### Author: ![mohaya](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/m/dbc845/32.png) [@mohaya](https://discourse.vtk.org/u/mohaya)
#### Post date: [May 8, 2023, 12:59am UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/5 "2023-05-08T00:59:03Z")

</div>

Basically, I want to have a single `vtkActor` represent many copies of the same geometry and use it to render them. Let’s say a million cubes, for example.

The goal is to call OpenGL functions directly to draw them for maximum performance, avoiding possible overheads from VTK. This would be achieved by reimplementing `RenderOpaqueGeometry` and `RenderTranslucentPolygonalGeometry` in a new class, and using all OpenGL machinery needed within them, finishing with some `glDraw___` call. These 2 render methods seemed enough for this goal, serving as direct entry points for OpenGL with no need to reference a `vtkMapper` as in `vtkActor::Render`. Honestly, being able to execute OpenGL with GLSL shaders that are agnostic to VTK would be awesome.

Unfortunately, I kind of got stuck on the GLEW issue, so don’t have a concrete result to show besides the `CustomActor` class skeleton. The main idea is simple though, just wanted to reach out for some advice (on the implementation and possibly on the weird GLEW error), as I figured someone must have tried this before.

---

<div class="post-metadata">

### Author: ![sankhesh](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sankhesh/32/73_2.png) [@sankhesh](https://discourse.vtk.org/u/sankhesh)
#### Post date: [May 8, 2023, 2:05pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/6 "2023-05-08T14:05:47Z")

</div>

What you are referring to is called instanced rendering. `vtkGlyph3DMapper` does exactly that.

You can override functions as much as you like, however, keep in mind that VTK considers actors as containers for prop transforms and properties. The task of transforming, scalar lookup, rasterization, and picking is left to the mapper. It might be a small detail when you are dealing with a single class but might cause issues when you have a complex application involving different views, many data types, etc.

About the GLEW issue, do you want VTK to create a native window or are you trying to render VTK inside an external OpenGL context?

---

<div class="post-metadata">

### Author: ![mohaya](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/m/dbc845/32.png) [@mohaya](https://discourse.vtk.org/u/mohaya)
#### Post date: [May 8, 2023, 9:16pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/7 "2023-05-08T21:16:21Z")

</div>

Thanks, I’ll have a closer look at `vtkGlyph3DMapper`.

The GLEW error arises from the `main.cpp` I wrote above. I’m simply creating a `vtkOpenGLRenderWindow` and trying to make it a valid OpenGL context with `OpenGLInit()` and `MakeCurrent()`, which causes GLEW to fail loading gl functions that I want to use.

The program still renders the scene as expected, though, which is odd unless VTK has another rendering backend other than OpenGL. Tried this in both CPU and GPU and got the same behavior.

---

<div class="post-metadata">

### Author: ![sankhesh](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sankhesh/32/73_2.png) [@sankhesh](https://discourse.vtk.org/u/sankhesh)
#### Post date: [May 9, 2023, 1:22pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/8 "2023-05-09T13:22:48Z")

</div>

> [@mohaya](#):
>
> The GLEW error arises from the `main.cpp` I wrote above. I’m simply creating a `vtkOpenGLRenderWindow` and trying to make it a valid OpenGL context with `OpenGLInit()` and `MakeCurrent()`, which causes GLEW to fail loading gl functions that I want to use.

Yes, and that is why I asked what is your intended windowing system. The `vtkOpenGLRenderWindow` cannot be used like that. If you would like for VTK to create a window, just instantiate a `vtkRenderWindow` and call `Render` on it. It will create a context and initialize it for VTK rendering. Once done, your custom classes would just need to include the `vtk_glew.h` header for access to the GL api. If you’d like to do VTK rendering in an OpenGL context created by a different application, you need to use `vtkExternalOpenGLRenderWindow`.

---

<div class="post-metadata">

### Author: ![mohaya](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/m/dbc845/32.png) [@mohaya](https://discourse.vtk.org/u/mohaya)
#### Post date: [May 11, 2023, 4:21pm UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/9 "2023-05-11T16:21:11Z")

</div>

Thank you! Your inputs helped me solve the issue and better understand the VTK way of doing things.

---

<div class="post-metadata">

### Author: ![gpu](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/g/e47c2d/32.png) [@gpu](https://discourse.vtk.org/u/gpu)
#### Post date: [August 26, 2023, 1:50am UTC](https://discourse.vtk.org/t/inheriting-from-vtkactor-for-custom-opengl-rendering/11358/10 "2023-08-26T01:50:18Z")

</div>

if i want to render a vtkTextureObejct to th FrameBuffer, only the texture fullfill the frameBuffer.  
which class should i inherit? still vtkActor? and which map should i inherit?  
thanks!
