vtkPainter and Friends

parakeetincurableSoftware and s/w Development

Dec 13, 2013 (3 years and 7 months ago)

186 views

vtkPainter and Friends

Kenneth Moreland

Sandia National Laboratories

Sandia is a multiprogram laboratory operated by Sandia Corporation, a Lockheed Martin Company,

for the United States Department of Energy’s National Nuclear Security Administration


under contract DE
-
AC04
-
94AL85000.

Motivation


Rendering performance of VTK
(vtkOpenGLPolyDataMapper) is legendary for its
mediocrity.


Principally limited to OpenGL 1.0 functions.


Relies heavily on display lists.


To be fair, mapper improved significantly in past
couple of years (as did nVidia’s display lists).


We
know

we can do better with vertex arrays.


Enter vtkOpenGLVertexArrayMapper.


Saw 4x improvement and declared success.

Motivation


Soon found problems with vertex array mapper.


Taking advantage of OpenGL extensions meant
subclassing.


A factory had to choose the “right one” up front.


Worked well only on limited poly data.


Mapper contains lots of “hacks” for rendering all
types of data.


Hacks worked poorly and obfuscated the code.

What’s Wrong?


A vtkPolyDataMapper is required to render
anything you throw at it.


There are many combinations.


4

cell types x
3

normal configs x
3

scalar configs x
2

tcoord configs =
72


Does not include tuple sizes and data types.


Handling all of them reasonably inevitably leads to
obfuscated code.


All rendering approaches have their drawbacks.


Calling glVertex, glColor, etc. is API bound.


Display lists have high overhead.


Vertex arrays do not work well on cell data and can
be API bound.

Goal: A More Flexible Mapper


The mapper should change its rendering strategy
(i.e. display list vs. vertex array) based on input.


It should be easy to add new rendering
methods/incorporate new OpenGL extensions.


It should be Cg/HLSL ready.


It should (hopefully) handle everything we have
not thought of yet gracefully.

Approach: Strategy Pattern

Context

ContextInterface()

Strategy

AlgorithmInterface()

ConcreteStrategyA

AlgorithmInterface()

ConcreteStrategyB

AlgorithmInterface()

ConcreteStrategyC

AlgorithmInterface()

Application

vtkPainterPolyDataMapper

vtkPolyDataPainter

vtkStandardPolyDataPainter

vtkDisplayListPainter


vtkDefaultPainter


What is a vtkPainter?


A vtkPainter is responsible solely for issuing
rendering commands that draw primitives.


Establishing pipeline state is left for the thin
mapper, property, and other classes.


Mapper calls DrawVerts(), DrawLines(),
DrawPolys(), and DrawStrips().


A vtkPainter does
not

have to support all types of
poly data.


It is free to render some types poorly or not at all.


Making a painter is easy compared to making a
poly data mapper.

Some Painter Implementations


vtkStandardPainter


A jack of all trades. A master at none.


vtkPointsPainter, vtkLinesPainter,
vtkPolygonsPainter, vtkTSTripsPainter


Painters optimized for rendering a particular type of
polygon (but no other type of polygon).

Painter Decorators


All painters have a delegate painter that can do all
or some of the rendering work.


A painter can operate by simply modifying the
behavior of (or decorating) its delegate.


The behavior of the delegate painter is modified by
some pre
-

or post
-
processing.


From the outside, a decorating painter behaves
just like any other painter.

Example Painter Decorators


Existing painter decorators.


vtkDisplayListPainter


vtkClipPlanesPainter


vtkLightingPainter


vtkScalarsToColorsPainter


vtkCoincidentTopologyResolutionPainter


vtkRepresentationPainter


Other possible decorators


Sorting


View dependent level
-
of
-
detail


Hardware friendly layout (triangulation, stripping,
partitioning, cache miss minimization, cell to point, etc.)


???


Note the flexibility (although there may be memory copy
overheads).

Establishing a Painter Pipeline


Most often, you need a combination of several
painters (lighting, coloring, drawing, etc.) to get a
viable image.


Establishing this pipeline can be confusing and
annoying.


Solution: use vtkDefaultPainter.


The default painter is a meta
-
painter that internally
sets up a default pipeline that establishes all of the
most common non
-
drawing operations (the
delegate performs the drawing).


Replicates the non
-
drawing operations of the
original vtkOpenGLPolyDataMapper.

Choosing a Painter for Drawing


Sometimes you will have a painter in mind, most
often you will not.


How does an application choose a painter?


Solution: use vtkChooserPainter.


The default painter was programmed with implicit
knowledge about some set of painters.


Based on the poly data, the rendering system, and
information given by the application, the default
painter will pick a reasonable (if not optimal)
painting algorithm.


vtkChooserPainter is the default delegate painter
for vtkDefaultPainter.

State Maintained by vtkPainter Superclass


A vtkPolyData (cell and point data is ignored).


Usage flags.


StaticData, ConserveMemory, HighQuality,
BuildNormals.


These flags may be ignored by some painters.

Attribute Arrays


A painter defines primitives by sending data from
attribute arrays to the graphics card.


The order the attributes are sent determines (in
part) the nature of the primitives.


The data in the attributes (plus the rendering
system state) determine the position and colors.


Each attribute array has an index.


Attributes can be defined on points or cells.


Attribute meaning usually corresponds to
vtkDataSetAttributes::AttributeTypes enums (with
NUM_ATTRIBUTES mapped to point positions),
but this can be overridden for shaders.

Painter Device Adapters


An abstract wrapper around OpenGL drawing
functions.


Used instead of calling functions such as glBegin,
glEnd, glVertex*, and glDrawElements.


Works with the abstract attributes.


Default OpenGL adapter maps to positions, colors,
normals, and texture coordinates in the same way
as the aliases in vtkPainter.


Can be substituted for another rendering API.

Integrating Cg


Create a subclass of vtkPainterDeviceAdapter.


Map attribute indices to vertex
-
program variable
parameters.


Call the appropriate Cg lib functions.


It’s probably best to maintain the attribute aliases.


Set in the painter any attribute arrays that do not
fall into the standard aliases (point position,
color, normal, and texture coordinate).


That’s it. Were you, like, expecting something
more difficult?

Class Overview

vtkPainterPolyDataMapper

vtkPolyDataMapper

vtkPolyDataPainter

vtkPainterDeviceAdapter

vtkPointsPainter

vtkStandardPainter

vtkPrimitivePainter

vtkLinesPainter

vtkPolygonsPainter

vtkChooserPainter

vtkDisplayListPainter

DelegatePainter

Painter

vtkOpenGLPainterDeviceAdapter

vtkLightingPainter

vtkClipPlanesPainter

vtkRepresentationPainter

vtkScalarsToColorsPainter

vtkCoincidentTopologyResolutionPainter

vtkPainter

vtkTStripsPainter

vtkDisplayListPainter

Performance (vtkSNL)

Saint Helens / 151,916 polys / static
0
2
4
6
8
10
Millions
Frame
Polygons / sec
Old
Painters
Saint Helens / 151,916 polys / dynamic
0
0.2
0.4
0.6
0.8
1
1.2
1.4
Millions
Frame
Polygons / sec
Old
Painters
MechPart / 337,380 polys / static
0
2
4
6
8
10
12
14
Millions
Frame
Polygons / sec
Old
Painters
MechPart / 337,380 polys / dynamic
0
0.5
1
1.5
2
2.5
Millions
Frame
Polygons / sec
Old
Painters
Performance (vtkSNL)

Exodus Surface / 3,312,640 polys / static
0
2
4
6
8
10
12
14
Millions
Frame
Polygons / sec
Old
Painters
Exodus Surface / 3,312,640 polys / dynamic
0
0.2
0.4
0.6
0.8
1
1.2
1.4
1.6
1.8
Millions
Frame
Polygons / sec
Old
Painters
Turbulance Simulation Isosurface / 7,371,193 polys / static
0
5
10
15
20
Millions
Frame
Polygons / sec
Old
Painters
Turbulance Simulation Isosurface / 7,371,193 polys / dynamic
.
Frame
Polygons / sec
Old
Painters
Conclusions


Disadvantages


Higher API overhead.


Particularly problematic with the virtual functions in
vtkPainterDeviceAdapter.


Aggravates an already existing problem (and, yeah,
vtkStandardPainter is really slow).


Runaway combinations in attributes.


No choice but to iterate over attributes.


Looser coupling.


Excessive memory reordering/copying may be
required.

Conclusions


Advantages


Looser coupling.


Better code separation, less obfuscation.


Easier to employ rendering techniques/extensions.


Dynamic choosing of rendering technique.


Technique is specific to the data/state.


The extra overhead can be mitigated by using the
best painter for the job.


A decorator can apply a feature to any other painter
(even another decorator).


Cg ready.