Developer Documentation
VolumeMeshNodeGLCompatT_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 #include "VolumeMeshNode.hh"
43 
44 //== NAMESPACES ===============================================================
45 
46 namespace ACG {
47 namespace SceneGraph {
48 
49 
50 //== IMPLEMENTATION ==========================================================
51 
52 template<class VolumeMeshT>
54 
55  // save state
56  bool clientStateEnabledVertexArray = GLState::isClientStateEnabled(GL_VERTEX_ARRAY);
57  bool clientStateEnabledColorArray = GLState::isClientStateEnabled(GL_COLOR_ARRAY);
58  bool clientStateEnabledNormalArray = GLState::isClientStateEnabled(GL_NORMAL_ARRAY);
59  bool clientStateEnabledTexCoordArray = GLState::isClientStateEnabled(GL_TEXTURE_COORD_ARRAY);
60 
61  GLState::depthRange(0.01, 1.0);
62  if (lastCellDrawMode_)
63  {
64  //draw cells so the user cannot pick invisible stuff
65 
66  GLState::bindBuffer(GL_ARRAY_BUFFER, cellsBufferManager_.getBuffer());
67  GLState::enableClientState(GL_VERTEX_ARRAY);
68  GLState::vertexPointer(3, GL_FLOAT, cellsBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
69 
70  GLState::disableClientState(GL_NORMAL_ARRAY);
71  GLState::disableClientState(GL_COLOR_ARRAY);
72 
73  Vec4f bc = _state.specular_color();
74  _state.set_color(Vec4f(0.0,0.0,0.0,0.0));
75 
76  glDrawArrays(GL_TRIANGLES, 0, cellsBufferManager_.getNumOfVertices());
77 
78  _state.set_color(bc);
79  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
80  }
81 
82  if (lastFaceDrawMode_)
83  {
84  //draw faces so the user cannot pick invisible stuff
85 
86  GLState::bindBuffer(GL_ARRAY_BUFFER, facesBufferManager_.getBuffer());
87  GLState::enableClientState(GL_VERTEX_ARRAY);
88  GLState::vertexPointer(3, GL_FLOAT, facesBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
89 
90  GLState::disableClientState(GL_NORMAL_ARRAY);
91  GLState::disableClientState(GL_COLOR_ARRAY);
92 
93  Vec4f bc = _state.specular_color();
94  _state.set_color(Vec4f(0.0,0.0,0.0,0.0));
95 
96  glDrawArrays(GL_TRIANGLES, 0, facesBufferManager_.getNumOfVertices());
97 
98  _state.set_color(bc);
99  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
100  }
101 
102  GLenum oldDepthFunc = _state.depthFunc();
103 
104  GLState::depthRange(0.0, 1.0);
105 
106  _state.set_depthFunc(GL_LEQUAL);
107 
108  switch (_target) {
109  case PICK_VERTEX: {
110  if (lastPickTarget_ != PICK_VERTEX)
111  vertexPickBufferManager_.invalidateColors();
112  _state.pick_set_maximum(mesh_.n_vertices());
113  pickVerticesCompat(_state);
114  break;
115  }
116 
117  case PICK_EDGE: {
118  _state.pick_set_maximum(mesh_.n_edges());
119  pickEdgesCompat(_state, 0);
120  break;
121  }
122 
123  case PICK_FACE: {
124  _state.pick_set_maximum(mesh_.n_faces());
125  pickFacesCompat(_state, 0);
126  break;
127  }
128 
129  case PICK_CELL: {
130  _state.pick_set_maximum(mesh_.n_cells());
131  pickCellsCompat(_state, 0);
132  break;
133  }
134 
135  case PICK_ANYTHING: {
136  if (lastPickTarget_ != PICK_ANYTHING)
137  vertexPickBufferManager_.invalidateColors();
138 
139  int nv = mesh_.n_vertices();
140  int ne = mesh_.n_edges();
141  int nf = mesh_.n_faces();
142  int nc = mesh_.n_cells();
143 
144  _state.pick_set_maximum(nv + ne + nf + nc);
145  pickVerticesCompat(_state);
146  pickEdgesCompat(_state, nv);
147  pickFacesCompat(_state, nv + ne);
148  pickCellsCompat(_state, nv + ne + nf);
149  break;
150  }
151 
152  default:
153  break;
154  }
155 
156  _state.set_depthFunc(oldDepthFunc);
157 
158  lastPickTarget_ = _target;
159 
160  // restore state
161  if (clientStateEnabledVertexArray)
162  GLState::enableClientState(GL_VERTEX_ARRAY);
163  else
164  GLState::disableClientState(GL_VERTEX_ARRAY);
165 
166  if (clientStateEnabledColorArray)
167  GLState::enableClientState(GL_COLOR_ARRAY);
168  else
169  GLState::disableClientState(GL_COLOR_ARRAY);
170 
171  if (clientStateEnabledNormalArray)
172  GLState::enableClientState(GL_NORMAL_ARRAY);
173  else
174  GLState::disableClientState(GL_NORMAL_ARRAY);
175 
176  if (clientStateEnabledTexCoordArray)
177  GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
178  else
179  GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
180 
181 }
182 
183 //----------------------------------------------------------------------------
184 
185 
186 
187 template<class VolumeMeshT>
189 
190  if (lastDrawMode_ & drawModes_.vertexBasedDrawModes)
191  vertexPickBufferManager_.enableVertexPrimitives();
192  else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
193  vertexPickBufferManager_.enableVertexOnCellPrimitives();
194  else
195  vertexPickBufferManager_.enableVertexPrimitives();
196 
197  vertexPickBufferManager_.disableNormals();
198  vertexPickBufferManager_.enablePickColors();
199 
200 
201 
202  GLState::bindBuffer(GL_ARRAY_BUFFER, vertexPickBufferManager_.getPickBuffer(_state, 0));
203 
204  GLState::enableClientState(GL_VERTEX_ARRAY);
205  GLState::vertexPointer(3, GL_FLOAT, vertexPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
206 
207  GLState::enableClientState(GL_COLOR_ARRAY);
208  GLState::colorPointer(4, GL_UNSIGNED_BYTE, vertexPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(vertexPickBufferManager_.getColorOffset()));
209 
210  GLState::shadeModel(GL_SMOOTH);
211  GLState::disable(GL_LIGHTING);
212 
213  float oldPointSize = _state.point_size();
214  _state.set_point_size(1.5*_state.point_size());
215 
216  glDrawArrays(GL_POINTS, 0, vertexPickBufferManager_.getNumOfVertices());
217 
218  _state.set_point_size(oldPointSize);
219 
220  GLState::disableClientState(GL_COLOR_ARRAY);
221  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
222 
223 }
224 
225 //----------------------------------------------------------------------------
226 
227 
228 template<class VolumeMeshT>
229 void VolumeMeshNodeT<VolumeMeshT>::pickEdgesCompat(GLState& _state, unsigned int _offset) {
230 
231  if ((lastDrawMode_ & (drawModes_.cellBasedDrawModes | drawModes_.edgesOnCells)) && !(lastDrawMode_ & (drawModes_.edgeBasedDrawModes & ~drawModes_.edgesOnCells)))
232  edgePickBufferManager_.enableEdgeOnCellPrimitives();
233  else
234  edgePickBufferManager_.enableEdgePrimitives();
235 
236  edgePickBufferManager_.enablePickColors();
237  edgePickBufferManager_.disableNormals();
238 
239  GLState::bindBuffer(GL_ARRAY_BUFFER, edgePickBufferManager_.getPickBuffer(_state, _offset));
240 
241  GLState::enableClientState(GL_VERTEX_ARRAY);
242  GLState::vertexPointer(3, GL_FLOAT, edgePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
243 
244  GLState::enableClientState(GL_COLOR_ARRAY);
245  GLState::colorPointer(4, GL_UNSIGNED_BYTE, edgePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(edgePickBufferManager_.getColorOffset()));
246 
247  GLState::shadeModel(GL_SMOOTH);
248  GLState::disable(GL_LIGHTING);
249 
250  float oldLineWidth = _state.line_width();
251  _state.set_line_width(4.0*_state.line_width());
252 
253  glDrawArrays(GL_LINES, 0, edgePickBufferManager_.getNumOfVertices());
254 
255  _state.set_line_width(oldLineWidth);
256 
257  GLState::disableClientState(GL_COLOR_ARRAY);
258  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
259 
260 }
261 
262 //----------------------------------------------------------------------------
263 
264 
265 template<class VolumeMeshT>
266 void VolumeMeshNodeT<VolumeMeshT>::pickFacesCompat(GLState& _state, unsigned int _offset) {
267 
268  if (lastDrawMode_ & (drawModes_.faceBasedDrawModes | drawModes_.halffaceBasedDrawModes))
269  facePickBufferManager_.enableFacePrimitives();
270  else if (lastDrawMode_ & drawModes_.cellBasedDrawModes)
271  facePickBufferManager_.enableFaceOnCellPrimitives();
272  else
273  facePickBufferManager_.enableFacePrimitives();
274 
275  facePickBufferManager_.disableNormals();
276  facePickBufferManager_.enablePickColors();
277 
278  GLState::bindBuffer(GL_ARRAY_BUFFER, facePickBufferManager_.getPickBuffer(_state, _offset));
279 
280  GLState::enableClientState(GL_VERTEX_ARRAY);
281  GLState::vertexPointer(3, GL_FLOAT, facePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
282 
283  GLState::enableClientState(GL_COLOR_ARRAY);
284  GLState::colorPointer(4, GL_UNSIGNED_BYTE, facePickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(facePickBufferManager_.getColorOffset()));
285 
286  GLState::shadeModel(GL_SMOOTH);
287  GLState::disable(GL_LIGHTING);
288 
289  glDrawArrays(GL_TRIANGLES, 0, facePickBufferManager_.getNumOfVertices());
290 
291  GLState::disableClientState(GL_COLOR_ARRAY);
292  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
293 }
294 
295 //----------------------------------------------------------------------------
296 
297 
298 template<class VolumeMeshT>
299 void VolumeMeshNodeT<VolumeMeshT>::pickCellsCompat(GLState& _state, unsigned int _offset) {
300 
301  cellPickBufferManager_.enablePickColors();
302  cellPickBufferManager_.disableNormals();
303  cellPickBufferManager_.enableCellPrimitives();
304 
305  GLState::bindBuffer(GL_ARRAY_BUFFER, cellPickBufferManager_.getPickBuffer(_state, _offset));
306 
307  GLState::enableClientState(GL_VERTEX_ARRAY);
308  GLState::vertexPointer(3, GL_FLOAT, cellPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(0));
309 
310  GLState::enableClientState(GL_COLOR_ARRAY);
311  GLState::colorPointer(4, GL_UNSIGNED_BYTE, cellPickBufferManager_.getStride(), reinterpret_cast<GLvoid*>(cellPickBufferManager_.getColorOffset()));
312 
313  GLState::shadeModel(GL_SMOOTH);
314  GLState::disable(GL_LIGHTING);
315 
316  glDrawArrays(GL_TRIANGLES, 0, cellPickBufferManager_.getNumOfVertices());
317 
318  GLState::disableClientState(GL_COLOR_ARRAY);
319  GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
320 }
321 //=============================================================================
322 } // namespace SceneGraph
323 } // namespace ACG
324 //=============================================================================
static bool isClientStateEnabled(GLenum _cap)
returns true, if a client state is enabled
Definition: GLState.cc:1613
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1729
picks edges (may not be implemented for all nodes)
Definition: PickTarget.hh:80
const Vec4f & specular_color() const
get specular color
Definition: GLState.hh:941
void pickVerticesCompat(GLState &_state)
pick vertices using opengl compatibility profile
float point_size() const
get point size
Definition: GLState.hh:970
void pickCompat(GLState &_state, PickTarget _target)
picking using opengl compatibility profile
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
void pickCellsCompat(GLState &_state, unsigned int _offset)
pick cells using opengl compatibility profile
Namespace providing different geometric functions concerning angles.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
void pickFacesCompat(GLState &_state, unsigned int _offset)
pick faces using opengl compatibility profile
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Definition: GLState.cc:1918
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition: GLState.cc:1757
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Definition: GLState.cc:1584
void set_point_size(float _f)
set point size
Definition: GLState.cc:776
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
Definition: GLState.cc:1570
void pickEdgesCompat(GLState &_state, unsigned int _offset)
pick edges using opengl compatibility profile
void set_color(const Vec4f &_col)
set color
Definition: GLState.cc:691
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
Definition: GLState.cc:1962
void set_line_width(float _f)
set line width
Definition: GLState.cc:791
picks faces (may not be implemented for all nodes)
Definition: PickTarget.hh:76
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
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820