Commit a356c66d authored by Jan Möbius's avatar Jan Möbius
Browse files

Fixed SceneGraph multipass and single pass rendering.

Previously the standard enter and leave functions had been active for picking too,
resulting in picking failiures when e.g. Blending was active.

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@8857 383ad7c9-94d9-4d36-a494-682f7c89f535
parent d8d7ee05
......@@ -870,13 +870,13 @@ void QtBaseViewer::drawScene_mono()
if (sceneGraphRoot_)
{
if (! renderPicking_ ) {
SceneGraph::DrawAction action(curDrawMode_, false);
SceneGraph::traverse(sceneGraphRoot_, action, *glstate_, curDrawMode_);
SceneGraph::DrawAction action(curDrawMode_, *glstate_ , false);
SceneGraph::traverse(sceneGraphRoot_, action);
if( blending_ )
{
SceneGraph::DrawAction action(curDrawMode_, true);
SceneGraph::traverse(sceneGraphRoot_, action, *glstate_, curDrawMode_);
SceneGraph::DrawAction action(curDrawMode_, *glstate_, true);
SceneGraph::traverse(sceneGraphRoot_, action);
}
} else {
......
......@@ -192,12 +192,17 @@ traverse( BaseNode* _node, Action& _action )
enter/leave functions of the action if they have been implemented.
This function traverses the scene graph multiple times if multipass
rendering is turned on. GLState holds attributes to control
render passes. Attention: Render passes are 1-indexed.
render passes. Attention: Render passes are 1-indexed.\n
!!! You should ot use this function directly. Use the traverse_multipass function
which controls the glstate too. This function will also manage the passes for you!!!
**/
template <class Action>
void
traverse_multipass ( BaseNode* _node, Action& _action, const unsigned int& _pass )
{
// Process node if it exists
if (_node) {
BaseNode::StatusMode status(_node->status());
......@@ -207,8 +212,9 @@ traverse_multipass ( BaseNode* _node, Action& _action, const unsigned int& _pass
if (status != BaseNode::HideSubtree) {
// Executes this nodes enter function (if available and active in multipass)
if ( _node->multipassStatusActive(_pass) )
if ( _node->multipassStatusActive(_pass) ) {
if_has_enter(_action, _node);
}
// If the node itself is hidden, don't call the action on it.
// Additionally check if rendering order is node first. otherwise, we will call it after the children.
......@@ -247,73 +253,6 @@ traverse_multipass ( BaseNode* _node, Action& _action, const unsigned int& _pass
} // if(node_)
}
//----------------------------------------------------------------------------
/** This is a meta action class that is used to wrap an action from the
traverse( BaseNode*, Action&, GLState&, unsigned int) into the
traverse( BaseNode*, Action&) function
**/
template <class Action>
class MetaAction
{
public:
MetaAction (Action & _action, GLState& _state, DrawModes::DrawMode _drawMode) :
action_(_action),
state_(_state),
drawMode_(_drawMode)
{
}
bool operator()(BaseNode* _node)
{
return action_(_node, state_);
}
void enter (BaseNode *_node)
{
if ( _node->drawMode() == DrawModes::DEFAULT )
_node->enter(state_, drawMode_);
else
_node->enter(state_, _node->drawMode());
}
void leave (BaseNode *_node)
{
if ( _node->drawMode() == DrawModes::DEFAULT )
_node->leave(state_, drawMode_);
else
_node->leave(state_, _node->drawMode());
}
private:
Action &action_;
GLState &state_;
DrawModes::DrawMode drawMode_;
};
//----------------------------------------------------------------------------
/** Traverse the scenegraph starting at the node \c _node and apply
the action \c action to each node. When arriving at a node, its
BaseNode::enter() function is called, then \c _action is applied
and the node's children are traversed. After that the
BaseNode::leave() method is called.
\see ACG::SceneGraph::BaseNode
**/
template <class Action>
void
traverse( BaseNode* _node,
Action& _action,
GLState& _state,
DrawModes::DrawMode _drawmode=DrawModes::DEFAULT)
{
MetaAction<Action> action (_action, _state, _drawmode);
traverse(_node, action);
}
//----------------------------------------------------------------------------
......@@ -339,8 +278,6 @@ traverse_multipass( BaseNode* _node,
GLState& _state,
DrawModes::DrawMode _drawmode=DrawModes::DEFAULT)
{
MetaAction<Action> action (_action, _state, _drawmode);
// Reset render pass counter
_state.reset_render_pass();
......@@ -351,7 +288,7 @@ traverse_multipass( BaseNode* _node,
for(unsigned int pass = BaseNode::PASS_1; pass <= (BaseNode::PASS_1 + max_passes); ++pass) {
// Traverse scenegraph
traverse_multipass (_node, action, pass);
traverse_multipass (_node, _action, pass);
// Increment render pass counter by 1
_state.next_render_pass();
}
......@@ -682,25 +619,44 @@ class DrawAction
public:
/// Constructor: draws the scenegraph using _drawMode
DrawAction(DrawModes::DrawMode _drawMode, bool _blending)
: drawMode_(_drawMode), blending_(_blending) {}
DrawAction(DrawModes::DrawMode _drawMode, GLState& _state, bool _blending) :
state_(_state),
drawMode_(_drawMode),
blending_(_blending) {}
bool operator()(BaseNode* _node, GLState& _state)
bool operator()( BaseNode* _node )
{
// draw only if Material status == DrawAction status
if(_state.blending() == blending_)
if(state_.blending() == blending_)
{
_node->setDirty (false);
if (_node->drawMode() == DrawModes::DEFAULT)
_node->draw(_state, drawMode_);
_node->draw(state_, drawMode_);
else
_node->draw(_state, _node->drawMode());
_node->draw(state_, _node->drawMode());
}
return true;
}
void enter(BaseNode* _node)
{
if (_node->drawMode() == DrawModes::DEFAULT)
_node->enter(state_, drawMode_);
else
_node->enter(state_, _node->drawMode());
}
void leave(BaseNode* _node)
{
if (_node->drawMode() == DrawModes::DEFAULT)
_node->leave(state_, drawMode_);
else
_node->leave(state_, _node->drawMode());
}
private:
GLState& state_;
DrawModes::DrawMode drawMode_;
bool blending_;
};
......@@ -775,16 +731,18 @@ class MouseEventAction
public:
MouseEventAction(QMouseEvent* _event) : event_(_event) {}
MouseEventAction(QMouseEvent* _event, GLState& _state) :
state_(_state),
event_(_event) {}
bool operator()(BaseNode* _node, GLState& _state)
bool operator()(BaseNode* _node )
{
_node->mouseEvent(_state, event_);
_node->mouseEvent(state_, event_);
return true;
}
private:
GLState& state_;
QMouseEvent* event_;
};
......
......@@ -474,23 +474,9 @@ bool scenegraphRegionPick( const unsigned int _examiner,
void traverse( ACG::SceneGraph::MouseEventAction &_action ) {
// Single pass action, as the mouse action will only update the graph.
// If its changed, it will be set to dirty and an automatic redraw is triggered.
ACG::SceneGraph::traverse(sceneGraphRootNode_, _action,viewerProperties().glState() );
ACG::SceneGraph::traverse(sceneGraphRootNode_, _action );
}
//Warning : Dont use template function as external static pointer for examiner widget is not resolved correctly!!
void traverse( const unsigned int _examiner, ACG::SceneGraph::MouseEventAction &_action ) {
if ( _examiner >= examiner_widgets_.size() ) {
std::cerr << "Wrong examiner id" << std::endl;
return;
}
// Single pass action, as the mouse action will only update the graph.
// If its changed, it will be set to dirty and an automatic redraw is triggered.
ACG::SceneGraph::traverse(sceneGraphRootNode_, _action,viewerProperties(_examiner).glState() );
}
const std::string pickMode () {
// No seperate draw modes available all should have the same so take first
return viewerProperties().pickMode();
......
......@@ -264,8 +264,6 @@ bool scenegraphRegionPick( const unsigned int _examiner,
DLLEXPORT
void traverse( ACG::SceneGraph::MouseEventAction &_action );
/// Execute Scenegraph traversal with action and a specified examiner
void traverse( const unsigned int _examiner, ACG::SceneGraph::MouseEventAction &_action );
/// Get the current Picking mode
DLLEXPORT
......
......@@ -604,12 +604,12 @@ void glViewer::drawScene_mono()
}
}
ACG::SceneGraph::DrawAction action( properties_.drawMode() , false);
ACG::SceneGraph::DrawAction action( properties_.drawMode(), *glstate_ , false);
ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, action, *glstate_, properties_.drawMode() );
if( blending_ )
{
ACG::SceneGraph::DrawAction action(properties_.drawMode(), true);
ACG::SceneGraph::DrawAction action(properties_.drawMode(), *glstate_, true);
ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, action, *glstate_, properties_.drawMode());
}
......
......@@ -348,7 +348,7 @@ void MovePlugin::slotMouseEvent(QMouseEvent* _event) {
}
// interaction
ACG::SceneGraph::MouseEventAction action(_event);
ACG::SceneGraph::MouseEventAction action(_event,PluginFunctions::viewerProperties().glState());
PluginFunctions::traverse(action);
if (_event->buttons() == Qt::LeftButton)
......
......@@ -298,6 +298,7 @@ void SelectionPlugin::componentSelection(QMouseEvent* _event) {
if ( PluginFunctions::getPickedObject(node_idx, object) ) {
if ( object->picked(node_idx) && object->dataType(DATA_TRIANGLE_MESH) ){
#include <../OpenFlipper/Plugin-Selection/SelectionPlugin.hh>
componentSelection(PluginFunctions::triMesh(object), target_idx);
}
......@@ -560,8 +561,8 @@ void SelectionPlugin::handleLassoSelection(QMouseEvent* _event, bool _volume) {
bool updateGL = state.updateGL ();
state.set_updateGL (false);
SelectVolumeAction action(&region, this);
ACG::SceneGraph::traverse (PluginFunctions::getRootNode(), action, state);
SelectVolumeAction action(&region, this, state);
ACG::SceneGraph::traverse (PluginFunctions::getRootNode(), action );
state.set_updateGL (updateGL);
}
......@@ -814,7 +815,7 @@ int SelectionPlugin::createMeshFromSelection( int _objectId ){
/// Traverse the scenegraph and call the selection function for nodes
bool SelectVolumeAction::operator()(BaseNode* _node, ACG::GLState& _state)
bool SelectVolumeAction::operator()(BaseNode* _node)
{
BaseObjectData *object = 0;
if (PluginFunctions::getPickedObject(_node->id (), object))
......@@ -823,17 +824,17 @@ bool SelectVolumeAction::operator()(BaseNode* _node, ACG::GLState& _state)
if ( object->dataType(DATA_TRIANGLE_MESH) ) {
TriMesh* m = PluginFunctions::triMesh(object);
selected = plugin_->volumeSelection (m, _state, region_);
selected = plugin_->volumeSelection (m, state_, region_);
} else if ( object->dataType(DATA_POLY_MESH) ) {
PolyMesh* m = PluginFunctions::polyMesh(object);
selected = plugin_->volumeSelection (m, _state, region_);
selected = plugin_->volumeSelection (m, state_, region_);
#ifdef ENABLE_TSPLINEMESH_SUPPORT
} else if ( object->dataType(DATA_TSPLINE_MESH) ) {
TSplineMesh* m = PluginFunctions::tsplineMesh(object);
selected = plugin_->volumeSelection (m, _state, region_);
selected = plugin_->volumeSelection (m, state_, region_);
#endif
}
......
......@@ -761,17 +761,17 @@ class SelectVolumeAction
{
public:
SelectVolumeAction(QRegion *_region, SelectionPlugin *_plugin) :
region_(_region), plugin_(_plugin) {}
SelectVolumeAction(QRegion *_region, SelectionPlugin *_plugin,ACG::GLState& _state) :
state_(_state),region_(_region), plugin_(_plugin) {}
void enter (BaseNode* /*_node*/) {};
void leave (BaseNode* /*_node*/) {};
bool operator()(BaseNode* _node, ACG::GLState& _state);
bool operator()(BaseNode* _node );
private:
ACG::GLState& state_;
QRegion *region_;
SelectionPlugin *plugin_;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment