MeshNode2T.cc 48.2 KB
Newer Older
1
2
3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2014 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
#include <ACG/GL/GLError.hh>
57

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


namespace ACG {
namespace SceneGraph {
    

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


#include "MeshNode2T.hh"

template<class Mesh>
Jan Möbius's avatar
Jan Möbius committed
71
72
MeshNodeT<Mesh>::
MeshNodeT(Mesh&        _mesh,
73
              BaseNode*    _parent,
Jan Möbius's avatar
Jan Möbius committed
74
75
              std::string  _name ): 
  BaseNode(_parent, _name),
76
  mesh_(_mesh),
77
  drawMesh_(0),
78
79
  enableNormals_(true),
  enableColors_(true),
Jan Möbius's avatar
Jan Möbius committed
80
  enabled_arrays_(0),
81
  updateVertexPicking_(true),
Jan Möbius's avatar
Jan Möbius committed
82
  vertexPickingBaseIndex_(0),
83
  updateEdgePicking_(true),
Jan Möbius's avatar
Jan Möbius committed
84
  edgePickingBaseIndex_(0),
85
  updateFacePicking_(true),
Jan Möbius's avatar
Jan Möbius committed
86
  facePickingBaseIndex_(0),
87
  updateAnyPicking_(true),
88
  anyPickingBaseIndex_(0),
89
  perFaceTextureIndexAvailable_(false),
90
  perFaceTextureCoordsAvailable_(false),
91
92
93
94
  textureMap_(0),
  polyEdgeBuf_(0),
  polyEdgeBufSize_(0),
  polyEdgeBufTex_(0)
95
{
96
 
97
  /// \todo : Handle vbo not supported
98
  if ( ! checkExtensionSupported("GL_ARB_vertex_buffer_object") ) {
99
100
    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
101
  
102
  drawMesh_ = new DrawMeshT<Mesh>(mesh_);
103
  
104
105
106
}  

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

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

  if (mesh_.has_halfedge_normals())
    drawModes |= DrawModes::SOLID_SMOOTH_SHADED_FEATURES;
138
  
139
140
141
  if (mesh_.has_vertex_colors())
  {
    drawModes |= DrawModes::POINTS_COLORED;
142
    drawModes |= DrawModes::SOLID_POINTS_COLORED;
143
144
145

    if (mesh_.has_vertex_normals())
      drawModes |= DrawModes::SOLID_POINTS_COLORED_SHADED;
146
  }
147
148
149
150
151

  if(mesh_.has_edge_colors())
  {
    drawModes |= DrawModes::EDGES_COLORED;
  }
152
153
154
155
156

  if(mesh_.has_halfedge_colors())
  {
    drawModes |= DrawModes::HALFEDGES_COLORED;
  }
157
  
158
159
160
161
162
  if (mesh_.has_face_colors()) {
    drawModes |= DrawModes::SOLID_FACES_COLORED;
    
    if( mesh_.has_face_normals() )
      drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
163
164
165

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

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

template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
195
MeshNodeT<Mesh>::
196
draw(GLState& _state, const DrawModes::DrawMode& _drawMode) {
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*  
  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();
*/
217
    
218
  GLenum prev_depth = _state.depthFunc();
219
  
220
  glPushAttrib(GL_ENABLE_BIT);
221

222
223
224
225
226
227
228
229
  /// 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);


230
  if ( (_drawMode & DrawModes::POINTS) || (_drawMode & DrawModes::POINTS_COLORED) || (_drawMode & DrawModes::POINTS_SHADED )  ) {
231
    
232
233
    _state.set_color( _state.specular_color() );

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

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

    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() );
274

275
276
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
277
278
279

    drawMesh_->disableColors();

280
    draw_lines();
281
282

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

//    drawMesh_->SetFlatShading();
    drawMesh_->disableColors();
297
298
299

    Vec4f  clear_color  = _state.clear_color();
    clear_color[3] = 1.0;
300
    _state.set_color( clear_color );
301

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

311
    _state.set_color( _state.specular_color() );
312

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


  if (_drawMode & DrawModes::EDGES_COLORED)
  {
    enable_arrays( PER_EDGE_VERTEX_ARRAY | PER_EDGE_COLOR_ARRAY );
324
325
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
326
327
328
    draw_lines();
  }  

329
330
  if (_drawMode & DrawModes::HALFEDGES)
  {
331
    _state.set_color( _state.specular_color() );
332

333
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY);
334
335
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
336
337
338
339
340
341
    draw_halfedges();
  }  

  if (_drawMode & DrawModes::HALFEDGES_COLORED)
  {
    enable_arrays( PER_HALFEDGE_VERTEX_ARRAY | PER_HALFEDGE_COLOR_ARRAY );
342
343
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
344
345
    draw_halfedges();
  }  
346

347
  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors() )
348
349
350
351
352
353
354
355
356
357
358
359
  {
    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() )
360
  {
361
362
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
363
    ACG::GLState::depthRange(0.01, 1.0);
364
    if ( enableNormals_ ) {
365
       ACG::GLState::enable(GL_COLOR_MATERIAL);
366
    } else {
367
      ACG::GLState::disable(GL_COLOR_MATERIAL);
368
    }
369

370
371
    drawMesh_->usePerVertexColors();

372
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
373
    ACG::GLState::depthRange(0.0, 1.0);
374
  }
375

376
  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals() && mesh_.n_faces() > 0)
377
  {
378
379
    ACG::GLState::enable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
380
    ACG::GLState::depthRange(0.01, 1.0);
381
382
383
384
385

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

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

395
    drawMesh_->usePerVertexNormals();
396
397
398
    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
399
    ACG::GLState::depthRange(0.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
400
401
402
403
404
405
406
407
408
409
410
411
412
413
  }
  
  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();
414
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY );
Jan Möbius's avatar
Jan Möbius committed
415
    ACG::GLState::disable(GL_LIGHTING);
416
    ACG::GLState::shadeModel(GL_SMOOTH);
Jan Möbius's avatar
Jan Möbius committed
417
    ACG::GLState::depthRange(0.01, 1.0);
418

Jan Möbius's avatar
Jan Möbius committed
419
    drawMesh_->usePerVertexNormals();
420
421
422
423
    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();

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

    drawMesh_->usePerFaceColors();

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
445
    ACG::GLState::depthRange(0.0, 1.0);
446
447
448
    
    _state.set_base_color(base_color_backup);
  }
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464


  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);
  }
465
  
466
  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals()  && mesh_.n_faces() > 0 )
467
468
  {
    Vec4f base_color_backup = _state.base_color();
469
    ACG::GLState::enable(GL_LIGHTING);
470
    
471
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
472
    ACG::GLState::depthRange(0.01, 1.0);
473
474
475
476
477
478
//    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
479
    ACG::GLState::depthRange(0.0, 1.0);
480
481
482
    
    _state.set_base_color(base_color_backup);
  }
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501

  
  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);
  }
502
503
504
505

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

506
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED )  && mesh_.has_vertex_texcoords2D())
507
508
  {
    ///\todo enableTexCoords_
509
//    enable_arrays(VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY );
510
511
512
    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
513
    ACG::GLState::depthRange(0.01, 1.0);
514
515

    drawMesh_->disableColors();
516
    drawMesh_->usePerVertexTexcoords();
517

518
519
520
521
522
523

    // texture environment: fragment color = texture sample
    GLint prevTexEnvMode = 0;
    glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &prevTexEnvMode);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

524
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
525
    ACG::GLState::depthRange(0.0, 1.0);
526
    ACG::GLState::disable(GL_TEXTURE_2D);
527
528

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, prevTexEnvMode);
529
530
  }
  
531
532
  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
  {
533
//    enable_arrays(VERTEX_ARRAY | NORMAL_VERTEX_ARRAY | TEXCOORD_VERTEX_ARRAY);
534
535
536
    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
537
    ACG::GLState::depthRange(0.01, 1.0);
538
539
540

    drawMesh_->setSmoothShading();
    drawMesh_->disableColors();
541
    drawMesh_->usePerVertexTexcoords();
542
543

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
544
    ACG::GLState::depthRange(0.0, 1.0);
545
    ACG::GLState::disable(GL_TEXTURE_2D);
546
547
  }
  
548
    
549
  // Textured by using coordinates stored in halfedges ... arrays generated by stripprocessor
550
  if ( (_drawMode & DrawModes::SOLID_2DTEXTURED_FACE)  && mesh_.n_faces() > 0 )
551
  {
552
    ACG::GLState::enable(GL_TEXTURE_2D);
553
    
554
//    enable_arrays( PER_FACE_VERTEX_ARRAY | PER_FACE_TEXCOORD_ARRAY );
555
    
556
557
    ACG::GLState::disable(GL_LIGHTING);
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
558
    ACG::GLState::depthRange(0.01, 1.0);
559
560

    drawMesh_->disableColors();
561
    drawMesh_->usePerHalfedgeTexcoords();
562

563
564
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

565
    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
566
    ACG::GLState::depthRange(0.0, 1.0);
567
    
568
    ACG::GLState::disable(GL_TEXTURE_2D);
569
570
  }
  
571

572
  // Textured by using coordinates stored in halfedges
573
  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_face_normals()  && mesh_.n_faces() > 0)
574
  {
575
    ACG::GLState::enable(GL_TEXTURE_2D);
576
577

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

579
    ACG::GLState::enable(GL_LIGHTING);
580
    ACG::GLState::shadeModel(GL_FLAT);
Jan Möbius's avatar
Jan Möbius committed
581
    ACG::GLState::depthRange(0.01, 1.0);
582

583
    drawMesh_->setFlatShading();
584
    drawMesh_->disableColors();
585
    drawMesh_->usePerHalfedgeTexcoords();
586
587

    draw_faces();
Jan Möbius's avatar
Jan Möbius committed
588
    ACG::GLState::depthRange(0.0, 1.0);
589
    ACG::GLState::disable(GL_TEXTURE_2D);
590

591
  }
592

Jan Möbius's avatar
Jan Möbius committed
593
594
  enable_arrays(0);
  
595
  // Unbind all remaining buffers
596
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB , 0 );
597
  
598
  glPopAttrib();
599
600
}

601
602

template <class Mesh>
603
void ACG::SceneGraph::MeshNodeT<Mesh>::getRenderObjects( IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat )
604
{
605
  RenderObject ro;
606
607
608

  ro.debugName = "MeshNode";
   
609
610
611
612
613
614
615
  // 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
Jan Möbius's avatar
Jan Möbius committed
616
    ro.initFromState(&_state);
617
618
619
620
621
    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;
622
    ro.setMaterial(_mat);
623

624
625
626
    ro.shaderDesc.vertexTemplateFile = ""; //QString(props->vertexShader().c_str());
    ro.shaderDesc.geometryTemplateFile = ""; //QString(props->geometryShader().c_str());
    ro.shaderDesc.fragmentTemplateFile = ""; //QString(props->fragmentShader().c_str());
Jan Möbius's avatar
Jan Möbius committed
627

628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
    // ------------------------
    // 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;
    }

658
    ro.shaderDesc.addTextureType(GL_TEXTURE_2D,false,0);
659
660
661
662
663
664
665

    switch (props->texcoordSource())
    {
    case DrawModes::TEXCOORD_PER_VERTEX: drawMesh_->usePerVertexTexcoords(); break;
    case DrawModes::TEXCOORD_PER_HALFEDGE: drawMesh_->usePerHalfedgeTexcoords(); break;
    default:
      {
666
        ro.shaderDesc.clearTextures();
667
668
669
670
671
672
673
674
675
676
677
678
679
      }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())
    {
Jan Möbius's avatar
Jan Möbius committed
680
681
682
683
684
685
686
687
688
      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;
689
690
    }

Jan Möbius's avatar
Jan Möbius committed
691
692
    if (props->flatShaded())
      ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
693
694
695
696
697
698
699
700

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

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

701
      // use specular color for lines
702
703
704
705
706
      if (_drawMode.isAtomic() )
        ro.emissive = ro.specular;
      else
        ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());

Jan Möbius's avatar
Jan Möbius committed
707
708
      // allow wireframe + solid mode
      ro.depthFunc = GL_LEQUAL;
709

Jan Möbius's avatar
Jan Möbius committed
710
711
712
713
      // use alpha blending for anti-aliasing in combined wireframe + solid mode
      ro.blending = true;
      ro.blendSrc = GL_SRC_ALPHA;
      ro.blendDest = GL_ONE_MINUS_SRC_ALPHA;
714

Jan Möbius's avatar
Jan Möbius committed
715
716
717
      // use geometry shaders to simulate line width
   
      QString geomTemplate = ShaderProgGenerator::getShaderDir();
718
      geomTemplate += "Wireframe/geometry_wire.tpl";
719

Jan Möbius's avatar
Jan Möbius committed
720
      QString fragTemplate = ShaderProgGenerator::getShaderDir();
721
722
723
      fragTemplate += "Wireframe/fragment_wire.tpl";

#ifdef GL_ARB_texture_buffer_object
724
      if (!mesh_.is_trimesh())
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
      {
        // use modified shader for npoly meshes
        // the shader can identify non-face edges with the poly edge buffer
        updatePolyEdgeBuf();

        if (polyEdgeBufTex_)
        {
          geomTemplate = ShaderProgGenerator::getShaderDir();
          geomTemplate += "Wireframe/geometry_npoly_wire.tpl";

          fragTemplate = ShaderProgGenerator::getShaderDir();
          fragTemplate += "Wireframe/fragment_npoly_wire.tpl";

          RenderObject::Texture roTex;
          roTex.id = polyEdgeBufTex_;
          roTex.type = GL_TEXTURE_BUFFER;

          // bind poly edge buffer to texture stage 2
          ro.setUniform("polyEdgeBuffer", 2);
          ro.addTexture(roTex, 2, false);
        }
      }
#endif
748

Jan Möbius's avatar
Jan Möbius committed
749
750
      ro.shaderDesc.geometryTemplateFile = geomTemplate;
      ro.shaderDesc.fragmentTemplateFile = fragTemplate;
751

752
      ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
Jan Möbius's avatar
Jan Möbius committed
753
754
      ro.setUniform("lineWidth", _state.line_width());

Jan Möbius's avatar
Jan Möbius committed
755
756
      add_face_RenderObjects(_renderer, &ro);
    }
757

Jan Möbius's avatar
Jan Möbius committed
758
759
760
    if (props->primitive()  == DrawModes::PRIMITIVE_HIDDENLINE)
    {
      ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
761
762
      drawMesh_->disableColors();

Jan Möbius's avatar
Jan Möbius committed
763
764
765
766
767
      // use specular color for lines
      if (_drawMode.isAtomic() )
        ro.emissive = ro.specular;
      else
        ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());
768

Jan Möbius's avatar
Jan Möbius committed
769
770
      // use shaders to simulate line width
      QString geomTemplate = ShaderProgGenerator::getShaderDir();
771
      geomTemplate += "Wireframe/geometry_hidden.tpl";
772

Jan Möbius's avatar
Jan Möbius committed
773
774
      QString fragTemplate = ShaderProgGenerator::getShaderDir();
      fragTemplate += "Wireframe/fragment_hidden.tpl";
775

776
#ifdef GL_ARB_texture_buffer_object
777
      if (!mesh_.is_trimesh())
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
      {
        // use modified shader for npoly meshes
        // the shader can identify non-face edges with the poly edge buffer
        updatePolyEdgeBuf();

        if (polyEdgeBufTex_)
        {
          geomTemplate = ShaderProgGenerator::getShaderDir();
          geomTemplate += "Wireframe/geometry_npoly_hidden.tpl";

          fragTemplate = ShaderProgGenerator::getShaderDir();
          fragTemplate += "Wireframe/fragment_npoly_hidden.tpl";

          RenderObject::Texture roTex;
          roTex.id = polyEdgeBufTex_;
          roTex.type = GL_TEXTURE_BUFFER;

          // bind poly edge buffer to texture stage 2
          ro.setUniform("polyEdgeBuffer", 2);
          ro.addTexture(roTex, 2, false);
        }
      }
#endif


Jan Möbius's avatar
Jan Möbius committed
803
804
      ro.shaderDesc.geometryTemplateFile = geomTemplate;
      ro.shaderDesc.fragmentTemplateFile = fragTemplate;
805

806
      ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
Jan Möbius's avatar
Jan Möbius committed
807
      ro.setUniform("lineWidth", _state.line_width());
808
      ro.setUniform("bkColor", _state.clear_color());
Jan Möbius's avatar
Jan Möbius committed
809

Jan Möbius's avatar
Jan Möbius committed
810
      add_face_RenderObjects(_renderer, &ro);
811

812
813
814
815
816
817
818
819
820
    }

    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();
Jan Möbius's avatar
Jan Möbius committed
821
      ro.glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
822

823
824
825
      // use specular color for lines
      ro.emissive = ro.specular;

Jan Möbius's avatar
Jan Möbius committed
826
827
828
829
830
831
832
833


      // use shaders to simulate line width
      QString geomTemplate = ShaderProgGenerator::getShaderDir();
      geomTemplate += "Wireframe/geom_line2quad.tpl";

      ro.shaderDesc.geometryTemplateFile = geomTemplate;

Jan Möbius's avatar
Jan Möbius committed
834
835
836
      ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
      ro.setUniform("lineWidth", _state.line_width());

837
838
839
840
841
842
843
844
845
846
      _renderer->addRenderObject(&ro);

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

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

Jan Möbius's avatar
Jan Möbius committed
847
      // buffers in system memory
848
849
850
851
852
      if (props->colored())
        ro.vertexDecl = drawMesh_->getHalfedgeVertexDeclaration();
      else
        ro.vertexDecl = drawMesh_->getHalfedgeColoredVertexDeclaration();

853
854
855
      // use specular color for lines
      ro.emissive = ro.specular;

Jan Möbius's avatar
Jan Möbius committed
856
      ro.glDrawArrays(GL_LINES, 0, int(mesh_.n_halfedges() * 2));
857

Jan Möbius's avatar
Jan Möbius committed
858
859
860
861
862
863
864
865


      // use shaders to simulate line width
      QString geomTemplate = ShaderProgGenerator::getShaderDir();
      geomTemplate += "Wireframe/geom_line2quad.tpl";

      ro.shaderDesc.geometryTemplateFile = geomTemplate;

Jan Möbius's avatar
Jan Möbius committed
866
867
868
      ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
      ro.setUniform("lineWidth", _state.line_width());

869
870
871
872
873
874
875
876
877
878
879
      _renderer->addRenderObject(&ro);
    }  


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

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

    switch (props->primitive())
    {
880
881
    case DrawModes::PRIMITIVE_POINT:
      {
882
883
884
885
886
887
888
889
        if (ro.shaderDesc.shadeMode == SG_SHADE_UNLIT)
        {
          // use specular color for points
          if (_drawMode.isAtomic() )
            ro.emissive = ro.specular;
          else
            ro.emissive = OpenMesh::color_cast<ACG::Vec3f>(_state.overlay_color());
        }
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905

        // use shaders to simulate line width
        QString geomTemplate = ShaderProgGenerator::getShaderDir();
        geomTemplate += "PointSize/geometry.tpl";

        QString fragTemplate = ShaderProgGenerator::getShaderDir();
        fragTemplate += "PointSize/fragment.tpl";

        ro.shaderDesc.geometryTemplateFile = geomTemplate;
        ro.shaderDesc.fragmentTemplateFile = fragTemplate;

        ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
        ro.setUniform("pointSize", _mat->pointSize());

        add_point_RenderObjects(_renderer, &ro);
      } break;
906
907
908
909
    case DrawModes::PRIMITIVE_EDGE:
      {
        // use specular color for lines
        ro.emissive = ro.specular;
Jan Möbius's avatar
Jan Möbius committed
910
911
912
913
914
915
916

        // use shaders to simulate line width
        QString geomTemplate = ShaderProgGenerator::getShaderDir();
        geomTemplate += "Wireframe/geom_line2quad.tpl";

        ro.shaderDesc.geometryTemplateFile = geomTemplate;

Jan Möbius's avatar
Jan Möbius committed
917
918
919
        ro.setUniform("screenSize", Vec2f((float)_state.viewport_width(), (float)_state.viewport_height()));
        ro.setUniform("lineWidth", _state.line_width());

920
921
        add_line_RenderObjects(_renderer, &ro);
      } break;
922
    case DrawModes::PRIMITIVE_POLYGON: add_face_RenderObjects(_renderer, &ro); break;
Jan Möbius's avatar
Jan Möbius committed
923
    default: break;
924
925
    }
  }
926
927
928
929
930
931
932
933
934
935
936

}


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

937
938
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
939
MeshNodeT<Mesh>::
940
draw_vertices() {
941
  drawMesh_->drawVertices();
942
943
}

944
945
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
946
MeshNodeT<Mesh>::
947
draw_lines() {
948

949
950
951
  if ((enabled_arrays_ & PER_EDGE_COLOR_ARRAY) && (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY))
  {
    // colored edges still slow
Jan Möbius's avatar
Jan Möbius committed
952
    glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
953
  }
954
  else
955
    drawMesh_->drawLines();
956
957
}

958
959
960
961
962
963
964
965
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
Jan Möbius's avatar
Jan Möbius committed
966
    glDrawArrays(GL_LINES, 0, int(mesh_.n_edges() * 2));
967
968
969
970
  }
  else
    drawMesh_->addLineRenderObjects(_renderer, _baseObj);
}
971
972
973
974
975
976
977

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 )
Jan Möbius's avatar
Jan Möbius committed
978
    glDrawArrays(GL_LINES, 0, int(mesh_.n_halfedges() * 2));
979
980
981
982
983
  // Something went wrong here!
  else
    std::cerr << "Unable to Draw! halfedge array configuration is invalid!!" << std::endl;
}

984
985
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
986
MeshNodeT<Mesh>::
987
988
draw_faces() {
  drawMesh_->draw(textureMap_);
989
990
}

991
992
993
994
995
996
997
template<class Mesh>
void
MeshNodeT<Mesh>::
add_face_RenderObjects(IRenderer* _renderer, const RenderObject* _baseObj) {
  drawMesh_->addTriRenderObjects(_renderer, _baseObj, textureMap_);
}

998
999
template<class Mesh>
void
Jan Möbius's avatar
Jan Möbius committed
1000
MeshNodeT<Mesh>::
1001
enable_arrays(unsigned int _arrays) {
1002

Jan Möbius's avatar
Jan Möbius committed
1003
  // Unbind everything to ensure sane settings
1004
1005
  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
  ACG::GLState::bindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1006

1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
  //===================================================================
  // 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
1019
1020
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::vertexPointer( drawMesh_->perEdgeVertexBuffer() );   
1021
      
1022
      ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1023
1024
1025
1026
1027
      
    }
  } else if (enabled_arrays_ & PER_EDGE_VERTEX_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_VERTEX_ARRAY;
1028
    ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
  } 
  
  //===================================================================
  // 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
1043
1044
      ACG::GLState::bindBuffer(GL_ARRAY_BUFFER_ARB, 0);
      ACG::GLState::colorPointer( drawMesh_->perEdgeColorBuffer() );
1045
      
1046
      ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1047
1048
1049
1050
1051
      
    }
  } else if (enabled_arrays_ & PER_EDGE_COLOR_ARRAY) {
    // Disable Vertex array
    enabled_arrays_ &= ~PER_EDGE_COLOR_ARRAY;
1052
    ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1053
  }   
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067