Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PolyLineCollectionNodeT.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS PolyLineNodeT - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #define ACG_POLYLINECOLLECTIONNODET_C
60 
61 //== INCLUDES =================================================================
62 
63 
64 
65 #include "PolyLineCollectionNodeT.hh"
66 #include <ACG/GL/gl.hh>
67 #include <ACG/Utils/VSToolsT.hh>
68 #include <vector>
69 #include <OpenMesh/Core/Utils/vector_cast.hh>
70 
71 #ifdef _WIN32
72 #include <cstdint>
73 #else
74 #include <stdint.h>
75 #endif
76 
77 //== NAMESPACES ===============================================================
78 
79 namespace ACG {
80 namespace SceneGraph {
81 
82 //== IMPLEMENTATION ==========================================================
83 
85 template <class PolyLineCollection>
87  BaseNode(_parent, _name),
88  polyline_collection_(_pl),
89  vbo_(0),
90  updateVBO_(true),
91  sphere_(0),
92  total_vertex_count_(0)
93 
94 {
95  // Initial default draw mode
97 }
98 
99 //----------------------------------------------------------------------------
100 
101 template <class PolyLineCollection>
102 void
104 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
105 {
106  for(typename PolyLineCollection::iterator it = polyline_collection_.iter(); it; ++it){
107  typename PolyLineCollection::PolyLine* polyline = *it;
108 
109  if(polyline){
110  for (unsigned int i=0; i< polyline->n_vertices(); ++i)
111  {
112  _bbMin.minimize(polyline->point(i));
113  _bbMax.maximize(polyline->point(i));
114  }
115  }
116  }
117 }
118 
119 
120 //----------------------------------------------------------------------------
121 
122 
123 template <class PolyLineCollection>
127 {
129 }
130 
131 
132 //----------------------------------------------------------------------------
133 
134 
135 template <class PolyLineCollection>
136 void
138 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
139 {
140  // Block if we do not have any polylines
141  if ( polyline_collection_.n_polylines() == 0 )
142  return;
143 
144  // Update the vbo only if required.
145  if ( updateVBO_ )
146  updateVBO();
147 
148  ACG::GLState::disable(GL_LIGHTING);
149  ACG::GLState::disable(GL_TEXTURE_2D);
150 
151  // Bind the vertex array
152  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, vbo_);
153  vertexDecl_.activateFixedFunction();
154 
155  ACG::Vec4f color = _state.ambient_color() + _state.diffuse_color();
156 
157  // draw points
158  if (_drawMode & DrawModes::POINTS)
159  {
160  _state.set_color( color );
161 
162  // Draw all vertices (don't care about selection)
163  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
164  typename PolyLineCollection::PolyLine* polyline = *it;
165 
166  if(polyline && polyline->n_vertices() > 0){
167  glDrawArrays(GL_POINTS, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
168  }
169  }
170 
171 
172  float point_size_old = _state.point_size();
173  _state.set_point_size(point_size_old+4.0f);
174 
175  _state.set_color( Vec4f(1.0f,0.0f,0.0f,1.0f) );
176 
177  // Draw selected polylines
178  for(typename PolyLineCollection::index_iterator it = polyline_collection_.selected_iter(); it; ++it){
179  typename PolyLineCollection::PolyLine* polyline = *it;
180 
181  if(polyline && polyline->n_vertices() > 0){
182  glDrawArrays(GL_POINTS, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
183  }
184  }
185 
186  _state.set_point_size(point_size_old);
187 
188  }
189 
190  // draw line segments
191  if (_drawMode & DrawModes::WIREFRAME) {
192 
193  _state.set_color( color );
194 
195  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
196  typename PolyLineCollection::PolyLine* polyline = *it;
197 
198  if(polyline && polyline->n_vertices() > 0){
199  if ( polyline->is_closed() ){
200  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second);
201 
202  }else{
203  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
204  }
205  }
206  }
207 
208  float line_width_old = _state.line_width();
209  _state.set_color(Vec4f(1, 0, 0, 1));
210  _state.set_line_width(2 * line_width_old);
211 
212  for(typename PolyLineCollection::index_iterator it = polyline_collection_.selected_iter(); it; ++it){
213  typename PolyLineCollection::PolyLine* polyline = *it;
214 
215  if(polyline && polyline->n_vertices() > 0){
216  if ( polyline->is_closed() ){
217  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second);
218  }else{
219  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
220  }
221 
222  //offset += polyline->n_vertices() + 1;
223  }
224  }
225 
226  // Draw selected edges
227  std::vector<int> selected_indices;
228  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
229  typename PolyLineCollection::PolyLine* polyline = *it;
230 
231 
232  if(polyline){
233  int offset = offsets_[it.idx()].first;
234  for(size_t i = 0; i < polyline->n_vertices(); ++i){
235  if(!polyline->is_closed() && i == polyline->n_vertices() - 1){
236  continue;
237  }
238  if(polyline->edge_selected(i)){
239  selected_indices.push_back(offset + i);
240  selected_indices.push_back(offset + i + 1);
241  }
242  }
243  }
244  }
245 
246  if(selected_indices.size() > 0){
247  glDrawElements(GL_LINES, selected_indices.size(), GL_UNSIGNED_INT, selected_indices.data());
248  }
249 
250  _state.set_line_width(line_width_old);
251 
252  }
253 
254  vertexDecl_.deactivateFixedFunction();
255  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
256 }
257 
258 //----------------------------------------------------------------------------
259 
260 
261 template <class PolyLineCollection>
262 void
264 pick(GLState& _state, PickTarget _target)
265 {
266 
267  if ( polyline_collection_.n_polylines() == 0 )
268  return;
269 
270  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, vbo_);
271  vertexDecl_.activateFixedFunction();;
272 
273  _state.pick_set_maximum(2);
274 
275  glDepthRange(0.0, 0.999999);
276 
277 
278  float point_size_old = _state.point_size();
279  glPointSize(point_size_old+3.0f);
280  if ((drawMode() & DrawModes::POINTS) && (_target == PICK_VERTEX || _target == PICK_ANYTHING))
281  {
282  _state.pick_set_name(0);
283 
284  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
285  typename PolyLineCollection::PolyLine* polyline = *it;
286 
287  if(polyline && polyline->n_vertices() > 0){
288  glDrawArrays(GL_POINTS, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
289  }
290  }
291  }
292  glPointSize(point_size_old);
293 
294  float line_width_old = _state.line_width();
295  glLineWidth(line_width_old+3.0f);
296  // draw line segments
297  if ((drawMode() & DrawModes::WIREFRAME) && (_target == PICK_EDGE || _target == PICK_ANYTHING)) {
298 
299  _state.pick_set_name(1);
300 
301  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
302  typename PolyLineCollection::PolyLine* polyline = *it;
303 
304  if(polyline && polyline->n_vertices() > 0){
305  if ( polyline->is_closed() ){
306  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second);
307 
308  }else{
309  glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
310  }
311  }
312  }
313  }
314  glLineWidth(line_width_old);
315  glDepthRange(0.0, 1.0);
316 
317  vertexDecl_.deactivateFixedFunction();
318  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
319 }
320 
321 //----------------------------------------------------------------------------
322 
323 template <class PolyLineCollection>
324 void
327 
328  bool lines_did_change = false;
329 
330  if( offsets_.size() != polyline_collection_.n_polylines() ){
331  offsets_.resize(polyline_collection_.n_polylines());
332  lines_did_change = true;
333  }
334 
335  int offset = 0;
336  total_vertex_count_ = 0;
337  for(typename PolyLineCollection::iterator it = polyline_collection_.iter(); it; ++it){
338  std::pair<size_t, size_t> current_offset;
339  current_offset.first = offset;
340  if(*it){
341  current_offset.second = it->n_vertices() + 1;
342  }else{
343  current_offset.second = 0;
344  }
345 
346  if(current_offset != offsets_[it.idx()]){
347  lines_did_change = true;
348  }
349 
350  offsets_[it.idx()] = current_offset;
351  total_vertex_count_ += current_offset.second;
352 
353  offset += current_offset.second;
354  }
355 
356  if(lines_did_change){
357 
358  // Update the vertex declaration based on the input data:
359  vertexDecl_.clear();
360 
361  // We always output vertex positions
362  vertexDecl_.addElement(GL_FLOAT, 3, ACG::VERTEX_USAGE_POSITION);
363 
364  // create vbo if it does not exist
365  if (!vbo_)
366  GLState::genBuffersARB(1, &vbo_);
367 
368  // size in bytes of vbo, create additional vertex for closed loop indexing
369  unsigned int bufferSize = vertexDecl_.getVertexStride() * offset;
370 
371  // Create the required array
372  char* vboData_ = new char[bufferSize];
373 
374  for(typename PolyLineCollection::iterator it = polyline_collection_.iter(); it; ++it){
375  typename PolyLineCollection::PolyLine* polyline = *it;
376 
377  if(polyline && polyline->n_vertices() > 0){
378  size_t offset = offsets_[it.idx()].first;
379  for (unsigned int i = 0 ; i < polyline->n_vertices(); ++i) {
380  writeVertex(polyline, i, vboData_ + (offset + i) * vertexDecl_.getVertexStride());
381  }
382 
383  // First point is added to the end for a closed loop
384  writeVertex(polyline, 0, vboData_ + (offset + polyline->n_vertices()) * vertexDecl_.getVertexStride());
385  }
386  }
387 
388  // Move data to the buffer in gpu memory
389  GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_);
390  GLState::bufferDataARB(GL_ARRAY_BUFFER_ARB, bufferSize , vboData_ , GL_STATIC_DRAW_ARB);
391  GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
392 
393  // Remove the local storage
394  delete[] vboData_;
395  }
396 
397  // Update done.
398  updateVBO_ = false;
399 }
400 
401 
402 //----------------------------------------------------------------------------
403 
404 template <class PolyLineCollection>
405 void
407 writeVertex(typename PolyLineCollection::PolyLine* _polyline, unsigned int _vertex, void* _dst) {
408 
409  ACG::Vec3f& pos = *((ACG::Vec3f*)_dst);
410 
411  pos = OpenMesh::vector_cast<ACG::Vec3f>(_polyline->point(_vertex));
412 }
413 
414 //----------------------------------------------------------------------------
415 
416 template <class PolyLineCollection>
417 void
420 
421  // Block if we do not have any vertices
422  if ( polyline_collection_.n_polylines() == 0 )
423  return;
424 
425  // init base render object
427 
428  _state.enable(GL_COLOR_MATERIAL);
429  _state.enable(GL_LIGHTING);
430  ro.initFromState(&_state);
431 
432  ro.setMaterial(_mat);
433 
434  // draw after scene-meshes
435  ro.priority = 1;
436 
437  // Update the vbo only if required.
438  if ( updateVBO_ )
439  updateVBO();
440 
441  // Set to the right vbo
442  ro.vertexBuffer = vbo_;
443 
444  // decl must be static or member, renderer does not make a copy
445  ro.vertexDecl = &vertexDecl_;
446 
447  // Set style
448  ro.debugName = "PolyLineCollection";
449  ro.blending = false;
450  ro.depthTest = true;
451 
452  // Default color
453  ACG::Vec4f defaultColor = _state.ambient_color() + _state.diffuse_color();
454  ACG::Vec4f selectionColor = ACG::Vec4f(1.0,0.0,0.0,1.0);
455 
456  // Viewport size
457  ACG::Vec2f screenSize(float(_state.viewport_width()), float(_state.viewport_height()));
458 
459  for (size_t i = 0; i < _drawMode.getNumLayers(); ++i) {
460  ACG::SceneGraph::Material localMaterial = *_mat;
461 
462  const ACG::SceneGraph::DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
463 
464  ro.setupShaderGenFromDrawmode(props);
465  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
466 
467  //---------------------------------------------------
468  // No lighting!
469  // Therefore we need some emissive color
470  //---------------------------------------------------
471  localMaterial.baseColor(defaultColor);
472  ro.setMaterial(&localMaterial);
473 
474 
475  if(props->primitive() == ACG::SceneGraph::DrawModes::PRIMITIVE_POINT){
476  // Render all vertices which are selected via an index buffer
477  ro.debugName = "polyline.Points.selected";
478  localMaterial.baseColor(selectionColor);
479  ro.setMaterial(&localMaterial);
480 
481  // Point Size geometry shader
482  ro.setupPointRendering(_mat->pointSize(), screenSize);
483 
484  // Render all vertices (ignore selection here!)
485  ro.debugName = "polylinecollection.Points";
486  localMaterial.baseColor(defaultColor);
487  ro.setMaterial(&localMaterial);
488 
489 
490  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
491  if(*it && (*it)->n_vertices() > 0){
492  ro.glDrawArrays(GL_POINTS, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
493 
494  // Point Size geometry shader
495  ro.setupPointRendering(_mat->pointSize(), screenSize);
496 
497  // apply user settings
498  applyRenderObjectSettings(props->primitive(), &ro);
499 
500  _renderer->addRenderObject(&ro);
501  }
502  }
503 
504  }else if(props->primitive() == ACG::SceneGraph::DrawModes::PRIMITIVE_WIREFRAME){
505  // Render all edges which are selected via an index buffer
506  ro.debugName = "polyline.Wireframe.selected";
507  localMaterial.baseColor(selectionColor);
508  ro.setMaterial(&localMaterial);
509 
510  // Line Width geometry shader
511  ro.setupLineRendering(_state.line_width(), screenSize);
512 
513  ro.debugName = "polylinecollection.Wireframe";
514  localMaterial.baseColor(defaultColor);
515  ro.setMaterial(&localMaterial);
516  // The first point is mapped to an additional last point in buffer, so we can
517  // just Render one point more to get a closed line
518 
519  //int offset = 0;
520  for(typename PolyLineCollection::index_iterator it = polyline_collection_.visible_iter(); it; ++it){
521  if(*it && (*it)->n_vertices() > 0){
522  if ( (*it)->is_closed() ){
523  ro.glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second);
524  }else{
525  ro.glDrawArrays(GL_LINE_STRIP, offsets_[it.idx()].first, offsets_[it.idx()].second-1);
526  }
527 
528  //offset += (*it)->n_vertices() + 1;
529 
530  // Line Width geometry shader
531  ro.setupLineRendering(_state.line_width(), screenSize);
532 
533  // apply user settings
534  applyRenderObjectSettings(props->primitive(), &ro);
535 
536  _renderer->addRenderObject(&ro);
537  }
538 
539 
540  }
541 
542 
543  }
544  }
545 
546 }
547 
548 //=============================================================================
549 } // namespace SceneGraph
550 } // namespace ACG
551 //=============================================================================
void getRenderObjects(ACG::IRenderer *_renderer, ACG::GLState &_state, const ACG::SceneGraph::DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat)
Add the objects to the given renderer.
void pick(GLState &_state, PickTarget _target)
picking
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1048
int viewport_height() const
get viewport height
Definition: MeshNode2T.cc:827
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: MeshNode2T.cc:215
const Vec4f & diffuse_color() const
get diffuse color
Definition: MeshNode2T.cc:939
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
void draw(GLState &, const DrawModes::DrawMode &_drawMode)
draw lines and normals
static void bufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2138
const Vec4f & diffuse_color() const
get diffuse color
Definition: GLState.hh:939
Interface class between scenegraph and renderer.
Definition: MeshNode2T.cc:105
static void genBuffersARB(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2130
picks edges (may not be implemented for all nodes)
Definition: BaseNode.hh:106
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition: DrawModes.cc:541
const Vec4f & ambient_color() const
get ambient color
Definition: MeshNode2T.cc:934
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void enable(GLenum _cap)
replaces glEnable, but supports locking
const Vec4f & ambient_color() const
get ambient color
Definition: GLState.hh:934
static void disable(GLenum _cap)
replaces glDisable, but supports locking
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
Definition: MeshNode2T.cc:461
void writeVertex(typename PolyLineCollection::PolyLine *_polyline, unsigned int _vertex, void *_dst)
Write vertex data for rendering to a buffer.
void updateVBO()
Trigger an update of the vbo.
float line_width() const
get line width
Definition: GLState.hh:978
int priority
Priority to allow sorting of objects.
Definition: MeshNode2T.cc:123
float point_size() const
get point size
Definition: GLState.hh:973
Point & point(unsigned int _i)
Get a point of the polyline.
Definition: PolyLineT.hh:148
int viewport_width() const
get viewport width
Definition: MeshNode2T.cc:825
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:86
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Definition: MeshNode2T.cc:169
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
Definition: GLState.hh:576
PolyLineCollectionNodeT(PolyLineCollection &_pl, BaseNode *_parent=0, std::string _name="<PolyLineCollectionNode>")
Constructor.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
bool is_closed() const
Check if the polyline is marked as closed.
Definition: PolyLineT.hh:113
void pointSize(float _sz)
set point size (default: 1.0)
Definition: MeshNode2T.cc:211
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
DrawModes::DrawMode availableDrawModes() const
return available draw modes
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
void set_point_size(float _f)
set point size
Definition: GLState.cc:775
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
void set_color(const Vec4f &_col)
set color
Definition: GLState.cc:690
size_t n_vertices() const
Get number of vertices.
Definition: PolyLineT.hh:122
float line_width() const
get line width
Definition: MeshNode2T.cc:978
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1058
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
size_t getNumLayers() const
returns the layer count
Definition: DrawModes.cc:537
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: MeshNode2T.cc:232
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: MeshNode2T.cc:183
void set_line_width(float _f)
set line width
Definition: GLState.cc:790
void baseColor(const Vec4f &_c)
set the base color
Definition: MeshNode2T.cc:167
picks verices (may not be implemented for all nodes)
Definition: BaseNode.hh:108