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