%-*- latex -*-

\chapter{Rendering}
\label{chap:Rendering}

\index{rendering|(}

Rendering, the generation of images from data, is a key component to visualization.
To assist with rendering, \VTKm provides a rendering package to produce imagery from data, which is located in the \vtkmrendering{} namespace.

The rendering package in \VTKm is not intended to be a fully featured
rendering system or library. Rather, it is a lightweight rendering package
with two primary use cases:
\begin{enumerate}
\item New users getting started with \VTKm need a ``quick and dirty''
  render method to see their visualization results.
\item In situ visualization that integrates \VTKm with a simulation or
  other data-generation system might need a lightweight rendering method.
\end{enumerate}

Both of these use cases require just a basic rendering platform. Because
\VTKm is designed to be integrated into larger systems, it does not aspire
to have a fully featured rendering system.

\begin{didyouknow}
  \VTKm's big sister toolkit VTK is already integrated with \VTKm and has
  its own fully featured rendering system. If you need more rendering
  capabilities than what \VTKm provides, you can leverage VTK instead.
\end{didyouknow}


\section{Scenes and Actors}
\label{sec:Scene}
\label{sec:Actor}

\index{rendering!actor|(}
\index{actor|(}

The primary intent of the rendering package in \VTKm is to visually display the data that is loaded and processed.
Data are represented in \VTKm by \vtkmcont{DataSet} objects, which are described in Chapter \ref{chap:DataSet}.
They are also the unit created from I/O operations (Chapter \ref{chap:FileIO} and filters (Chapter \ref{chap:RunningFilters}).

To render a \textidentifier{DataSet}, the data are wrapped in a
\vtkmrendering{Actor} class. The \textidentifier{Actor} holds the
components of the \textidentifier{DataSet} to render (a cell set, a
coordinate system, and a field). A color table can also be optionally be
specified, but a default color table will be specified otherwise.

\index{actor|)}
\index{rendering!actor|)}

\index{rendering!scene|(}
\index{scene|(}

\textidentifier{Actor}s are collected together in an object called
\vtkmrendering{Scene}. An \textidentifier{Actor} is added to a
\textidentifier{Scene} with the \classmember*{Scene}{AddActor} method. The following
example demonstrates creating a \textidentifier{Scene} with one
\textidentifier{Actor}.

\index{scene|)}
\index{rendering!scene|)}

\vtkmlisting{Creating an \textidentifier{Actor} and adding it to a \textidentifier{Scene}.}{ActorScene.cxx}


\section{Canvas}
\label{sec:Canvas}

\index{rendering!canvas|(}
\index{canvas|(}

A \keyterm{canvas} is a unit that represents the image space that is the target of the rendering.
The canvas' primary function is to manage the buffers that hold the working image data during the rendering.
The canvas also manages the context and state of the rendering subsystem.

\vtkmrendering{Canvas} is the base class of all canvas objects.
Each type of rendering system has its own canvas subclass, but currently the only rendering system provided by \VTKm is the internal ray tracer.
\index{canvas!ray tracer} The canvas for the ray tracer is \vtkmrendering{CanvasRayTracer}.
\textidentifier{CanvasRayTracer} is typically constructed by giving the width and height of the image to render.

\vtkmlisting{Creating a canvas for rendering.}{Canvas.cxx}

\index{canvas|)}
\index{rendering!canvas|)}


\section{Mappers}
\label{sec:Mapper}

\index{rendering!mapper|(}
\index{mapper|(}

A \keyterm{mapper} is a unit that converts data (managed by an
\textidentifier{Actor}) and issues commands to the rendering subsystem to
generate images. All mappers in \VTKm are a subclass of
\vtkmrendering{Mapper}. Different rendering systems (as established by the
\textidentifier{Canvas}) often require different mappers. Also, different
mappers could render different types of data in different ways. For
example, one mapper might render polygonal surfaces whereas another might
render polyhedra as a translucent volume. Thus, a mapper should be picked
to match both the rendering system of the \textidentifier{Canvas} and the
data in the \textidentifier{Actor}.

The following mappers are provided by \VTKm.

\begin{description}
\item[\vtkmrendering{MapperRayTracer}]
  Uses \VTKm's built in ray tracing system to render the visible surface of a mesh.
  \textidentifier{MapperRayTracer} only works in conjunction with \textidentifier{CanvasRayTracer}.
\item[\vtkmrendering{MapperCylinder}]
Uses \VTKm's built in ray tracing system to render cylinders as lines of a mesh.
\textidentifier{MapperCylinder} only works in conjunction with \textidentifier{CanvasRayTracer}.
\item[\vtkmrendering{MapperGlyphScalar}]
Uses \VTKm's built in ray tracing system to render glyphs at the visible points/vertices of a mesh. It suports rendering points as spheres, axis-aligned cubes, axes and camera-facing quads, coloring the points based on the values of a scalar field.
\textidentifier{MapperGlyphScalar} only works in conjunction with \textidentifier{CanvasRayTracer}.
\item[\vtkmrendering{MapperGlyphVector}]
Uses \VTKm's built in ray tracing system to render arrows at the visible points/vertices of a mesh. It suports rendering points by coloring the points based on the values of a vector field.
\textidentifier{MapperGlyphVector} only works in conjunction with \textidentifier{CanvasRayTracer}.
\item[\vtkmrendering{MapperQuad}]
Uses \VTKm's built in ray tracing system to render the visible quadrilaterals of a mesh.
\textidentifier{MapperQuad} only works in conjunction with \textidentifier{CanvasRayTracer}.

\item[\vtkmrendering{MapperVolume}]
  Uses \VTKm's built in ray tracing system to render polyhedra as a translucent volume.
  \textidentifier{MapperVolume} only works in conjunction with \textidentifier{CanvasRayTracer}.
\item[\vtkmrendering{MapperWireframer}]
  Uses \VTKm's built in ray tracing system to render the cell edges (i.e. the ``wireframe'') of a mesh.
  \textidentifier{MapperWireframer} only works in conjunction with \textidentifier{CanvasRayTracer}.  
\end{description}

\index{mapper|)}
\index{rendering!mapper|)}


\section{Views}
\label{sec:View}

\index{rendering!view|(}
\index{view|(}

A \keyterm{view} is a unit that collects all the structures needed to
perform rendering. It contains everything needed to take a
\textidentifier{Scene} (Section~\ref{sec:Scene}) and use a
\textidentifier{Mapper} (Section~\ref{sec:Mapper}) to render it onto a
\textidentifier{Canvas} (Section~\ref{sec:Canvas}). The view also annotates
the image with spatial and scalar properties.

The base class for all views is \vtkmrendering{View}.
\textidentifier{View} is an abstract class, and you must choose one of the three provided subclasses, \vtkmrendering{View3D}, \vtkmrendering{View2D}, and \vtkmrendering{View3D}, depending on the type of data being presented.
All three view classes take a \textidentifier{Scene}, a \textidentifier{Mapper}, and a \textidentifier{Canvas} as arguments to their constructor.

\vtkmlisting[ex:ConstructView]{Constructing a \textidentifier{View}.}{ConstructView.cxx}

\index{color!background}
\index{color!foreground}
\index{background color}
\index{foreground color}
The \textidentifier{View} also maintains a \keyterm{background color} (the color used in areas where nothing is drawn) and a \keyterm{foreground color} (the color used for annotation elements).
By default, the \textidentifier{View} has a black background and a white foreground.
These can be set in the view's constructor, but it is a bit more readable to set them using the \classmember{View}{SetBackground} and \classmember{View}{SetForeground} methods.
In either case, the colors are specified using the \vtkmrendering{Color} helper class, which manages the red, green, and blue color channels as well as an optional alpha channel.
These channel values are given as floating point values between 0 and 1.

\vtkmlisting[ex:ViewColors]{Changing the background and foreground colors of a \textidentifier{View}.}{ViewColors.cxx}

\begin{commonerrors}
  Although the background and foreground colors are set independently, it will be difficult or impossible to see the annotation if there is not enough contrast between the background and foreground colors.
  Thus, when changing a \textidentifier{View}'s background color, it is always good practice to also change the foreground color.
\end{commonerrors}

Once the \textidentifier{View} is constructed, intialized, and set up, it is ready to render.
This is done by calling the \classmember{View}{Paint} method.

\vtkmlisting[ex:PaintView]{Using \textidentifier{Canvas}\textmethod{::Paint} in a display callback.}{PaintView.cxx}

Putting together Examples \ref{ex:ConstructView}, \ref{ex:ViewColors}, and \ref{ex:PaintView}, the final render of a view looks like that in Figure~\ref{fig:ExampleRendering}.

\begin{figure}[htb]
  \centering
  \includegraphics[width=5.5in]{images/BasicRendering}
  \caption{
    Example output of \VTKm's rendering system.
  }
  \label{fig:ExampleRendering}
\end{figure}

Of course, the \vtkmrendering{CanvasRayTracer} created in \ref{ex:ConstructView} is an offscreen rendering buffer, so you cannot immediately see the image.
When doing batch visualization, an easy way to output the image to a file for later viewing is with the \classmember{View}{SaveAs} method.
This method can save the image in either PNG or in the portable pixelmap (PPM) format.

\vtkmlisting{Saving the result of a render as an image file.}{SaveView.cxx}

We visit doing interactive rendering in a GUI later in Section~\ref{sec:InteractiveRendering}.

\index{view|)}
\index{rendering!view|)}


\section{Changing Rendering Modes}

\index{rendering!mapper|(}
\index{mapper|(}

Example~\ref{ex:ConstructView} constructs the default mapper for ray tracing, which renders the data as an opaque solid.
However, you can change the rendering mode by using one of the other mappers listed in Section~\ref{sec:Mapper}.
For example, say you just wanted to see a wireframe\index{wireframe} representation of your data.
You can achieve this by using \vtkmrendering{MapperWireframer}.

\vtkmlisting{Creating a mapper for a wireframe representation.}{MapperEdge.cxx}

Alternatively, perhaps you wish to render just the points of mesh.
\vtkmrendering{MapperGlyphScalar} renders the points as glyphs and also optionally can scale the glyphs based on field values.

\vtkmlisting{Creating a mapper for point representation.}{MapperGlyphScalar.cxx}

These mappers respectively render the images shown in Figure~\ref{fig:AlternateMappers}.
Other mappers, such as those that can render translucent volumes, are also available.

\begin{figure}[htb]
  \includegraphics[width=.49\linewidth,clip=true,trim=510px 260px 510px 260px]{images/EdgeRendering}
  \hfill
  \includegraphics[width=.49\linewidth,clip=true,trim=510px 260px 510px 260px]{images/GlyphRenderingCubes}
  \includegraphics[width=.49\linewidth,clip=true,trim=510px 260px 510px 260px]{images/GlyphRenderingSpheres}
  \hfill
  \includegraphics[width=.49\linewidth,clip=true,trim=510px 260px 510px 260px]{images/GlyphRenderingArrows}
  \caption[Alternate rendering modes.]{
    Examples of alternate rendering modes using different mappers.
    The top left image is rendered with \textidentifier{MapperWireframer}.
    The top right and bottom left images are rendered with \textidentifier{MapperGlyphScalar}.
    The bottom right image is rendered with \textidentifier{MapperGlyphVector}.
  }
  \label{fig:AlternateMappers}
\end{figure}

\index{mapper|)}
\index{rendering!mapper|)}


\section{Manipulating the Camera}

\index{rendering!camera|(}
\index{camera|(}

The \vtkmrendering{View} uses an object called \vtkmrendering{Camera} to
describe the vantage point from which to draw the geometry. The camera can
be retrieved from the \classmember{View}{GetCamera} method.
That retrieved camera can be directly manipulated or a new camera can be
provided by calling \classmember{View}{SetCamera}.
In this section we discuss camera setups typical during view set up.
Camera movement during interactive rendering is revisited in Section~\ref{sec:InteractiveCameraMovement}.

A \textidentifier{Camera} operates in one of two major modes: 2D mode or 3D
mode. 2D mode is designed for looking at flat geometry (or close to flat
geometry) that is parallel to the x-y plane. 3D mode provides the freedom
to place the camera anywhere in 3D space. The different modes can be set
with \classmember*{Camera}{SetModeTo2D} and \classmember*{Camera}{SetModeTo3D}, respectively. The
interaction with the camera in these two modes is very different.

\subsection{2D Camera Mode}

\index{rendering!camera!2D|(}
\index{camera!2D|(}

The 2D camera is restricted to looking at some region of the x-y plane.

\subsubsection{View Range}

\index{rendering!camera!view range|(}
\index{camera!view range|(}

The vantage point of a 2D camera can be specified by simply giving the
region in the x-y plane to look at. This region is specified by calling
\classmember{Camera}{SetViewRange2D}. This method takes the
left, right, bottom, and top of the region to view. Typically these are set
to the range of the geometry in world space as shown in
Figure~\ref{fig:CameraViewRange2D}.

\begin{figure}[htb]
  \centering
  \includegraphics{images/CameraViewRange2D}
  \caption{The view range bounds to give a \textidentifier{Camera}.}
  \label{fig:CameraViewRange2D}
\end{figure}

There are 3 overloaded versions of the \classmember*{Camera}{SetViewRange2D} method.
The first version takes the 4 range values, left, right, bottom, and top,
as separate arguments in that order. The second version takes two
\vtkm{Range} objects specifying the range in the x and y directions,
respectively. The third version trakes a single \vtkm{Bounds} object, which
completely specifies the spatial range. (The range in z is ignored.) The
\textidentifier{Range} and \textidentifier{Bounds} objects are documented
later in Sections \ref{sec:Range} and \ref{sec:Bounds}, respectively.

\index{camera!view range|)}
\index{rendering!camera!view range|)}

\subsubsection{Pan}

\index{rendering!camera!pan|(}
\index{camera!pan|(}

A camera pan moves the viewpoint left, right, up, or down. A camera pan is
performed by calling the \classmember{Camera}{Pan} method.
\classmember*{Camera}{Pan} takes two arguments: the amount to pan in x and the amount
to pan in y.

The pan is given with respect to the projected space. So a pan of $1$ in
the x direction moves the camera to focus on the right edge of the image
whereas a pan of $-1$ in the x direction moves the camera to focus on the
left edge of the image.

\vtkmlisting{Panning the camera.}{Pan.cxx}

\index{camera!pan|)}
\index{rendering!camera!pan|)}

\subsubsection{Zoom}

\index{rendering!camera!zoom|(}
\index{camera!zoom|(}

A camera zoom draws the geometry larger or smaller. A camera zoom is
performed by calling the \classmember{Camera}{Zoom} method.
\classmember*{Camera}{Zoom} takes a single argument specifying the zoom factor. A
positive number draws the geometry larger (zoom in), and larger zoom factor
results in larger geometry. Likewise, a negative number draws the geometry
smaller (zoom out). A zoom factor of 0 has no effect.

\vtkmlisting{Zooming the camera.}{Zoom.cxx}

\index{camera!zoom|)}
\index{rendering!camera!zoom|)}

\index{camera!2D|)}
\index{rendering!camera!2D|)}

\subsection{3D Camera Mode}

\index{rendering!camera!3D|(}
\index{camera!3D|(}

The 3D camera is a free-form camera that can be placed anywhere in 3D space
and can look in any direction. The projection of the 3D camera is based on
the \index{pinhole camera}\index{camera!pinhole} pinhole camera model in
which all viewing rays intersect a single point. This single point is the
camera's position.

\subsubsection{Position and Orientation}

\index{rendering!camera!position}
\index{camera!position}
\index{rendering!camera!look at}
\index{camera!look at}
\index{look at}
\index{rendering!camera!focal point}
\index{camera!focal point}
\index{focal point}

The position of the camera, which is the point where the observer is viewing the scene, can be set with the \classmember{Camera}{SetPosition} method.
The direction the camera is facing is specified by giving a position to focus on.
This is called either the ``look at'' point or the focal point and is specified with the \classmember{Camera}{SetLookAt} method.
Figure~\ref{fig:CameraPositionOrientation3D} shows the relationship between the position and look at points.

\begin{figure}[htb]
  \centering
  \includegraphics{images/CameraPositionOrientation}
  \caption{The position and orientation parameters for a
    \textidentifier{Camera}.}
  \label{fig:CameraPositionOrientation3D}
\end{figure}

\index{rendering!camera!view up}
\index{rendering!camera!up}
\index{camera!view up}
\index{camera!up}
\index{view up}

In addition to specifying the direction to point the camera, the camera
must also know which direction is considered ``up.'' This is specified with
the view up vector using the \classmember{Camera}{SetViewUp} method. The view up vector points from the camera position
(in the center of the image) to the top of the image. The view up vector in
relation to the camera position and orientation is shown in
Figure~\ref{fig:CameraPositionOrientation3D}.

\index{rendering!camera!field of view}
\index{camera!field of view}
\index{field of view}

Another important parameter for the camera is its field of view.
The field of view specifies how wide of a region the camera can see.
It is specified by giving the angle in degrees of the cone of visible region emanating from the pinhole of the camera to the \classmember{Camera}{SetFieldOfView} method.
The field of view angle in relation to the camera orientation is shown in Figure~\ref{fig:CameraPositionOrientation3D}.
A field of view angle of $60^{\circ}$ usually works well.

\index{rendering!camera!clipping range}
\index{camera!clipping range}
\index{clipping range}
\index{rendering!camera!near clip plane}
\index{camera!near clip plane}
\index{near clip plane}
\index{rendering!camera!far clip plane}
\index{camera!far clip plane}
\index{far clip plane}

Finally, the camera must specify a clipping region that defines the valid
range of depths for the object. This is a pair of planes parallel to the
image that all visible data must lie in. Each of these planes is defined
simply by their distance to the camera position. The near clip plane is
closer to the camera and must be in front of all geometry. The far clip
plane is further from the camera and must be behind all geometry. The
distance to both the near and far planes are specified with the
\classmember{Camera}{SetClippingRange} method.
Figure~\ref{fig:CameraPositionOrientation3D} shows the clipping planes in
relationship to the camera position and orientation.

\vtkmlisting{Directly setting \protect\vtkmrendering{Camera} position and orientation.}{CameraPositionOrientation.cxx}

\subsubsection{Movement}

In addition to specifically setting the position and orientation of the
camera, \vtkmrendering{Camera} contains several convenience methods that
move the camera relative to its position and look at point.

\index{rendering!camera!elevation}
\index{camera!elevation}
\index{elevation}

\index{rendering!camera!azimuth}
\index{camera!azimuth}
\index{azimuth}

Two such methods are elevation and azimuth, which move the camera around
the sphere centered at the look at point. \classmember{Camera}{Elevation} raises or
lowers the camera. Positive values raise the camera up (in the direction of
the view up vector) whereas negative values lower the camera down.
\classmember{Camera}{Azimuth} moves the camera around the look at point to the left or
right. Positive values move the camera to the right whereas negative values
move the camera to the left. Both \classmember*{Camera}{Elevation} and
\classmember*{Camera}{Azimuth} specify the amount of rotation in terms of degrees.
Figure~\ref{fig:CameraMovement} shows the relative movements of
\classmember*{Camera}{Elevation} and \classmember*{Camera}{Azimuth}.

\begin{figure}[htb]
  \centering
  \includegraphics{images/CameraMovement}
  \caption{\textidentifier{Camera} movement functions relative to position
    and orientation.}
  \label{fig:CameraMovement}
\end{figure}

\vtkmlisting{Moving the camera around the look at point.}{CameraMovement.cxx}

\begin{commonerrors}
  The \classmember{Camera}{Elevation} and \classmember{Camera}{Azimuth} methods change the position of the camera, but not the view up vector.
  This can cause some wild camera orientation changes when the direction of the camera view is near parallel to the view up vector, which often happens when the elevation is raised or lowered by about 90 degrees.
\end{commonerrors}

In addition to rotating the camera around the look at point, you can move
the camera closer or further from the look at point. This is done with the
\classmember{Camera}{Dolly} method. The \classmember*{Camera}{Dolly} method takes a single value
that is the factor to scale the distance between camera and look at point.
Values greater than one move the camera away, values less than one move the
camera closer. The direction of dolly movement is shown in
Figure~\ref{fig:CameraMovement}.

Finally, the \classmember{Camera}{Roll} method rotates the camera around the viewing
direction. It has the effect of rotating the rendered image. The
\classmember*{Camera}{Roll} method takes a single value that is the angle to rotate in
degrees. The direction of roll movement is shown in
Figure~\ref{fig:CameraMovement}.

\subsubsection{Pan}

\index{rendering!camera!pan|(}
\index{camera!pan|(}

A camera pan moves the viewpoint left, right, up, or down. A camera pan is
performed by calling the \classmember{Camera}{Pan} method.
\classmember*{Camera}{Pan} takes two arguments: the amount to pan in x and the amount
to pan in y.

The pan is given with respect to the projected space. So a pan of $1$ in
the x direction moves the camera to focus on the right edge of the image
whereas a pan of $-1$ in the x direction moves the camera to focus on the
left edge of the image.

\vtkmlisting{Panning the camera.}{Pan.cxx}

\index{camera!pan|)}
\index{rendering!camera!pan|)}

\subsubsection{Zoom}

\index{rendering!camera!zoom|(}
\index{camera!zoom|(}

A camera zoom draws the geometry larger or smaller. A camera zoom is
performed by calling the \classmember{Camera}{Zoom} method.
\classmember*{Camera}{Zoom} takes a single argument specifying the zoom factor. A
positive number draws the geometry larger (zoom in), and larger zoom factor
results in larger geometry. Likewise, a negative number draws the geometry
smaller (zoom out). A zoom factor of 0 has no effect.

\vtkmlisting{Zooming the camera.}{Zoom.cxx}

\index{camera!zoom|)}
\index{rendering!camera!zoom|)}

\index{camera!3D|)}
\index{rendering!camera!3D|)}

\index{camera|)}
\index{rendering!camera|)}

\subsubsection{Reset}

\index{rendering!camera!reset|(}
\index{camera!reset|(}

Setting a specific camera position and orientation can be frustrating,
particularly when the size, shape, and location of the geometry is not
known a priori. Typically this involves querying the data and finding a
good camera orientation.

To make this process simpler, \vtkmrendering{Camera} has a convenience
method named \classmember{Camera}{ResetToBounds} that automatically positions the
camera based on the spatial bounds of the geometry. The most expedient
method to find the spatial bounds of the geometry being rendered is to get
the \vtkmrendering{Scene} object and call \classmember*{Scene}{GetSpatialBounds}. The
\textidentifier{Scene} object can be retrieved from the
\vtkmrendering{View}, which, as described in Section~\ref{sec:View}, is the
central object for managing rendering.

\vtkmlisting{Resetting a \textidentifier{Camera} to view geometry.}{ResetCamera.cxx}

The \classmember*{Camera}{ResetToBounds} method operates by placing the look at point
in the center of the bounds and then placing the position of the camera
relative to that look at point. The position is such that the view
direction is the same as before the call to \classmember*{Camera}{ResetToBounds} and
the distance between the camera position and look at point has the bounds
roughly fill the rendered image. This behavior is a convenient way to
update the camera to make the geometry most visible while still preserving
the viewing position. If you want to reset the camera to a new viewing
angle, it is best to set the camera to be pointing in the right direction
and then calling \classmember*{Camera}{ResetToBounds} to adjust the position.

\vtkmlisting{Resetting a \textidentifier{Camera} to be axis aligned.}{AxisAlignedCamera.cxx}

\index{camera!reset|)}
\index{rendering!camera!reset|)}


\section{Interactive Rendering}
\label{sec:InteractiveRendering}

\index{rendering!interactive|(}
\index{interactive rendering|(}

So far in our description of \VTKm's rendering capabilities we have talked about doing rendering of fixed scenes.
However, an important use case of scientific visualization is to provide an interactive rendering system to explore data.
In this case, you want to render into a GUI application that lets the user interact manipulate the view.
The full design of a 3D visualization application is well outside the scope of this book, but we discuss in general terms what you need to plug \VTKm's rendering into such a system.

In this section we discuss two important concepts regarding interactive rendering.
First, we need to write images into a GUI while they are being rendered.
Second, we want to translate user interaction to camera movement.

\subsection{Rendering Into a GUI}

\index{rendering!OpenGL|(}
\index{interactive rendering!OpenGL|(}
\index{OpenGL|(}

Before being able to show rendering to a user, we need a system rendering context in which to push the images.
In this section we demonstrate the display of images using the OpenGL rendering system, which is common for scientific visualization applications.
That said, you could also use other rendering systems like DirectX or even paste images into a blank widget.

Creating an OpenGL context varies depending on the OS platform you are using.
If you do not already have an application you want to integrate with \VTKm's rendering, you may wish to start with graphics utility API such as GLUT or GLFW.
The process of initializing an OpenGL context is not discussed here.

The process of rendering into an OpenGL context is straightforward.
First call \classmember*{View}{Paint} on the \textidentifier{View} object to do the actual rendering.
Second, get the image color data out of the \textidentifier{View}'s \textidentifier{Canvas} object.
This is done by calling \classmember{Canvas}{GetColorBuffer}.
This will return a \vtkmcont{ArrayHandle} object containing the image's pixel color data.
(\textidentifier{ArrayHandle}s are discussed in detail in Chapter \ref{chap:BasicArrayHandles} and subsequent chapters.)
A raw pointer can be pulled out of this \textidentifier{ArrayHandle} by casting it to the \vtkmcont{ArrayHandleBase} subclass and calling the \classmember*{ArrayHandleBase}{GetReadPointer} method on that.
Third, the pixel color data are pasted into the OpenGL render context.
There are multiple ways to do so, but the most straightforward way is to use the \textcode{glDrawPixels} function provided by OpenGL.
Fourth, swap the OpenGL buffers.
The method to swap OpenGL buffers varies by OS platform.
The aforementioned graphics libraries GLUT and GLFW each provide a function for doing so.

\vtkmlisting{Rendering a \textidentifier{View} and pasting the result to an active OpenGL context.}{RenderToOpenGL.cxx}

\index{OpenGL|)}
\index{interactive rendering!OpenGL|)}
\index{rendering!OpenGL|)}

\subsection{Camera Movement}
\label{sec:InteractiveCameraMovement}

\index{rendering!camera!mouse|(}
\index{camera!interactive|(}
\index{camera!mouse|(}

When interactively manipulating the camera in a windowing system, the camera is usually moved in response to mouse movements.
Typically, mouse movements are detected through callbacks from the windowing system back to your application.
Once again, the details on how this works depend on your windowing system.
The assumption made in this section is that through the windowing system you will be able to track the x-y pixel location of the mouse cursor at the beginning of the movement and the end of the movement.
Using these two pixel coordinates, as well as the current width and height of the render space, we can make several typical camera movements.

\begin{commonerrors}
  Pixel coordinates in \VTKm's rendering system originate in the lower-left corner of the image.
  However, windowing systems generally report mouse coordinates with the origin in the \emph{upper}-left corner.
  The upshot is that the y coordinates will have to be reversed when translating mouse coordinates to \VTKm image coordinates.
  This inverting is present in all the following examples.
\end{commonerrors}

\subsubsection{Rotate}

\index{mouse rotation|(}

A common and important mode of interaction with 3D views is to allow the user to rotate the object under inspection by dragging the mouse.
To facilitate this type of interactive rotation, \vtkmrendering{Camera} provides a convenience method named \classmember*{Camera}{TrackballRotate}.
The \classmember*{Camera}{TrackballRotate} method takes a start and end position of the mouse on the image and rotates viewpoint as if the user grabbed a point on a sphere centered in the image at the start position and moved under the end position.

The \classmember*{Camera}{TrackballRotate} method is typically called from within a mouse movement callback.
The callback must record the pixel position from the last event and the new pixel position of the mouse.
Those pixel positions must be normalized to the range -1 to 1 where the position (-1,-1) refers to the lower left of the image and (1,1) refers to the upper right of the image.
The following example demonstrates the typical operations used to establish rotations when dragging the mouse.

\vtkmlisting{Interactive rotations through mouse dragging with \textidentifier{Camera}\textmethod{::TrackballRotate}.}{MouseRotate.cxx}

\index{mouse rotation|)}

\subsubsection{Pan}

Panning can be performed by calling \classmember{Camera}{Pan} with the translation relative to the width and height of the canvas.
For the translation to track the movement of the mouse cursor, simply scale the pixels the mouse has traveled by the width and height of the image.

\vtkmlisting{Pan the view based on mouse movements.}{MousePan.cxx}

\subsubsection{Zoom}

Zooming can be performed by calling \classmember{Camera}{Zoom} with a positive or negative zoom factor.
When using \classmember*{Camera}{Zoom} to respond to mouse movements, a natural zoom will divide the distance traveled by the mouse pointer by the width or height of the screen as demonstrated in the following example.

\vtkmlisting{Zoom the view based on mouse movements.}{MouseZoom.cxx}

\index{camera!mouse|)}
\index{camera!interactive|)}
\index{rendering!camera!mouse|)}

\index{interactive rendering|)}
\index{rendering!interactive|)}


\section{Color Tables}
\label{sec:ColorTables}

\index{rendering!color tables|(}
\index{color tables|(}

\index{pseudocolor}
An important feature of \VTKm's rendering units is the ability to
pseudocolor objects based on scalar data. This technique maps each scalar
to a potentially unique color. This mapping from scalars to colors is
defined by a \vtkmcont{ColorTable} object. A
\textidentifier{ColorTable} can be specified as an optional argument when
constructing a \vtkmrendering{Actor}. (Use of \textidentifier{Actor}s is
discussed in Section~\ref{sec:Actor}.)

\vtkmlisting{Specifying a \textidentifier{ColorTable} for an \textidentifier{Actor}.}{SpecifyColorTable.cxx}

The easiest way to create a \textidentifier{ColorTable} is to provide the
name of one of the many predefined sets of color provided by VTK-m. A list
of all available predefined color tables is provided below.

% Insert an inline table
\newlength{\fontdrop}		% Set length to drop below baseline so that
\settodepth{\fontdrop}{()}	% we can drop the image to fill the actual line
\newcommand*{\includecolortable}[1]{%
  \raisebox{-\fontdrop}{\includegraphics[height=10pt,width=1in]{images/ColorTables/#1}}%
}
\NewDocumentCommand{\ctcolumns}{ o m }{
  \IfValueTF{#1}{
    \includecolortable{#1}
  }{
    \includecolortable{#2}
  }
  & #2 &
}

\begin{xltabular}{\textwidth}{llX}
  \ctcolumns{Viridis}
  Matplotlib Virdis, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white.
  This is the default color map.
  \index{rendering!color tables!default}
  \index{color tables!default} \\
  \ctcolumns[Cool-to-Warm]{Cool to Warm}
  A color table designed to be perceptually even, to work well on shaded 3D surfaces, and to generally perform well across many uses.\\
  \ctcolumns[Cool-to-Warm-Extended]{Cool to Warm Extended}
  This colormap is an expansion on cool to warm that moves through a wider range of hue and saturation.
  Useful if you are looking for a greater level of detail, but the darker colors at the end might interfere with 3D surfaces.\\
  \ctcolumns{Inferno}
  Matplotlib Inferno, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white.\\
  \ctcolumns{Plasma}
  Matplotlib Plasma, which is designed to have perceptual uniformity, accessibility to color blind viewers, and good conversion to black and white.\\
  \ctcolumns[Black-Body-Radiation]{Black-Body Radiation}
  The colors are inspired by the wavelengths of light from black body radiation.
  The actual colors used are designed to be perceptually uniform.\\
  \ctcolumns[X-Ray]{X Ray}
  Greyscale colormap useful for making volume renderings similar to what you would expect in an x-ray.\\
  \ctcolumns{Green}
  A sequential color map of green varied by saturation.\\
  \ctcolumns[Black---Blue---White]{Black - Blue - White}
  A sequential color map from black to blue to white.\\
  \ctcolumns[Blue-to-Orange]{Blue to Orange}
  A double-ended (diverging) color table that goes from dark blues to a neutral white and then a dark orange at the other end.\\
  \ctcolumns[Gray-to-Red]{Gray to Red}
  A double-ended (diverging) color table with black/gray at the low end and orange/red at the high end.\\
  \ctcolumns[Cold-and-Hot]{Cold and Hot}
  A double-ended color map with a black middle color and diverging values to either side.
  Colors go from red to yellow on the positive side and through blue on the negative side.\\
  \ctcolumns[Blue---Green---Orange]{Blue - Green - Orange}
  A three-part color map with blue at the low end, green in the middle, and orange at the high end.\\
  \ctcolumns[Yellow---Gray---Blue]{Yellow - Gray - Blue}
  A three-part color map with yellow at the low end, gray in the middle, and blue at the high end.\\
  \ctcolumns[Rainbow-Uniform]{Rainbow Uniform}
  A color table that spans the hues of a rainbow.
  There have been many scientific perceptual studies on the effectiveness of rainbow colors, and they uniformly found them to be ineffective.
  This color table modifies the hues to make them more perceptually uniform, which should improve the effectiveness of the colors.
  However, we still recommend the other color tables over this one.\\
  \ctcolumns{Jet}
  A rainbow color table that adds some darkness for greater perceptual resolution.
  The ends of the jet color table might be too dark for 3D surfaces.\\
  \ctcolumns[Rainbow-Desaturated]{Rainbow Desaturated}
  All the badness of the rainbow color table with periodic dark points added, which can help identify rate of change.\\
\end{xltabular}

\fix{There is more functionality to document in
  \textidentifier{ColorTable}. In particular, building color tables by
  adding control points. However, I am not bothering to document that right
  now because (1) I don't think many people will use it and (2) it is
  pretty clear from the Doxygen.}

\index{color tables|)}
\index{rendering!color tables|)}

\index{rendering|)}
