Browse Source

*** empty log message ***

David Rose 25 years ago
parent
commit
59b4ba566a
1 changed files with 157 additions and 0 deletions
  1. 157 0
      panda/src/doc/howto.control_render_order

+ 157 - 0
panda/src/doc/howto.control_render_order

@@ -0,0 +1,157 @@
+Panda has two primary modes of rendering: with or without a separate
+"Cull" traversal.
+
+In the simplest case, Panda renders directly, without a separate Cull
+traversal.  In this case, the scene graph is traversed with a simple
+depth-first, left-to-right in-order traversal, and GeomNodes are sent
+to the graphics engine as they are encountered.
+
+When operating in this mode, the only way to control render order is
+to adjust the order of nodes within the hierarchy.  It is possible to
+do this by either building the hierarchy in a specific order (each
+reparenting operation in the scene graph appends the new node to the
+end of its parent's children list), or more explicitly, by setting a
+sort order on each arc as it is created or moved (the NodePath
+reparenting methods support an optional sort parameter, and the
+NodeRelation class has a set_sort() method).  Normally the sort order
+on each arc is zero, but it may be explicitly set to any integer.  A
+node's list of children will always be kept in order from lowest to
+highest sort order, and where siblings have an equal sort order, they
+will be arranged in the order in which they were added.
+
+More commonly, Panda is operated using a Cull traversal.  This
+traversal makes a complete pass through the scene graph before
+rendering anything, collecting together all the GeomNodes that are to
+be rendered and arranging them in a suitable order before passing them
+to the graphics engine.  It is somewhat inappropriately named;
+although it does do view-frustum culling, so does the simpler direct
+traversal; it should more properly be called the State Sorting
+traversal.
+
+When the Cull traversal is in use, the hierarchy order is irrelevant.
+Instead, the Cull traversal uses a binning system to support user
+control of the order in which things are rendered.
+
+As the Cull traversal encounters GeomNodes, it assigns each one to a
+particular bin, identified by name.  These bins are selected by
+setting a GeomBinTransition above the arc in question, or by calling
+NodePath::set_bin().
+
+After all the GeomNodes have been identified, the various bins are
+sorted in order according to each bin's sort index, which is specified
+by GeomBin::set_sort().  This is an arbitary integer assigned to each
+bin, and the lower-number bins are drawn first.  Each bin is then
+responsible for drawing its contents--the set of GeomNodes assigned to
+it--in whatever order it likes.  The various kinds of bins render
+their GeomNodes in different ways:
+
+  GeomBinStateSorted -- collects together all GeomNodes that share a
+    common state and renders them at once, before switching to the
+    next group of GeomNode with a common state.  Attempts to minimize
+    the state changes between groups of GeomNodes.  The goal of this
+    bin is to minimize the number of state changes sent to the
+    graphics engine, and so reduce rendering overhead.
+
+  GeomBinBackToFront -- renders everything in order from the furthest
+    away to the closest.  This is generally necessary for correct
+    transparent and semitransparent rendering.  The ordering is based
+    on the center of each GeomNode's bounding volume, relative to the
+    camera plane.
+
+  GeomBinNormal -- assigns each GeomNode to one of two sub-bins:
+    transparent geometry is assigned to a GeomBinBackToFront, while
+    opaque geometry is assigned to a GeomBinStateSorted.  This is the
+    kind of bin that 'default' is defined to be; it is the bin that
+    all GeomNodes are assigned to when no other bin is explicitly
+    specified.
+
+  GeomBinUnsorted -- renders everything in no particular order.
+
+  GeomBinFixed -- renders everything according to a user-specified
+    order, potentially per GeomNode.  Each GeomBinTransition that
+    specifies a GeomBinFixed bin may also include an optional sort
+    order (this is an optional second parameter to the
+    GeomBinTransition constructor, as well as to NodePath::set_bin());
+    the GeomBinFixed will render low-number nodes before high-number
+    nodes.
+
+If no bin is explicitly specified, each GeomNode is assigned to a bin
+named 'default', which is of type GeomBinNormal; this bin is created
+at startup and contains two sub-bins, one for transparent geometry and
+one for nontransparent geometry.  The nontransparent bin is rendered
+first, with its contents in state-sorted order, followed by the
+transparent bin, with its contents in order from back to front.  This
+usually provides correct behavior for transparent and semitransparent
+objects, which must generally be rendered after everything behind them
+has already been rendered.
+
+However, this sometimes fails, particularly with large, flat polygons
+stacked closely in front of one another.  In cases like these it may
+be necessary to explicitly specify an ordering.
+
+There is another predefined bin available called 'fixed'.  Nothing
+will ever be rendered in 'fixed' (or any other bin, other than
+'default') unless it is explicitly assigned to it.  The 'fixed' bin is
+of type GeomBinFixed, and renders its objects according to a fixed
+ordering, specified as the second parameter to the GeomBinTransition
+constructor, or to NodePath::set_bin().  There is also another
+predefined bin called 'background', which is another bin of type
+GeomBinFixed.
+
+The order of all the predefined bins (and their predefined sort
+orders) is as follows:
+
+  10 - 'default'    : GeomBinNormal (opaque sub-bin)
+  20 - 'background' : GeomBinFixed
+  30 - 'default'    : GeomBinNormal (transparent sub-bin)
+  40 - 'fixed'      : GeomBinFixed
+
+Thus, the 'fixed' bin can be used for things that must be rendered
+correctly relative to each other, but should render after all other
+things in the scene graph, while the 'background' bin can be used for
+things that must render before other transparent things in the scene
+graph (it's particularly useful for large, flat polygons on the
+horizon).
+
+Other bins may easily be defined, either at run time or via a line in
+a Configrc file.  It is also possible to redefine any of the
+predefined bins by defining a new bin with the same name.
+
+To define a bin via the Configrc file, add a line beginning with
+"cull-bin" and consisting of three space-separated fields: the name of
+the bin, the bin sort order, and the type of bin.  For example, to
+create an bin called 'shadow' to render shadows in no particular
+order, but before any other transparent objects are rendered, you may
+add the line:
+
+  cull-bin shadow 15 unsorted
+
+The valid bin types are normal, unsorted, state-sorted, fixed, or
+back-to-front.
+
+To define a bin at run time, you simply create a bin of the
+appropriate type using its constructor, and then assign it to the
+current render traverser via GeomBin::set_traverser().  To do this,
+you must get a pointer to the current traverser via
+GraphicsStateGuardian::get_render_traverser().  This will either be a
+DirectRenderTraverser or a CullTraverser.
+
+A GeomBin may only be assigned to a CullTraverser.  If the current
+render traverser is not a CullTraverser, then Panda is operating
+without a Cull traversal, and you cannot meaningfully assign things to
+GeomBins anyway.
+
+For example, the following Python code creates the same GeomBin
+defined above:
+
+  shadowBin = GeomBinUnsorted('shadow')
+  shadowBin.setSort(15)
+  try:
+    shadowBin.setTraverser(win.getGsg().getRenderTraverser())
+  except:
+    pass
+
+The try .. except block is a good idea to protect against the case in
+which getRenderTraverser() does not return a CullTraverser.
+
+