Developer Documentation
VolumeMeshNodeT_impl.hh
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 
43 #define VOLUMEMESHNODET_CC
44 
45 //== INCLUDES =================================================================
46 
47 #include "VolumeMeshNode.hh"
48 
49 #include <ACG/GL/gl.hh>
50 #include <ACG/Utils/VSToolsT.hh>
51 #include <vector>
52 #include <type_traits>
53 
54 #include <ACG/GL/RenderObject.hh>
55 #include <ACG/GL/VertexDeclaration.hh>
56 #include <ACG/GL/IRenderer.hh>
57 #include <ACG/ShaderUtils/GLSLShader.hh>
58 #include <ACG/GL/ShaderCache.hh>
59 #include <ACG/Geometry/Types/PlaneType.hh>
60 
61 #include <OpenVolumeMesh/Mesh/HexahedralMesh.hh>
62 
64 
65 
66 //== NAMESPACES ===============================================================
67 
68 namespace ACG {
69 namespace SceneGraph {
70 
71 //== IMPLEMENTATION ==========================================================
72 
73 
74 template<class VolumeMeshT>
76  OpenVolumeMesh::StatusAttrib& _statusAttrib,
80  const MaterialNode* _matNode, BaseNode* _parent,
81  std::string _name) :
82  BaseNode(_parent, _name),
83  mesh_(_mesh),
84  scale_(1.0),
85  boundary_only_(false),
86  translucency_factor_(0.1f),
87  selection_color_(ACG::Vec4f(1.0f, 0.0f, 0.0f, 1.0f)),
88  statusAttrib_(_statusAttrib),
89  colorAttrib_(_colorAttrib),
90  normalAttrib_(_normalAttrib),
91  texcoordAttrib_(_texcoordAttrib),
92  materialNode_(_matNode),
93 
94  cellsBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
95  facesBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
96  edgesBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
97  verticesBufferManager_(_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
98 
99  cellSelectionBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
100  faceSelectionBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
101  edgeSelectionBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
102  vertexSelectionBufferManager_(_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
103 
104  cellPickBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
105  facePickBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
106  edgePickBufferManager_ (_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
107  vertexPickBufferManager_(_mesh, _statusAttrib, _colorAttrib, _normalAttrib, _texcoordAttrib),
108 
109  drawModes_(),
110  lastDrawMode_ (DrawModes::NONE),
111  lastCellDrawMode_ (DrawModes::NONE),
112  lastFaceDrawMode_ (DrawModes::NONE),
113  lastEdgeDrawMode_ (DrawModes::NONE),
114  lastVertexDrawMode_(DrawModes::NONE),
115  lastPickTarget_(PICK_ANYTHING),
116  face_normals_calculated_(false),
117  vertex_normals_calculated_(false)
118 {
119  vertexSelectionBufferManager_.setSelectionOnly(true);
120  edgeSelectionBufferManager_.setSelectionOnly(true);
121  faceSelectionBufferManager_.setSelectionOnly(true);
122  cellSelectionBufferManager_.setSelectionOnly(true);
123 }
124 
125 
126 //----------------------------------------------------------------------------
127 
128 template<class VolumeMeshT>
130 
131 }
132 
133 //----------------------------------------------------------------------------
134 
135 template<class VolumeMeshT>
137 
138  int n_vertices(mesh_.n_vertices());
139  for (int i = 0; i < n_vertices; ++i) {
140  Vec3d p(mesh_.vertex(VertexHandle(i)));
141  _bbMin.minimize(p);
142  _bbMax.maximize(p);
143  }
144 }
145 
146 //----------------------------------------------------------------------------
147 
148 
149 template<class VolumeMeshT>
151  DrawModes::DrawMode result;
152 
153  if (mesh_.n_cells() > 0)
154  {
155  result |= drawModes_.cellsTransparent;
156  result |= drawModes_.cellsFlatShaded;
157  result |= drawModes_.cellsSmoothShaded;
158  result |= drawModes_.cellsPhongShaded;
159  if (colorAttrib_.vertex_colors_available())
160  result |= drawModes_.cellsColoredPerVertex;
161  if (colorAttrib_.halfface_colors_available())
162  result |= drawModes_.cellsColoredPerHalfface;
163  if (colorAttrib_.face_colors_available())
164  result |= drawModes_.cellsColoredPerFace;
165  if (colorAttrib_.cell_colors_available())
166  result |= drawModes_.cellsColoredPerCell;
167  }
168 
169  if (mesh_.n_faces() > 0)
170  {
171  result |= drawModes_.facesFlatShaded;
172  result |= drawModes_.facesSmoothShaded;
173  result |= drawModes_.facesPhongShaded;
174  if (colorAttrib_.vertex_colors_available())
175  result |= drawModes_.facesColoredPerVertex;
176  if (colorAttrib_.face_colors_available())
177  result |= drawModes_.facesColoredPerFace;
178  if (colorAttrib_.face_colors_available())
179  result |= drawModes_.facesColoredPerFaceFlatShaded;
180  if (texcoordAttrib_.vertex_texcoords_available())
181  result |= drawModes_.facesTextured;
182  if (texcoordAttrib_.vertex_texcoords_available())
183  result |= drawModes_.facesTexturedShaded;
184  }
185 
186  if (mesh_.n_halffaces() > 0)
187  {
188  result |= drawModes_.halffacesFlatShaded;
189  result |= drawModes_.halffacesSmoothShaded;
190  result |= drawModes_.halffacesPhongShaded;
191  if (colorAttrib_.vertex_colors_available())
192  result |= drawModes_.halffacesColoredPerVertex;
193  if (colorAttrib_.halfface_colors_available())
194  result |= drawModes_.halffacesColoredPerHalfface;
195  }
196 
197  if (mesh_.n_edges() > 0)
198  {
199  result |= drawModes_.edgesWireframe;
200 
201  if (mesh_.n_cells () > 0)
202  result |= drawModes_.edgesOnCells;
203  if (mesh_.n_faces() > 0)
204  result |= drawModes_.edgesHiddenLine;
205  if (colorAttrib_.edge_colors_available())
206  result |= drawModes_.edgesColoredPerEdge;
207 
208  if (std::is_base_of<HexahedralMeshTopologyKernel, VolumeMeshT>::value)
209  {
210  result |= drawModes_.irregularInnerEdges;
211  result |= drawModes_.irregularOuterEdges;
212  }
213  }
214 
215  if (mesh_.n_halfedges() > 0)
216  {
217  result |= drawModes_.halfedgesWireframe;
218 
219  if (mesh_.n_faces() > 0)
220  result |= drawModes_.halfedgesHiddenLine;
221  if (colorAttrib_.halfedge_colors_available())
222  result |= drawModes_.halfedgesColoredPerHalfedge;
223  }
224 
225  if (mesh_.n_vertices() > 0)
226  {
227  result |= drawModes_.verticesFlatShaded;
228 
229  if (colorAttrib_.vertex_colors_available())
230  result |= drawModes_.verticesColored;
231  }
232 
233  return result;
234 
235 }
236 
237 
238 //----------------------------------------------------------------------------
239 
240 
241 template<class VolumeMeshT>
243 {
244 
245  ACG::GLState::depthRange(0.01, 1.0);
246 
247  cellsBufferManager_.setOptionsFromDrawMode(_drawMode);
248  GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
249  GLState::enableClientState(GL_VERTEX_ARRAY);
250  GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
251 
252  GLState::enableClientState(GL_NORMAL_ARRAY);
253  GLState::normalPointer(GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(cellsBufferManager_.getNormalOffset()));
254 
255  if (_drawMode & (drawModes_.cellsColoredPerCell | drawModes_.cellsColoredPerFace | drawModes_.cellsColoredPerHalfface | drawModes_.cellsColoredPerVertex))
256  {
257  //for a drawmode with colors we have to activate and bind colors
258  GLState::enableClientState(GL_COLOR_ARRAY);
259  GLState::colorPointer(4, GL_UNSIGNED_BYTE, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(cellsBufferManager_.getColorOffset()));
260 
261  GLState::shadeModel(GL_SMOOTH);
262  GLState::disable(GL_LIGHTING);
263  GLState::enable(GL_DEPTH_TEST);
264 
265  }
266  else if (_drawMode & drawModes_.cellsSmoothShaded)
267  {
268  GLState::shadeModel(GL_SMOOTH);
269  GLState::enable(GL_LIGHTING);
270  GLState::enable(GL_DEPTH_TEST);
271  }
272  else if (_drawMode & drawModes_.cellsFlatShaded)
273  {
274  GLState::shadeModel(GL_FLAT);
275  GLState::enable(GL_LIGHTING);
276  GLState::enable(GL_DEPTH_TEST);
277  }
278  else if (_drawMode & drawModes_.cellsTransparent)
279  {
280  GLState::shadeModel(GL_FLAT);
281  GLState::disable(GL_LIGHTING);
282  GLState::disable(GL_DEPTH_TEST);
283  GLState::disableClientState(GL_COLOR_ARRAY);
284  Vec4f bc = _state.specular_color();
285  _state.set_color(Vec4f(bc[0],bc[1],bc[2],translucency_factor_));
286  GLState::enable(GL_BLEND);
287  GLState::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
288  }
289 
290  glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
291 
292  if (_drawMode & drawModes_.cellsTransparent)
293  {
294  _state.set_color(_state.base_color());
295  GLState::disable(GL_BLEND);
296  }
297 
298  GLState::disableClientState(GL_COLOR_ARRAY);
299  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
300 
301  ACG::GLState::depthRange(0.0, 1.0);
302 }
303 
304 template<class VolumeMeshT>
306 {
307 
308  ACG::GLState::depthRange(0.01, 1.0);
309 
310  //faces are drawn from both sides, halffaces only when facing the camera
311  //however, if we only draw the boundary, we draw halffaces from both sides so we can see them
312  //when looking inside the object
313  if ((_drawMode & drawModes_.faceBasedDrawModes) || boundary_only_)
314  {
315  GLState::disable(GL_CULL_FACE);
316  }
317  else
318  {
319  GLState::enable(GL_CULL_FACE);
320  GLState::cullFace(GL_BACK);
321  }
322 
323  GLState::enable(GL_DEPTH_TEST);
324 
325  facesBufferManager_.setOptionsFromDrawMode(_drawMode);
326  GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
327  GLState::enableClientState(GL_VERTEX_ARRAY);
328  GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
329 
330  if (_drawMode & (drawModes_.hiddenLineBackgroundFaces))
331  {
332  GLState::disable(GL_LIGHTING);
333  GLState::shadeModel(GL_FLAT);
334  GLState::disableClientState(GL_COLOR_ARRAY);
335  GLState::disableClientState(GL_NORMAL_ARRAY);
336  _state.set_color(_state.clear_color());
337  }
338  else if (_drawMode & (drawModes_.facesColoredPerFace | drawModes_.facesColoredPerVertex
339  | drawModes_.halffacesColoredPerHalfface | drawModes_.halffacesColoredPerVertex ))
340  {
341  GLState::enableClientState(GL_COLOR_ARRAY);
342  GLState::colorPointer(4, GL_UNSIGNED_BYTE, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getColorOffset()));
343 
344  GLState::disable(GL_LIGHTING);
345  GLState::shadeModel(GL_SMOOTH);
346  }
347  else if (_drawMode & (drawModes_.facesColoredPerFaceFlatShaded))
348  {
349  GLState::enable(GL_COLOR_MATERIAL);
350 
351  GLState::enableClientState(GL_COLOR_ARRAY);
352  GLState::colorPointer(4, GL_UNSIGNED_BYTE, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getColorOffset()));
353 
354  GLState::enable(GL_LIGHTING);
355  GLState::shadeModel(GL_FLAT);
356 
357  GLState::enableClientState(GL_NORMAL_ARRAY);
358  GLState::normalPointer(GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getNormalOffset()));
359  }
360  else if (_drawMode & (drawModes_.facesTexturedShaded) )
361  {
362  glClientActiveTexture(GL_TEXTURE0);
363  ACG::GLState::texcoordPointer(2, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getTexCoordOffset()));
364  ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
365 
366  GLState::enable(GL_LIGHTING);
367  GLState::disableClientState(GL_COLOR_ARRAY);
368 
369  GLState::enableClientState(GL_NORMAL_ARRAY);
370  GLState::normalPointer(GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getNormalOffset()));
371 
372  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
373  GLState::shadeModel(GL_SMOOTH);
374  }
375  else if (_drawMode & (drawModes_.facesTextured) )
376  {
377  glClientActiveTexture(GL_TEXTURE0);
378  ACG::GLState::texcoordPointer(2, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getTexCoordOffset()));
379  ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
380 
381  GLState::disableClientState(GL_COLOR_ARRAY);
382  GLState::disableClientState(GL_NORMAL_ARRAY);
383 
384  GLState::disable(GL_LIGHTING);
385  GLState::shadeModel(GL_SMOOTH);
386 
387  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
388  }
389  else
390  {
391  GLState::enable(GL_LIGHTING);
392  GLState::disableClientState(GL_COLOR_ARRAY);
393 
394  GLState::enableClientState(GL_NORMAL_ARRAY);
395  GLState::normalPointer(GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facesBufferManager_.getNormalOffset()));
396 
397  GLState::shadeModel(GL_SMOOTH);
398  }
399 
400  glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
401 
402  GLState::disableClientState(GL_COLOR_ARRAY);
403 
404  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
405 
406  if (_drawMode & (drawModes_.edgesHiddenLine | drawModes_.halfedgesHiddenLine))
407  _state.set_color(_state.base_color());
408 
409  ACG::GLState::depthRange(0.0, 1.0);
410 }
411 
412 template<class VolumeMeshT>
414 {
415  ACG::GLState::depthRange(0.0, 1.0);
416 
417  edgesBufferManager_.setDefaultColor(_state.specular_color());
418  edgesBufferManager_.setOptionsFromDrawMode(_drawMode);
419 
420  GLState::bindBuffer(GL_ARRAY_BUFFER, edgesBufferManager_.getBuffer());
421  GLState::enableClientState(GL_VERTEX_ARRAY);
422  GLState::vertexPointer(3, GL_FLOAT, edgesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
423 
424  if (_drawMode & ( drawModes_.edgesColoredPerEdge | drawModes_.halfedgesColoredPerHalfedge |
425  drawModes_.irregularInnerEdges | drawModes_.irregularOuterEdges ))
426  {
427  GLState::enableClientState(GL_COLOR_ARRAY);
428  GLState::colorPointer(4, GL_UNSIGNED_BYTE, edgesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(edgesBufferManager_.getColorOffset()));
429 
430  GLState::disable(GL_LIGHTING);
431  GLState::shadeModel(GL_SMOOTH);
432 
433  glLineWidth(_state.line_width() * 2.0f);
434  }
435  else
436  {
437  _state.set_color( _state.specular_color() );
438 
439  ACG::GLState::disable(GL_LIGHTING);
440  ACG::GLState::shadeModel(GL_FLAT);
441 
442  GLState::disableClientState(GL_NORMAL_ARRAY);
443  }
444 
445 
446  glDrawArrays(GL_LINES, 0, edgesBufferManager_.getNumOfVertices());
447  glLineWidth(_state.line_width());
448 
449  GLState::disableClientState(GL_COLOR_ARRAY);
450 
451  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
452 
453 }
454 
455 template<class VolumeMeshT>
457 {
458  verticesBufferManager_.setOptionsFromDrawMode(_drawMode);
459  GLState::bindBuffer(GL_ARRAY_BUFFER, verticesBufferManager_.getBuffer());
460  GLState::enableClientState(GL_VERTEX_ARRAY);
461  GLState::vertexPointer(3, GL_FLOAT, verticesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
462 
463  GLState::depthRange(0.0,1.0);
464 
465  if (_drawMode & ( drawModes_.verticesColored ))
466  {
467  GLState::enableClientState(GL_COLOR_ARRAY);
468  GLState::colorPointer(4, GL_UNSIGNED_BYTE, verticesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(verticesBufferManager_.getColorOffset()));
469 
470  GLState::disable(GL_LIGHTING);
471  GLState::shadeModel(GL_SMOOTH);
472  }
473  else
474  {
475  _state.set_color( _state.specular_color() );
476 
477  ACG::GLState::disable(GL_LIGHTING);
478  ACG::GLState::shadeModel(GL_FLAT);
479 
480  GLState::disableClientState(GL_NORMAL_ARRAY);
481  }
482 
483  glDrawArrays(GL_POINTS, 0, verticesBufferManager_.getNumOfVertices());
484 
485  GLState::disableClientState(GL_COLOR_ARRAY);
486 
487  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
488 
489 }
490 
491 template<class VolumeMeshT>
493 {
494 
495  //save current shader
496  GLint currentProgramm;
497  glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgramm);
498  //disable shader for drawing of the selecttion
500 
501  GLState::enable(GL_DEPTH_TEST);
502  GLState::depthFunc(GL_LEQUAL);
503  _state.set_color( selection_color_ );
504 
505  GLState::disable(GL_LIGHTING);
506  GLState::shadeModel(GL_FLAT);
507  glDisable(GL_CULL_FACE);
508  GLState::disableClientState(GL_NORMAL_ARRAY);
509  GLState::disableClientState(GL_COLOR_ARRAY);
510 
511  GLState::disable(GL_TEXTURE_2D);
512 
513  GLState::enableClientState(GL_VERTEX_ARRAY);
514 
515  if ((_drawMode & drawModes_.cellBasedDrawModes) && !(_drawMode & drawModes_.vertexBasedDrawModes))
516  vertexSelectionBufferManager_.enableVertexOnCellPrimitives();
517  else
518  vertexSelectionBufferManager_.enableVertexPrimitives();
519 
520  if ((_drawMode & (drawModes_.cellBasedDrawModes | drawModes_.edgesOnCells)) && !(_drawMode & (drawModes_.edgeBasedDrawModes & ~drawModes_.edgesOnCells)))
521  edgeSelectionBufferManager_.enableEdgeOnCellPrimitives();
522  else
523  edgeSelectionBufferManager_.enableEdgePrimitives();
524 
525  if ((_drawMode & drawModes_.cellBasedDrawModes) && !(_drawMode & (drawModes_.faceBasedDrawModes | drawModes_.halffaceBasedDrawModes)))
526  faceSelectionBufferManager_.enableFaceOnCellPrimitives();
527  else
528  faceSelectionBufferManager_.enableFacePrimitives();
529 
530  cellSelectionBufferManager_.enableCellPrimitives();
531 
532  glLineWidth(1.5*_state.line_width());
533 
534  GLState::depthRange(0.0,1.0);
535 
536  GLState::bindBuffer(GL_ARRAY_BUFFER, vertexSelectionBufferManager_.getBuffer());
537  GLState::vertexPointer(3, GL_FLOAT, 0, 0);
538  glDrawArrays(GL_POINTS, 0, vertexSelectionBufferManager_.getNumOfVertices());
539 
540  GLState::bindBuffer(GL_ARRAY_BUFFER, edgeSelectionBufferManager_.getBuffer());
541  GLState::vertexPointer(3, GL_FLOAT, 0, 0);
542  glDrawArrays(GL_LINES, 0, edgeSelectionBufferManager_.getNumOfVertices());
543 
544  GLState::depthRange(0.01,1.0);
545 
546  GLState::bindBuffer(GL_ARRAY_BUFFER, faceSelectionBufferManager_.getBuffer());
547  GLState::vertexPointer(3, GL_FLOAT, 0, 0);
548  glDrawArrays(GL_TRIANGLES, 0, faceSelectionBufferManager_.getNumOfVertices());
549 
550  GLState::bindBuffer(GL_ARRAY_BUFFER, cellSelectionBufferManager_.getBuffer());
551  GLState::vertexPointer(3, GL_FLOAT, 0, 0);
552  glDrawArrays(GL_TRIANGLES, 0, cellSelectionBufferManager_.getNumOfVertices());
553 
554  GLState::depthRange(0.0,1.0);
555 
556  _state.set_color(_state.base_color());
557 
558  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
559 
560 
561  glLineWidth(_state.line_width());
562 
563  ACG::GLState::useProgram(currentProgramm);
564 
565 }
566 
567 template<class VolumeMeshT>
569 {
570  invalidateAllDrawBuffers();
571  invalidateAllPickingBuffers();
572  invalidateAllSelectionBuffers();
573 }
574 
575 template<class VolumeMeshT>
577 {
578  cellsBufferManager_.invalidate();
579  facesBufferManager_.invalidate();
580  edgesBufferManager_.invalidate();
581  verticesBufferManager_.invalidate();
582 }
583 
584 template<class VolumeMeshT>
586 {
587  cellPickBufferManager_.invalidate();
588  facePickBufferManager_.invalidate();
589  edgePickBufferManager_.invalidate();
590  vertexPickBufferManager_.invalidate();
591 }
592 
593 template<class VolumeMeshT>
595 {
596  cellSelectionBufferManager_.invalidate();
597  faceSelectionBufferManager_.invalidate();
598  edgeSelectionBufferManager_.invalidate();
599  vertexSelectionBufferManager_.invalidate();
600 }
601 
602 template<class VolumeMeshT>
604 
605  //save state
606  GLboolean lighting = false;
607  glGetBooleanv(GL_LIGHTING, &lighting);
608  GLboolean color_material = false;
609  glGetBooleanv(GL_COLOR_MATERIAL, &color_material);
610  GLboolean blend = false;
611  glGetBooleanv(GL_BLEND, &blend);
612  GLboolean depth = false;
613  glGetBooleanv(GL_DEPTH_TEST, &depth);
614  GLenum prev_depth = _state.depthFunc();
615  GLboolean cullFace = false;
616  glGetBooleanv(GL_CULL_FACE, &cullFace);
617  GLint cullFaceMode;
618  glGetIntegerv(GL_CULL_FACE_MODE, &cullFaceMode);
619  GLint texmode;
620  glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texmode);
621  GLboolean texturing;
622  glGetBooleanv(GL_TEXTURE_2D, &texturing);
623  const Vec4f oldColor = _state.color();
624 
625  // ignore two sided lighting setting and turn it off
626  GLboolean lightModel = _state.twosided_lighting();
627  _state.set_twosided_lighting(false);
628 
629  bool clientStateEnabledVertexArray = GLState::isClientStateEnabled(GL_VERTEX_ARRAY);
630  bool clientStateEnabledColorArray = GLState::isClientStateEnabled(GL_COLOR_ARRAY);
631  bool clientStateEnabledNormalArray = GLState::isClientStateEnabled(GL_NORMAL_ARRAY);
632  bool clientStateEnabledTexCoordArray = GLState::isClientStateEnabled(GL_TEXTURE_COORD_ARRAY);
633 
634  DrawModes::DrawMode cellDrawMode = drawModes_.getFirstCellDrawMode(_drawMode);
635  DrawModes::DrawMode faceDrawMode = drawModes_.getFirstFaceDrawMode(_drawMode);
636  DrawModes::DrawMode edgeDrawMode = drawModes_.getFirstEdgeDrawMode(_drawMode);
637  DrawModes::DrawMode vertexDrawMode = drawModes_.getFirstVertexDrawMode(_drawMode);
638 
639  if (!face_normals_calculated_)
640  {
641  if ( (cellDrawMode & drawModes_.cellsFlatShaded) ||
642  (faceDrawMode & (drawModes_.facesFlatShaded | drawModes_.halffacesFlatShaded | drawModes_.facesTexturedShaded)) )
643  update_face_normals();
644  }
645  if (!vertex_normals_calculated_)
646  {
647  if ( (cellDrawMode & (drawModes_.cellsSmoothShaded | drawModes_.cellsPhongShaded)) ||
648  (faceDrawMode & (drawModes_.facesSmoothShaded | drawModes_.halffacesSmoothShaded | drawModes_.facesPhongShaded | drawModes_.halffacesPhongShaded)) )
649  update_vertex_normals();
650  }
651 
652  //the VolumeMeshBufferManager can handle non atomic drawmodes if it consists of one
653  // edge based draw mode (except edges on cells) and irregular edges
654  edgeDrawMode |= _drawMode & (drawModes_.irregularInnerEdges | drawModes_.irregularOuterEdges);
655 
656  // enable twosided lighting for per_face_flat_shaded
657  if(faceDrawMode & (drawModes_.facesColoredPerFaceFlatShaded))
658  _state.set_twosided_lighting(true);
659 
660  if (cellDrawMode)
661  drawCells(_state, cellDrawMode);
662  else
663  cellsBufferManager_.free();
664  if (faceDrawMode)
665  drawFaces(_state, faceDrawMode);
666  else
667  facesBufferManager_.free();
668  if (edgeDrawMode)
669  drawEdges(_state, edgeDrawMode);
670  else
671  edgesBufferManager_.free();
672  if (vertexDrawMode)
673  drawVertices(_state, vertexDrawMode);
674  else
675  verticesBufferManager_.free();
676 
677  drawSelection(_state, cellDrawMode | faceDrawMode | edgeDrawMode | vertexDrawMode);
678 
679 
680  lastDrawMode_ = cellDrawMode | faceDrawMode | edgeDrawMode | vertexDrawMode;
681  lastCellDrawMode_ = cellDrawMode;
682  lastFaceDrawMode_ = faceDrawMode;
683  lastEdgeDrawMode_ = edgeDrawMode;
684  lastVertexDrawMode_ = vertexDrawMode;
685 
686  //restore state
687  if(lighting)
688  ACG::GLState::enable(GL_LIGHTING);
689  else
690  ACG::GLState::disable(GL_LIGHTING);
691  if(color_material)
692  ACG::GLState::enable(GL_COLOR_MATERIAL);
693  else
694  ACG::GLState::disable(GL_COLOR_MATERIAL);
695  if(blend)
696  ACG::GLState::enable(GL_BLEND);
697  else
698  ACG::GLState::disable(GL_BLEND);
699  if(depth)
700  ACG::GLState::enable(GL_DEPTH_TEST);
701  else
702  ACG::GLState::disable(GL_DEPTH_TEST);
703  _state.depthFunc(prev_depth);
704  if(cullFace)
705  ACG::GLState::enable(GL_CULL_FACE);
706  else
707  ACG::GLState::disable(GL_CULL_FACE);
708  ACG::GLState::cullFace(cullFaceMode);
709  if(texturing)
710  ACG::GLState::enable(GL_TEXTURE_2D);
711  else
712  ACG::GLState::disable(GL_TEXTURE_2D);
713  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texmode);
714  _state.set_color(oldColor);
715 
716  _state.set_twosided_lighting(lightModel);
717 
718  if (clientStateEnabledVertexArray)
719  GLState::enableClientState(GL_VERTEX_ARRAY);
720  else
721  GLState::disableClientState(GL_VERTEX_ARRAY);
722 
723  if (clientStateEnabledColorArray)
724  GLState::enableClientState(GL_COLOR_ARRAY);
725  else
726  GLState::disableClientState(GL_COLOR_ARRAY);
727 
728  if (clientStateEnabledNormalArray)
729  GLState::enableClientState(GL_NORMAL_ARRAY);
730  else
731  GLState::disableClientState(GL_NORMAL_ARRAY);
732 
733  if (clientStateEnabledTexCoordArray)
734  GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
735  else
736  GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
737 
738 }
739 
740 
741 
742 template<class VolumeMeshT>
744 {
745  RenderObject ro;
746  ro.initFromState(&_state);
747 
748  ro.debugName = "VolumeMeshNodeCells";
749 
750  //Todo: use DrawModeProperties
751 
752  // reset renderobject
753  ro.depthTest = true;
754  ro.depthWrite = true;
755  ro.depthFunc = GL_LESS;
756  ro.setMaterial(_mat);
757 
759 
760  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
761 
762  ro.depthRange = Vec2f(0.01f, 1.0f);
763 
764  if (_drawMode & (drawModes_.cellsColoredPerCell | drawModes_.cellsColoredPerFace | drawModes_.cellsColoredPerHalfface | drawModes_.cellsColoredPerVertex))
765  {
766  ro.shaderDesc.vertexColors = true;
767  ro.shaderDesc.numLights = -1;
768  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
769  }
770  else if (_drawMode & drawModes_.cellsSmoothShaded)
771  {
772  ro.shaderDesc.numLights = 0;
773  ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
774  }
775  else if (_drawMode & drawModes_.cellsFlatShaded)
776  {
777  ro.shaderDesc.numLights = 0;
778  ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
779  }
780  else if (_drawMode & drawModes_.cellsTransparent)
781  {
782  ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
783  ro.shaderDesc.numLights = -1;
784  ro.depthTest = false;
785 
786  ro.diffuse = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
787  ro.ambient = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
788  ro.specular = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
789  ro.emissive = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
790 
791  ro.alpha = translucency_factor_;
792  ro.blending = true;
793  ro.blendDest = GL_ONE_MINUS_SRC_ALPHA;
794  ro.blendSrc = GL_SRC_ALPHA;
795  }
796 
797  cellsBufferManager_.setOptionsFromDrawMode(_drawMode);
798  ro.vertexBuffer = cellsBufferManager_.getBuffer();
799  ro.vertexDecl = cellsBufferManager_.getVertexDeclaration();
800 
801  ro.glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
802  if (cellsBufferManager_.getNumOfVertices() > 0) {
803  _renderer->addRenderObject(&ro);
804  }
805 }
806 
807 template<class VolumeMeshT>
809 {
810  RenderObject ro;
811  ro.initFromState(&_state);
812 
813  ro.debugName = "VolumeMeshNodeFaces";
814 
815  //Todo: use DrawModeProperties
816 
817  // reset renderobject
818  ro.depthTest = true;
819  ro.depthWrite = true;
820  ro.depthFunc = GL_LESS;
821  ro.setMaterial(_mat);
822 
824 
825  ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
826 
827  ro.depthRange = Vec2f(0.01f, 1.0f);
828 
829  facesBufferManager_.setOptionsFromDrawMode(_drawMode);
830 
831 
832  if ((_drawMode & drawModes_.faceBasedDrawModes) || boundary_only_)
833  ro.culling = false;
834  else
835  ro.culling = true;
836 
837  if (_drawMode & (drawModes_.hiddenLineBackgroundFaces))
838  {
839  ro.shaderDesc.numLights = -1;
840  ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
841 
842  ro.shaderDesc.vertexColors = false;
843 
844  ro.diffuse = ACG::Vec3f(_state.clear_color()[0],_state.clear_color()[1],_state.clear_color()[2]);
845  ro.ambient = ACG::Vec3f(_state.clear_color()[0],_state.clear_color()[1],_state.clear_color()[2]);
846  ro.specular = ACG::Vec3f(_state.clear_color()[0],_state.clear_color()[1],_state.clear_color()[2]);
847  ro.emissive = ACG::Vec3f(_state.clear_color()[0],_state.clear_color()[1],_state.clear_color()[2]);
848  }
849  else if (_drawMode & (drawModes_.facesColoredPerFace | drawModes_.facesColoredPerVertex
850  | drawModes_.halffacesColoredPerHalfface | drawModes_.halffacesColoredPerVertex ))
851  {
852  ro.shaderDesc.vertexColors = true;
853  ro.shaderDesc.numLights = -1;
854  ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
855  }
856  else if (_drawMode & drawModes_.facesColoredPerFaceFlatShaded)
857  {
858  ro.shaderDesc.vertexColors = true;
859  ro.shaderDesc.numLights = -1;
860  ro.shaderDesc.shadeMode = SG_SHADE_FLAT;
861  }
862  else
863  {
864  ro.shaderDesc.numLights = 0;
865  ro.shaderDesc.vertexColors = false;
866  }
867 
868  ro.vertexBuffer = facesBufferManager_.getBuffer();
869  ro.vertexDecl = facesBufferManager_.getVertexDeclaration();
870 
871  ro.glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
872  if (facesBufferManager_.getNumOfVertices() > 0) {
873  _renderer->addRenderObject(&ro);
874  }
875 }
876 
877 template<class VolumeMeshT>
879 {
880  RenderObject ro;
881  ro.initFromState(&_state);
882 
883  ro.debugName = "VolumeMeshNodeEdges";
884 
885  //Todo: use DrawModeProperties
886 
887  // reset renderobject
888  ro.depthRange = Vec2f(0.0f, 1.0f);
889  ro.depthTest = true;
890  ro.depthWrite = true;
891  ro.depthFunc = GL_LESS;
892  ro.setMaterial(_mat);
893 
895 
896  // no lighting, as there are no normals anyway
897  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
898 
899  // thick lines
900  if (_mat && _mat->lineWidth() > 1.0f)
901  ro.setupLineRendering(_mat->lineWidth(), ACG::Vec2f(_state.viewport_width(), _state.viewport_height()));
902 
903  edgesBufferManager_.setDefaultColor(_state.specular_color());
904  edgesBufferManager_.setOptionsFromDrawMode(_drawMode);
905 
906  if (_drawMode & ( drawModes_.edgesColoredPerEdge | drawModes_.halfedgesColoredPerHalfedge |
907  drawModes_.irregularInnerEdges | drawModes_.irregularOuterEdges ))
908  {
909  ro.shaderDesc.vertexColors = true;
910  }
911  else
912  {
913  ro.emissive = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
914  }
915 
916  ro.vertexBuffer = edgesBufferManager_.getBuffer();
917  ro.vertexDecl = edgesBufferManager_.getVertexDeclaration();
918 
919  ro.glDrawArrays(GL_LINES, 0, edgesBufferManager_.getNumOfVertices());
920  if (edgesBufferManager_.getNumOfVertices() > 0) {
921  _renderer->addRenderObject(&ro);
922  }
923 }
924 
925 template<class VolumeMeshT>
927 {
928  RenderObject ro;
929  ro.initFromState(&_state);
930 
931  ro.debugName = "VolumeMeshNodeVertices";
932 
933 
934  //Todo: use DrawModeProperties
935 
936  // reset renderobject
937  ro.depthRange = Vec2f(0.0f, 1.0f);
938  ro.depthTest = true;
939  ro.depthWrite = true;
940  ro.depthFunc = GL_LESS;
941  ro.setMaterial(_mat);
942 
944 
945  // no lighting, as there are no normals anyway
946  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
947 
948  // draw with point size
949  if (_mat && _mat->pointSize() > 1.0f)
950  ro.setupPointRendering(_mat->pointSize(), ACG::Vec2f(_state.viewport_width(), _state.viewport_height()));
951 
952  verticesBufferManager_.setDefaultColor(_state.specular_color());
953  verticesBufferManager_.setOptionsFromDrawMode(_drawMode);
954 
955 
956  if (_drawMode & ( drawModes_.verticesColored ))
957  ro.shaderDesc.vertexColors = true;
958  else
959  ro.emissive = ACG::Vec3f(_state.specular_color()[0],_state.specular_color()[1],_state.specular_color()[2]);
960 
961  ro.vertexBuffer = verticesBufferManager_.getBuffer();
962  ro.vertexDecl = verticesBufferManager_.getVertexDeclaration();
963 
964  ro.glDrawArrays(GL_POINTS, 0, verticesBufferManager_.getNumOfVertices());
965  if (verticesBufferManager_.getNumOfVertices() > 0) {
966  _renderer->addRenderObject(&ro);
967  }
968 }
969 
970 
971 
972 template<class VolumeMeshT>
974 {
975  RenderObject ro;
976  ro.initFromState(&_state);
977 
978  ro.debugName = "VolumeMeshNodeSelections";
979 
980  ro.setMaterial(_mat);
981 
982  ro.depthTest = true;
983  ro.depthFunc = GL_LEQUAL;
984 
986  ro.shaderDesc.vertexColors = false;
987  ro.shaderDesc.numLights = -1;
988  ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
989 
990  ro.diffuse = ACG::Vec3f(selection_color_[0],selection_color_[1],selection_color_[2]);
991  ro.ambient = ACG::Vec3f(selection_color_[0],selection_color_[1],selection_color_[2]);
992  ro.specular = ACG::Vec3f(selection_color_[0],selection_color_[1],selection_color_[2]);
993  ro.emissive = ACG::Vec3f(selection_color_[0],selection_color_[1],selection_color_[2]);
994 
995  if ((_drawMode & drawModes_.cellBasedDrawModes) && !(_drawMode & drawModes_.vertexBasedDrawModes))
996  vertexSelectionBufferManager_.enableVertexOnCellPrimitives();
997  else
998  vertexSelectionBufferManager_.enableVertexPrimitives();
999 
1000  if ((_drawMode & (drawModes_.cellBasedDrawModes | drawModes_.edgesOnCells)) && !(_drawMode & (drawModes_.edgeBasedDrawModes & ~drawModes_.edgesOnCells)))
1001  edgeSelectionBufferManager_.enableEdgeOnCellPrimitives();
1002  else
1003  edgeSelectionBufferManager_.enableEdgePrimitives();
1004 
1005  if ((_drawMode & drawModes_.cellBasedDrawModes) && !(_drawMode & (drawModes_.faceBasedDrawModes | drawModes_.halffaceBasedDrawModes)))
1006  faceSelectionBufferManager_.enableFaceOnCellPrimitives();
1007  else
1008  faceSelectionBufferManager_.enableFacePrimitives();
1009 
1010  cellSelectionBufferManager_.enableCellPrimitives();
1011 
1012  ro.depthRange = Vec2f(0.0f,1.0f);
1013 
1014  ro.vertexBuffer = vertexSelectionBufferManager_.getBuffer();
1015  ro.vertexDecl = vertexSelectionBufferManager_.getVertexDeclaration();
1016  ro.glDrawArrays(GL_POINTS, 0, vertexSelectionBufferManager_.getNumOfVertices());
1017  if (vertexSelectionBufferManager_.getNumOfVertices())
1018  {
1019  ro.debugName = "VolumeMeshNode.VertexSelections";
1020  ro.setupPointRendering(_state.point_size(), ACG::Vec2f(_state.viewport_width(), _state.viewport_height()));
1021  _renderer->addRenderObject(&ro);
1022 
1023  // reset shader templates
1024  ro.shaderDesc.vertexTemplateFile = "";
1025  ro.shaderDesc.geometryTemplateFile = "";
1026  ro.shaderDesc.fragmentTemplateFile = "";
1027  }
1028 
1029  ro.vertexBuffer = edgeSelectionBufferManager_.getBuffer();
1030  ro.vertexDecl = edgeSelectionBufferManager_.getVertexDeclaration();
1031  ro.glDrawArrays(GL_LINES, 0, edgeSelectionBufferManager_.getNumOfVertices());
1032  if (edgeSelectionBufferManager_.getNumOfVertices())
1033  {
1034  ro.debugName = "VolumeMeshNode.EdgeSelections";
1035 
1036  ro.setupLineRendering(_state.line_width(), ACG::Vec2f(_state.viewport_width(), _state.viewport_height()));
1037  _renderer->addRenderObject(&ro);
1038 
1039  // reset shader templates
1040  ro.shaderDesc.vertexTemplateFile = "";
1041  ro.shaderDesc.geometryTemplateFile = "";
1042  ro.shaderDesc.fragmentTemplateFile = "";
1043  }
1044 
1045  ro.depthRange = Vec2f(0.01f, 1.0f);
1046 
1047  ro.vertexBuffer = faceSelectionBufferManager_.getBuffer();
1048  ro.vertexDecl = faceSelectionBufferManager_.getVertexDeclaration();
1049  ro.glDrawArrays(GL_TRIANGLES, 0, faceSelectionBufferManager_.getNumOfVertices());
1050  if (faceSelectionBufferManager_.getNumOfVertices())
1051  {
1052  ro.debugName = "VolumeMeshNode.FaceSelections";
1053 
1054  _renderer->addRenderObject(&ro);
1055  }
1056 
1057  ro.vertexBuffer = cellSelectionBufferManager_.getBuffer();
1058  ro.vertexDecl = cellSelectionBufferManager_.getVertexDeclaration();
1059  ro.glDrawArrays(GL_TRIANGLES, 0, cellSelectionBufferManager_.getNumOfVertices());
1060  if (cellSelectionBufferManager_.getNumOfVertices())
1061  {
1062  ro.debugName = "VolumeMeshNode.CellSelections";
1063  _renderer->addRenderObject(&ro);
1064  }
1065 
1066 
1067 }
1068 
1069 template<class VolumeMeshT>
1070 void VolumeMeshNodeT<VolumeMeshT>::getRenderObjects(IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat)
1071 {
1072 
1073  DrawModes::DrawMode cellDrawMode = drawModes_.getFirstCellDrawMode(_drawMode);
1074  DrawModes::DrawMode faceDrawMode = drawModes_.getFirstFaceDrawMode(_drawMode);
1075  DrawModes::DrawMode edgeDrawMode = drawModes_.getFirstEdgeDrawMode(_drawMode);
1076  DrawModes::DrawMode vertexDrawMode = drawModes_.getFirstVertexDrawMode(_drawMode);
1077 
1078  if (!face_normals_calculated_)
1079  {
1080  if ( (cellDrawMode & drawModes_.cellsFlatShaded) ||
1081  (faceDrawMode & (drawModes_.facesFlatShaded | drawModes_.halffacesFlatShaded | drawModes_.facesTexturedShaded)) )
1082  update_face_normals();
1083  }
1084  if (!vertex_normals_calculated_)
1085  {
1086  if ( (cellDrawMode & (drawModes_.cellsSmoothShaded | drawModes_.cellsPhongShaded)) ||
1087  (faceDrawMode & (drawModes_.facesSmoothShaded | drawModes_.halffacesSmoothShaded | drawModes_.facesPhongShaded | drawModes_.halffacesPhongShaded)) )
1088  update_vertex_normals();
1089  }
1090 
1091  //the VolumeMeshBufferManager can handle non atomic drawmodes if it consists of one
1092  // edge based draw mode (except edges on cells) and irregular edges
1093  edgeDrawMode |= _drawMode & (drawModes_.irregularInnerEdges | drawModes_.irregularOuterEdges);
1094 
1095  if (cellDrawMode)
1096  getCellRenderObjects(_renderer, _state, cellDrawMode, _mat);
1097  else
1098  cellsBufferManager_.free();
1099  if (faceDrawMode)
1100  getFaceRenderObjects(_renderer, _state, faceDrawMode, _mat);
1101  else
1102  facesBufferManager_.free();
1103  if (edgeDrawMode)
1104  getEdgeRenderObjects(_renderer, _state, edgeDrawMode, _mat);
1105  else
1106  edgesBufferManager_.free();
1107  if (vertexDrawMode)
1108  getVertexRenderObjects(_renderer, _state, vertexDrawMode, _mat);
1109  else
1110  verticesBufferManager_.free();
1111 
1112  getSelectionRenderObjects(_renderer, _state, cellDrawMode | faceDrawMode | edgeDrawMode | vertexDrawMode, _mat);
1113 
1114 }
1115 
1116 //----------------------------------------------------------------------------
1117 
1118 
1119 template<class VolumeMeshT>
1121  bool drawModeOverride = false;
1122  if(lastDrawMode_ == DrawModes::NONE) // no last drawmode so the picking renderer
1123  { // is probably calling this function for rendering
1124  lastDrawMode_ = drawMode();
1125  drawModeOverride = true;
1126  }
1127 
1128  if(_state.compatibilityProfile())
1129  pickCompat(_state, _target);
1130  else
1131  {
1132  GLState::depthRange(0.01, 1.0);
1133  if (lastCellDrawMode_)
1134  {
1135  //draw cells so the user cannot pick invisible stuff
1136 
1137  GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
1138 
1139  GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
1140 
1141  Vec4f bc = _state.specular_color();
1142  _state.set_color(Vec4f(0.0,0.0,0.0,0.0));
1143 
1144  glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
1145 
1146  _state.set_color(bc);
1147  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1148  }
1149 
1150  if (lastFaceDrawMode_)
1151  {
1152  //draw faces so the user cannot pick invisible stuff
1153 
1154  GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
1155  GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
1156 
1157  Vec4f bc = _state.specular_color();
1158  _state.set_color(Vec4f(0.0,0.0,0.0,0.0));
1159 
1160  glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
1161 
1162  _state.set_color(bc);
1163  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1164  }
1165 
1166  GLenum oldDepthFunc = _state.depthFunc();
1167 
1168  GLState::depthRange(0.0, 1.0);
1169 
1170  _state.set_depthFunc(GL_LEQUAL);
1171 
1172  switch (_target) {
1173  case PICK_VERTEX: {
1174  if (lastPickTarget_ != PICK_VERTEX)
1175  vertexPickBufferManager_.invalidateColors();
1176  _state.pick_set_maximum(mesh_.n_vertices());
1177  pickVertices(_state);
1178  break;
1179  }
1180 
1181  case PICK_EDGE: {
1182  _state.pick_set_maximum(mesh_.n_edges());
1183  pickEdges(_state, 0);
1184  break;
1185  }
1186 
1187  case PICK_FACE: {
1188  _state.pick_set_maximum(mesh_.n_faces());
1189  pickFaces(_state, 0);
1190  break;
1191  }
1192 
1193  case PICK_CELL: {
1194  _state.pick_set_maximum(mesh_.n_cells());
1195  pickCells(_state, 0);
1196  break;
1197  }
1198 
1199  case PICK_ANYTHING: {
1200  if (lastPickTarget_ != PICK_ANYTHING)
1201  vertexPickBufferManager_.invalidateColors();
1202 
1203  int nv = mesh_.n_vertices();
1204  int ne = mesh_.n_edges();
1205  int nf = mesh_.n_faces();
1206  int nc = mesh_.n_cells();
1207 
1208  _state.pick_set_maximum(nv + ne + nf + nc);
1209  pickVertices(_state);
1210  pickEdges(_state, nv);
1211  pickFaces(_state, nv + ne);
1212  pickCells(_state, nv + ne + nf);
1213  break;
1214  }
1215 
1216  default:
1217  break;
1218  }
1219 
1220  _state.set_depthFunc(oldDepthFunc);
1221  lastPickTarget_ = _target;
1222  }
1223  if(drawModeOverride)
1224  lastDrawMode_ = DrawModes::NONE;
1225 }
1226 
1227 template<class VolumeMeshT>
1229 {
1230  cellsBufferManager_.clearCutPlanes();
1231  facesBufferManager_.clearCutPlanes();
1232  edgesBufferManager_.clearCutPlanes();
1233  verticesBufferManager_.clearCutPlanes();
1234 
1235  cellSelectionBufferManager_.clearCutPlanes();
1236  faceSelectionBufferManager_.clearCutPlanes();
1237  edgeSelectionBufferManager_.clearCutPlanes();
1238  vertexSelectionBufferManager_.clearCutPlanes();
1239 
1240  cellPickBufferManager_.clearCutPlanes();
1241  facePickBufferManager_.clearCutPlanes();
1242  edgePickBufferManager_.clearCutPlanes();
1243  vertexPickBufferManager_.clearCutPlanes();
1244 }
1245 
1246 //----------------------------------------------------------------------------
1247 
1248 
1249 
1250 template<class VolumeMeshT>
1252 
1253  if (lastDrawMode_ & drawModes_.vertexBasedDrawModes)
1254  vertexPickBufferManager_.enableVertexPrimitives();
1255  else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
1256  vertexPickBufferManager_.enableVertexOnCellPrimitives();
1257  else
1258  vertexPickBufferManager_.enableVertexPrimitives();
1259 
1260  vertexPickBufferManager_.disableNormals();
1261  vertexPickBufferManager_.enablePickColors();
1262 
1263  static GLSL::Program* pickVertexShader_;
1264  static ACG::ShaderGenDesc desc;
1265  desc.vertexColors = true;
1266  desc.vertexTemplateFile = "Picking/vertexPassColors.glsl";
1267  desc.fragmentTemplateFile = "Picking/passColors_fs.glsl";
1268 
1269  // load from cache
1270  pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,nullptr);
1271 
1272  // check link status
1273  if(!( pickVertexShader_ && pickVertexShader_->isLinked()))
1274  return;
1275  GLState::bindBuffer(GL_ARRAY_BUFFER, vertexPickBufferManager_.getPickBuffer(_state, 0));
1276  pickVertexShader_->use();
1277  vertexPickBufferManager_.getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1278 
1279  pickVertexShader_->setUniform("pickVertexOffset", static_cast<int>(_state.pick_current_index()));
1280  pickVertexShader_->setUniform("mWVP", _state.projection() * _state.modelview());
1281 
1282  float oldPointSize = _state.point_size();
1283  _state.set_point_size(1.5*_state.point_size());
1284 
1285  glDrawArrays(GL_POINTS, 0, vertexPickBufferManager_.getNumOfVertices());
1286 
1287  vertexPickBufferManager_.getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1288  pickVertexShader_->disable();
1289  _state.set_point_size(oldPointSize);
1290 
1291  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1292 
1293 }
1294 
1295 //----------------------------------------------------------------------------
1296 
1297 
1298 template<class VolumeMeshT>
1299 void VolumeMeshNodeT<VolumeMeshT>::pickEdges(GLState& _state, unsigned int _offset) {
1300 
1301  if ((lastDrawMode_ & (drawModes_.cellBasedDrawModes | drawModes_.edgesOnCells)) && !(lastDrawMode_ & (drawModes_.edgeBasedDrawModes & ~drawModes_.edgesOnCells)))
1302  edgePickBufferManager_.enableEdgeOnCellPrimitives();
1303  else
1304  edgePickBufferManager_.enableEdgePrimitives();
1305 
1306  edgePickBufferManager_.enablePickColors();
1307  edgePickBufferManager_.disableNormals();
1308 
1309  static GLSL::Program* pickVertexShader_;
1310  static ACG::ShaderGenDesc desc;
1311  desc.vertexColors = true;
1312  desc.vertexTemplateFile = "Picking/vertexPassColors.glsl";
1313  desc.fragmentTemplateFile = "Picking/passColors_fs.glsl";
1314 
1315  // load from cache
1316  pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,nullptr);
1317 
1318  // check link status
1319  if(!( pickVertexShader_ && pickVertexShader_->isLinked()))
1320  return;
1321  GLState::bindBuffer(GL_ARRAY_BUFFER, edgePickBufferManager_.getPickBuffer(_state, _offset));
1322 
1323  pickVertexShader_->use();
1324  edgePickBufferManager_.getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1325 
1326  pickVertexShader_->setUniform("pickVertexOffset", static_cast<int>(_state.pick_current_index()));
1327  pickVertexShader_->setUniform("mWVP", _state.projection() * _state.modelview());
1328 
1329  float oldLineWidth = _state.line_width();
1330  _state.set_line_width(4.0*_state.line_width());
1331 
1332  glDrawArrays(GL_LINES, 0, edgePickBufferManager_.getNumOfVertices());
1333 
1334  edgePickBufferManager_.getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1335  pickVertexShader_->disable();
1336  _state.set_line_width(oldLineWidth);
1337 
1338  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1339 
1340 }
1341 
1342 //----------------------------------------------------------------------------
1343 
1344 
1345 template<class VolumeMeshT>
1346 void VolumeMeshNodeT<VolumeMeshT>::pickFaces(GLState& _state, unsigned int _offset) {
1347 
1348  if (lastDrawMode_ & (drawModes_.faceBasedDrawModes | drawModes_.halffaceBasedDrawModes))
1349  facePickBufferManager_.enableFacePrimitives();
1350  else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
1351  facePickBufferManager_.enableFaceOnCellPrimitives();
1352  else
1353  facePickBufferManager_.enableFacePrimitives();
1354 
1355  facePickBufferManager_.disableNormals();
1356  facePickBufferManager_.enablePickColors();
1357 
1358  static GLSL::Program* pickVertexShader_;
1359  static ACG::ShaderGenDesc desc;
1360  desc.vertexColors = true;
1361  desc.vertexTemplateFile = "Picking/vertexPassColors.glsl";
1362  desc.fragmentTemplateFile = "Picking/passColors_fs.glsl";
1363 
1364  // load from cache
1365  pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,nullptr);
1366 
1367  // check link status
1368  if(!( pickVertexShader_ && pickVertexShader_->isLinked()))
1369  return;
1370  GLState::bindBuffer(GL_ARRAY_BUFFER, facePickBufferManager_.getPickBuffer(_state, _offset));
1371 
1372  pickVertexShader_->use();
1373  facePickBufferManager_.getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1374 
1375  pickVertexShader_->setUniform("pickVertexOffset", static_cast<int>(_state.pick_current_index()));
1376  pickVertexShader_->setUniform("mWVP", _state.projection() * _state.modelview());
1377 
1378  glDrawArrays(GL_TRIANGLES, 0, facePickBufferManager_.getNumOfVertices());
1379 
1380  facePickBufferManager_.getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1381  pickVertexShader_->disable();
1382  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1383 }
1384 
1385 //----------------------------------------------------------------------------
1386 
1387 
1388 template<class VolumeMeshT>
1389 void VolumeMeshNodeT<VolumeMeshT>::pickCells(GLState& _state, unsigned int _offset) {
1390 
1391  cellPickBufferManager_.enablePickColors();
1392  cellPickBufferManager_.disableNormals();
1393  cellPickBufferManager_.enableCellPrimitives();
1394 
1395  static GLSL::Program* pickVertexShader_;
1396  static ACG::ShaderGenDesc desc;
1397  desc.vertexColors = true;
1398  desc.vertexTemplateFile = "Picking/vertexPassColors.glsl";
1399  desc.fragmentTemplateFile = "Picking/passColors_fs.glsl";
1400 
1401  // load from cache
1402  pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,nullptr);
1403 
1404  // check link status
1405  if(!( pickVertexShader_ && pickVertexShader_->isLinked()))
1406  return;
1407  GLState::bindBuffer(GL_ARRAY_BUFFER, cellPickBufferManager_.getPickBuffer(_state, _offset));
1408 
1409  pickVertexShader_->use();
1410  cellPickBufferManager_.getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1411 
1412  pickVertexShader_->setUniform("pickVertexOffset", static_cast<int>(_state.pick_current_index()));
1413  pickVertexShader_->setUniform("mWVP", _state.projection() * _state.modelview());
1414 
1415 
1416  glDrawArrays(GL_TRIANGLES, 0, cellPickBufferManager_.getNumOfVertices());
1417 
1418 
1419  cellPickBufferManager_.getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1420  pickVertexShader_->disable();
1421  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
1422 }
1423 
1424 //----------------------------------------------------------------------------
1425 
1426 template<class VolumeMeshT>
1428 {
1429  normalAttrib_.update_face_normals();
1430  face_normals_calculated_ = true;
1431 }
1432 
1433 //----------------------------------------------------------------------------
1434 
1435 template<class VolumeMeshT>
1437 {
1438  normalAttrib_.update_vertex_normals();
1439  vertex_normals_calculated_ = true;
1440  //update_vertex_normals will also compute face normals
1441  face_normals_calculated_ = true;
1442 }
1443 
1444 //----------------------------------------------------------------------------
1445 
1446 template<class VolumeMeshT>
1447 void VolumeMeshNodeT<VolumeMeshT>::add_cut_plane(const Vec3d& _p, const Vec3d& _n, const Vec3d& _xsize,
1448  const Vec3d& _ysize) {
1449 
1450  add_cut_plane(Plane(_p, _n, _xsize, _ysize));
1451 }
1452 
1453 template<class VolumeMeshT>
1455 {
1456  scale_ = _scale;
1457  cellsBufferManager_.setScale(scale_);
1458  edgesBufferManager_.setScale(scale_);
1459  cellSelectionBufferManager_.setScale(scale_);
1460  faceSelectionBufferManager_.setScale(scale_);
1461  edgeSelectionBufferManager_.setScale(scale_);
1462  vertexSelectionBufferManager_.setScale(scale_);
1463  cellPickBufferManager_.setScale(scale_);
1464  facePickBufferManager_.setScale(scale_);
1465  edgePickBufferManager_.setScale(scale_);
1466  vertexPickBufferManager_.setScale(scale_);
1467 }
1468 
1469 template<class VolumeMeshT>
1471 {
1472  boundary_only_ = _boundary;
1473 
1474  cellsBufferManager_.setBoundaryOnly(_boundary);
1475  facesBufferManager_.setBoundaryOnly(_boundary);
1476  edgesBufferManager_.setBoundaryOnly(_boundary);
1477  verticesBufferManager_.setBoundaryOnly(_boundary);
1478 
1479  cellSelectionBufferManager_.setBoundaryOnly(_boundary);
1480  faceSelectionBufferManager_.setBoundaryOnly(_boundary);
1481  edgeSelectionBufferManager_.setBoundaryOnly(_boundary);
1482  vertexSelectionBufferManager_.setBoundaryOnly(_boundary);
1483 
1484  cellPickBufferManager_.setBoundaryOnly(_boundary);
1485  facePickBufferManager_.setBoundaryOnly(_boundary);
1486  edgePickBufferManager_.setBoundaryOnly(_boundary);
1487  vertexPickBufferManager_.setScale(_boundary);
1488 
1489 }
1490 
1491 template<class VolumeMeshT>
1492 void VolumeMeshNodeT<VolumeMeshT>::set_topology_changed(bool _topology_changed)
1493 {
1494  if (_topology_changed)
1495  invalidateAllBuffers();
1496 }
1497 
1498 template<class VolumeMeshT>
1500 {
1501  if (_geom_changed)
1502  invalidateAllBuffers();
1503 }
1504 
1505 template<class VolumeMeshT>
1506 void VolumeMeshNodeT<VolumeMeshT>::set_color_changed(bool _color_changed)
1507 {
1508  if (_color_changed)
1509  {
1510  cellsBufferManager_.invalidateColors();
1511  facesBufferManager_.invalidateColors();
1512  edgesBufferManager_.invalidateColors();
1513  verticesBufferManager_.invalidateColors();
1514  }
1515 
1516 }
1517 
1518 template<class VolumeMeshT>
1519 void VolumeMeshNodeT<VolumeMeshT>::set_texture_changed(bool _texture_changed)
1520 {
1521  if (_texture_changed)
1522  {
1523  cellsBufferManager_.invalidateTexCoords();
1524  facesBufferManager_.invalidateTexCoords();
1525  edgesBufferManager_.invalidateTexCoords();
1526  verticesBufferManager_.invalidateTexCoords();
1527  }
1528 
1529 }
1530 
1531 template<class VolumeMeshT>
1532 void VolumeMeshNodeT<VolumeMeshT>::set_selection_changed(bool _selection_changed)
1533 {
1534  if (_selection_changed)
1535  invalidateAllSelectionBuffers();
1536 }
1537 
1538 //----------------------------------------------------------------------------
1539 
1540 
1541 template<class VolumeMeshT>
1543  cellsBufferManager_.addCutPlane(_p);
1544  facesBufferManager_.addCutPlane(_p);
1545  edgesBufferManager_.addCutPlane(_p);
1546  verticesBufferManager_.addCutPlane(_p);
1547 
1548  cellSelectionBufferManager_.addCutPlane(_p);
1549  faceSelectionBufferManager_.addCutPlane(_p);
1550  edgeSelectionBufferManager_.addCutPlane(_p);
1551  vertexSelectionBufferManager_.addCutPlane(_p);
1552 
1553  cellPickBufferManager_.addCutPlane(_p);
1554  facePickBufferManager_.addCutPlane(_p);
1555  edgePickBufferManager_.addCutPlane(_p);
1556  vertexPickBufferManager_.addCutPlane(_p);
1557 }
1558 
1559 
1560 //=============================================================================
1561 } // namespace SceneGraph
1562 } // namespace ACG
1563 //=============================================================================
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:563
const Vec4f & specular_color() const
get specular color
Definition: GLState.hh:941
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition: GLState.cc:1757
Namespace providing different geometric functions concerning angles.
void clearTextures()
disables texture support and removes all texture types
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
Definition: GLState.cc:1984
void update_face_normals()
updates face normals
void lineWidth(float _sz)
set line width (default: 1.0)
void update_vertex_normals()
updates vertex normals
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:119
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
void pointSize(float _sz)
set point size (default: 1.0)
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.cc:822
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:786
VolumeMeshNodeT(const VolumeMesh &_mesh, OpenVolumeMesh::StatusAttrib &_statusAttrib, OpenVolumeMesh::ColorAttrib< Vec4f > &_colorAttrib, OpenVolumeMesh::NormalAttrib< VolumeMesh > &_normalAttrib, OpenVolumeMesh::TexCoordAttrib< Vec2f > &_texcoordAttrib, const MaterialNode *_matNode, BaseNode *_parent=0, std::string _name="<VolumeMeshNode>")
Constructor.
void set_color(const Vec4f &_col)
set color
Definition: GLState.cc:691
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:61
int viewport_width() const
get viewport width
Definition: GLState.hh:822
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
float point_size() const
get point size
Definition: GLState.hh:970
float line_width() const
get line width
Definition: GLState.hh:975
void set_depthFunc(const GLenum &_depth_func)
Call glDepthFunc() to actually change the depth comparison function, and store the new value in this ...
Definition: GLState.cc:948
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:921
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:355
Vec2f depthRange
glDepthRange: (znear, zmax)
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
Vec3f diffuse
material definitions
GLSL program class.
Definition: GLSLShader.hh:211
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:102
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
A data structure basing on PolyhedralMesh with specializations for hexahedra.
void set_point_size(float _f)
set point size
Definition: GLState.cc:776
static void useProgram(GLuint _program)
replaces glUseProgram, supports locking
Definition: GLState.cc:2157
bool twosided_lighting()
get whether transparenet or solid objects should be drawn
Definition: GLState.hh:1040
void set_line_width(float _f)
set line width
Definition: GLState.cc:791
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
int viewport_height() const
get viewport height
Definition: GLState.hh:824
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1729
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:104
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:791
const Vec4f & color()
set color
Definition: GLState.hh:916
ShaderGenDesc shaderDesc
Drawmode and other shader params.
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:535
static void cullFace(GLenum _mode)
replaces glCullFace, supports locking
Definition: GLState.cc:1743
bool isLinked()
Returns if the program object has been succesfully linked.
Definition: GLSLShader.cc:370
GLenum blendDest
glBlendFunc: GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ONE_MINUS_SRC_ALPHA ...
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
Definition: GLState.cc:1570
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:385
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
void use()
Enables the program object for using.
Definition: GLSLShader.cc:345