MeshNode2T.cc 33 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>::
Jan Möbius's avatar
Jan Möbius committed
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
131
  if (mesh_.has_face_normals())
    drawModes |= DrawModes::SOLID_FLAT_SHADED;
  
132
133
134
  if (mesh_.has_vertex_colors())
  {
    drawModes |= DrawModes::POINTS_COLORED;
135
    drawModes |= DrawModes::SOLID_POINTS_COLORED;
136
  }
137
138
139
140
141

  if(mesh_.has_edge_colors())
  {
    drawModes |= DrawModes::EDGES_COLORED;
  }
142
143
144
145
146

  if(mesh_.has_halfedge_colors())
  {
    drawModes |= DrawModes::HALFEDGES_COLORED;
  }
147
  
148
149
150
151
152
153
154
  if (mesh_.has_face_colors()) {
    drawModes |= DrawModes::SOLID_FACES_COLORED;
    
    if( mesh_.has_face_normals() )
      drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
  }
  
155
156
157
  if ( mesh_.has_vertex_texcoords2D() ) {
    drawModes |= DrawModes::SOLID_TEXTURED;
    
158
159
    if (mesh_.has_vertex_normals())
      drawModes |= DrawModes::SOLID_TEXTURED_SHADED; 
160
161
  }
  
162
  if ( perFaceTextureCoordsAvailable_ ) {
163
164
165
166
167
168
    drawModes |= DrawModes::SOLID_2DTEXTURED_FACE;
    
    if (mesh_.has_face_normals())
      drawModes |= DrawModes::SOLID_2DTEXTURED_FACE_SHADED;
  }
  
169
170
171
172
173
  return drawModes;
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
174
MeshNodeT<Mesh>::
175
boundingBox(Vec3d& _bbMin, Vec3d& _bbMax) {
Jan Möbius's avatar
Jan Möbius committed
176
177
  _bbMin.minimize(bbMin_);
  _bbMax.maximize(bbMax_);
178
179
180
181
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
182
MeshNodeT<Mesh>::
183
draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*  
  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();
*/
204
    
205
  GLenum prev_depth = _state.depthFunc();
206
  
207
  unsigned int arrays = NONE;
208
  
209
  glPushAttrib(GL_ENABLE_BIT);
210

211
212
213
214
215
216
217
218
  /// 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);


219
  if ( (_drawMode & DrawModes::POINTS) || (_drawMode & DrawModes::POINTS_COLORED) || (_drawMode & DrawModes::POINTS_SHADED )  ) {
220
    
221
    ACG::GLState::shadeModel(GL_FLAT);
222
223
    
    if ( _drawMode & DrawModes::POINTS_SHADED  ) {
224
      ACG::GLState::enable(GL_LIGHTING);
225
    } else
226
      ACG::GLState::disable(GL_LIGHTING);
227
  
228
229
    // Use Colors in this mode if allowed
    if ( enableColors_ && (_drawMode & DrawModes::POINTS_COLORED) )
230
231
232
    {
      drawMesh_->usePerVertexColors();

233
      // If we have colors and lighting with normals, we have to use colormaterial
234
      if ( enableNormals_ && (_drawMode & DrawModes::POINTS_SHADED ) )
235
        ACG::GLState::enable(GL_COLOR_MATERIAL);
236
      else
237
        ACG::GLState::disable(GL_COLOR_MATERIAL);
238
    }
239
240
    else
      drawMesh_->disableColors();
241
    
242
    // Bring the arrays online
243
//    enable_arrays(arrays);
244
245
    
    // Draw vertices
246
247
248
    draw_vertices();
  }
  
249
250
  
  /// \todo We can render also wireframe shaded and with vertex colors
251
252
  if (_drawMode & DrawModes::WIREFRAME)
  {
253
//    enable_arrays( VERTEX_ARRAY | LINE_INDEX_ARRAY );
254
255
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
256
257
258

    drawMesh_->disableColors();

259
    draw_lines();
Jan Möbius's avatar
Jan Möbius committed
260
  }  
261
  
Jan Möbius's avatar
Jan Möbius committed
262
263
  if (_drawMode & DrawModes::HIDDENLINE)
  {
264
//    enable_arrays(VERTEX_ARRAY);
Jan Möbius's avatar
Jan Möbius committed
265
266
267
268
269
270
271
    
    // First:
    // Render all faces in background color to initialize z-buffer
    Vec4f  clear_color = _state.clear_color();
    Vec4f  base_color  = _state.base_color();
    clear_color[3] = 1.0;
    
272
273
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
274
275
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    _state.set_base_color(clear_color);
276
277
278

//    drawMesh_->SetFlatShading();
    drawMesh_->disableColors();
Jan Möbius's avatar
Jan Möbius committed
279
    
Jan Möbius's avatar
Jan Möbius committed
280
    ACG::GLState::depthRange(0.01, 1.0);
281
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
282
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
283
284
285
    
    // Second
    // Render the lines. All lines not on the front will be skipped in z-test
286
//    enable_arrays(VERTEX_ARRAY|LINE_INDEX_ARRAY);
287
    ACG::GLState::depthFunc(GL_LEQUAL);
Jan Möbius's avatar
Jan Möbius committed
288
289
    _state.set_base_color(base_color);
    draw_lines();
290
291
    
    //restore depth buffer comparison function for the next draw calls inside this function
292
    ACG::GLState::depthFunc(prev_depth);
Jan Möbius's avatar
Jan Möbius committed
293
294
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }
295
296
297
298
299


  if (_drawMode & DrawModes::EDGES_COLORED)
  {
    enable_arrays( PER_EDGE_VERTEX_ARRAY | PER_EDGE_COLOR_ARRAY );
300
301
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
302
303
304
    draw_lines();
  }  

305
306
307
  if (_drawMode & DrawModes::HALFEDGES)
  {
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY);
308
309
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
310
311
312
313
314
315
    draw_halfedges();
  }  

  if (_drawMode & DrawModes::HALFEDGES_COLORED)
  {
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY | PER_HALFEDGE_COLOR_ARRAY );
316
317
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
318
319
    draw_halfedges();
  }  
Jan Möbius's avatar
Jan Möbius committed
320
  
321
322
  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors() )
  {
323
324
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
325
    ACG::GLState::depthRange(0.01, 1.0);
326
    if ( enableNormals_ ) {
327
       ACG::GLState::enable(GL_COLOR_MATERIAL);
328
    } else {
329
      ACG::GLState::disable(GL_COLOR_MATERIAL);
330
    }
331

332
333
    drawMesh_->usePerVertexColors();

334
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
335
    ACG::GLState::depthRange(0.0, 1.0);
336
337
  }
  
338
  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
339
  {
340
341
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
342
    ACG::GLState::depthRange(0.01, 1.0);
343
344
345
346
347

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

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
348
    ACG::GLState::depthRange(0.0, 1.0);
349
350
351
  }
  
  
Jan Möbius's avatar
Jan Möbius committed
352
353
  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals() )
  {
354
355
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
356
    ACG::GLState::depthRange(0.01, 1.0);
357
358
359
360

    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
361
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  }
  
  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();
376
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY );
377
378
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
379
    ACG::GLState::depthRange(0.01, 1.0);
380
381
382
383
384

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

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
385
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
386
387
388
389
390
391
392
    
    //disable own Phong shader
    //         program->disable();
    //       }
    //     }
  }
  
393
  
394
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED ) && mesh_.has_face_colors()  && mesh_.n_faces() > 0)
395
396
397
  {
    Vec4f base_color_backup = _state.base_color();
    
398
399
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
400
    ACG::GLState::depthRange(0.01, 1.0);
401
402
403
404
405
//    enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY);    

    drawMesh_->usePerFaceColors();

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
406
    ACG::GLState::depthRange(0.0, 1.0);
407
408
409
410
411
    
    _state.set_base_color(base_color_backup);
  }
  
  
412
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals()  && mesh_.n_faces() > 0 )
413
414
  {
    Vec4f base_color_backup = _state.base_color();
415
    ACG::GLState::enable(GL_LIGHTING);
416
    
417
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
418
    ACG::GLState::depthRange(0.01, 1.0);
419
420
421
422
423
424
//    enable_arrays(PER_FACE_VERTEX_ARRAY | PER_FACE_COLOR_ARRAY | PER_FACE_NORMAL_ARRAY );

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

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
425
    ACG::GLState::depthRange(0.0, 1.0);
426
427
428
429
    
    _state.set_base_color(base_color_backup);
  }
  
430
431
  // Rebind the previous texture
  ACG::GLState::bindTexture(lastTarget,lastBuffer);
432
  
433
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED )  && mesh_.has_vertex_texcoords2D())
434
435
  {
    ///\todo enableTexCoords_
436
//    enable_arrays(VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY );
437
438
439
    ACG::GLState::enable(GL_TEXTURE_2D);
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
440
    ACG::GLState::depthRange(0.01, 1.0);
441
442

    drawMesh_->disableColors();
443
    drawMesh_->usePerVertexTexcoords();
444
445

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
446
    ACG::GLState::depthRange(0.0, 1.0);
447
    ACG::GLState::disable(GL_TEXTURE_2D);
448
449
  }
  
450
451
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
  {
452
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY);
453
454
455
    ACG::GLState::enable(GL_TEXTURE_2D);
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
456
    ACG::GLState::depthRange(0.01, 1.0);
457
458
459

    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
460
    drawMesh_->usePerVertexTexcoords();
461
462

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
463
    ACG::GLState::depthRange(0.0, 1.0);
464
    ACG::GLState::disable(GL_TEXTURE_2D);
465
466
  }
  
467
    
468
  // Textured by using coordinates stored in halfedges ... arrays generated by stripprocessor
469
  if ( (_drawMode & DrawModes::SOLID_2DTEXTURED_FACE)  && mesh_.n_faces() > 0 )
470
  {
471
    ACG::GLState::enable(GL_TEXTURE_2D);
472
    
473
//    enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY );
474
    
475
476
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
477
    ACG::GLState::depthRange(0.01, 1.0);
478
479

    drawMesh_->disableColors();
480
    drawMesh_->usePerHalfedgeTexcoords();
481
482

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
483
    ACG::GLState::depthRange(0.0, 1.0);
484
    
485
    ACG::GLState::disable(GL_TEXTURE_2D);
486
487
488
  }
  
  // Textured by using coordinates stored in halfedges
489
  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_face_normals()  && mesh_.n_faces() > 0)
490
  {
491
    ACG::GLState::enable(GL_TEXTURE_2D);
492
    
493
//    enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY | PER_FACE_PER_VERTEX_NORMAL_ARRAY );
494

495
496
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
497
    ACG::GLState::depthRange(0.01, 1.0);
498
499
500

    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
501
    drawMesh_->usePerHalfedgeTexcoords();
502
503

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
504
    ACG::GLState::depthRange(0.0, 1.0);
505
    ACG::GLState::disable(GL_TEXTURE_2D);
506
507
508
    
  }
  
Jan Möbius's avatar
Jan Möbius committed
509
510
  enable_arrays(0);
  
511
  // Unbind all remaining buffers
512
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB , 0 );
513
  
514
  glPopAttrib();
515
516
517
518
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
519
MeshNodeT<Mesh>::
520
draw_vertices() {
521
  drawMesh_->drawVertices();
522
523
}

524
525
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
526
MeshNodeT<Mesh>::
527
draw_lines() {
528

529
530
531
  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
  {
    // colored edges still slow
532
    glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
533
  }
534
  else
535
    drawMesh_->drawLines();
536
537
}

538
539
540
541
542
543
544
545
546
547
548
549
550

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;
}

551
552
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
553
MeshNodeT<Mesh>::
554
555
draw_faces() {
  drawMesh_->draw(textureMap_);
556
557
}

558
559
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
560
MeshNodeT<Mesh>::
561
enable_arrays(unsigned int _arrays) {
562

Jan Möbius's avatar
Jan Möbius committed
563
  // Unbind everything to ensure sane settings
564
565
  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
566

567
568
569
570
571
572
573
574
575
576
577
578
  //===================================================================
  // 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
579
580
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::vertexPointer( drawMesh_->perEdgeVertexBuffer() );   
581
      
582
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
583
584
585
586
587
      
    }
  } else if (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_VERTEX_ARRAY;
588
    ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  } 
  
  //===================================================================
  // 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
603
604
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->perEdgeColorBuffer() );
605
      
606
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
607
608
609
610
611
      
    }
  } else if (enabled_arrays_ & PER_EDGE_COLOR_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_COLOR_ARRAY;
612
    ACG::GLState::disableClientState(GL_COLOR_ARRAY);
613
  }   
614
615
616
617
618
619
620
621
622
623
624
625
626
627


  //===================================================================
  // 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
628
629
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::vertexPointer( drawMesh_->perHalfedgeVertexBuffer() );   
630
      
631
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
632
633
634
635
636
      
    }
  } else if (enabled_arrays_ & PER_HALFEDGE_VERTEX_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_HALFEDGE_VERTEX_ARRAY;
637
    ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
638
639
640
641
642
643
644
645
646
647
648
649
650
651
  } 
  
  //===================================================================
  // 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
652
653
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->perHalfedgeColorBuffer() );
654
      
655
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
656
657
658
659
660
      
    }
  } else if (enabled_arrays_ & PER_HALFEDGE_COLOR_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_HALFEDGE_COLOR_ARRAY;
661
    ACG::GLState::disableClientState(GL_COLOR_ARRAY);
662
  }   
663

664
665
666
667
  //===================================================================
  // Check for OpenGL Errors
  //===================================================================    
  glCheckErrors();
668
669
670
671
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
672
MeshNodeT<Mesh>::
673
pick(GLState& _state, PickTarget _target) {
674
675
676
677
678
679
680
681
682
683
684
685
686
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
  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
717
MeshNodeT<Mesh>::
718
pick_vertices(GLState& _state, bool _front)
719
{  
720
  GLenum prev_depth = _state.depthFunc();
721
  
Jan Möbius's avatar
Jan Möbius committed
722
723
  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
  v_end(mesh_.vertices_end());
724
  
Jan Möbius's avatar
Jan Möbius committed
725
  if (!_state.pick_set_maximum (mesh_.n_vertices())) {
726
    omerr() << "MeshNode::pick_vertices: color range too small, " << "picking failed\n";
Jan Möbius's avatar
Jan Möbius committed
727
728
729
    return;
  }
  
730
731
732
733
734
735
  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
736
737
738
739
    
    Vec4f  clear_color = _state.clear_color();
    Vec4f  base_color  = _state.base_color();
    clear_color[3] = 1.0;
740

Jan Möbius's avatar
Jan Möbius committed
741
742
743
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    _state.set_base_color(clear_color);
    
Jan Möbius's avatar
Jan Möbius committed
744
    ACG::GLState::depthRange(0.01, 1.0);
745
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
746
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
747
748
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
749
    ACG::GLState::depthFunc(GL_LEQUAL);
Jan Möbius's avatar
Jan Möbius committed
750
751
752
753
754
    _state.set_base_color(base_color);
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }
  
755
  if (_state.color_picking () ) {
756
    
757
758
759
760
761
762
763
764
765
    if ( updateVertexPicking_ || _state.pick_current_index () != vertexPickingBaseIndex_) {
      drawMesh_->updatePickingVertices(_state);
      vertexPickingBaseIndex_ = _state.pick_current_index ();
      updateVertexPicking_    = false;

      // Invalidate the any picking buffers
      // as they are changed for the current picking now
      updateAnyPicking_ = true;
    }
766
    
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
    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);
783
      
784
785
786
787
788
789
790
791
792
793
794
      // 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;
  }
  
795
  ACG::GLState::depthFunc(prev_depth);
796
  
797
798
799
800
}

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
801
MeshNodeT<Mesh>::
802
pick_edges(GLState& _state, bool _front)
803
{  
804
  GLenum prev_depth = _state.depthFunc();
805
  
Jan Möbius's avatar
Jan Möbius committed
806
  if (!_state.pick_set_maximum (mesh_.n_edges())) {
807
    omerr() << "MeshNode::pick_edges: color range too small, " << "picking failed\n";
Jan Möbius's avatar
Jan Möbius committed
808
809
810
    return;
  }
  
811
812
813
814
815
816
  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
817
818
819
820
821
822
823
824
    
    Vec4f  clear_color = _state.clear_color();
    Vec4f  base_color  = _state.base_color();
    clear_color[3] = 1.0;
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    _state.set_base_color(clear_color);
    
Jan Möbius's avatar
Jan Möbius committed
825
    ACG::GLState::depthRange(0.01, 1.0);
826
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
827
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
828
829
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
830
    ACG::GLState::depthFunc(GL_LEQUAL);
Jan Möbius's avatar
Jan Möbius committed
831
832
833
834
    _state.set_base_color(base_color);
    
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    
835
    // disable all other arrays
Jan Möbius's avatar
Jan Möbius committed
836
837
838
    enable_arrays(0);
  }
  
839
  if (_state.color_picking () ) {
Jan Möbius's avatar
Jan Möbius committed
840
    
841
842
843
844
845
846
847
848
849
850
    if ( updateEdgePicking_ || _state.pick_current_index () != edgePickingBaseIndex_) {
      drawMesh_->updatePickingEdges(_state);
      edgePickingBaseIndex_ = _state.pick_current_index ();
      updateEdgePicking_    = false;

      // Invalidate the any picking buffers
      // as they are changed for the current picking now
      updateAnyPicking_ = true;
    }
    
851
    if ( mesh_.n_edges() != 0 && drawMesh_) {
852
853
      
      // For this version we load the colors directly not from vbo
854
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
855
      
856
857
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
858
      
859
860
      ACG::GLState::vertexPointer(drawMesh_->perEdgeVertexBuffer());
      ACG::GLState::colorPointer(drawMesh_->pickEdgeColorBuffer());
861
862
863
      
      glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
      
864
865
      ACG::GLState::disableClientState(GL_COLOR_ARRAY);
      ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
866
      
867
868
      // disable all other arrays
      enable_arrays(0); 
869
      
870
    }
871
    
Jan Möbius's avatar
Jan Möbius committed
872
  } else {
873
    std::cerr << "No fallback pick_edges!" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
874
875
  }
  
876
  ACG::GLState::depthFunc(prev_depth);
877
  
878
879
}

Jan Möbius's avatar
Jan Möbius committed
880
881
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
882
MeshNodeT<Mesh>::
Jan Möbius's avatar
Jan Möbius committed
883
884
885
886
887
888
pick_faces(GLState& _state)
{
  typename Mesh::ConstFaceIter        f_it(mesh_.faces_sbegin()),
  f_end(mesh_.faces_end());
  typename Mesh::ConstFaceVertexIter  fv_it;
  
889
890
891
892
  if ( mesh_.n_vertices() == 0 ) {
    std::cerr << "pick_faces: No vertices in Mesh!" << std::endl;
    return;
  }
Jan Möbius's avatar
Jan Möbius committed
893
894
895
  
  if ( mesh_.n_faces() > 0 ) {
    if (!_state.pick_set_maximum (mesh_.n_faces())) {
896
      omerr() << "MeshNode::pick_faces: color range too small, " << "picking failed\n";
Jan Möbius's avatar
Jan Möbius committed
897
898
899
900
901
902
903
904
905
906
      return;
    }
  } else {
    if (!_state.pick_set_maximum (1)) {
      omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
      return;
    }
  }
  
  if (_state.color_picking ()) {
907
908
909
910
911
912
913
914
915
916
917
    
    if ( updateFacePicking_ || _state.pick_current_index () != facePickingBaseIndex_) {
      drawMesh_->updatePickingFaces(_state);
      facePickingBaseIndex_ = _state.pick_current_index ();
      updateFacePicking_    = false;

      // Invalidate the any picking buffers
      // as they are changed for the current picking now
      updateAnyPicking_ = true;
    }
    
918
919
920
    if ( mesh_.n_faces() != 0 ) {
      
      // For this version we load the colors directly not from vbo
921
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
922
      
923
924
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
925
      
926
927
      ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
      ACG::GLState::colorPointer(drawMesh_->pickFaceColorBuffer());
928
      
929
      glDrawArrays(GL_TRIANGLES, 0, 3 * drawMesh_->getNumTris());
930
      
931
932
      ACG::GLState::disableClientState(GL_COLOR_ARRAY);
      ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
933
934
935
      
      // disable all other arrays
      enable_arrays(0);
936
      
937
    }
938
    
Jan Möbius's avatar
Jan Möbius committed
939
  } else
940
    std::cerr << "No fallback pick_faces!" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
941
942
943
  
}

944
945
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
946
MeshNodeT<Mesh>::
947
pick_any(GLState& _state)
948
{    
949
  GLenum prev_depth = _state.depthFunc();
950
951
  unsigned int numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
  
952
953
954
955
956
  if ( mesh_.n_vertices() == 0 ) {
    std::cerr << "pick_any: No vertices in Mesh!" << std::endl;
    return;
  }
  
957
958
  // nothing to pick ?
  if (numElements <= 0) {
959
    std::cerr << "pick_any: Number of elements : 0 " << std::endl;
960
961
962
963
964
965
966
967
968
    return;
  }
  
  if (!_state.pick_set_maximum (numElements))
  {
    omerr() << "MeshNode::pick_any: color range too small, " << "picking failed\n";
    return;
  }
  
969
  if (_state.color_picking()) {
970
971
972
973
974
975
976
977
978
979
980
981

    if ( updateAnyPicking_ || _state.pick_current_index () != anyPickingBaseIndex_) {
      drawMesh_->updatePickingAny(_state);
      anyPickingBaseIndex_ = _state.pick_current_index ();
      updateAnyPicking_    = false;

      // Invalidate the face edge and vertex picking buffers
      // as they are changed for the any picking now
      updateFacePicking_   = true;
      updateEdgePicking_   = true;
      updateVertexPicking_ = true;
    }
982
    
983
    // For this version we load the colors directly, not from vbo
984
    ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
985

Jan Möbius's avatar
Jan Möbius committed
986
987
988
    ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
    ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);

989
990
    ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
    ACG::GLState::enableClientState(GL_COLOR_ARRAY);
991
    
992
    // If we do not have any faces, we generate an empty list here.  
993
    if ( mesh_.n_faces() != 0 && drawMesh_) {
994
      
995
996
      ACG::GLState::vertexPointer(drawMesh_->pickFaceVertexBuffer());
      ACG::GLState::colorPointer(drawMesh_->pickFaceColorBuffer());
997
      
998
      glDrawArrays(GL_TRIANGLES, 0, 3 * drawMesh_->getNumTris());
999
    }
1000