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