Commit bb5e4014 authored by Hans-Christian Ebke's avatar Hans-Christian Ebke
Browse files

On behalf of Patrick Schmidt: Proper line node picking.


git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@20770 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 67b2a548
......@@ -67,6 +67,7 @@ LineNode::LineNode( LineMode _mode,
BaseNode* _parent,
std::string _name ) :
MaterialNode(_parent, _name, MaterialNode::BaseColor | MaterialNode::LineWidth),
picking_line_width_(NAN),
line_mode_(_mode),
draw_always_on_top (false),
prev_depth_(GL_LESS),
......@@ -367,6 +368,88 @@ leave(GLState& _state , const DrawModes::DrawMode& _drawMode)
//----------------------------------------------------------------------------
void LineNode::pick(GLState& _state , PickTarget _target)
{
if (n_points() == 0)
return;
// Bind the vertex array
ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
ACG::GLState::vertexPointer( &(points_)[0] );
ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
const unsigned int n_edges = n_points() - 1;
switch (_target)
{
case PICK_EDGE:
{
_state.pick_set_maximum (n_edges);
pick_edges(_state, 0);
break;
}
case PICK_ANYTHING:
{
_state.pick_set_maximum (n_edges);
pick_edges(_state, 0);
break;
}
default:
break;
}
//Disable the vertex array
ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
}
//----------------------------------------------------------------------------
void LineNode::pick_edges(GLState& _state, unsigned int _offset)
{
// Check if we have any edges to draw (% 0 causes division by zero on windows)
if (n_points() < 2)
return;
const float line_width_old = _state.line_width();
_state.set_line_width(picking_line_width());
_state.pick_set_name (0);
glDepthRange(0.0, 0.99);
if (line_mode_ == PolygonMode)
{
const unsigned int n_edges = n_points() - 1;
for (unsigned int i = 0; i < n_edges; ++i)
{
_state.pick_set_name(i + _offset);
glBegin(GL_LINES);
glArrayElement(i);
glArrayElement(i + 1);
glEnd();
}
}
else if (line_mode_ == LineSegmentsMode)
{
const unsigned int n_edges = n_points() / 2;
for (unsigned int i = 0; i < n_edges; ++i)
{
_state.pick_set_name(i + _offset);
glBegin(GL_LINES);
glArrayElement(2*i);
glArrayElement(2*i + 1);
glEnd();
}
}
glDepthRange(0.0, 1.0);
_state.set_line_width(line_width_old);
}
//----------------------------------------------------------------------------
void LineNode::createVBO()
{
if (!updateVBO_)
......
......@@ -132,9 +132,12 @@ public:
/// reset depth function to what it was before enter()
void leave(GLState& _state, const DrawModes::DrawMode& _drawMode);
/// Draw the line using the GL picking name stack
void pick(GLState& _state , PickTarget _target);
/// reserve mem for _n lines
void reserve_lines(unsigned int _n) { points_.reserve(2*_n); }
/// reserve mem for _n points
void reserve_points(unsigned int _n) { points_.reserve(_n); }
......@@ -162,6 +165,14 @@ public:
/// add color 4f (only for LineMode == LineSegmentsMode)
void add_color(const Color4f _c);
/// set line width used by the picking renderer
void set_picking_line_width(float _width) { picking_line_width_ = _width; }
/// get line width used by the picking renderer. Defaults to line_width().
float picking_line_width() const
{
return (picking_line_width_ != NAN) ? picking_line_width_ : line_width();
}
/// number of points
size_t n_points() const { return points_.size(); }
......@@ -200,9 +211,17 @@ public:
void getRenderObjects(IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const ACG::SceneGraph::Material* _mat);
protected:
void pick_vertices(GLState& _state);
void pick_edges (GLState& _state, unsigned int _offset);
/// creates the vbo only if update was requested
void createVBO();
/// Line width used by the picking renderer. If this is not set (i.e. NAN),
/// line_width() is used instead.
float picking_line_width_;
PointVector points_;
ColorVector colors_;
Color4fVector colors4f_;
......
Markdown is supported
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