Detailed Description
The QGLRenderSequencer class orders the rendering of QGLSceneNode instances.
The QGLRenderSequencer class works with the QGLRenderOrderComparator and QGLRenderOrder classes to optimize the rendering order of scene nodes.
In general instances of this class are managed by QGLPainter and it should not be necessary to explicitly create or manipulate them.
The render sequencer works by tracking instances of QGLRenderOrder objects in a queue. As the scene graph is traversed during a call to a top-level node's QGLSceneNode::draw() function, the sequencer adds one QGLRenderOrder to the queue for each unique combination of rendering attributes.
The top level scene graph node loops once for each unique combination - it does this in QGLSceneNode::draw() by calling nextInSequence(). At each iteration, a current QGLRenderOrder is maintained, and only nodes matching that order - as determined by QGLRenderOrder::operator==() - are rendered in that pass. Non-matching nodes are added to a queue in the order specified by QGLRenderOrder::operator<().
Once an iteration/pass of the scene graph is done, the next order is pulled from the front of the queue and the current QGLRenderOrder is set to it.
Since the rendering attributes at a node are a function both of that node, and attributes inherited from its parents, and since a given node may appear multiple times at different places in the scene, it can thus have different attributes and orders in each place. So there is no one-to-one mapping between nodes and attributes.
To deal with this, QGLRenderOrder mappings are discovered during rendering. There is no discovery pass. First, the initial QGLRenderOrder is lazily set when the first geometry is actually drawn to the GPU - latching in that order as the first current order. From that point, orders discovered that are distinct from the current one are skipped in this rendering pass - by returning false from renderInSequence() - and are instead added to the queue for rendering on a subsequent pass.
When the final pass has been made, renderInSequence() returns false to the top level QGLSceneNode, indicating that looping over passes is complete.
Member Function Documentation
QGLRenderSequencer::QGLRenderSequencer(QGLPainter * painter)
Construct a new QGLRenderSequencer for the painter.
void QGLRenderSequencer::applyState()
Applies the current rendering state to the painter for this sequencer.
See also beginState() and endState().
void QGLRenderSequencer::beginState(QGLSceneNode * node)
Marks the render state for the node as started for this rendering pass. Call this before rendering node, or any child nodes of node.
Once the rendering state is no longer valid, call endState().
To actually apply the effective state, as inherited from previous calls to beginState() call the applyState() function.
See also endState() and applyState().
Returns the current render order comparator. By default this is an instance of the base class QGLRenderOrderComparator.
See also setComparator().
void QGLRenderSequencer::endState(QGLSceneNode * node)
Marks the render state for the node as done for this rendering pass.
If a node has called beginState(), then this function must be called to maintain the rendering stack. If this function call is not matched by a previous beginState() call undefined behaviour may result. In debug mode it may assert.
See also beginState() and applyState().
bool QGLRenderSequencer::nextInSequence()
Returns true if there is a next rendering state in the queue; and if there is a new order will be pulled from the queue, and its rendering attributes - materials, effects and so on - will be applied to the painter for this sequencer. Returns false when no more rendering states are queued and scene is completely rendered.
bool QGLRenderSequencer::renderInSequence(QGLSceneNode * node)
Returns true, when this node should be rendered, in the order dictated by QGLRenderOrder objects generated by the current render order Comparator. The node must be non-NULL.
When this function returns false, indicating that rendering should be skipped for the current pass, a check is made to ensure that a state object for this nodes rendering attributes is queued up for a later pass.
To customize the ordering, reimplement QGLRenderOrder and QGLRenderOrderComparator; then set the custom Comparator onto the current painter using setcompare().
See also reset(), top(), and nextInSequence().
void QGLRenderSequencer::reset()
Reset this sequencer to start from the top of the scene graph again. After this call the top() function will return NULL, and any scene node passed to the renderInSequence() function will be treated as the top of the scene graph. Also effects and materials will be ignored until latched in - QGLPainter::draw() will call latch() to achieve this.
See also top().
void QGLRenderSequencer::setComparator(QGLRenderOrderComparator * comparator)
Sets the current render order comparator. This is only needed if a custom rendering order is to be created. The argument comparator must be non-null, or undefined behaviour will result.
Any existing current comparator is destroyed.
See also renderInSequence() and comparator().
void QGLRenderSequencer::setPainter(QGLPainter * painter)
Sets the render sequencer to operate on painter.
void QGLRenderSequencer::setTop(QGLSceneNode * top)
Sets the current top node of the rendering tree to top.
See also top().
QGLSceneNode * QGLRenderSequencer::top() const
Returns the current top node of the rendering tree, or NULL if the sequencer has been reset.
See also setTop().