Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MeshNode2T.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 MeshNodeT - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #define ACG_MESHNODE_C
60 
61 #include <ACG/Geometry/GPUCacheOptimizer.hh>
62 #include <ACG/GL/DrawMesh.hh>
63 #include <ACG/GL/GLError.hh>
64 
65 //== NAMESPACES ===============================================================
66 
67 
68 namespace ACG {
69 namespace SceneGraph {
70 
71 
72 //== INCLUDES =================================================================
73 
74 
75 #include "MeshNode2T.hh"
76 
77 template<class Mesh>
79 MeshNodeT(Mesh& _mesh,
80  BaseNode* _parent,
81  std::string _name ):
82  MeshNodeBase(_parent, _name),
83  mesh_(_mesh),
84  drawMesh_(0),
85  enableNormals_(true),
86  enableColors_(true),
87  enabled_arrays_(0),
88  updateVertexPicking_(true),
89  vertexPickingBaseIndex_(0),
90  updateEdgePicking_(true),
91  edgePickingBaseIndex_(0),
92  updateFacePicking_(true),
93  facePickingBaseIndex_(0),
94  updateAnyPicking_(true),
95  anyPickingBaseIndex_(0),
96  perFaceTextureIndexAvailable_(false),
97  perFaceTextureCoordsAvailable_(false),
98  textureMap_(0),
99  draw_with_offset_(false)
100 {
101 
103  if ( ! checkExtensionSupported("GL_ARB_vertex_buffer_object") ) {
104  std::cerr << "Error! Vertex buffer objects are not supported! The meshNode will not work without them!" << std::endl;
105  }
106 
107  drawMesh_ = new DrawMeshT<Mesh>(mesh_);
109  // Hand draw mesh down to super class.
110  MeshNodeBase::supplyDrawMesh(drawMesh_);
111 }
113 template<class Mesh>
116 {
117  // Delete all allocated buffers
118  delete drawMesh_;
119 }
121 template<class Mesh>
126 
127  // We can always render points and a wireframe.
128  drawModes |= DrawModes::POINTS;
129  drawModes |= DrawModes::HIDDENLINE;
130  drawModes |= DrawModes::WIREFRAME;
131  drawModes |= DrawModes::HALFEDGES;
132 
133  if (mesh_.has_vertex_normals())
134  {
136  drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
138  }
139 
140  if (mesh_.has_face_normals())
143  if (mesh_.has_halfedge_normals())
145 
146  if (mesh_.has_vertex_colors())
147  {
151  if (mesh_.has_vertex_normals())
153  }
155  if(mesh_.has_edge_colors())
156  {
158  }
160  if(mesh_.has_halfedge_colors())
161  {
163  }
164 
165  if (mesh_.has_face_colors()) {
167 
168  if( mesh_.has_face_normals() )
171  if (mesh().has_vertex_normals()) {
174  if (perFaceTextureCoordsAvailable_)
176  }
177  }
178 
179  if ( mesh_.has_vertex_texcoords2D() ) {
181 
182  if (mesh_.has_vertex_normals())
184  }
185 
186  if ( perFaceTextureCoordsAvailable_ ) {
188 
189  if (mesh_.has_face_normals())
191  }
192 
193  return drawModes;
194 }
196 template<class Mesh>
197 void
199 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) {
200  _bbMin.minimize(bbMin_);
201  _bbMax.maximize(bbMax_);
202 }
204 template<class Mesh>
205 void
207 draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
208 
209 /*
210  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) ||
211  ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED) ||
212  ( _drawMode & DrawModes::SOLID_TEXTURED) ||
213  ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE))
214  {
215  drawMesh_->setFlatShading();
216  }
217  else
218  drawMesh_->setSmoothShading();
219 
221  if ( (_drawMode & DrawModes::SOLID_FACES_COLORED ||
222  _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED))
223  {
224  drawMesh_->usePerFaceColors();
225  }
226  else
227  drawMesh_->usePerVertexColors();
228 */
229 
230 
231  glPushAttrib(GL_ENABLE_BIT);
232 
233  GLenum prev_depth_offset = _state.depthFunc();
234  if(draw_with_offset_)
235  {
236  ACG::GLState::enable(GL_POLYGON_OFFSET_FILL);
237  glPolygonOffset(-1.0f, -10.0f);
239  }
240 
241  GLenum prev_depth = _state.depthFunc();
244  GLuint lastBuffer = ACG::GLState::getBoundTextureBuffer();
245  GLenum lastTarget = ACG::GLState::getBoundTextureTarget();
247  // Unbind to avoid painting textures on non textured primitives
251  if ( (_drawMode & DrawModes::POINTS) || (_drawMode & DrawModes::POINTS_COLORED) || (_drawMode & DrawModes::POINTS_SHADED ) ) {
252 
253  _state.set_color( _state.specular_color() );
256 
257  if ( _drawMode & DrawModes::POINTS_SHADED ) {
258  ACG::GLState::enable(GL_LIGHTING);
259  } else
260  ACG::GLState::disable(GL_LIGHTING);
261 
262  // Use Colors in this mode if allowed
263  if ( enableColors_ && (_drawMode & DrawModes::POINTS_COLORED) )
264  {
265  drawMesh_->usePerVertexColors();
267  // If we have colors and lighting with normals, we have to use colormaterial
268  if ( enableNormals_ && (_drawMode & DrawModes::POINTS_SHADED ) )
269  ACG::GLState::enable(GL_COLOR_MATERIAL);
270  else
271  ACG::GLState::disable(GL_COLOR_MATERIAL);
272  }
273  else
274  drawMesh_->disableColors();
275 
276  // Bring the arrays online
277 // enable_arrays(arrays);
278 
279  // Draw vertices
280  draw_vertices();
281  }
282 
283 
285  if (_drawMode & DrawModes::WIREFRAME)
286  {
287 
288  const Vec4f oldColor = _state.color();
290  // If the mode is atomic, we use the specular, otherwise we take the overlay color
291  if (_drawMode.isAtomic() )
292  _state.set_color( _state.specular_color() );
293  else
294  _state.set_color( _state.overlay_color() );
296  ACG::GLState::disable(GL_LIGHTING);
297  ACG::GLState::shadeModel(GL_FLAT);
299  drawMesh_->disableColors();
301  draw_lines();
302 
303  _state.set_color(oldColor);
304  }
305 
306  if (_drawMode & DrawModes::HIDDENLINE)
307  {
308 // enable_arrays(VERTEX_ARRAY);
309 
310  // First:
311  // Render all faces in background color to initialize z-buffer
312  ACG::GLState::disable(GL_LIGHTING);
313  ACG::GLState::shadeModel(GL_FLAT);
314  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
315 
316 // drawMesh_->SetFlatShading();
317  drawMesh_->disableColors();
318 
319  Vec4f clear_color = _state.clear_color();
320  clear_color[3] = 1.0;
321  _state.set_color( clear_color );
323  ACG::GLState::depthRange(0.01, 1.0);
324  draw_faces();
326 
327  // Second
328  // Render the lines. All lines not on the front will be skipped in z-test
329 // enable_arrays(VERTEX_ARRAY|LINE_INDEX_ARRAY);
332  _state.set_color( _state.specular_color() );
334  draw_lines();
335 
336  //restore depth buffer comparison function for the next draw calls inside this function
338  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
339  }
342  if (_drawMode & DrawModes::EDGES_COLORED)
343  {
344  enable_arrays( PER_EDGE_VERTEX_ARRAY | PER_EDGE_COLOR_ARRAY );
345  ACG::GLState::disable(GL_LIGHTING);
346  ACG::GLState::shadeModel(GL_FLAT);
347  draw_lines();
348  }
350  if (_drawMode & DrawModes::HALFEDGES)
351  {
352  _state.set_color( _state.specular_color() );
354  enable_arrays( PER_HALFEDGE_VERTEX_ARRAY);
355  ACG::GLState::disable(GL_LIGHTING);
357  draw_halfedges();
358  }
359 
360  if (_drawMode & DrawModes::HALFEDGES_COLORED)
361  {
362  enable_arrays( PER_HALFEDGE_VERTEX_ARRAY | PER_HALFEDGE_COLOR_ARRAY );
363  ACG::GLState::disable(GL_LIGHTING);
365  draw_halfedges();
366  }
367 
368  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors() )
369  {
370  ACG::GLState::disable(GL_LIGHTING);
374  drawMesh_->usePerVertexColors();
375 
376  draw_faces();
378  }
380  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED_SHADED ) && mesh_.has_vertex_colors() && mesh_.has_vertex_normals() )
381  {
382  ACG::GLState::enable(GL_LIGHTING);
384  ACG::GLState::depthRange(0.01, 1.0);
385  if ( enableNormals_ ) {
386  ACG::GLState::enable(GL_COLOR_MATERIAL);
387  } else {
388  ACG::GLState::disable(GL_COLOR_MATERIAL);
389  }
391  drawMesh_->usePerVertexColors();
393  draw_faces();
395  }
396 
397  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
398  {
399  ACG::GLState::enable(GL_LIGHTING);
401  ACG::GLState::depthRange(0.01, 1.0);
403  drawMesh_->setFlatShading();
404  drawMesh_->disableColors();
405 
406  draw_faces();
408  }
409 
410  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals() )
411  {
412  ACG::GLState::enable(GL_LIGHTING);
416  drawMesh_->usePerVertexNormals();
417  drawMesh_->setSmoothShading();
418  drawMesh_->disableColors();
419  draw_faces();
421  }
422 
423  if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
424  {
426  // if ( parent() != 0 ) {
427  // if ( parent()->className() == "ShaderNode" ) {
428  //
429  // ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
430  //
431  // GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
432  //
433  // // Enable own Phong shader
434  // program->use();
435 // enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY );
436  ACG::GLState::disable(GL_LIGHTING);
437  ACG::GLState::shadeModel(GL_SMOOTH);
439 
440  drawMesh_->usePerVertexNormals();
441  drawMesh_->setSmoothShading();
442  drawMesh_->disableColors();
444  draw_faces();
446 
447  //disable own Phong shader
448  // program->disable();
449  // }
450  // }
451  }
452 
453 
454  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED ) && mesh_.has_face_colors() && mesh_.n_faces() > 0)
455  {
456  Vec4f base_color_backup = _state.base_color();
457 
458  ACG::GLState::disable(GL_LIGHTING);
461 // enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY);
463  drawMesh_->usePerFaceColors();
465  draw_faces();
467 
468  _state.set_base_color(base_color_backup);
469  }
470 
472  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED_FEATURES ) && mesh_.has_halfedge_normals() && mesh_.n_faces() > 0)
473  {
474  ACG::GLState::enable(GL_LIGHTING);
478  drawMesh_->disableColors();
479  drawMesh_->setSmoothShading();
480  drawMesh_->usePerHalfedgeNormals();
482  draw_faces();
483 
485  }
486 
487  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals() && mesh_.n_faces() > 0 )
488  {
489  Vec4f base_color_backup = _state.base_color();
490  ACG::GLState::enable(GL_LIGHTING);
491 
492  ACG::GLState::shadeModel(GL_FLAT);
494 // enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY | PER_FACE_NORMAL_ARRAY );
496  drawMesh_->setFlatShading();
497  drawMesh_->usePerFaceColors();
498 
499  draw_faces();
501 
502  _state.set_base_color(base_color_backup);
503  }
505 
506  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_SMOOTH_SHADED ) && mesh_.has_face_colors() && mesh_.has_vertex_normals() && mesh_.n_faces() > 0)
507  {
508  Vec4f base_color_backup = _state.base_color();
510  ACG::GLState::enable(GL_LIGHTING);
512  ACG::GLState::depthRange(0.01, 1.0);
514  drawMesh_->setSmoothShading();
515  drawMesh_->usePerVertexNormals();
516  drawMesh_->usePerFaceColors();
519  drawMesh_->draw(textureMap_, true);
521 
522  _state.set_base_color(base_color_backup);
523  }
525  // Rebind the previous texture
526  ACG::GLState::bindTexture(lastTarget,lastBuffer);
527 
529  if ((_drawMode & DrawModes::SOLID_FACES_COLORED_2DTEXTURED_FACE_SMOOTH_SHADED) && mesh_.has_face_colors() && mesh_.has_vertex_normals() && mesh_.n_faces() > 0)
530  {
531  // face colors, texturing via halfedge texcoords, smooth shading of lighting color
533  Vec4f base_color_backup = _state.base_color();
535  ACG::GLState::enable(GL_TEXTURE_2D);
537  ACG::GLState::enable(GL_LIGHTING);
539  ACG::GLState::depthRange(0.01, 1.0);
540 
541  drawMesh_->setSmoothShading();
542  drawMesh_->usePerVertexNormals();
543  drawMesh_->usePerFaceColors();
544  drawMesh_->usePerHalfedgeTexcoords();
546  drawMesh_->draw(textureMap_, true);
549  ACG::GLState::disable(GL_TEXTURE_2D);
550 
551  _state.set_base_color(base_color_backup);
552  }
554  if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
555  {
556  ACG::GLState::enable(GL_TEXTURE_2D);
557  ACG::GLState::disable(GL_LIGHTING);
558  ACG::GLState::shadeModel(GL_FLAT);
559  ACG::GLState::depthRange(0.01, 1.0);
560 
561  drawMesh_->disableColors();
562  drawMesh_->usePerVertexTexcoords();
563 
564 
565  // texture environment: fragment color = texture sample
566  GLint prevTexEnvMode = 0;
567  glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &prevTexEnvMode);
568  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
569 
570  draw_faces();
571  ACG::GLState::depthRange(0.0, 1.0);
572  ACG::GLState::disable(GL_TEXTURE_2D);
573 
574  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, prevTexEnvMode);
575  }
577  if ((_drawMode & DrawModes::SOLID_ENV_MAPPED) && mesh_.has_vertex_normals())
578  {
579  ACG::GLState::enable(GL_TEXTURE_2D);
580  ACG::GLState::disable(GL_LIGHTING);
581  ACG::GLState::shadeModel(GL_FLAT);
582  ACG::GLState::depthRange(0.01, 1.0);
583 
584  drawMesh_->disableColors();
585  drawMesh_->usePerVertexTexcoords();
586 
588  // texture environment: fragment color = texture sample
589  GLint prevTexEnvMode = 0;
590  glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &prevTexEnvMode);
591  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
593  draw_faces();
594  ACG::GLState::depthRange(0.0, 1.0);
595  ACG::GLState::disable(GL_TEXTURE_2D);
596 
597  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, prevTexEnvMode);
598  }
599 
600  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
601  {
602 // enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY);
603  ACG::GLState::enable(GL_TEXTURE_2D);
604  ACG::GLState::enable(GL_LIGHTING);
605  ACG::GLState::shadeModel(GL_SMOOTH);
607 
608  drawMesh_->setSmoothShading();
609  drawMesh_->disableColors();
610  drawMesh_->usePerVertexTexcoords();
612  draw_faces();
613  ACG::GLState::depthRange(0.0, 1.0);
614  ACG::GLState::disable(GL_TEXTURE_2D);
615  }
616 
617 
618  // Textured by using coordinates stored in halfedges ... arrays generated by stripprocessor
619  if ( (_drawMode & DrawModes::SOLID_2DTEXTURED_FACE) && mesh_.n_faces() > 0 )
620  {
621  ACG::GLState::enable(GL_TEXTURE_2D);
622 
623 // enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY );
624 
625  ACG::GLState::disable(GL_LIGHTING);
627  ACG::GLState::depthRange(0.01, 1.0);
628 
629  drawMesh_->disableColors();
630  drawMesh_->usePerHalfedgeTexcoords();
631 
632  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
633 
634  draw_faces();
635  ACG::GLState::depthRange(0.0, 1.0);
636 
637  ACG::GLState::disable(GL_TEXTURE_2D);
638  }
639 
640 
641  // Textured by using coordinates stored in halfedges
642  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
643  {
644  ACG::GLState::enable(GL_TEXTURE_2D);
645 
646  // enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY | PER_FACE_PER_VERTEX_NORMAL_ARRAY );
647 
648  ACG::GLState::enable(GL_LIGHTING);
649  ACG::GLState::shadeModel(GL_FLAT);
651 
652  drawMesh_->setFlatShading();
653  drawMesh_->disableColors();
654  drawMesh_->usePerHalfedgeTexcoords();
655 
656  draw_faces();
657  ACG::GLState::depthRange(0.0, 1.0);
658  ACG::GLState::disable(GL_TEXTURE_2D);
659 
660  }
661 
662  enable_arrays(0);
663 
664  // Unbind all remaining buffers
665  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB , 0 );
666 
667  if(draw_with_offset_)
668  {
669  ACG::GLState::depthFunc(prev_depth_offset);
670  }
671 
672  glPopAttrib();
673 }
674 
675 
676 template <class Mesh>
677 void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
678 {
679  RenderObject ro;
680 
681  ro.debugName = "MeshNode";
682 
683  // shader gen setup (lighting, shademode, vertex-colors..)
684 
685  for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
686  {
687  const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
688 
689  // reset renderobject
690  ro.initFromState(&_state);
691  ro.priority = 0;
692  ro.depthRange = Vec2f(0.0f, 1.0f);
693  ro.depthTest = true; // some previous node disabled depth testing
694  ro.depthWrite = true;
695  ro.depthFunc = GL_LESS;
696  ro.setMaterial(_mat);
697 
699  ro.shaderDesc.vertexTemplateFile.clear(); //QString(props->vertexShader().c_str());
700  ro.shaderDesc.geometryTemplateFile.clear(); //QString(props->geometryShader().c_str());
701  ro.shaderDesc.fragmentTemplateFile.clear(); //QString(props->fragmentShader().c_str());
702 
705  // ------------------------
706  // 1. setup drawMesh based on property source
707 
708 
709  ro.shaderDesc.vertexColors = true;
710 
711  switch (props->colorSource())
712  {
713  case DrawModes::COLOR_PER_VERTEX: drawMesh_->usePerVertexColors(); break;
714  case DrawModes::COLOR_PER_FACE: drawMesh_->usePerFaceColors(); break;
715  default:
716  {
717  drawMesh_->disableColors();
718  ro.shaderDesc.vertexColors = false;
719  } break;
720  }
722  // only the polygon primitives can set the normal source
723  if (props->primitive() == DrawModes::PRIMITIVE_POLYGON)
724  {
725  switch (props->normalSource())
726  {
727  case DrawModes::NORMAL_PER_VERTEX: drawMesh_->usePerVertexNormals(); break;
728  case DrawModes::NORMAL_PER_HALFEDGE: drawMesh_->usePerHalfedgeNormals(); break;
729  default: break;
730  }
732  if (props->flatShaded())
733  drawMesh_->setFlatShading();
734  else
735  drawMesh_->setSmoothShading();
736  }
737 
739  ro.shaderDesc.addTextureType(GL_TEXTURE_2D,false,0);
740 
741  switch (props->texcoordSource())
742  {
743  case DrawModes::TEXCOORD_PER_VERTEX: drawMesh_->usePerVertexTexcoords(); break;
744  case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
745  default:
746  {
748  }break;
749  }
750 
751  // ------------------------
752  // 2. prepare renderobject
755  // enable / disable lighting
756  ro.shaderDesc.numLights = props->lighting() ? 0 : -1;
758  // TODO: better handling of attribute sources in shader gen
759  switch (props->lightStage())
760  {
762  ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
763  break;
765  ro.shaderDesc.shadeMode = SG_SHADE_PHONG;
766  break;
768  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
769  break;
770  }
771 
772  if (props->flatShaded())
773  ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
775  // handle 'special' primitives (wireframe, hiddenline, primitives in sysmem buffers)..
776 
777  if (props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
778  {
779  ro.debugName = "MeshNode.Wireframe";
780 
781  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
782  drawMesh_->disableColors();
783 
784  // use specular color for lines
785  if (_drawMode.isAtomic() )
786  ro.emissive = ro.specular;
787  else
788  ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());
790  // allow wireframe + solid mode
791  ro.depthFunc = GL_LEQUAL;
792  ro.priority = -1; // render before polygon
793 
794  ro.setupLineRendering(_state.line_width(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
795 
796  applyRenderObjectSettings(props->primitive(), &ro);
797  add_line_RenderObjects(_renderer, &ro);
798  }
800  if (props->primitive() == DrawModes::PRIMITIVE_HIDDENLINE)
801  {
802  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
803  drawMesh_->disableColors();
805  // use specular color for lines
806  if (_drawMode.isAtomic() )
807  ro.emissive = ro.specular;
808  else
809  ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());
810 
811  // eventually prepare depthbuffer first
812  int polyLayer = _drawMode.getLayerIndexByPrimitive(DrawModes::PRIMITIVE_POLYGON);
813  if ( (polyLayer > int(i) || polyLayer < 0) && ( mesh_.n_faces() != 0 ))
814  {
815  ro.priority = 0;
816 
817  applyRenderObjectSettings(DrawModes::PRIMITIVE_POLYGON, &ro);
818 
819  // disable color write
820  ro.glColorMask(0,0,0,0);
821 
822  ro.debugName = "MeshNode.HiddenLine.faces";
823  add_face_RenderObjects(_renderer, &ro);
824  }
827  // draw lines after depth image
828  ro.priority = 1;
829  ro.glColorMask(1,1,1,1);
830  ro.depthFunc = GL_LEQUAL;
831 
832  ro.setupLineRendering(_state.line_width(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
834  applyRenderObjectSettings(DrawModes::PRIMITIVE_HIDDENLINE, &ro);
836  ro.debugName = "MeshNode.HiddenLine.lines";
837  add_line_RenderObjects(_renderer, &ro);
838  }
840  if (props->colored() && props->primitive() == DrawModes::PRIMITIVE_EDGE)
841  {
842  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
843  ro.shaderDesc.vertexColors = true;
845  // note: colored edges are in sysmem, so they are directly bound to the VertexDeclaration
846  drawMesh_->updateEdgeHalfedgeVertexDeclarations();
847  ro.vertexDecl = drawMesh_->getEdgeColoredVertexDeclaration();
848  ro.glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
850  // use specular color for lines
851  ro.emissive = ro.specular;
852 
853  // line thickness
854  ro.setupLineRendering(_state.line_width(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
855 
856  applyRenderObjectSettings(props->primitive(), &ro);
857  ro.debugName = "MeshNode.Edges";
858  _renderer->addRenderObject(&ro);
860  // skip other edge primitives for this drawmode layer
861  continue;
862  }
864  if (props->primitive() == DrawModes::PRIMITIVE_HALFEDGE)
865  {
866  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
867 
868  // buffers in system memory
869  drawMesh_->updateEdgeHalfedgeVertexDeclarations();
870  if (props->colored())
871  ro.vertexDecl = drawMesh_->getHalfedgeVertexDeclaration();
872  else
873  ro.vertexDecl = drawMesh_->getHalfedgeColoredVertexDeclaration();
875  // use specular color for lines
876  ro.emissive = ro.specular;
877 
878  ro.glDrawArrays(GL_LINES, 0, int(mesh_.n_halfedges() * 2));
879 
881  // use shaders to simulate line width
882  ro.setupLineRendering(_state.line_width(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
884  applyRenderObjectSettings(props->primitive(), &ro);
885  ro.debugName = "MeshNode.HalfEdges";
886  _renderer->addRenderObject(&ro);
887  }
888 
890  // -----------------------------------------------------
891  // take care of all the other primitives
893  ro.depthRange = Vec2f(0.01f, 1.0f);
894 
895  switch (props->primitive())
896  {
897  case DrawModes::PRIMITIVE_POINT:
898  {
899  if (ro.shaderDesc.shadeMode == SG_SHADE_UNLIT)
900  {
901  // use specular color for points
902  if (_drawMode.isAtomic() )
903  ro.emissive = ro.specular;
904  else
905  ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());
906  }
907 
908  // use shaders to simulate point size
909  ro.setupPointRendering(_mat->pointSize(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
911  applyRenderObjectSettings(props->primitive(), &ro);
912  ro.debugName = "MeshNode.Points";
913  add_point_RenderObjects(_renderer, &ro);
914  } break;
915  case DrawModes::PRIMITIVE_EDGE:
916  {
917  // use specular color for lines
918  ro.emissive = ro.specular;
920  // use shaders to simulate line width
921  ro.setupLineRendering(_state.line_width(), Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
922 
923  applyRenderObjectSettings(props->primitive(), &ro);
924  ro.debugName = "MeshNode.Edges";
925  add_line_RenderObjects(_renderer, &ro);
926  } break;
927  case DrawModes::PRIMITIVE_POLYGON:
928  {
929  applyRenderObjectSettings(props->primitive(), &ro);
930 
931  if (!ro.shaderDesc.vertexTemplateFile.isEmpty())
932  drawMesh_->scanVertexShaderForInput(ro.shaderDesc.vertexTemplateFile.toStdString());
933 
934  bool useNonIndexed = (props->colorSource() == DrawModes::COLOR_PER_FACE) && (props->lightStage() == DrawModes::LIGHTSTAGE_SMOOTH) && !props->flatShaded();
935  if (!useNonIndexed && props->colorSource() == DrawModes::COLOR_PER_FACE)
937 
938  ro.debugName = "MeshNode.Faces";
939  add_face_RenderObjects(_renderer, &ro, useNonIndexed);
940 
942  } break;
943  default: break;
944  }
945  }
946 
947 }
948 
949 
950 template<class Mesh>
951 void
953 add_point_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
954  drawMesh_->addPointRenderObjects(_renderer, _baseObj);
955 }
956 
957 template<class Mesh>
958 void
961  drawMesh_->drawVertices();
962 }
964 template<class Mesh>
965 void
968 
969  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
970  {
971  // colored edges still slow
972  glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
973  }
974  else
975  drawMesh_->drawLines();
976 }
978 template<class Mesh>
979 void
981 add_line_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
982 
983  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
984  {
985  // colored edges still slow
986  glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
987  }
988  else
989  drawMesh_->addLineRenderObjects(_renderer, _baseObj);
990 }
991 
992 template<class Mesh>
993 void
996  // If we are rendering per edge per vertex attributes, we need to use a seperated vertex buffer!
997  if ( enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY )
998  glDrawArrays(GL_LINES, 0, int(mesh_.n_halfedges() * 2));
999  // Something went wrong here!
1000  else
1001  std::cerr << "Unable to Draw! halfedge array configuration is invalid!!" << std::endl;
1002 }
1003 
1004 template<class Mesh>
1005 void
1008  drawMesh_->draw(textureMap_);
1009 }
1010 
1011 template<class Mesh>
1012 void
1014 add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj, bool _nonindexed) {
1015  drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_, _nonindexed);
1016 }
1017 
1018 template<class Mesh>
1019 void
1021 enable_arrays(unsigned int _arrays) {
1022 
1023  // Unbind everything to ensure sane settings
1024  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1025  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1026 
1027  //===================================================================
1028  // per Edge Vertex Array
1029  //===================================================================
1030 
1031  // Check if we should enable the per face vertex array
1032  if (_arrays & PER_EDGE_VERTEX_ARRAY) {
1033 
1034  // Check if its already enabled
1035  if (!(enabled_arrays_ & PER_EDGE_VERTEX_ARRAY)) {
1036  enabled_arrays_ |= PER_EDGE_VERTEX_ARRAY;
1037 
1038  // For this version we load the colors directly not from vbo
1039  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1040  ACG::GLState::vertexPointer( drawMesh_->perEdgeVertexBuffer() );
1041 
1042  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1044  }
1045  } else if (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY) {
1046  // Disable Vertex array
1047  enabled_arrays_ &= ~PER_EDGE_VERTEX_ARRAY;
1049  }
1051  //===================================================================
1052  // per Edge Color Array
1053  //===================================================================
1055  // Check if we should enable the per face vertex array
1056  if ( mesh_.has_edge_colors() && ( _arrays & PER_EDGE_COLOR_ARRAY) ) {
1058  // Check if its already enabled
1059  if (!(enabled_arrays_ & PER_EDGE_COLOR_ARRAY)) {
1060  enabled_arrays_ |= PER_EDGE_COLOR_ARRAY;
1061 
1062  // For this version we load the colors directly not from vbo
1063  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1064  ACG::GLState::colorPointer( drawMesh_->perEdgeColorBuffer() );
1065 
1066  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1067 
1068  }
1069  } else if (enabled_arrays_ & PER_EDGE_COLOR_ARRAY) {
1070  // Disable Vertex array
1071  enabled_arrays_ &= ~PER_EDGE_COLOR_ARRAY;
1072  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1073  }
1075 
1076  //===================================================================
1077  // per Halfedge Vertex Array
1078  //===================================================================
1079 
1080  // Check if we should enable the per face vertex array
1081  if (_arrays & PER_HALFEDGE_VERTEX_ARRAY) {
1082 
1083  // Check if its already enabled
1084  if (!(enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY)) {
1085  enabled_arrays_ |= PER_HALFEDGE_VERTEX_ARRAY;
1086 
1087  // For this version we load the colors directly not from vbo
1088  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1089  ACG::GLState::vertexPointer( drawMesh_->perHalfedgeVertexBuffer() );
1090 
1091  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1092 
1093  }
1094  } else if (enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY) {
1095  // Disable Vertex array
1096  enabled_arrays_ &= ~PER_HALFEDGE_VERTEX_ARRAY;
1097  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1098  }
1099 
1100  //===================================================================
1101  // per Halfedge Color Array
1102  //===================================================================
1103 
1104  // Check if we should enable the per face vertex array
1105  if ( mesh_.has_halfedge_colors() && ( _arrays & PER_HALFEDGE_COLOR_ARRAY) ) {
1106 
1107  // Check if its already enabled
1108  if (!(enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY)) {
1109  enabled_arrays_ |= PER_HALFEDGE_COLOR_ARRAY;
1110 
1111  // For this version we load the colors directly not from vbo
1112  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1113  ACG::GLState::colorPointer( drawMesh_->perHalfedgeColorBuffer() );
1114 
1115  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1116 
1117  }
1118  } else if (enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY) {
1119  // Disable Vertex array
1120  enabled_arrays_ &= ~PER_HALFEDGE_COLOR_ARRAY;
1121  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1122  }
1123 
1124  //===================================================================
1125  // Check for OpenGL Errors
1126  //===================================================================
1127  glCheckErrors();
1128 }
1129 
1130 template<class Mesh>
1131 void
1133 pick(GLState& _state, PickTarget _target) {
1134 
1135  switch (_target)
1136  {
1137  case PICK_VERTEX:
1138  {
1139  pick_vertices(_state);
1140  break;
1141  }
1142  case PICK_FRONT_VERTEX:
1143  {
1144  pick_vertices(_state, true);
1145  break;
1146  }
1147 
1148  case PICK_ANYTHING:
1149  {
1150  pick_any(_state);
1151  break;
1152  }
1153  case PICK_FACE:
1154  {
1155  pick_faces(_state);
1156  break;
1157  }
1158 
1159  case PICK_EDGE:
1160  {
1161  pick_edges(_state);
1162  break;
1163  }
1164 
1165  case PICK_FRONT_EDGE:
1166  {
1167  pick_edges(_state, true);
1168  break;
1169  }
1170 
1171  default:
1172  break;
1173  }
1174 
1175 }
1176 
1177 template<class Mesh>
1178 void
1180 pick_vertices(GLState& _state, bool _front)
1181 {
1182  GLenum prev_depth = _state.depthFunc();
1183 
1184  if (!_state.pick_set_maximum (static_cast<unsigned int>(mesh_.n_vertices()))) {
1185  omerr() << "MeshNode::pick_vertices: color range too small, " << "picking failed\n";
1186  return;
1187  }
1188 
1189  if ( mesh_.n_vertices() == 0 ) {
1190  std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl;
1191  return;
1192  }
1193 
1194  if (_front && ( mesh_.n_faces() != 0 ) ) {
1195 
1196  Vec4f clear_color = _state.clear_color();
1197  Vec4f base_color = _state.base_color();
1198  clear_color[3] = 1.0;
1199 
1200  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1201  glColor(clear_color);
1202 
1203  ACG::GLState::depthRange(0.01, 1.0);
1204  draw_faces();
1205  ACG::GLState::depthRange(0.0, 1.0);
1206 
1207  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1208  ACG::GLState::depthFunc(GL_LEQUAL);
1209  glColor(base_color);
1210 
1211  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1212  }
1213 
1214  // picking implementations:
1215  // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 16 bytes per openmesh vertex)
1216  // 1 -> render mesh with picking shader (optimized, add. mem alloc: none for point-clouds, otherwise 4 bytes per openmesh vertex on gpu)
1217  int pickImplementationMethod = 0;
1218 
1219  // use optimized picking if supported
1220  if (drawMesh_->supportsPickingVertices_opt())
1221  pickImplementationMethod = 1;
1222 
1223  if (_state.color_picking () ) {
1224 
1225  if ( updateVertexPicking_ || _state.pick_current_index () != vertexPickingBaseIndex_) {
1226  if (pickImplementationMethod == 0)
1227  drawMesh_->updatePickingVertices(_state);
1228  else
1229  drawMesh_->updatePickingVertices_opt(_state);
1230  vertexPickingBaseIndex_ = _state.pick_current_index ();
1231  updateVertexPicking_ = false;
1232  }
1233 
1234  if (mesh_.n_vertices()) {
1235 
1236  if (pickImplementationMethod == 0) {
1237  // For this version we load the colors directly not from vbo
1238  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1239  ACG::GLState::colorPointer( drawMesh_->pickVertexColorBuffer() );
1240  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1241 
1242  // vertex positions
1243  ACG::GLState::vertexPointer( drawMesh_->pickVertexBuffer() );
1244  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1245 
1246  // Draw color picking
1247  glDrawArrays(GL_POINTS, 0, int(mesh_.n_vertices()));
1248 
1249  // Disable color array
1250  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1251 
1252  // disable vertex array
1253  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1254  }
1255  else if (pickImplementationMethod == 1){
1256 
1257  // optimized rendering of picking ids with shaders
1258  drawMesh_->drawPickingVertices_opt(_state.projection() * _state.modelview(), vertexPickingBaseIndex_);
1259 
1260  }
1261 
1262 
1263  } else {
1264  std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl;
1265  }
1266 
1267  } else {
1268  std::cerr << "No fallback pick_vertices!" << std::endl;
1269  }
1270 
1271  ACG::GLState::depthFunc(prev_depth);
1272 
1273 }
1274 
1275 template<class Mesh>
1276 void
1278 pick_edges(GLState& _state, bool _front)
1279 {
1280  GLenum prev_depth = _state.depthFunc();
1281 
1282  if (!_state.pick_set_maximum (static_cast<unsigned int>(mesh_.n_edges()))) {
1283  omerr() << "MeshNode::pick_edges: color range too small, " << "picking failed\n";
1284  return;
1285  }
1286 
1287  if ( mesh_.n_vertices() == 0 ) {
1288  std::cerr << "pick_edges: No vertices in Mesh!" << std::endl;
1289  return;
1290  }
1291 
1292  if ( _front && ( mesh_.n_faces() != 0 ) ) {
1293 
1294  Vec4f clear_color = _state.clear_color();
1295  Vec4f base_color = _state.base_color();
1296  clear_color[3] = 1.0;
1297 
1298  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1299  glColor(clear_color);
1300 
1301  ACG::GLState::depthRange(0.01, 1.0);
1302  draw_faces();
1303  ACG::GLState::depthRange(0.0, 1.0);
1304 
1305  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1306  ACG::GLState::depthFunc(GL_LEQUAL);
1307  glColor(base_color);
1308 
1309  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1310 
1311  // disable all other arrays
1312  enable_arrays(0);
1313  }
1314 
1315  if (_state.color_picking () && drawMesh_ ) {
1316 
1317  // picking implementations:
1318  // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 32 bytes per openmesh edge)
1319  // 1 -> render mesh with picking shader (add. mem alloc: none)
1320  int pickImplementationMethod = 0;
1321 
1322  // use optimized picking if supported
1323  if (drawMesh_->supportsPickingEdges_opt())
1324  pickImplementationMethod = 1;
1325 
1326  if ( updateEdgePicking_ || _state.pick_current_index () != edgePickingBaseIndex_) {
1327  if (pickImplementationMethod == 0)
1328  drawMesh_->updatePickingEdges(_state);
1329  else
1330  drawMesh_->updatePickingEdges_opt(_state);
1331  edgePickingBaseIndex_ = _state.pick_current_index ();
1332  updateEdgePicking_ = false;
1333  }
1334 
1335  if ( mesh_.n_edges() != 0 && drawMesh_) {
1336 
1337  if (pickImplementationMethod == 0){
1338  // For this version we load the colors directly not from vbo
1339  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1340 
1341  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1342  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1343 
1344  ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
1345  ACG::GLState::colorPointer(drawMesh_->pickEdgeColorBuffer());
1346 
1347  glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
1348 
1349  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1350  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1351 
1352  // disable all other arrays
1353  enable_arrays(0);
1354  }
1355  else if (pickImplementationMethod == 1){
1356  // optimized rendering of edge ids
1357  drawMesh_->drawPickingEdges_opt(_state.projection() * _state.modelview(), edgePickingBaseIndex_);
1358  }
1359 
1360 
1361  }
1363  } else {
1364  std::cerr << "No fallback pick_edges!" << std::endl;
1365  }
1367  ACG::GLState::depthFunc(prev_depth);
1368 
1369 }
1370 
1371 template<class Mesh>
1372 void
1375 {
1376 
1377  if ( mesh_.n_vertices() == 0 ) {
1378  std::cerr << "pick_faces: No vertices in Mesh!" << std::endl;
1379  return;
1380  }
1382  if ( mesh_.n_faces() > 0 ) {
1383  if (!_state.pick_set_maximum (static_cast<unsigned int>(mesh_.n_faces()))) {
1384  omerr() << "MeshNode::pick_faces: color range too small, " << "picking failed\n";
1385  return;
1386  }
1387  } else {
1388  if (!_state.pick_set_maximum (1)) {
1389  omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
1390  return;
1391  }
1392  }
1393 
1394  // picking implementations:
1395  // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 48 bytes per triangle)
1396  // 1 -> render mesh with picking shader (optimized, add. mem alloc: 4 bytes per triangle on gpu)
1397  int pickImplementationMethod = 0;
1398 
1399 
1400  // use optimized picking if supported
1401  if (drawMesh_->supportsPickingFaces_opt())
1402  pickImplementationMethod = 1;
1403 
1404 // pickImplementationMethod = 0;
1405 
1406  if (_state.color_picking ()) {
1407 
1408  if (pickImplementationMethod == 0) {
1409  // compatibility mode (unoptimized)
1410 
1411  if ( updateFacePicking_ || _state.pick_current_index () != facePickingBaseIndex_) {
1412  drawMesh_->updatePickingFaces(_state);
1413  facePickingBaseIndex_ = _state.pick_current_index ();
1414  updateFacePicking_ = false;
1415  }
1416 
1417  if ( mesh_.n_faces() != 0 ) {
1418 
1419  // For this version we load the colors directly not from vbo
1420  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1421 
1422  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1423  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1424 
1425  ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
1426  ACG::GLState::colorPointer(drawMesh_->pickFaceColorBuffer());
1427 
1428  glDrawArrays(GL_TRIANGLES, 0, int(3 * drawMesh_->getNumTris()));
1429 
1430  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1431  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1432 
1433  // disable all other arrays
1434  enable_arrays(0);
1435 
1436  }
1437 
1438  }
1439  else if (pickImplementationMethod == 1) {
1440 
1441  // render mesh with face picking shader (optimized)
1442 
1443  if ( updateFacePicking_ || _state.pick_current_index () != facePickingBaseIndex_) {
1444  drawMesh_->updatePickingFaces_opt(_state);
1445  facePickingBaseIndex_ = _state.pick_current_index ();
1446  updateFacePicking_ = false;
1447  }
1448 
1449  if ( mesh_.n_faces() != 0 ) {
1450 
1451  drawMesh_->drawPickingFaces_opt(_state.projection() * _state.modelview(), facePickingBaseIndex_);
1452 
1453  /* debug: print color id of first face
1454  Vec4uc facePickingOffsetColor = _state.pick_get_name_color(0);
1455 
1456  std::cout << "base_color: " << int(facePickingOffsetColor[0]) << " " <<
1457  int(facePickingOffsetColor[1]) << " " <<
1458  int(facePickingOffsetColor[2]) << " " <<
1459  int(facePickingOffsetColor[3]) << " " << std::endl;
1460  Vec4uc facePickingOffsetColor = _state.pick_get_name_color(0);
1461  */
1462  }
1463  }
1464  else
1465  std::cerr << "Unknown picking method in pick_faces!" << std::endl;
1466 
1467 
1468  } else
1469  std::cerr << "No fallback pick_faces!" << std::endl;
1470 
1471 }
1472 
1473 template<class Mesh>
1474 void
1477 {
1478  GLenum prev_depth = _state.depthFunc();
1479  size_t numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
1480 
1481  if ( mesh_.n_vertices() == 0 ) {
1482  std::cerr << "pick_any: No vertices in Mesh!" << std::endl;
1483  return;
1484  }
1485 
1486  // nothing to pick ?
1487  if (numElements == 0) {
1488  std::cerr << "pick_any: Number of elements : 0 " << std::endl;
1489  return;
1490  }
1491 
1492  if (!_state.pick_set_maximum (static_cast<unsigned int>(numElements)))
1493  {
1494  omerr() << "MeshNode::pick_any: color range too small, " << "picking failed\n";
1495  return;
1496  }
1497 
1498  if (_state.color_picking() && drawMesh_) {
1499 
1500  // picking implementations:
1501  // 0 -> render mesh with picking color buffer (compatibility mode, add. mem alloc: 48 bytes per triangle + 32 bytes per edge + 16 bytes per vertex)
1502  // 1 -> render mesh with picking shader (optimized, add. mem alloc: none [ shared memory with optimized vertex,edge,face picking ])
1503  int pickImplementationMethod = 0;
1504 
1505 
1506  // use optimized picking if supported
1507  if (drawMesh_->supportsPickingAny_opt())
1508  pickImplementationMethod = 1;
1509 
1510 
1511  if ( updateAnyPicking_ || _state.pick_current_index () != anyPickingBaseIndex_) {
1512  if (pickImplementationMethod == 0)
1513  drawMesh_->updatePickingAny(_state);
1514  else
1515  drawMesh_->updatePickingAny_opt(_state);
1516  anyPickingBaseIndex_ = _state.pick_current_index ();
1517  updateAnyPicking_ = false;
1518  }
1519 
1520  if (pickImplementationMethod == 0){
1521  // For this version we load the colors directly, not from vbo
1522  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1523 
1524  ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
1525  ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
1526 
1527  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1528  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1529 
1530  // If we do not have any faces, we generate an empty list here.
1531  if ( mesh_.n_faces() != 0 && drawMesh_) {
1532 
1533  ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
1534  ACG::GLState::colorPointer(drawMesh_->pickAnyFaceColorBuffer());
1535 
1536  glDrawArrays(GL_TRIANGLES, 0, int(3 * drawMesh_->getNumTris()));
1537  }
1538 
1539  ACG::GLState::depthFunc(GL_LEQUAL);
1540 
1541  // If we do not have any edges, we generate an empty list here.
1542  if ( mesh_.n_edges() != 0 && drawMesh_) {
1543 
1544  ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
1545  ACG::GLState::colorPointer(drawMesh_->pickAnyEdgeColorBuffer());
1546 
1547  glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
1548  }
1549 
1550  // For this version we load the colors directly not from vbo
1551  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1552  ACG::GLState::vertexPointer( drawMesh_->pickVertexBuffer() );
1553  ACG::GLState::colorPointer(drawMesh_->pickAnyVertexColorBuffer());
1554 
1555  // Draw color picking
1556  glDrawArrays(GL_POINTS, 0, int(mesh_.n_vertices()));
1557 
1558  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1559  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1560 
1561  // disable all other arrays
1562  enable_arrays(0);
1563  } else {
1564  // optimized version of any picking with shaders
1565  drawMesh_->drawPickingAny_opt(_state.projection() * _state.modelview(), anyPickingBaseIndex_);
1566  }
1567 
1568  } else
1569  std::cerr << "No fallback pick_any!" << std::endl;
1570 
1571  //restore depth buffer comparison function for the active display list
1572  ACG::GLState::depthFunc(prev_depth);
1573 
1574  glCheckErrors();
1575 }
1576 
1577 template<class Mesh>
1578 void
1582  /*
1583  updateFaceList_ = true;
1584  updateAnyList_ = true;
1585  */
1586 
1587  updateVertexPicking_ = true;
1588  updateEdgePicking_ = true;
1589  updateFacePicking_ = true;
1590  updateAnyPicking_ = true;
1591 
1592  // Set per edge arrays to invalid as they have to be regenerated
1593  drawMesh_->invalidatePerEdgeBuffers();
1594 
1595  // Set per halfedge arrays to invalid as they have to be regenerated
1596  drawMesh_->invalidatePerHalfedgeBuffers();
1597 
1598  drawMesh_->updateGeometry();
1599 
1600  drawMesh_->invalidateFullVBO();
1601 
1602  // First of all, we update the bounding box:
1603  bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
1604  bbMax_ = Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
1605  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
1606 
1607  for (; v_it!=v_end; ++v_it)
1608  {
1609  bbMin_.minimize(mesh_.point(*v_it));
1610  bbMax_.maximize(mesh_.point(*v_it));
1611  }
1612 }
1613 
1614 template<class Mesh>
1615 void
1618 
1619  drawMesh_->invalidatePerEdgeBuffers();
1620  drawMesh_->invalidatePerHalfedgeBuffers();
1621 
1622 
1623  drawMesh_->updateTopology();
1624 
1625  // Unbind the buffer after the work has been done
1626  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1627 }
1628 
1629 template<class Mesh>
1630 void
1633  drawMesh_->updateTextures();
1634 
1635  updateVertexPicking_ = true;
1636  updateFacePicking_ = true;
1637  updateAnyPicking_ = true;
1638 }
1639 
1640 
1641 
1642 template<class Mesh>
1643 void
1646 
1647  drawMesh_->invalidatePerEdgeBuffers();
1648  drawMesh_->invalidatePerHalfedgeBuffers();
1649 
1650  // TODO: optimize update strategy:
1651  // if only vertex colors have changed, then call UpdateGeometry() (faster)
1652  // for face colors we have to use UpdateFull()
1653  drawMesh_->updateFull();
1654 }
1655 
1656 template<class Mesh>
1657 void
1659 setIndexPropertyName( std::string _indexPropertyName ) {
1660 
1661  drawMesh_->setTextureIndexPropertyName(_indexPropertyName);
1662  perFaceTextureIndexAvailable_ = drawMesh_->perFaceTextureIndexAvailable() != 0;
1663 }
1664 
1665 template<class Mesh>
1666 const std::string&
1669 
1670  return drawMesh_->getTextureIndexPropertyName();
1671 }
1672 
1673 template<class Mesh>
1674 void
1676 setHalfedgeTextcoordPropertyName( std::string _halfedgeTextcoordPropertyName ){
1677 
1678  drawMesh_->setPerFaceTextureCoordinatePropertyName(_halfedgeTextcoordPropertyName);
1679  perFaceTextureCoordsAvailable_ = drawMesh_->perFaceTextureCoordinateAvailable() != 0;
1680 
1681 }
1682 
1683 
1684 
1685 
1686 template<class Mesh>
1687 unsigned int
1689 {
1690  unsigned int res = 0;
1691 
1692  if (drawMesh_)
1693  res += drawMesh_->getMemoryUsage();
1694 
1695  return res;
1696 }
1697 
1698 
1699 template<class Mesh>
1702 {
1703  return drawMesh_;
1704 }
1705 
1706 
1707 
1708 
1709 //=============================================================================
1710 } // namespace SceneGraph
1711 } // namespace ACG
1712 //=============================================================================
DrawMode SOLID_FACES_COLORED_SMOOTH_SHADED
draw smooth shaded and colored faces (requires vertex normals and face colors)
Definition: DrawModes.cc:101
Mesh Drawing Class.
Definition: DrawMesh.hh:172
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:108
static GLuint getBoundTextureBuffer()
get bound texture
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition: DrawModes.cc:541
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
Definition: MeshNode2T.cc:247
size_t getNumLayers() const
returns the layer count
Definition: DrawModes.cc:537
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
Draws the object.
DrawMode EDGES_COLORED
draw edges with colors (without shading)
Definition: DrawModes.cc:83
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: MeshNode2T.cc:232
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void enable(GLenum _cap)
replaces glEnable, but supports locking
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
DrawMeshT< Mesh > * getDrawMesh()
Get DrawMesh instance.
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
Definition: DrawModes.cc:86
int viewport_width() const
get viewport width
Definition: MeshNode2T.cc:825
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
void pick_any(GLState &_state)
Renders picking for all primitives.
static void disable(GLenum _cap)
replaces glDisable, but supports locking
DrawMode HALFEDGES
draw halfedges
Definition: DrawModes.cc:108
picks faces (should be implemented for all nodes)
Definition: BaseNode.hh:104
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
DrawMode SOLID_2DTEXTURED_FACE_SHADED
draw per halfedge textured faces
Definition: DrawModes.cc:103
void update_textures()
force an texture update
void draw_halfedges()
draws all halfedges of the mesh
void update_geometry()
the geometry of the mesh has changed
const GLMatrixd & modelview() const
get modelview matrix
Definition: MeshNode2T.cc:794
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
float line_width() const
get line width
Definition: MeshNode2T.cc:978
void setIndexPropertyName(std::string _indexPropertyName)
set the name of the property used for texture index specification
DrawMode SOLID_2DTEXTURED_FACE
draw per halfedge textured faces
Definition: DrawModes.cc:102
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:87
void add_face_RenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, bool _nonindexed=false)
Draws the object.
bool flatShaded() const
Is flat shading used (Normals per face)?
Definition: MeshNode2T.cc:231
virtual ~MeshNodeT()
Destructor.
int priority
Priority to allow sorting of objects.
Definition: MeshNode2T.cc:123
void clearTextures()
disables texture support and removes all texture types
Definition: MeshNode2T.cc:200
int viewport_height() const
get viewport height
Definition: MeshNode2T.cc:827
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
const Vec4f & overlay_color() const
Get overlay color.
Definition: MeshNode2T.cc:958
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
void update_color()
the colors of the mesh have changed
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
static GLenum getBoundTextureTarget()
get bound texture target
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:88
const std::string & indexPropertyName() const
Get current texture index property name.
void pick_edges(GLState &_state, bool _front=false)
Renders picking for edges _front: Only render front edges (not occluded by geometry) ...
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:146
MeshNodeT(Mesh &_mesh, BaseNode *_parent=0, std::string _name="<MeshNode>")
Default constructor.
void enable_arrays(unsigned int _arrays)
enable/disable vertex arrays according to the bits in _arrays
picks verices (may not be implemented for all nodes)
Definition: BaseNode.hh:108
ACG::SceneGraph::DrawModes::DrawMode availableDrawModes() const
return available draw modes
void add_line_RenderObjects(IRenderer *_renderer, const RenderObject *_baseObj)
Draws the object.
void update_topology()
the topology of the mesh has changed
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
bool checkExtensionSupported(const std::string &_extension)
Definition: gl.cc:73
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
Current bounding box.
picks edges (may not be implemented for all nodes)
Definition: BaseNode.hh:106
picks only visible front verices (may not be implemented for all nodes)
Definition: BaseNode.hh:115
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
const Vec4f & color()
set color
Definition: MeshNode2T.cc:919
DrawMode SOLID_ENV_MAPPED
draw environment mapped
Definition: DrawModes.cc:93
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
DrawMode POINTS_COLORED
draw colored, but not lighted points (requires point colors)
Definition: DrawModes.cc:80
void addTextureType(GLenum _type, bool _shadow, size_t _stage)
adds a texture type to the shader and enables texturing.
Definition: MeshNode2T.cc:191
void add_point_RenderObjects(IRenderer *_renderer, const RenderObject *_baseObj)
Draws the object.
bool isAtomic() const
Check if this is an atomic draw Mode.
Definition: DrawModes.cc:518
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
void draw_faces()
draws all faces of the mesh
Vec2f depthRange
glDepthRange: (znear, zmax)
Definition: MeshNode2T.cc:256
int getLayerIndexByPrimitive(DrawModePrimitive _type) const
search for layer with specified primitive
Definition: DrawModes.cc:632
Interface class between scenegraph and renderer.
Definition: MeshNode2T.cc:105
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
void draw_vertices()
draws all vertices of the mesh
DrawMode SOLID_POINTS_COLORED
draw colored, but not lighted faces using interpolated vertex colors
Definition: DrawModes.cc:91
void pick_faces(GLState &_state)
Renders picking for faces _front: Only render front faces (not occluded by geometry) ...
void set_color(const Vec4f &_col)
set color
void pointSize(float _sz)
set point size (default: 1.0)
Definition: MeshNode2T.cc:211
DrawMode SOLID_TEXTURED
draw textured faces
Definition: DrawModes.cc:94
DrawMode POINTS_SHADED
draw shaded points (requires point normals)
Definition: DrawModes.cc:81
void glCheckErrors()
Definition: GLError.hh:105
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
DrawMode SOLID_PHONG_SHADED
draw phong shaded faces
Definition: DrawModes.cc:89
unsigned int pick_current_index() const
Returns the current color picking index (can be used for caching)
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: MeshNode2T.cc:183
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
void pick(GLState &_state, PickTarget _target)
Draws the object in picking mode.
DrawMode SOLID_FACES_COLORED
draw colored, but not lighted faces using face colors
Definition: DrawModes.cc:90
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: MeshNode2T.cc:929
unsigned int getMemoryUsage()
measures the size in bytes of allocated memory
void draw_lines()
draws all edges of the mesh
void pick_vertices(GLState &_state, bool _front=false)
Renders picking for vertices _front: Only render front vertices (not occluded by geometry) ...
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Mesh Drawing Class.
Definition: MeshNode2T.cc:172
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
void setHalfedgeTextcoordPropertyName(std::string _halfedgeTextcoordPropertyName)
Set the name of the per face texture coordinate property.
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
Draws the object deferred.
Definition: MeshNode2T.cc:677
DrawMode SOLID_TEXTURED_SHADED
draw smooth shaded textured faces
Definition: DrawModes.cc:95
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
const Vec4f & specular_color() const
get specular color
Definition: MeshNode2T.cc:944
DrawMode SOLID_FACES_COLORED_2DTEXTURED_FACE_SMOOTH_SHADED
draw per halfedge texture faces modulated with face colors with smooth shading
Definition: DrawModes.cc:110
DrawMode SOLID_FACES_COLORED_FLAT_SHADED
draw flat shaded and colored faces (requires face normals and colors)
Definition: DrawModes.cc:100
DrawMode SOLID_POINTS_COLORED_SHADED
draw faces, but use Gouraud shading to interpolate vertex colors
Definition: DrawModes.cc:92
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
DrawMode SOLID_SMOOTH_SHADED_FEATURES
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:105
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: MeshNode2T.cc:215
DrawMode HALFEDGES_COLORED
draw halfedges with colors (without shading)
Definition: DrawModes.cc:109
picks only visible front edges (may not be implemented for all nodes)
Definition: BaseNode.hh:113
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:77
const Vec4f & clear_color() const
get background color
Definition: MeshNode2T.cc:924
QString vertexColorsInterpolator
interpolation qualifier for input vertex colors: "flat", "smooth", "noperspective" ...
Definition: MeshNode2T.cc:168
const GLMatrixd & projection() const
get projection matrix
Definition: MeshNode2T.cc:789
bool color_picking() const
Is color picking active?