MeshNode2T.cc 40.8 KB
Newer Older
1 2 3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  OpenFlipper is free software: you can redistribute it and/or modify      *
 *  it under the terms of the GNU Lesser General Public License as           *
 *  published by the Free Software Foundation, either version 3 of           *
 *  the License, or (at your option) any later version with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenFlipper is distributed in the hope that it will be useful,           *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *  GNU Lesser General Public License for more details.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37 38 39
 *   $Revision$                                                       *
 *   $Author$                                                      *
 *   $Date$                   *
40 41 42 43 44 45 46 47 48 49 50 51 52 53
 *                                                                           *
\*===========================================================================*/




//=============================================================================
//
//  CLASS MeshNodeT - IMPLEMENTATION
//
//=============================================================================

#define ACG_MESHNODE_C

54
#include <ACG/Geometry/GPUCacheOptimizer.hh>
55
#include <ACG/GL/DrawMesh.hh>
56

57 58 59 60 61 62 63 64 65 66 67 68 69
//== NAMESPACES ===============================================================


namespace ACG {
namespace SceneGraph {
    

//== INCLUDES =================================================================


#include "MeshNode2T.hh"

template<class Mesh>
Jan Möbius's avatar
Jan Möbius committed
70 71
MeshNodeT<Mesh>::
MeshNodeT(Mesh&        _mesh,
72
              BaseNode*    _parent,
Jan Möbius's avatar
Jan Möbius committed
73 74
              std::string  _name ): 
  BaseNode(_parent, _name),
75
  mesh_(_mesh),
76
  drawMesh_(0),
77 78
  enableNormals_(true),
  enableColors_(true),
Jan Möbius's avatar
Jan Möbius committed
79
  enabled_arrays_(0),
80
  updateVertexPicking_(true),
Jan Möbius's avatar
Jan Möbius committed
81
  vertexPickingBaseIndex_(0),
82
  updateEdgePicking_(true),
Jan Möbius's avatar
Jan Möbius committed
83
  edgePickingBaseIndex_(0),
84
  updateFacePicking_(true),
Jan Möbius's avatar
Jan Möbius committed
85
  facePickingBaseIndex_(0),
86
  updateAnyPicking_(true),
87
  anyPickingBaseIndex_(0),
88
  perFaceTextureIndexAvailable_(false),
89
  perFaceTextureCoordsAvailable_(false),
90
  textureMap_(0)
91
{
92
 
93
  /// \todo : Handle vbo not supported
94
  if ( ! checkExtensionSupported("GL_ARB_vertex_buffer_object") ) {
95 96
    std::cerr << "Error! Vertex buffer objects are not supported! The meshNode will not work without them!" << std::endl;
  }
Jan Möbius's avatar
Jan Möbius committed
97
  
98
  drawMesh_ = new DrawMeshT<Mesh>(mesh_);
99
  
100 101 102
}  

template<class Mesh>
Jan Möbius's avatar
Jan Möbius committed
103
MeshNodeT<Mesh>::
104 105 106
~MeshNodeT()
{
  // Delete all allocated buffers
107
  delete drawMesh_;
108 109 110
}

template<class Mesh>
Jan Möbius's avatar
Jan Möbius committed
111
DrawModes::DrawMode
Jan Möbius's avatar
Jan Möbius committed
112
MeshNodeT<Mesh>::
113
availableDrawModes() const {
Jan Möbius's avatar
Jan Möbius committed
114
  DrawModes::DrawMode drawModes(DrawModes::NONE);
115
  
116
  // We can always render points and a wireframe.
117
  drawModes |= DrawModes::POINTS;
Jan Möbius's avatar
Jan Möbius committed
118
  drawModes |= DrawModes::HIDDENLINE;
119
  drawModes |= DrawModes::WIREFRAME;
120
  drawModes |= DrawModes::HALFEDGES;
121
  
122 123
  if (mesh_.has_vertex_normals())
  {
124 125
    drawModes |= DrawModes::POINTS_SHADED;  
    drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
Jan Möbius's avatar
Jan Möbius committed
126
    drawModes |= DrawModes::SOLID_PHONG_SHADED;
127 128
  }
  
129 130
  if (mesh_.has_face_normals())
    drawModes |= DrawModes::SOLID_FLAT_SHADED;
131 132 133

  if (mesh_.has_halfedge_normals())
    drawModes |= DrawModes::SOLID_SMOOTH_SHADED_FEATURES;
134
  
135 136 137
  if (mesh_.has_vertex_colors())
  {
    drawModes |= DrawModes::POINTS_COLORED;
138
    drawModes |= DrawModes::SOLID_POINTS_COLORED;
139 140 141

    if (mesh_.has_vertex_normals())
      drawModes |= DrawModes::SOLID_POINTS_COLORED_SHADED;
142
  }
143 144 145 146 147

  if(mesh_.has_edge_colors())
  {
    drawModes |= DrawModes::EDGES_COLORED;
  }
148 149 150 151 152

  if(mesh_.has_halfedge_colors())
  {
    drawModes |= DrawModes::HALFEDGES_COLORED;
  }
153
  
154 155 156 157 158
  if (mesh_.has_face_colors()) {
    drawModes |= DrawModes::SOLID_FACES_COLORED;
    
    if( mesh_.has_face_normals() )
      drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
159 160 161

    if( mesh().has_vertex_normals() )
      drawModes |= DrawModes::SOLID_FACES_COLORED_SMOOTH_SHADED;
162 163
  }
  
164 165 166
  if ( mesh_.has_vertex_texcoords2D() ) {
    drawModes |= DrawModes::SOLID_TEXTURED;
    
167 168
    if (mesh_.has_vertex_normals())
      drawModes |= DrawModes::SOLID_TEXTURED_SHADED; 
169 170
  }
  
171
  if ( perFaceTextureCoordsAvailable_ ) {
172 173 174 175 176 177
    drawModes |= DrawModes::SOLID_2DTEXTURED_FACE;
    
    if (mesh_.has_face_normals())
      drawModes |= DrawModes::SOLID_2DTEXTURED_FACE_SHADED;
  }
  
178 179 180 181 182
  return drawModes;
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
183
MeshNodeT<Mesh>::
184
boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) {
Jan Möbius's avatar
Jan Möbius committed
185 186
  _bbMin.minimize(bbMin_);
  _bbMax.maximize(bbMax_);
187 188 189 190
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
191
MeshNodeT<Mesh>::
192
draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
/*  
  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) ||
    ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED) ||
    ( _drawMode & DrawModes::SOLID_TEXTURED) ||
    ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE))
  {
    drawMesh_->setFlatShading();
  }
  else
    drawMesh_->setSmoothShading();


  if ( (_drawMode & DrawModes::SOLID_FACES_COLORED ||
    _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED))
  {
    drawMesh_->usePerFaceColors();
  }
  else
    drawMesh_->usePerVertexColors();
*/
213
    
214
  GLenum prev_depth = _state.depthFunc();
215
  
216
  glPushAttrib(GL_ENABLE_BIT);
217

218 219 220 221 222 223 224 225
  /// get bound texture buffer and target
  GLuint lastBuffer = ACG::GLState::getBoundTextureBuffer();
  GLenum lastTarget = ACG::GLState::getBoundTextureTarget();

  // Unbind to avoid painting textures on non textured primitives
  ACG::GLState::bindTexture(lastTarget,0);


226
  if ( (_drawMode & DrawModes::POINTS) || (_drawMode & DrawModes::POINTS_COLORED) || (_drawMode & DrawModes::POINTS_SHADED )  ) {
227
    
228 229
    _state.set_color( _state.specular_color() );

230
    ACG::GLState::shadeModel(GL_FLAT);
231 232
    
    if ( _drawMode & DrawModes::POINTS_SHADED  ) {
233
      ACG::GLState::enable(GL_LIGHTING);
234
    } else
235
      ACG::GLState::disable(GL_LIGHTING);
236
  
237 238
    // Use Colors in this mode if allowed
    if ( enableColors_ && (_drawMode & DrawModes::POINTS_COLORED) )
239 240 241
    {
      drawMesh_->usePerVertexColors();

242
      // If we have colors and lighting with normals, we have to use colormaterial
243
      if ( enableNormals_ && (_drawMode & DrawModes::POINTS_SHADED ) )
244
        ACG::GLState::enable(GL_COLOR_MATERIAL);
245
      else
246
        ACG::GLState::disable(GL_COLOR_MATERIAL);
247
    }
248 249
    else
      drawMesh_->disableColors();
250
    
251
    // Bring the arrays online
252
//    enable_arrays(arrays);
253 254
    
    // Draw vertices
255 256 257
    draw_vertices();
  }
  
258 259
  
  /// \todo We can render also wireframe shaded and with vertex colors
260 261
  if (_drawMode & DrawModes::WIREFRAME)
  {
262 263 264 265 266 267 268 269

    const Vec4f oldColor = _state.color();

    // If the mode is atomic, we use the specular, otherwise we take the overlay color
    if (_drawMode.isAtomic() )
      _state.set_color( _state.specular_color() );
    else
      _state.set_color( _state.overlay_color() );
270

271 272
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
273 274 275

    drawMesh_->disableColors();

276
    draw_lines();
277 278

    _state.set_color(oldColor);
Jan Möbius's avatar
Jan Möbius committed
279
  }  
280
  
Jan Möbius's avatar
Jan Möbius committed
281 282
  if (_drawMode & DrawModes::HIDDENLINE)
  {
283
//    enable_arrays(VERTEX_ARRAY);
Jan Möbius's avatar
Jan Möbius committed
284 285 286
    
    // First:
    // Render all faces in background color to initialize z-buffer
287 288
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
289
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
290 291 292

//    drawMesh_->SetFlatShading();
    drawMesh_->disableColors();
293 294 295

    Vec4f  clear_color  = _state.clear_color();
    clear_color[3] = 1.0;
296
    _state.set_color( clear_color );
297

298
    ACG::GLState::depthRange(0.01, 1.0);
299
    draw_faces();
300
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
301 302 303
    
    // Second
    // Render the lines. All lines not on the front will be skipped in z-test
304
//    enable_arrays(VERTEX_ARRAY|LINE_INDEX_ARRAY);
305
    ACG::GLState::depthFunc(GL_LEQUAL);
306

307
    _state.set_color( _state.specular_color() );
308

Jan Möbius's avatar
Jan Möbius committed
309
    draw_lines();
310 311
    
    //restore depth buffer comparison function for the next draw calls inside this function
312
    ACG::GLState::depthFunc(prev_depth);
Jan Möbius's avatar
Jan Möbius committed
313 314
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }
315 316 317 318 319


  if (_drawMode & DrawModes::EDGES_COLORED)
  {
    enable_arrays( PER_EDGE_VERTEX_ARRAY | PER_EDGE_COLOR_ARRAY );
320 321
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
322 323 324
    draw_lines();
  }  

325 326
  if (_drawMode & DrawModes::HALFEDGES)
  {
327
    _state.set_color( _state.specular_color() );
328

329
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY);
330 331
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
332 333 334 335 336 337
    draw_halfedges();
  }  

  if (_drawMode & DrawModes::HALFEDGES_COLORED)
  {
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY | PER_HALFEDGE_COLOR_ARRAY );
338 339
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
340 341
    draw_halfedges();
  }  
342

343
  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors() )
344 345 346 347 348 349 350 351 352 353 354 355
  {
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
    ACG::GLState::depthRange(0.01, 1.0);

    drawMesh_->usePerVertexColors();

    draw_faces();
    ACG::GLState::depthRange(0.0, 1.0);
  }

  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED_SHADED ) && mesh_.has_vertex_colors() && mesh_.has_vertex_normals() )
356
  {
357 358
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
359
    ACG::GLState::depthRange(0.01, 1.0);
360
    if ( enableNormals_ ) {
361
       ACG::GLState::enable(GL_COLOR_MATERIAL);
362
    } else {
363
      ACG::GLState::disable(GL_COLOR_MATERIAL);
364
    }
365

366 367
    drawMesh_->usePerVertexColors();

368
    draw_faces();
369
    ACG::GLState::depthRange(0.0, 1.0);
370
  }
371

372
  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
373
  {
374 375
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
376
    ACG::GLState::depthRange(0.01, 1.0);
377 378 379 380 381

    drawMesh_->setFlatShading();
    drawMesh_->disableColors();

    draw_faces();
382
    ACG::GLState::depthRange(0.0, 1.0);
383 384
  }
  
Jan Möbius's avatar
Jan Möbius committed
385 386
  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals() )
  {
387 388
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
389
    ACG::GLState::depthRange(0.01, 1.0);
390

391
    drawMesh_->usePerVertexNormals();
392 393 394
    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
    draw_faces();
395
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
396 397 398 399 400 401 402 403 404 405 406 407 408 409
  }
  
  if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
  {
    ///\todo Integrate shader here! 
    //     if ( parent() != 0 ) {
    //       if ( parent()->className() == "ShaderNode" ) {
    //
    //         ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
    //
    //         GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
    //
    //         // Enable own Phong shader
    //         program->use();
410
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY );
Jan Möbius's avatar
Jan Möbius committed
411
    ACG::GLState::disable(GL_LIGHTING);
412
    ACG::GLState::shadeModel(GL_SMOOTH);
413
    ACG::GLState::depthRange(0.01, 1.0);
414

Jan Möbius's avatar
Jan Möbius committed
415
    drawMesh_->usePerVertexNormals();
416 417 418 419
    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();

    draw_faces();
420
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
421 422 423 424 425 426 427
    
    //disable own Phong shader
    //         program->disable();
    //       }
    //     }
  }
  
428
  
429
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED ) && mesh_.has_face_colors()  && mesh_.n_faces() > 0)
430 431 432
  {
    Vec4f base_color_backup = _state.base_color();
    
433 434
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
435
    ACG::GLState::depthRange(0.01, 1.0);
436 437 438 439 440
//    enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY);    

    drawMesh_->usePerFaceColors();

    draw_faces();
441
    ACG::GLState::depthRange(0.0, 1.0);
442 443 444
    
    _state.set_base_color(base_color_backup);
  }
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460


  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED_FEATURES ) && mesh_.has_halfedge_normals()  && mesh_.n_faces() > 0)
  {
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
    ACG::GLState::depthRange(0.01, 1.0);

    drawMesh_->disableColors();
    drawMesh_->setSmoothShading();
    drawMesh_->usePerHalfedgeNormals();

    draw_faces();

    ACG::GLState::depthRange(0.0, 1.0);
  }
461
  
462
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals()  && mesh_.n_faces() > 0 )
463 464
  {
    Vec4f base_color_backup = _state.base_color();
465
    ACG::GLState::enable(GL_LIGHTING);
466
    
467
    ACG::GLState::shadeModel(GL_FLAT);
468
    ACG::GLState::depthRange(0.01, 1.0);
469 470 471 472 473 474
//    enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY | PER_FACE_NORMAL_ARRAY );

    drawMesh_->setFlatShading();
    drawMesh_->usePerFaceColors();

    draw_faces();
475
    ACG::GLState::depthRange(0.0, 1.0);
476 477 478
    
    _state.set_base_color(base_color_backup);
  }
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497

  
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_SMOOTH_SHADED ) && mesh_.has_face_colors() && mesh_.has_vertex_normals() && mesh_.n_faces() > 0)
  {
    Vec4f base_color_backup = _state.base_color();

    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
    ACG::GLState::depthRange(0.01, 1.0);

    drawMesh_->setSmoothShading();
    drawMesh_->usePerVertexNormals();
    drawMesh_->usePerFaceColors();

    draw_faces();
    ACG::GLState::depthRange(0.0, 1.0);

    _state.set_base_color(base_color_backup);
  }
498 499 500 501

  // Rebind the previous texture
  ACG::GLState::bindTexture(lastTarget,lastBuffer);

502
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED )  && mesh_.has_vertex_texcoords2D())
503 504
  {
    ///\todo enableTexCoords_
505
//    enable_arrays(VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY );
506 507 508
    ACG::GLState::enable(GL_TEXTURE_2D);
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
509
    ACG::GLState::depthRange(0.01, 1.0);
510 511

    drawMesh_->disableColors();
512
    drawMesh_->usePerVertexTexcoords();
513 514

    draw_faces();
515
    ACG::GLState::depthRange(0.0, 1.0);
516
    ACG::GLState::disable(GL_TEXTURE_2D);
517 518
  }
  
519 520
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
  {
521
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY);
522 523 524
    ACG::GLState::enable(GL_TEXTURE_2D);
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
525
    ACG::GLState::depthRange(0.01, 1.0);
526 527 528

    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
529
    drawMesh_->usePerVertexTexcoords();
530 531

    draw_faces();
532
    ACG::GLState::depthRange(0.0, 1.0);
533
    ACG::GLState::disable(GL_TEXTURE_2D);
534 535
  }
  
536
    
537
  // Textured by using coordinates stored in halfedges ... arrays generated by stripprocessor
538
  if ( (_drawMode & DrawModes::SOLID_2DTEXTURED_FACE)  && mesh_.n_faces() > 0 )
539
  {
540
    ACG::GLState::enable(GL_TEXTURE_2D);
541
    
542
//    enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY );
543
    
544 545
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
546
    ACG::GLState::depthRange(0.01, 1.0);
547 548

    drawMesh_->disableColors();
549
    drawMesh_->usePerHalfedgeTexcoords();
550

551 552
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

553
    draw_faces();
554
    ACG::GLState::depthRange(0.0, 1.0);
555
    
556
    ACG::GLState::disable(GL_TEXTURE_2D);
557 558
  }
  
559

560
  // Textured by using coordinates stored in halfedges
561
  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_face_normals()  && mesh_.n_faces() > 0)
562
  {
563
    ACG::GLState::enable(GL_TEXTURE_2D);
564 565

    //    enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY | PER_FACE_PER_VERTEX_NORMAL_ARRAY );
566

567
    ACG::GLState::enable(GL_LIGHTING);
568
    ACG::GLState::shadeModel(GL_FLAT);
569
    ACG::GLState::depthRange(0.01, 1.0);
570

571
    drawMesh_->setFlatShading();
572
    drawMesh_->disableColors();
573
    drawMesh_->usePerHalfedgeTexcoords();
574 575

    draw_faces();
576
    ACG::GLState::depthRange(0.0, 1.0);
577
    ACG::GLState::disable(GL_TEXTURE_2D);
578

579
  }
580

Jan Möbius's avatar
Jan Möbius committed
581 582
  enable_arrays(0);
  
583
  // Unbind all remaining buffers
584
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB , 0 );
585
  
586
  glPopAttrib();
587 588
}

589 590

template <class Mesh>
591
void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
592
{
593 594
  RenderObject ro;
  ro.initFromState(&_state);
595 596 597

  ro.debugName = "MeshNode";
   
598 599 600 601 602 603 604 605 606 607 608 609
  // shader gen setup (lighting, shademode, vertex-colors..)
  
  for (unsigned int i = 0; i < _drawMode.getNumLayers(); ++i)
  {
    const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);

    // reset renderobject
    ro.priority = 0;
    ro.depthRange = Vec2f(0.0f, 1.0f);
    ro.depthTest = true; // some previous node disabled depth testing
    ro.depthWrite = true;
    ro.depthFunc = GL_LESS;
610
    ro.setMaterial(_mat);
611

Jan Möbius's avatar
Jan Möbius committed
612

613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
    // ------------------------
    // 1. setup drawMesh based on property source


    if (props->flatShaded())
      drawMesh_->setFlatShading();
    else
      drawMesh_->setSmoothShading();


    ro.shaderDesc.vertexColors = true;

    switch (props->colorSource())
    {
    case DrawModes::COLOR_PER_VERTEX: drawMesh_->usePerVertexColors(); break;
    case DrawModes::COLOR_PER_FACE: drawMesh_->usePerFaceColors(); break;
    default:
      {
        drawMesh_->disableColors(); 
        ro.shaderDesc.vertexColors = false;
      } break;
    }

    switch (props->normalSource())
    {
    case DrawModes::NORMAL_PER_VERTEX: drawMesh_->usePerVertexNormals(); break;
    case DrawModes::NORMAL_PER_HALFEDGE: drawMesh_->usePerHalfedgeNormals(); break;
    default: break;
    }

643
    ro.shaderDesc.addTextureType(GL_TEXTURE_2D,false,0);
644 645 646 647 648 649 650

    switch (props->texcoordSource())
    {
    case DrawModes::TEXCOORD_PER_VERTEX: drawMesh_->usePerVertexTexcoords(); break;
    case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
    default:
      {
651
        ro.shaderDesc.clearTextures();
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
      }break;
    }

    // ------------------------
    // 2. prepare renderobject


    // enable / disable lighting
    ro.shaderDesc.numLights = props->lighting() ? 0 : -1;

    // TODO: better handling of attribute sources in shader gen

    switch (props->lightStage())
    {
    case DrawModes::LIGHTSTAGE_SMOOTH: ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD; break;;
    case DrawModes::LIGHTSTAGE_PHONG: ro.shaderDesc.shadeMode = SG_SHADE_PHONG; break;;
    case DrawModes::LIGHTSTAGE_UNLIT: ro.shaderDesc.shadeMode = SG_SHADE_UNLIT; break;;
    }

Jan Möbius's avatar
Jan Möbius committed
671 672
    if (props->flatShaded())
      ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
673 674 675 676 677 678 679 680

    // handle 'special' primitives (wireframe, hiddenline, primitives in sysmem buffers)..

    if (props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
    {
      ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
      drawMesh_->disableColors();

681
      // use specular color for lines
682 683 684 685 686
      if (_drawMode.isAtomic() )
        ro.emissive = ro.specular;
      else
        ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());

687

688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
      add_line_RenderObjects(_renderer, &ro);
    }

    if (props->primitive()  == DrawModes::PRIMITIVE_HIDDENLINE)
    {
      // First:
      // Render all faces in background color to initialize z-buffer

      ro.priority = -1; // priority allows sorting for layers

      ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;

      // color mask = none
      // depth mask = enabled
      ro.glColorMask(0,0,0,0);
      ro.depthTest = true;
      ro.depthWrite = true;
      ro.depthFunc = GL_LESS;

      ro.fillMode = GL_FILL;

      drawMesh_->disableColors();

      ro.depthRange = Vec2f(0.01f, 1.0f);

      add_face_RenderObjects(_renderer, &ro);


      // Second
      // Render the lines. All lines not on the front will be skipped in z-test
      ro.priority = 0; // render after z cullers

      ro.glColorMask(1,1,1,1);
      ro.depthTest = true;
      ro.depthWrite = true;
      ro.depthFunc = GL_LEQUAL;

      ro.depthRange = Vec2f(0.0f, 1.0f);

727 728 729
      // use specular color for lines
      ro.emissive = ro.specular;

730 731 732 733 734 735 736 737 738 739 740 741
      add_line_RenderObjects(_renderer, &ro);
    }

    if (props->colored() && props->primitive()  == DrawModes::PRIMITIVE_EDGE)
    {
      ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
      ro.shaderDesc.vertexColors = true;

      // note: colored edges are in sysmem, so they are directly bound to the VertexDeclaration
      ro.vertexDecl = drawMesh_->getEdgeColoredVertexDeclaration();
      ro.glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);

742 743 744
      // use specular color for lines
      ro.emissive = ro.specular;

745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
      _renderer->addRenderObject(&ro);

       // skip other edge primitives for this drawmode layer
      continue;
    }  

    if (props->primitive()  == DrawModes::PRIMITIVE_HALFEDGE)
    {
      ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;

      // buffers in sysmem
      if (props->colored())
        ro.vertexDecl = drawMesh_->getHalfedgeVertexDeclaration();
      else
        ro.vertexDecl = drawMesh_->getHalfedgeColoredVertexDeclaration();

761 762 763
      // use specular color for lines
      ro.emissive = ro.specular;

764 765 766 767 768 769 770 771 772 773 774 775 776 777
      ro.glDrawArrays(GL_LINES, 0, mesh_.n_halfedges() * 2);

      _renderer->addRenderObject(&ro);
    }  


    // -----------------------------------------------------
    // take care of all the other primitives

    ro.depthRange = Vec2f(0.01f, 1.0f);

    switch (props->primitive())
    {
    case DrawModes::PRIMITIVE_POINT: add_point_RenderObjects(_renderer, &ro); break;
778 779 780 781 782 783
    case DrawModes::PRIMITIVE_EDGE:
      {
        // use specular color for lines
        ro.emissive = ro.specular;
        add_line_RenderObjects(_renderer, &ro);
      } break;
784
    case DrawModes::PRIMITIVE_POLYGON: add_face_RenderObjects(_renderer, &ro); break;
Jan Möbius's avatar
Jan Möbius committed
785
    default: break;
786 787
    }
  }
788 789 790 791 792 793 794 795 796 797 798

}


template<class Mesh>
void
MeshNodeT<Mesh>::
add_point_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
  drawMesh_->addPointRenderObjects(_renderer, _baseObj);
}

799 800
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
801
MeshNodeT<Mesh>::
802
draw_vertices() {
803
  drawMesh_->drawVertices();
804 805
}

806 807
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
808
MeshNodeT<Mesh>::
809
draw_lines() {
810

811 812 813
  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
  {
    // colored edges still slow
814
    glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
815
  }
816
  else
817
    drawMesh_->drawLines();
818 819
}

820 821 822 823 824 825 826 827 828 829 830 831 832
template<class Mesh>
void
MeshNodeT<Mesh>::
add_line_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {

  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
  {
    // colored edges still slow
    glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
  }
  else
    drawMesh_->addLineRenderObjects(_renderer, _baseObj);
}
833 834 835 836 837 838 839 840 841 842 843 844 845

template<class Mesh>
void
MeshNodeT<Mesh>::
draw_halfedges() {
  // If we are rendering per edge per vertex attributes, we need to use a seperated vertex buffer!
  if ( enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY )
    glDrawArrays(GL_LINES, 0, mesh_.n_halfedges() * 2);
  // Something went wrong here!
  else
    std::cerr << "Unable to Draw! halfedge array configuration is invalid!!" << std::endl;
}

846 847
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
848
MeshNodeT<Mesh>::
849 850
draw_faces() {
  drawMesh_->draw(textureMap_);
851 852
}

853 854 855 856 857 858 859
template<class Mesh>
void
MeshNodeT<Mesh>::
add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
  drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_);
}

860 861
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
862
MeshNodeT<Mesh>::
863
enable_arrays(unsigned int _arrays) {
864

Jan Möbius's avatar
Jan Möbius committed
865
  // Unbind everything to ensure sane settings
866 867
  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
868

869 870 871 872 873 874 875 876 877 878 879 880
  //===================================================================
  // per Edge Vertex Array
  //===================================================================  
  
  // Check if we should enable the per face vertex array
  if (_arrays & PER_EDGE_VERTEX_ARRAY)  {
    
    // Check if its already enabled
    if (!(enabled_arrays_ & PER_EDGE_VERTEX_ARRAY)) {
      enabled_arrays_ |= PER_EDGE_VERTEX_ARRAY;
      
      // For this version we load the colors directly not from vbo
881 882
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::vertexPointer( drawMesh_->perEdgeVertexBuffer() );   
883
      
884
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
885 886 887 888 889
      
    }
  } else if (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_VERTEX_ARRAY;
890
    ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
891 892 893 894 895 896 897 898 899 900 901 902 903 904
  } 
  
  //===================================================================
  // per Edge Color Array
  //===================================================================  
  
  // Check if we should enable the per face vertex array
  if ( mesh_.has_edge_colors()  && ( _arrays & PER_EDGE_COLOR_ARRAY) )  {
    
    // Check if its already enabled
    if (!(enabled_arrays_ & PER_EDGE_COLOR_ARRAY)) {
      enabled_arrays_ |= PER_EDGE_COLOR_ARRAY;
      
      // For this version we load the colors directly not from vbo
905 906
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->perEdgeColorBuffer() );
907
      
908
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
909 910 911 912 913
      
    }
  } else if (enabled_arrays_ & PER_EDGE_COLOR_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_COLOR_ARRAY;
914
    ACG::GLState::disableClientState(GL_COLOR_ARRAY);
915
  }   
916 917 918 919 920 921 922 923 924 925 926 927 928 929


  //===================================================================
  // per Halfedge Vertex Array
  //===================================================================  
  
  // Check if we should enable the per face vertex array
  if (_arrays & PER_HALFEDGE_VERTEX_ARRAY)  {
    
    // Check if its already enabled
    if (!(enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY)) {
      enabled_arrays_ |= PER_HALFEDGE_VERTEX_ARRAY;
      
      // For this version we load the colors directly not from vbo
930 931
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::vertexPointer( drawMesh_->perHalfedgeVertexBuffer() );   
932
      
933
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
934 935 936 937 938
      
    }
  } else if (enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_HALFEDGE_VERTEX_ARRAY;
939
    ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
940 941 942 943 944 945 946 947 948 949 950 951 952 953
  } 
  
  //===================================================================
  // per Halfedge Color Array
  //===================================================================  
  
  // Check if we should enable the per face vertex array
  if ( mesh_.has_halfedge_colors()  && ( _arrays & PER_HALFEDGE_COLOR_ARRAY) )  {
    
    // Check if its already enabled
    if (!(enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY)) {
      enabled_arrays_ |= PER_HALFEDGE_COLOR_ARRAY;
      
      // For this version we load the colors directly not from vbo
954 955
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->perHalfedgeColorBuffer() );
956
      
957
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
958 959 960 961 962
      
    }
  } else if (enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_HALFEDGE_COLOR_ARRAY;
963
    ACG::GLState::disableClientState(GL_COLOR_ARRAY);
964
  }   
965

966 967 968 969
  //===================================================================
  // Check for OpenGL Errors
  //===================================================================    
  glCheckErrors();
970 971 972 973
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
974
MeshNodeT<Mesh>::
975
pick(GLState& _state, PickTarget _target) {
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
  switch (_target)
  {
    case PICK_VERTEX:
    {
      pick_vertices(_state);
      break;
    }
    case PICK_FRONT_VERTEX:
    {
      pick_vertices(_state, true);
      break;
    }
    
    case PICK_ANYTHING:
    {
      pick_any(_state);
      break;
    }
    case PICK_FACE:
    {
      pick_faces(_state);
      break;
    }
    
    case PICK_EDGE:
    {
      pick_edges(_state);
      break;
    }
    
    case PICK_FRONT_EDGE:
    {
      pick_edges(_state, true);
      break;
    }
    
    default:
      break;
  }
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
1019
MeshNodeT<Mesh>::
1020
pick_vertices(GLState& _state, bool _front)
1021
{  
1022
  GLenum prev_depth = _state.depthFunc();
1023
  
Jan Möbius's avatar
Jan Möbius committed
1024 1025
  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
  v_end(mesh_.vertices_end());
1026
  
Jan Möbius's avatar
Jan Möbius committed
1027
  if (!_state.pick_set_maximum (mesh_.n_vertices())) {
1028
    omerr() << "MeshNode::pick_vertices: color range too small, " << "picking failed\n";
Jan Möbius's avatar
Jan Möbius committed
1029 1030 1031
    return;
  }
  
1032 1033 1034 1035 1036 1037
  if ( mesh_.n_vertices() == 0 ) {
    std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl;
    return;
  }
  
  if (_front && ( mesh_.n_faces() != 0 ) ) {
Jan Möbius's avatar
Jan Möbius committed
1038 1039 1040 1041
    
    Vec4f  clear_color = _state.clear_color();
    Vec4f  base_color  = _state.base_color();
    clear_color[3] = 1.0;
1042

Jan Möbius's avatar
Jan Möbius committed
1043
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1044
    glColor(clear_color);
Jan Möbius's avatar
Jan Möbius committed
1045
    
1046
    ACG::GLState::depthRange(0.01, 1.0);
1047
    draw_faces();
1048
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
1049 1050
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1051
    ACG::GLState::depthFunc(GL_LEQUAL);
1052
    glColor(base_color);
Jan Möbius's avatar
Jan Möbius committed
1053 1054 1055 1056
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }
  
1057
  if (_state.color_picking () ) {
1058
    
1059 1060 1061 1062 1063
    if ( updateVertexPicking_ || _state.pick_current_index () != vertexPickingBaseIndex_) {
      drawMesh_->updatePickingVertices(_state);
      vertexPickingBaseIndex_ = _state.pick_current_index ();
      updateVertexPicking_    = false;
    }
1064
    
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
    if (drawMesh_) {
      
      // For this version we load the colors directly not from vbo
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->pickVertexColorBuffer() );   
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);    
      
      // vertex positions
      ACG::GLState::vertexPointer( drawMesh_->pickVertexBuffer() );
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
      
      // Draw color picking
      glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
      
      // Disable color array
      ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1081
      
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
      // disable vertex array
      ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
      
    } else {
     std::cerr << "pick_vertices: No vertices in Mesh!" << std::endl; 
    }
    
  } else {
    std::cerr << "No fallback pick_vertices!" << std::endl;
  }
  
1093
  ACG::GLState::depthFunc(prev_depth);
1094
  
1095 1096 1097 1098
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
1099
MeshNodeT<Mesh>::
1100
pick_edges(GLState& _state, bool _front)
1101
{  
1102
  GLenum prev_depth = _state.depthFunc();
1103
  
Jan Möbius's avatar
Jan Möbius committed
1104
  if (!_state.pick_set_maximum (mesh_.n_edges())) {
1105
    omerr() << "MeshNode::pick_edges: color range too small, " << "picking failed\n";
Jan Möbius's avatar
Jan Möbius committed
1106 1107 1108
    return;
  }
  
1109 1110 1111 1112 1113 1114
  if ( mesh_.n_vertices() == 0 ) {
    std::cerr << "pick_edges: No vertices in Mesh!" << std::endl;
    return;
  }
  
  if ( _front && ( mesh_.n_faces() != 0 ) ) {
Jan Möbius's avatar
Jan Möbius committed
1115 1116 1117 1118 1119 1120
    
    Vec4f  clear_color = _state.clear_color();
    Vec4f  base_color  = _state.base_color();
    clear_color[3] = 1.0;
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1121
    glColor(clear_color);
Jan Möbius's avatar
Jan Möbius committed
1122
    
1123
    ACG::GLState::depthRange(0.01, 1.0);
1124
    draw_faces();
1125
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
1126 1127
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1128
    ACG::GLState::depthFunc(GL_LEQUAL);
1129
    glColor(base_color);
Jan Möbius's avatar
Jan Möbius committed
1130 1131 1132
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    
1133
    // disable all other arrays
Jan Möbius's avatar
Jan Möbius committed
1134 1135 1136
    enable_arrays(0);
  }
  
1137
  if (_state.color_picking () ) {
Jan Möbius's avatar
Jan Möbius committed
1138
    
1139 1140 1141 1142 1143 1144
    if ( updateEdgePicking_ || _state.pick_current_index () != edgePickingBaseIndex_) {
      drawMesh_->updatePickingEdges(_state);
      edgePickingBaseIndex_ = _state.pick_current_index ();
      updateEdgePicking_    = false;
    }
    
1145
    if ( mesh_.n_edges() != 0 && drawMesh_) {
1146 1147
      
      // For this version we load the colors directly not from vbo
1148
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
1149
      
1150 1151
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1152
      
1153 1154
      ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
      ACG::GLState::colorPointer(drawMesh_->pickEdgeColorBuffer());
1155 1156 1157
      
      glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
      
1158 1159
      ACG::GLState::disableClientState(GL_COLOR_ARRAY);
      ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
Jan Möbius's avatar