[vtkusers] Performance leak in multipass rendering resolved
Rocco Gasteiger
post at rocco-gasteiger.de
Fri Jan 15 04:41:51 EST 2010
Dear VTK-Users,
in a previous post
(http://www.vtk.org/pipermail/vtkusers/2009-December/104490.html) I reported
a strong performance leak during rendering twice of my object with the new
multipass framework of VTK. Especially, if my object consist of many
triangles. Now, I figured out what the problem was by examine the source
code of the vtkOpenGLMapper and want to shade these information with the
VTK-community, especially these users which have not yet a deep
understanding of the rendering pipeline of VTK, like me.
In the render-routine of my derived vtkRenderPass-class I changed some actor
properties, e.g., surface rendering style (wireframe or surface) or opacity
via actor->GetProperty()->SetOpacity(
) in each pass. This occurred a
deletion and new creation of the display lists of the corresponding
polydata-object in the mapper. Because this happened every frame, the
performance leak occurred.
To resolve it, I use the property key capability of the frame work by
orientation to vtkShadowMappPass. Like in my previous approach, I create
different actors of my object based on the same vtkPolyData object. After
this, I set the properties of each actor in that way I want to use it in the
corresponding pass (e.g. wireframe). Additionally I set different
vtkInformation-objects with special keys as property keys to the actors. In
my render-routine of my derived vtkRenderingPass I set the required keys to
my render state object and only these actor(s) with the same key is (are)
rendered. Now I can call
this->DelegatePass->Render(&newRenderState); multiple times with setting the
correct key property and without performace leak.
Here is a (pseudo-)code snippet which illustrate what I have done. For
simplification I distinguish between my main-routine (definition of the
vtkPolyData, vtkRenderer and so on) and my derived vtkRenderPass-class
vtkMyRenderPass.
///////////////
Main-routine:
///////////////
// 1. Setup actors with corresponding key properties
mySurfaceMapper->SetInput(myVtkPolyData);
mySurfaceActor->SetMapper(mySurfaceMapper);
myWireframeSurfaceActor->SetMapper(mySurfaceMapper);
vtkSmartPointer<vtkInformation>surfacePropKey =
vtkSmartPointer<vtkInformation>::New();
surfacePropKey ->Set(vtkMyRenderPass::SURFACE(), 0);
surfaceActor->SetPropertyKeys(surfacePropKey);
vtkSmartPointer<vtkInformation>wirfeframePropKey =
vtkSmartPointer<vtkInformation>::New();
wirfeframePropKey ->Set(vtkMyRenderPass::WIREFRAME(), 0);
myWireframeSurfaceActor->SetPropertyKeys(wirfeframePropKey);
// 2. Create all necessary passes (vtkLightsPass, vtkOpaquePass,
vtkTranslucentPass, and so on), collect them
// in a vtkRenderPassCollection, pass it into a vtkSequencePass and delegate
it to a vtkCameraPass.
// 3. Create vtkMyRenderPass and set its delegate pass to the vtkCameraPass.
////////////////////
vtkMyRenderPass
////////////////////
// 1. Setup pass like other rendering passes e.g. vtkShadowMappPass (e.g.
frame buffers, texture objects, shaders,
)
// 2. Define the property keys in the header file
static vtkInformationIntegerKey *SURFACE();
static vtkInformationIntegerKey *WIREFRAME ();
//
and the corresponding macros in the c++-file
vtkInformationKeyMacro(vtkMyRenderPass,SURFACE,Integer);
vtkInformationKeyMacro(vtkMyRenderPass, WIREFRAME,Integer);
// 3. Create vtkInformation-object which holds the current required keys
if (this->requiredKeys == 0) this->requiredKeys =
vtkSmartPointer<vtkInformation>::New();
this->requiredKeys->Set(vtkMyRenderPass::SURFACE(),0);
// 4. Create vtkRenderState object, set key-object, framebuffers and so on
vtkRenderState newRenderState(renderer);
newRenderState.SetPropArrayAndCount(renderState->GetPropArray(),
renderState->GetPropArrayCount());
newRenderState.SetRequiredKeys(requiredKeys);
newRenderState.SetFrameBuffer(this->FrameBufferObject);
// 5. Render first pass
this->DelegatePass->Render(renderState);
this->NumberOfRenderedProps +=
this->DelegatePass->GetNumberOfRenderedProps();
// 6. Remove key SURFACE and set key WIREFRAME
requiredKeys->Remove(vtkHiddenLineDesignerPass::SURFACE_SEMI());
requiredKeys->Set(vtkMyRenderPass::WIREFRAME(),0);
newRenderState.SetRequiredKeys(requiredKeys);
// 7. Render second pass
this->DelegatePass->Render(renderState);
this->NumberOfRenderedProps +=
this->DelegatePass->GetNumberOfRenderedProps();
// 8. Remove key WIREFRAME to have a clean key-property object for a new
call of the render-routine
requiredKeys->Remove(vtkMyRenderPass:: WIREFRAME());
I hope this small example helps somebody by implementing its on multipass
algorithms. The capability of the key property object is a very flexible and
good design decision . Thanks to François Bertel for designing and
implementing this framework!
Best regards, Rocco
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100115/c3853c1a/attachment.htm>
More information about the vtkusers
mailing list