Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MeshNode2T.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openflipper.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenFlipper. *
9  * *
10  * OpenFlipper is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenFlipper is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenFlipper. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36  * *
37  * $Revision: 14990 $ *
38  * $Author: moebius $ *
39  * $Date: 2012-07-13 08:33:32 +0200 (Fr, 13 Jul 2012) $ *
40  * *
41 \*===========================================================================*/
42 
43 
44 
45 
46 //=============================================================================
47 //
48 // CLASS MeshNodeT - IMPLEMENTATION
49 //
50 //=============================================================================
51 
52 #define ACG_MESHNODE_C
53 
54 #include <ACG/Geometry/GPUCacheOptimizer.hh>
55 #include <ACG/GL/DrawMesh.hh>
56 
57 //== NAMESPACES ===============================================================
58 
59 
60 namespace ACG {
61 namespace SceneGraph {
62 
63 
64 //== INCLUDES =================================================================
65 
66 
67 #include "MeshNode2T.hh"
68 
69 template<class Mesh>
71 MeshNodeT(Mesh& _mesh,
72  BaseNode* _parent,
73  std::string _name ):
74  BaseNode(_parent, _name),
75  mesh_(_mesh),
76  drawMesh_(0),
77  enableNormals_(true),
78  enableColors_(true),
79  enabled_arrays_(0),
80  updateVertexPicking_(true),
81  vertexPickingBaseIndex_(0),
82  updateEdgePicking_(true),
83  edgePickingBaseIndex_(0),
84  updateFacePicking_(true),
85  facePickingBaseIndex_(0),
86  updateAnyPicking_(true),
87  anyPickingBaseIndex_(0),
88  perFaceTextureIndexAvailable_(false),
89  perFaceTextureCoordsAvailable_(false),
90  textureMap_(0)
91 {
92 
94  if ( ! checkExtensionSupported("GL_ARB_vertex_buffer_object") ) {
95  std::cerr << "Error! Vertex buffer objects are not supported! The meshNode will not work without them!" << std::endl;
96  }
97 
98  drawMesh_ = new DrawMeshT<Mesh>(mesh_);
99 
100 }
102 template<class Mesh>
105 {
106  // Delete all allocated buffers
107  delete drawMesh_;
108 }
110 template<class Mesh>
115 
116  // We can always render points and a wireframe.
117  drawModes |= DrawModes::POINTS;
118  drawModes |= DrawModes::HIDDENLINE;
119  drawModes |= DrawModes::WIREFRAME;
120  drawModes |= DrawModes::HALFEDGES;
121 
122  if (mesh_.has_vertex_normals())
123  {
127  }
128 
129  if (mesh_.has_face_normals())
130  drawModes |= DrawModes::SOLID_FLAT_SHADED;
132  if (mesh_.has_halfedge_normals())
134 
135  if (mesh_.has_vertex_colors())
136  {
140  if (mesh_.has_vertex_normals())
142  }
144  if(mesh_.has_edge_colors())
145  {
146  drawModes |= DrawModes::EDGES_COLORED;
147  }
149  if(mesh_.has_halfedge_colors())
150  {
152  }
153 
154  if (mesh_.has_face_colors()) {
156 
157  if( mesh_.has_face_normals() )
160  if( mesh().has_vertex_normals() )
162  }
163 
164  if ( mesh_.has_vertex_texcoords2D() ) {
166 
167  if (mesh_.has_vertex_normals())
169  }
170 
171  if ( perFaceTextureCoordsAvailable_ ) {
173 
174  if (mesh_.has_face_normals())
176  }
177 
178  return drawModes;
179 }
181 template<class Mesh>
182 void
184 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) {
185  _bbMin.minimize(bbMin_);
186  _bbMax.maximize(bbMax_);
187 }
189 template<class Mesh>
190 void
192 draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
193 /*
194  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) ||
195  ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED) ||
196  ( _drawMode & DrawModes::SOLID_TEXTURED) ||
197  ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE))
198  {
199  drawMesh_->setFlatShading();
200  }
201  else
202  drawMesh_->setSmoothShading();
203 
204 
205  if ( (_drawMode & DrawModes::SOLID_FACES_COLORED ||
206  _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED))
207  {
208  drawMesh_->usePerFaceColors();
209  }
210  else
211  drawMesh_->usePerVertexColors();
212 */
213 
214  GLenum prev_depth = _state.depthFunc();
215 
216  unsigned int arrays = NONE;
217 
218  glPushAttrib(GL_ENABLE_BIT);
221  GLuint lastBuffer = ACG::GLState::getBoundTextureBuffer();
222  GLenum lastTarget = ACG::GLState::getBoundTextureTarget();
224  // Unbind to avoid painting textures on non textured primitives
225  ACG::GLState::bindTexture(lastTarget,0);
228  if ( (_drawMode & DrawModes::POINTS) || (_drawMode & DrawModes::POINTS_COLORED) || (_drawMode & DrawModes::POINTS_SHADED ) ) {
229 
231 
232  if ( _drawMode & DrawModes::POINTS_SHADED ) {
233  ACG::GLState::enable(GL_LIGHTING);
234  } else
235  ACG::GLState::disable(GL_LIGHTING);
236 
237  // Use Colors in this mode if allowed
238  if ( enableColors_ && (_drawMode & DrawModes::POINTS_COLORED) )
239  {
240  drawMesh_->usePerVertexColors();
242  // If we have colors and lighting with normals, we have to use colormaterial
243  if ( enableNormals_ && (_drawMode & DrawModes::POINTS_SHADED ) )
244  ACG::GLState::enable(GL_COLOR_MATERIAL);
245  else
246  ACG::GLState::disable(GL_COLOR_MATERIAL);
247  }
248  else
249  drawMesh_->disableColors();
250 
251  // Bring the arrays online
252 // enable_arrays(arrays);
253 
254  // Draw vertices
255  draw_vertices();
256  }
257 
258 
260  if (_drawMode & DrawModes::WIREFRAME)
261  {
262 // enable_arrays( VERTEX_ARRAY | LINE_INDEX_ARRAY );
263  ACG::GLState::disable(GL_LIGHTING);
266  drawMesh_->disableColors();
268  draw_lines();
269  }
270 
271  if (_drawMode & DrawModes::HIDDENLINE)
272  {
273 // enable_arrays(VERTEX_ARRAY);
274 
275  // First:
276  // Render all faces in background color to initialize z-buffer
277  Vec4f clear_color = _state.clear_color();
278  Vec4f base_color = _state.base_color();
279  clear_color[3] = 1.0;
280 
281  ACG::GLState::disable(GL_LIGHTING);
282  ACG::GLState::shadeModel(GL_FLAT);
283  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
284  _state.set_base_color(clear_color);
286 // drawMesh_->SetFlatShading();
287  drawMesh_->disableColors();
288 
289  ACG::GLState::depthRange(0.01, 1.0);
290  draw_faces();
292 
293  // Second
294  // Render the lines. All lines not on the front will be skipped in z-test
295 // enable_arrays(VERTEX_ARRAY|LINE_INDEX_ARRAY);
297  _state.set_base_color(base_color);
298  draw_lines();
299 
300  //restore depth buffer comparison function for the next draw calls inside this function
301  ACG::GLState::depthFunc(prev_depth);
302  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
303  }
306  if (_drawMode & DrawModes::EDGES_COLORED)
307  {
308  enable_arrays( PER_EDGE_VERTEX_ARRAY | PER_EDGE_COLOR_ARRAY );
309  ACG::GLState::disable(GL_LIGHTING);
310  ACG::GLState::shadeModel(GL_FLAT);
311  draw_lines();
312  }
314  if (_drawMode & DrawModes::HALFEDGES)
315  {
316  enable_arrays( PER_HALFEDGE_VERTEX_ARRAY);
317  ACG::GLState::disable(GL_LIGHTING);
319  draw_halfedges();
320  }
321 
322  if (_drawMode & DrawModes::HALFEDGES_COLORED)
323  {
324  enable_arrays( PER_HALFEDGE_VERTEX_ARRAY | PER_HALFEDGE_COLOR_ARRAY );
325  ACG::GLState::disable(GL_LIGHTING);
326  ACG::GLState::shadeModel(GL_FLAT);
327  draw_halfedges();
328  }
330  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors() )
331  {
332  ACG::GLState::disable(GL_LIGHTING);
334  ACG::GLState::depthRange(0.01, 1.0);
335 
336  drawMesh_->usePerVertexColors();
337 
338  draw_faces();
339  ACG::GLState::depthRange(0.0, 1.0);
340  }
341 
342  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED_SHADED ) && mesh_.has_vertex_colors() && mesh_.has_vertex_normals() )
343  {
344  ACG::GLState::enable(GL_LIGHTING);
346  ACG::GLState::depthRange(0.01, 1.0);
347  if ( enableNormals_ ) {
348  ACG::GLState::enable(GL_COLOR_MATERIAL);
349  } else {
350  ACG::GLState::disable(GL_COLOR_MATERIAL);
351  }
352 
353  drawMesh_->usePerVertexColors();
354 
355  draw_faces();
357  }
359  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
360  {
361  ACG::GLState::enable(GL_LIGHTING);
363  ACG::GLState::depthRange(0.01, 1.0);
365  drawMesh_->setFlatShading();
366  drawMesh_->disableColors();
368  draw_faces();
370  }
371 
372 
373  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals() )
374  {
375  ACG::GLState::enable(GL_LIGHTING);
376  ACG::GLState::shadeModel(GL_SMOOTH);
377  ACG::GLState::depthRange(0.01, 1.0);
379  drawMesh_->usePerVertexNormals();
380  drawMesh_->setSmoothShading();
381  drawMesh_->disableColors();
382  draw_faces();
383  ACG::GLState::depthRange(0.0, 1.0);
384  }
385 
386  if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
387  {
389  // if ( parent() != 0 ) {
390  // if ( parent()->className() == "ShaderNode" ) {
391  //
392  // ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
393  //
394  // GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
395  //
396  // // Enable own Phong shader
397  // program->use();
398 // enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY );
399  ACG::GLState::disable(GL_LIGHTING);
402 
403  drawMesh_->usePerVertexNormals();
404  drawMesh_->setSmoothShading();
405  drawMesh_->disableColors();
407  draw_faces();
409 
410  //disable own Phong shader
411  // program->disable();
412  // }
413  // }
414  }
415 
416 
417  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED ) && mesh_.has_face_colors() && mesh_.n_faces() > 0)
418  {
419  Vec4f base_color_backup = _state.base_color();
420 
421  ACG::GLState::disable(GL_LIGHTING);
423  ACG::GLState::depthRange(0.01, 1.0);
424 // enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY);
425 
426  drawMesh_->usePerFaceColors();
428  draw_faces();
430 
431  _state.set_base_color(base_color_backup);
432  }
433 
434  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_SMOOTH_SHADED ) && mesh_.has_face_colors() && mesh_.has_vertex_normals() && mesh_.n_faces() > 0)
435  {
436  Vec4f base_color_backup = _state.base_color();
438  ACG::GLState::enable(GL_LIGHTING);
439  ACG::GLState::shadeModel(GL_SMOOTH);
441 
442  drawMesh_->setSmoothShading();
443  drawMesh_->usePerVertexNormals();
444  drawMesh_->usePerFaceColors();
446  draw_faces();
447  ACG::GLState::depthRange(0.0, 1.0);
449  _state.set_base_color(base_color_backup);
450  }
452  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED_FEATURES ) && mesh_.has_halfedge_normals() && mesh_.n_faces() > 0)
453  {
454  ACG::GLState::enable(GL_LIGHTING);
455  ACG::GLState::shadeModel(GL_SMOOTH);
457 
458  drawMesh_->disableColors();
459  drawMesh_->setSmoothShading();
460  drawMesh_->usePerHalfedgeNormals();
462  draw_faces();
463 
465  }
466 
467  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals() && mesh_.n_faces() > 0 )
468  {
469  Vec4f base_color_backup = _state.base_color();
470  ACG::GLState::enable(GL_LIGHTING);
471 
473  ACG::GLState::depthRange(0.01, 1.0);
474 // enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY | PER_FACE_NORMAL_ARRAY );
475 
476  drawMesh_->setFlatShading();
477  drawMesh_->usePerFaceColors();
478 
479  draw_faces();
481 
482  _state.set_base_color(base_color_backup);
483  }
484 
485  // Rebind the previous texture
486  ACG::GLState::bindTexture(lastTarget,lastBuffer);
487 
488  if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
489  {
491 // enable_arrays(VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY );
492  ACG::GLState::enable(GL_TEXTURE_2D);
493  ACG::GLState::disable(GL_LIGHTING);
494  ACG::GLState::shadeModel(GL_FLAT);
495  ACG::GLState::depthRange(0.01, 1.0);
496 
497  drawMesh_->disableColors();
498  drawMesh_->usePerVertexTexcoords();
499 
500  draw_faces();
501  ACG::GLState::depthRange(0.0, 1.0);
502  ACG::GLState::disable(GL_TEXTURE_2D);
503  }
504 
505  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
506  {
507 // enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY);
508  ACG::GLState::enable(GL_TEXTURE_2D);
509  ACG::GLState::enable(GL_LIGHTING);
510  ACG::GLState::shadeModel(GL_SMOOTH);
511  ACG::GLState::depthRange(0.01, 1.0);
512 
513  drawMesh_->setSmoothShading();
514  drawMesh_->disableColors();
515  drawMesh_->usePerVertexTexcoords();
516 
517  draw_faces();
519  ACG::GLState::disable(GL_TEXTURE_2D);
520  }
521 
522 
523  // Textured by using coordinates stored in halfedges ... arrays generated by stripprocessor
524  if ( (_drawMode & DrawModes::SOLID_2DTEXTURED_FACE) && mesh_.n_faces() > 0 )
525  {
526  ACG::GLState::enable(GL_TEXTURE_2D);
527 
528 // enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY );
529 
530  ACG::GLState::disable(GL_LIGHTING);
531  ACG::GLState::shadeModel(GL_FLAT);
534  drawMesh_->disableColors();
535  drawMesh_->usePerHalfedgeTexcoords();
536 
537  draw_faces();
538  ACG::GLState::depthRange(0.0, 1.0);
539 
540  ACG::GLState::disable(GL_TEXTURE_2D);
541  }
542 
543  // Textured by using coordinates stored in halfedges
544  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
545  {
546  ACG::GLState::enable(GL_TEXTURE_2D);
547 
548 // enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY | PER_FACE_PER_VERTEX_NORMAL_ARRAY );
549 
550  ACG::GLState::enable(GL_LIGHTING);
551  ACG::GLState::shadeModel(GL_SMOOTH);
554  drawMesh_->usePerVertexNormals();
555  drawMesh_->setSmoothShading();
556  drawMesh_->disableColors();
557  drawMesh_->usePerHalfedgeTexcoords();
559  draw_faces();
560  ACG::GLState::depthRange(0.0, 1.0);
561  ACG::GLState::disable(GL_TEXTURE_2D);
562 
563  }
564 
565  enable_arrays(0);
566 
567  // Unbind all remaining buffers
568  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB , 0 );
569 
570  glPopAttrib();
571 }
572 
573 
574 template <class Mesh>
576 {
578  ro.initFromState(&_state);
579 
580  // shader gen setup (lighting, shademode, vertex-colors..)
581 
582  for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
583  {
584  const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
585 
586  // reset renderobject
587  ro.priority = 0;
588  ro.depthRange = Vec2f(0.0f, 1.0f);
589  ro.depthTest = true; // some previous node disabled depth testing
590  ro.depthWrite = true;
591  ro.depthFunc = GL_LESS;
592 
593  // ------------------------
594  // 1. setup drawMesh based on property source
595 
596 
597  if (props->flatShaded())
598  drawMesh_->setFlatShading();
599  else
600  drawMesh_->setSmoothShading();
601 
602 
603  ro.shaderDesc.vertexColors = true;
604 
605  switch (props->colorSource())
606  {
607  case DrawModes::COLOR_PER_VERTEX: drawMesh_->usePerVertexColors(); break;
608  case DrawModes::COLOR_PER_FACE: drawMesh_->usePerFaceColors(); break;
609  default:
610  {
611  drawMesh_->disableColors();
612  ro.shaderDesc.vertexColors = false;
613  } break;
614  }
616  switch (props->normalSource())
617  {
618  case DrawModes::NORMAL_PER_VERTEX: drawMesh_->usePerVertexNormals(); break;
619  case DrawModes::NORMAL_PER_HALFEDGE: drawMesh_->usePerHalfedgeNormals(); break;
620  default: break;
621  }
622 
623  ro.shaderDesc.textured = true;
624 
625  switch (props->texcoordSource())
626  {
627  case DrawModes::TEXCOORD_PER_VERTEX: drawMesh_->usePerVertexTexcoords(); break;
628  case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
629  default:
630  {
631  ro.shaderDesc.textured = false;
632  }break;
633  }
634 
635  // ------------------------
636  // 2. prepare renderobject
637 
638 
639  // enable / disable lighting
640  ro.shaderDesc.numLights = props->lighting() ? 0 : -1;
641 
642  // TODO: better handling of attribute sources in shader gen
643  if (props->flatShaded())
644  ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
645 
646  switch (props->lightStage())
647  {
648  case DrawModes::LIGHTSTAGE_SMOOTH: ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD; break;;
649  case DrawModes::LIGHTSTAGE_PHONG: ro.shaderDesc.shadeMode = SG_SHADE_PHONG; break;;
650  case DrawModes::LIGHTSTAGE_UNLIT: ro.shaderDesc.shadeMode = SG_SHADE_UNLIT; break;;
651  }
654  // handle 'special' primitives (wireframe, hiddenline, primitives in sysmem buffers)..
655 
656  if (props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
657  {
658  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
659  drawMesh_->disableColors();
660 
661  add_line_RenderObjects(_renderer, &ro);
662  }
663 
664  if (props->primitive() == DrawModes::PRIMITIVE_HIDDENLINE)
665  {
666  // First:
667  // Render all faces in background color to initialize z-buffer
668 
669  ro.priority = -1; // priority allows sorting for layers
670 
671  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
673  // color mask = none
674  // depth mask = enabled
675  ro.glColorMask(0,0,0,0);
676  ro.depthTest = true;
677  ro.depthWrite = true;
678  ro.depthFunc = GL_LESS;
679 
680  ro.fillMode = GL_FILL;
681 
682  drawMesh_->disableColors();
684  ro.depthRange = Vec2f(0.01f, 1.0f);
685 
686  add_face_RenderObjects(_renderer, &ro);
687 
688 
689  // Second
690  // Render the lines. All lines not on the front will be skipped in z-test
691  ro.priority = 0; // render after z cullers
693  ro.glColorMask(1,1,1,1);
694  ro.depthTest = true;
695  ro.depthWrite = true;
696  ro.depthFunc = GL_LEQUAL;
697 
698  ro.depthRange = Vec2f(0.0f, 1.0f);
699 
700  add_line_RenderObjects(_renderer, &ro);
701  }
702 
703  if (props->colored() && props->primitive() == DrawModes::PRIMITIVE_EDGE)
704  {
705  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
706  ro.shaderDesc.vertexColors = true;
707 
708  // note: colored edges are in sysmem, so they are directly bound to the VertexDeclaration
709  ro.vertexDecl = drawMesh_->getEdgeColoredVertexDeclaration();
710  ro.glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
711 
712  _renderer->addRenderObject(&ro);
714  // skip other edge primitives for this drawmode layer
715  continue;
716  }
717 
718  if (props->primitive() == DrawModes::PRIMITIVE_HALFEDGE)
719  {
720  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
721 
722  // buffers in sysmem
723  if (props->colored())
724  ro.vertexDecl = drawMesh_->getHalfedgeVertexDeclaration();
725  else
726  ro.vertexDecl = drawMesh_->getHalfedgeColoredVertexDeclaration();
727 
728  ro.glDrawArrays(GL_LINES, 0, mesh_.n_halfedges() * 2);
729 
730  _renderer->addRenderObject(&ro);
731  }
732 
733 
734  // -----------------------------------------------------
735  // take care of all the other primitives
736 
737  ro.depthRange = Vec2f(0.01f, 1.0f);
738 
739  switch (props->primitive())
740  {
741  case DrawModes::PRIMITIVE_POINT: add_point_RenderObjects(_renderer, &ro); break;
742  case DrawModes::PRIMITIVE_EDGE: add_line_RenderObjects(_renderer, &ro); break;
743  case DrawModes::PRIMITIVE_POLYGON: add_face_RenderObjects(_renderer, &ro); break;
744  default: break;
745  }
746  }
747 
748 }
749 
750 
751 template<class Mesh>
752 void
754 add_point_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
755  drawMesh_->addPointRenderObjects(_renderer, _baseObj);
756 }
758 template<class Mesh>
759 void
762  drawMesh_->drawVertices();
763 }
764 
765 template<class Mesh>
766 void
769 
770  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
771  {
772  // colored edges still slow
773  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
774  }
775  else
776  drawMesh_->drawLines();
777 }
778 
779 template<class Mesh>
780 void
782 add_line_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
783 
784  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
785  {
786  // colored edges still slow
787  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
788  }
789  else
790  drawMesh_->addLineRenderObjects(_renderer, _baseObj);
791 }
792 
793 template<class Mesh>
794 void
797  // If we are rendering per edge per vertex attributes, we need to use a seperated vertex buffer!
798  if ( enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY )
799  glDrawArrays(GL_LINES, 0, mesh_.n_halfedges() * 2);
800  // Something went wrong here!
801  else
802  std::cerr << "Unable to Draw! halfedge array configuration is invalid!!" << std::endl;
803 }
804 
805 template<class Mesh>
806 void
809  drawMesh_->draw(textureMap_);
810 }
811 
812 template<class Mesh>
813 void
815 add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
816  drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_);
817 }
818 
819 template<class Mesh>
820 void
822 enable_arrays(unsigned int _arrays) {
824  // Unbind everything to ensure sane settings
825  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
826  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
828  //===================================================================
829  // per Edge Vertex Array
830  //===================================================================
831 
832  // Check if we should enable the per face vertex array
833  if (_arrays & PER_EDGE_VERTEX_ARRAY) {
834 
835  // Check if its already enabled
836  if (!(enabled_arrays_ & PER_EDGE_VERTEX_ARRAY)) {
837  enabled_arrays_ |= PER_EDGE_VERTEX_ARRAY;
838 
839  // For this version we load the colors directly not from vbo
840  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
841  ACG::GLState::vertexPointer( drawMesh_->perEdgeVertexBuffer() );
842 
843  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
844 
845  }
846  } else if (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY) {
847  // Disable Vertex array
848  enabled_arrays_ &= ~PER_EDGE_VERTEX_ARRAY;
849  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
850  }
851 
852  //===================================================================
853  // per Edge Color Array
854  //===================================================================
855 
856  // Check if we should enable the per face vertex array
857  if ( mesh_.has_edge_colors() && ( _arrays & PER_EDGE_COLOR_ARRAY) ) {
858 
859  // Check if its already enabled
860  if (!(enabled_arrays_ & PER_EDGE_COLOR_ARRAY)) {
861  enabled_arrays_ |= PER_EDGE_COLOR_ARRAY;
862 
863  // For this version we load the colors directly not from vbo
864  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
865  ACG::GLState::colorPointer( drawMesh_->perEdgeColorBuffer() );
866 
867  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
868 
869  }
870  } else if (enabled_arrays_ & PER_EDGE_COLOR_ARRAY) {
871  // Disable Vertex array
872  enabled_arrays_ &= ~PER_EDGE_COLOR_ARRAY;
873  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
874  }
875 
876 
877  //===================================================================
878  // per Halfedge Vertex Array
879  //===================================================================
880 
881  // Check if we should enable the per face vertex array
882  if (_arrays & PER_HALFEDGE_VERTEX_ARRAY) {
883 
884  // Check if its already enabled
885  if (!(enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY)) {
886  enabled_arrays_ |= PER_HALFEDGE_VERTEX_ARRAY;
887 
888  // For this version we load the colors directly not from vbo
889  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
890  ACG::GLState::vertexPointer( drawMesh_->perHalfedgeVertexBuffer() );
891 
893 
894  }
895  } else if (enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY) {
896  // Disable Vertex array
897  enabled_arrays_ &= ~PER_HALFEDGE_VERTEX_ARRAY;
899  }
900 
901  //===================================================================
902  // per Halfedge Color Array
903  //===================================================================
904 
905  // Check if we should enable the per face vertex array
906  if ( mesh_.has_halfedge_colors() && ( _arrays & PER_HALFEDGE_COLOR_ARRAY) ) {
907 
908  // Check if its already enabled
909  if (!(enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY)) {
910  enabled_arrays_ |= PER_HALFEDGE_COLOR_ARRAY;
911 
912  // For this version we load the colors directly not from vbo
913  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
914  ACG::GLState::colorPointer( drawMesh_->perHalfedgeColorBuffer() );
915 
916  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
917 
918  }
919  } else if (enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY) {
920  // Disable Vertex array
921  enabled_arrays_ &= ~PER_HALFEDGE_COLOR_ARRAY;
922  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
923  }
924 
925  //===================================================================
926  // Check for OpenGL Errors
927  //===================================================================
928  glCheckErrors();
929 }
930 
931 template<class Mesh>
932 void
934 pick(GLState& _state, PickTarget _target) {
935  switch (_target)
936  {
938  {
939  pick_vertices(_state);
940  break;
941  }
943  {
944  pick_vertices(_state, true);
945  break;
946  }
947 
948  case PICK_ANYTHING:
949  {
950  pick_any(_state);
951  break;
952  }
953  case PICK_FACE:
954  {
955  pick_faces(_state);
956  break;
957  }
958 
959  case PICK_EDGE:
960  {
961  pick_edges(_state);
962  break;
963  }
964 
965  case PICK_FRONT_EDGE:
966  {
967  pick_edges(_state, true);
968  break;
969  }
970 
971  default:
972  break;
973  }
974 }
975 
976 template<class Mesh>
977 void
979 pick_vertices(GLState& _state, bool _front)
980 {
981  GLenum prev_depth = _state.depthFunc();
982 
983  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
984  v_end(mesh_.vertices_end());
985 
986  if (!_state.pick_set_maximum (mesh_.n_vertices())) {
987  omerr() << "MeshNode::pick_vertices: color range too small, " << "picking failed\n";
988  return;
989  }
990 
991  if ( mesh_.n_vertices() == 0 ) {
992  std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl;
993  return;
994  }
995 
996  if (_front && ( mesh_.n_faces() != 0 ) ) {
997 
998  Vec4f clear_color = _state.clear_color();
999  Vec4f base_color = _state.base_color();
1000  clear_color[3] = 1.0;
1001 
1002  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1003  _state.set_base_color(clear_color);
1004 
1005  ACG::GLState::depthRange(0.01, 1.0);
1006  draw_faces();
1007  ACG::GLState::depthRange(0.0, 1.0);
1008 
1009  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1010  ACG::GLState::depthFunc(GL_LEQUAL);
1011  _state.set_base_color(base_color);
1012 
1013  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1014  }
1015 
1016  if (_state.color_picking () ) {
1017 
1018  if ( updateVertexPicking_ || _state.pick_current_index () != vertexPickingBaseIndex_) {
1019  drawMesh_->updatePickingVertices(_state);
1020  vertexPickingBaseIndex_ = _state.pick_current_index ();
1021  updateVertexPicking_ = false;
1022  }
1023 
1024  if (drawMesh_) {
1025 
1026  // For this version we load the colors directly not from vbo
1027  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1028  ACG::GLState::colorPointer( drawMesh_->pickVertexColorBuffer() );
1029  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1030 
1031  // vertex positions
1032  ACG::GLState::vertexPointer( drawMesh_->pickVertexBuffer() );
1033  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1034 
1035  // Draw color picking
1036  glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1037 
1038  // Disable color array
1039  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1040 
1041  // disable vertex array
1042  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1043 
1044  } else {
1045  std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl;
1046  }
1047 
1048  } else {
1049  std::cerr << "No fallback pick_vertices!" << std::endl;
1050  }
1051 
1052  ACG::GLState::depthFunc(prev_depth);
1053 
1054 }
1055 
1056 template<class Mesh>
1057 void
1059 pick_edges(GLState& _state, bool _front)
1060 {
1061  GLenum prev_depth = _state.depthFunc();
1062 
1063  if (!_state.pick_set_maximum (mesh_.n_edges())) {
1064  omerr() << "MeshNode::pick_edges: color range too small, " << "picking failed\n";
1065  return;
1066  }
1067 
1068  if ( mesh_.n_vertices() == 0 ) {
1069  std::cerr << "pick_edges: No vertices in Mesh!" << std::endl;
1070  return;
1071  }
1072 
1073  if ( _front && ( mesh_.n_faces() != 0 ) ) {
1074 
1075  Vec4f clear_color = _state.clear_color();
1076  Vec4f base_color = _state.base_color();
1077  clear_color[3] = 1.0;
1078 
1079  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1080  _state.set_base_color(clear_color);
1081 
1082  ACG::GLState::depthRange(0.01, 1.0);
1083  draw_faces();
1084  ACG::GLState::depthRange(0.0, 1.0);
1085 
1086  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1087  ACG::GLState::depthFunc(GL_LEQUAL);
1088  _state.set_base_color(base_color);
1089 
1090  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1091 
1092  // disable all other arrays
1093  enable_arrays(0);
1094  }
1095 
1096  if (_state.color_picking () ) {
1097 
1098  if ( updateEdgePicking_ || _state.pick_current_index () != edgePickingBaseIndex_) {
1099  drawMesh_->updatePickingEdges(_state);
1100  edgePickingBaseIndex_ = _state.pick_current_index ();
1101  updateEdgePicking_ = false;
1102  }
1103 
1104  if ( mesh_.n_edges() != 0 && drawMesh_) {
1105 
1106  // For this version we load the colors directly not from vbo
1107  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1108 
1109  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1110  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1111 
1112  ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
1113  ACG::GLState::colorPointer(drawMesh_->pickEdgeColorBuffer());
1114 
1115  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1116 
1117  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1118  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1119 
1120  // disable all other arrays
1121  enable_arrays(0);
1122 
1123  }
1124 
1125  } else {
1126  std::cerr << "No fallback pick_edges!" << std::endl;
1127  }
1128 
1129  ACG::GLState::depthFunc(prev_depth);
1130 
1131 }
1132 
1133 template<class Mesh>
1134 void
1137 {
1138  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1139  f_end(mesh_.faces_end());
1140  typename Mesh::ConstFaceVertexIter fv_it;
1141 
1142  if ( mesh_.n_vertices() == 0 ) {
1143  std::cerr << "pick_faces: No vertices in Mesh!" << std::endl;
1144  return;
1145  }
1146 
1147  if ( mesh_.n_faces() > 0 ) {
1148  if (!_state.pick_set_maximum (mesh_.n_faces())) {
1149  omerr() << "MeshNode::pick_faces: color range too small, " << "picking failed\n";
1150  return;
1151  }
1152  } else {
1153  if (!_state.pick_set_maximum (1)) {
1154  omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
1155  return;
1156  }
1157  }
1158 
1159  if (_state.color_picking ()) {
1160 
1161  if ( updateFacePicking_ || _state.pick_current_index () != facePickingBaseIndex_) {
1162  drawMesh_->updatePickingFaces(_state);
1163  facePickingBaseIndex_ = _state.pick_current_index ();
1164  updateFacePicking_ = false;
1165  }
1166 
1167  if ( mesh_.n_faces() != 0 ) {
1168 
1169  // For this version we load the colors directly not from vbo
1170  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1171 
1172  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1173  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1174 
1175  ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
1176  ACG::GLState::colorPointer(drawMesh_->pickFaceColorBuffer());
1177 
1178  glDrawArrays(GL_TRIANGLES, 0, 3 * drawMesh_->getNumTris());
1179 
1180  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1181  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1182 
1183  // disable all other arrays
1184  enable_arrays(0);
1185 
1186  }
1187 
1188  } else
1189  std::cerr << "No fallback pick_faces!" << std::endl;
1190 
1191 }
1192 
1193 template<class Mesh>
1194 void
1197 {
1198  GLenum prev_depth = _state.depthFunc();
1199  unsigned int numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
1200 
1201  if ( mesh_.n_vertices() == 0 ) {
1202  std::cerr << "pick_any: No vertices in Mesh!" << std::endl;
1203  return;
1204  }
1205 
1206  // nothing to pick ?
1207  if (numElements <= 0) {
1208  std::cerr << "pick_any: Number of elements : 0 " << std::endl;
1209  return;
1210  }
1211 
1212  if (!_state.pick_set_maximum (numElements))
1213  {
1214  omerr() << "MeshNode::pick_any: color range too small, " << "picking failed\n";
1215  return;
1216  }
1217 
1218  if (_state.color_picking()) {
1219 
1220  if ( updateAnyPicking_ || _state.pick_current_index () != anyPickingBaseIndex_) {
1221  drawMesh_->updatePickingAny(_state);
1222  anyPickingBaseIndex_ = _state.pick_current_index ();
1223  updateAnyPicking_ = false;
1224  }
1225 
1226  // For this version we load the colors directly, not from vbo
1227  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1228 
1229  ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
1230  ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
1231 
1232  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1233  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1234 
1235  // If we do not have any faces, we generate an empty list here.
1236  if ( mesh_.n_faces() != 0 && drawMesh_) {
1237 
1238  ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
1239  ACG::GLState::colorPointer(drawMesh_->pickAnyFaceColorBuffer());
1240 
1241  glDrawArrays(GL_TRIANGLES, 0, 3 * drawMesh_->getNumTris());
1242  }
1243 
1244  ACG::GLState::depthFunc(GL_LEQUAL);
1245 
1246  // If we do not have any edges, we generate an empty list here.
1247  if ( mesh_.n_edges() != 0 && drawMesh_) {
1248 
1249  ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
1250  ACG::GLState::colorPointer(drawMesh_->pickAnyEdgeColorBuffer());
1251 
1252  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1253  }
1254 
1255  // For this version we load the colors directly not from vbo
1256  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1257  ACG::GLState::vertexPointer( drawMesh_->pickVertexBuffer() );
1258  ACG::GLState::colorPointer(drawMesh_->pickAnyVertexColorBuffer());
1259 
1260  // Draw color picking
1261  glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1262 
1263  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1264  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1265 
1266  // disable all other arrays
1267  enable_arrays(0);
1268  } else
1269  std::cerr << "No fallback pick_any!" << std::endl;
1270 
1271  //restore depth buffer comparison function for the active display list
1272  ACG::GLState::depthFunc(prev_depth);
1273 
1274  glCheckErrors();
1275 }
1276 
1277 template<class Mesh>
1278 void
1282  /*
1283  updateFaceList_ = true;
1284  updateAnyList_ = true;
1285  */
1286 
1287  updateVertexPicking_ = true;
1288  updateEdgePicking_ = true;
1289  updateFacePicking_ = true;
1290  updateAnyPicking_ = true;
1291 
1292  // Set per edge arrays to invalid as they have to be regenerated
1293  drawMesh_->invalidatePerEdgeBuffers();
1294 
1295  // Set per halfedge arrays to invalid as they have to be regenerated
1296  drawMesh_->invalidatePerHalfedgeBuffers();
1297 
1298  drawMesh_->updateGeometry();
1299 
1300 
1301  // First of all, we update the bounding box:
1302  bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
1303  bbMax_ = Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
1304  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
1305  v_end(mesh_.vertices_end());
1306 
1307  for (; v_it!=v_end; ++v_it)
1308  {
1309  bbMin_.minimize(mesh_.point(v_it));
1310  bbMax_.maximize(mesh_.point(v_it));
1311  }
1312 }
1313 
1314 template<class Mesh>
1315 void
1318 
1319  drawMesh_->invalidatePerEdgeBuffers();
1320  drawMesh_->invalidatePerHalfedgeBuffers();
1321 
1322 
1323  drawMesh_->updateTopology();
1324 
1325  // Unbind the buffer after the work has been done
1326  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1327 }
1328 
1329 template<class Mesh>
1330 void
1333  drawMesh_->updateTextures();
1334 
1335 }
1336 
1337 
1338 
1339 template<class Mesh>
1340 void
1343 
1344  drawMesh_->invalidatePerEdgeBuffers();
1345  drawMesh_->invalidatePerHalfedgeBuffers();
1346 
1347  // TODO: optimize update strategy:
1348  // if only vertex colors have changed, then call UpdateGeometry() (faster)
1349  // for face colors we have to use UpdateFull()
1350  drawMesh_->updateFull();
1351 }
1352 
1353 template<class Mesh>
1354 void
1356 setIndexPropertyName( std::string _indexPropertyName ) {
1357 
1358  drawMesh_->setTextureIndexPropertyName(_indexPropertyName);
1359  perFaceTextureIndexAvailable_ = drawMesh_->perFaceTextureIndexAvailable() != 0;
1360 }
1361 
1362 template<class Mesh>
1363 const std::string&
1366 
1367  return drawMesh_->getTextureIndexPropertyName();
1368 }
1369 
1370 template<class Mesh>
1371 void
1373 setHalfedgeTextcoordPropertyName( std::string _halfedgeTextcoordPropertyName ){
1374 
1375  drawMesh_->setPerFaceTextureCoordinatePropertyName(_halfedgeTextcoordPropertyName);
1376  perFaceTextureCoordsAvailable_ = drawMesh_->perFaceTextureCoordinateAvailable() != 0;
1377 
1378 }
1379 
1380 
1381 
1382 
1383 template<class Mesh>
1384 unsigned int
1386 {
1387  unsigned int res = 0;
1388 
1389  if (drawMesh_)
1390  res += drawMesh_->getMemoryUsage();
1391 
1392  return res;
1393 }
1394 
1395 
1396 
1397 
1398 //=============================================================================
1399 } // namespace SceneGraph
1400 } // namespace ACG
1401 //=============================================================================