Developer Documentation
GlutPrimitiveNode.cc
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  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS GlutPrimitiveNode - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 
60 //== INCLUDES =================================================================
61 
62 #include "GlutPrimitiveNode.hh"
63 
64 #include <ACG/GL/IRenderer.hh>
65 
66 
67 //== NAMESPACES ===============================================================
68 
69 namespace ACG {
70 namespace SceneGraph {
71 
72 
73 //== IMPLEMENTATION ==========================================================
74 
75 GlutPrimitiveNode::GlutPrimitiveNode( BaseNode* _parent,
76  std::string _name )
77  : BaseNode(_parent, _name),
78  setColor_(true)
79 {
80  const int slices = 20;
81  const int stacks = 20;
82 
83  sphere_ = new ACG::GLSphere(slices,stacks);
84 };
85 
86 //----------------------------------------------------------------------------
87 
88 GlutPrimitiveNode::GlutPrimitiveNode(GlutPrimitiveType _type,
89  BaseNode* _parent,
90  std::string _name) :
91  BaseNode(_parent, _name),
92  setColor_(true)
93 {
94  const int slices = 20;
95  const int stacks = 20;
96 
97  // add a single primitive of the given type
98  Primitive p(_type);
99  primitives_.push_back(p);
100 
101  sphere_ = new ACG::GLSphere(slices, stacks);
102 }
103 
104 void
106 set_position(const Vec3d& _p, int _idx)
107 {
108  if (_idx > -1 && _idx < (int)primitives_.size())
109  primitives_[_idx].position = _p;
110 }
111 
112 //----------------------------------------------------------------------------
113 
114 const Vec3d
116 get_position(int _idx) const
117 {
118  if (_idx > -1 && _idx < (int)primitives_.size())
119  return primitives_[_idx].position;
120 
121  return Vec3d(-1,-1,-1);
122 }
123 
124 //----------------------------------------------------------------------------
125 
126 void
128 set_size(double _s, int _idx)
129 {
130  if (_idx > -1 && _idx < (int)primitives_.size())
131  primitives_[_idx].size = _s;
132 }
133 
134 //----------------------------------------------------------------------------
135 
136 double
138 get_size(int _idx) const
139 {
140  if (_idx > -1 && _idx < (int)primitives_.size())
141  return primitives_[_idx].size;
142  return -1;
143 }
144 
145 //----------------------------------------------------------------------------
146 
147 void
149 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
150 {
151  for (int i = 0; i < (int)primitives_.size(); ++i)
152  {
153  Vec3d sizeVec(primitives_[i].size, primitives_[i].size, primitives_[i].size);
154  _bbMax.maximize(primitives_[i].position + sizeVec);
155  _bbMin.minimize(primitives_[i].position - sizeVec);
156  }
157 }
158 
159 //----------------------------------------------------------------------------
160 
164 {
165  return ( DrawModes::POINTS |
171 }
172 
173 //----------------------------------------------------------------------------
174 
175 void
177 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
178 {
179  float backupColorDiffuse[4];
180  float backupColorAmbient[4];
181  if ( setColor_ ) {
182  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
183  glGetFloatv(GL_CURRENT_COLOR,backupColorDiffuse);
184  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
185  glGetFloatv(GL_CURRENT_COLOR,backupColorAmbient);
186  }
187  for (size_t i = 0; i < primitives_.size(); ++i)
188  {
189 
190 
191  glPushMatrix();
192  glTranslatef(primitives_[i].position[0], primitives_[i].position[1], primitives_[i].position[2]);
193 
194 
195  if (_drawMode & DrawModes::POINTS)
196  {
197  ACG::GLState::disable(GL_LIGHTING);
198  ACG::GLState::shadeModel(GL_FLAT);
199  glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
200  draw_obj(i);
201  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
202  }
203 
204 
205  if (_drawMode & DrawModes::WIREFRAME)
206  {
207  ACG::GLState::disable(GL_LIGHTING);
208  ACG::GLState::shadeModel(GL_FLAT);
209  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
210  draw_obj(i);
211  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
212  }
213 
214  if (_drawMode & DrawModes::SOLID_FACES_COLORED)
215  {
216  ACG::GLState::disable(GL_LIGHTING);
217  ACG::GLState::shadeModel(GL_FLAT);
218  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
219 
220  if ( setColor_ ) {
221  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
222  glColor(primitives_[i].color);
223  }
224 
225  draw_obj(i);
226 
227  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
228  }
229 
230  if (_drawMode & DrawModes::HIDDENLINE)
231  {
232  Vec4f base_color_backup = _state.base_color();
233 
234  ACG::GLState::disable(GL_LIGHTING);
235  ACG::GLState::shadeModel(GL_FLAT);
236 
237  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
238  glColor(_state.clear_color());
239  ACG::GLState::depthRange(0.01, 1.0);
240  draw_obj(i);
241 
242  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
243  glColor(base_color_backup);
244  ACG::GLState::depthRange(0.0, 1.0);
245  draw_obj(i);
246 
247  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
248  }
249 
250 
251  if (_drawMode & DrawModes::SOLID_FLAT_SHADED)
252  {
253  ACG::GLState::enable( GL_COLOR_MATERIAL );
254  ACG::GLState::enable(GL_LIGHTING);
255  ACG::GLState::shadeModel(GL_FLAT);
256 
257  if ( setColor_ ) {
258  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
259  glColor(primitives_[i].color);
260  }
261 
262  draw_obj(i);
263  }
264 
265 
266  if (_drawMode & DrawModes::SOLID_SMOOTH_SHADED)
267  {
268  ACG::GLState::enable( GL_COLOR_MATERIAL );
269  ACG::GLState::enable(GL_LIGHTING);
270  ACG::GLState::shadeModel(GL_SMOOTH);
271 
272  if ( setColor_ ) {
273  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
274  glColor(primitives_[i].color);
275  }
276 
277  draw_obj(i);
278  }
279 
280  glPopMatrix();
281  if ( setColor_ ) {
282  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
283  glColor4fv(backupColorDiffuse);
284  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
285  glColor4fv(backupColorAmbient);
286  }
287  } // end of primitives iter
288 }
289 
290 //----------------------------------------------------------------------------
291 
292 size_t
295 {
296  Primitive p(_type, _pos, _axis, _color);
297  primitives_.push_back(p);
298  return primitives_.size() - 1;
299 }
300 
301 //----------------------------------------------------------------------------
302 
303 void
304 GlutPrimitiveNode::draw_obj(int _idx) const
305 {
306  if (_idx < 0 || _idx >= (int)primitives_.size()) // range check
307  return;
308 
309  Vec3d axis = primitives_[_idx].axis;
310  double size = axis.norm();
311 
312  if (size > 1e-10)
313  {
314  glPushMatrix();
315 
316  Vec3d direction = axis;
317  Vec3d z_axis(0,0,1);
318  Vec3d rot_normal;
319  double rot_angle;
320 
321  direction.normalize();
322  rot_angle = acos((z_axis | direction)) * 180 / M_PI;
323  rot_normal = ((z_axis % direction).normalize());
324 
325 
326  if (fabs(rot_angle) > 0.0001 && fabs(180 - rot_angle) > 0.0001)
327  glRotatef(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
328  else
329  glRotatef(rot_angle,1,0,0);
330 
331 
332  switch (primitives_[_idx].type)
333  {
334  case CONE:
335  glutSolidCone(primitives_[_idx].size, primitives_[_idx].innersize, primitives_[_idx].slices, primitives_[_idx].stacks);
336  break;
337 
338  case CUBE:
339  glutSolidCube(primitives_[_idx].size);
340  break;
341 
342  case DODECAHEDRON:
343  glutSolidDodecahedron();
344  break;
345 
346  case ICOSAHEDRON:
347  glutSolidIcosahedron();
348  break;
349 
350  case OCTAHEDRON:
351  glutSolidOctahedron();
352  break;
353 
354  case SPHERE:
355  glutSolidSphere(primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks);
356  break;
357 
358  case TEAPOT:
359  glutSolidTeapot(primitives_[_idx].size);
360  break;
361 
362  case TETRAHEDRON:
363  glutSolidTetrahedron();
364  break;
365 
366  case TORUS:
367  glutSolidTorus(primitives_[_idx].innersize, primitives_[_idx].size, primitives_[_idx].slices, primitives_[_idx].stacks);
368  break;
369  }
370 
371  glPopMatrix();
372  }
373 }
374 
375 //----------------------------------------------------------------------------
376 
377 void
379 pick(GLState& _state , PickTarget _target)
380 {
381  // initialize picking stack
382  if (!_state.pick_set_maximum (primitives_.size()))
383  {
384  std::cerr << "Strange pickSetMaximum failed for index " << primitives_.size() << " in GlutPrimitiveNode\n";
385  return;
386  }
387 
388  switch (_target)
389  {
390  case PICK_ANYTHING:
391  case PICK_FACE:
392  {
393  for (int i = 0; i < (int)primitives_.size(); ++i)
394  {
395  _state.pick_set_name(i);
396  glPushMatrix();
397  glTranslatef(primitives_[i].position[0], primitives_[i].position[1], primitives_[i].position[2]);
398  draw_obj(i);
399  glPopMatrix();
400  }
401  break;
402  }
403 
404  default:
405  break;
406  }
407 }
408 
409 //----------------------------------------------------------------------------
410 
411 void
413 getRenderObjects(IRenderer* _renderer, GLState& _state , const DrawModes::DrawMode& _drawMode , const Material* _mat) {
414 
415  // init base render object
416  RenderObject ro;
417  ro.initFromState(&_state);
418 
419  // the selection sphere uses alpha blending against scene meshes
420  // set priority-order > 0 to draw this after meshes
421  ro.priority = 1;
422 
423  // enable depth-test
424  ro.depthTest = true;
425 
426  for (int i = 0; i < (int)primitives_.size(); ++i)
427  {
428 
429  // Set the right position
430  _state.push_modelview_matrix();
431  _state.translate(primitives_[i].position);
432  ro.modelview = _state.modelview();
433  _state.pop_modelview_matrix();
434 
435  Material localMaterial = *_mat;
436  if (setColor_)
437  {
438  //localMaterial.color(primitives_[i].color);
439  //localMaterial.ambientColor(primitives_[i].color);
440  localMaterial.diffuseColor(primitives_[i].color);
441  localMaterial.baseColor(primitives_[i].color * .5);
442  }
443 
444  ro.setMaterial(&localMaterial);
445  ro.shaderDesc.shadeMode = SG_SHADE_PHONG;
446 
447  switch (primitives_[i].type) {
448  case SPHERE:
449 
450  // Sphere
451  ro.debugName = (QString("glutprimitive.sphere no %1: ").arg(i)+QString(name().c_str())).toLatin1();
452 
453  sphere_->addToRenderer(_renderer, &ro, primitives_[i].size);
454 
455  break;
456 
457  default:
458  // TODO: The other glut primitives are not yet supported by the advanced renderers
459  std::cerr << "Sorry, but the glut renderer objects are not available for this renderer yet!" << std::endl;
460  break;
461  }
462 
463 
464  }
465 
466 }
467 
468 
469 //=============================================================================
470 } // namespace SceneGraph
471 } // namespace ACG
472 //=============================================================================
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:924
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax)
update bounding box
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:88
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:146
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
Definition: DrawModes.cc:86
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:87
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:84
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1006
int priority
Priority to allow sorting of objects.
void baseColor(const Vec4f &_c)
set the base color
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:79
DrawModes::DrawMode availableDrawModes() const
return available draw modes
PickTarget
What target to use for picking.
Definition: BaseNode.hh:99
void set_size(double _s, int _idx=0)
set size
const Vec3d get_position(int _idx=0) const
get position
GLMatrixd modelview
Modelview transform.
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:562
GlutPrimitiveType
Lists all available primivites.
size_t add_primitive(GlutPrimitiveType _type, Vec3d _pos, Vec3d _axis, ACG::Vec4f _color)
static void enable(GLenum _cap)
replaces glEnable, but supports locking
DrawMode SOLID_FACES_COLORED
draw colored, but not lighted faces using face colors
Definition: DrawModes.cc:90
void set_position(const Vec3d &_p, int _idx=0)
set position
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:929
void pick(GLState &_state, PickTarget _target)
picking
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:531
bool pick_set_maximum(unsigned int _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1047
void diffuseColor(const Vec4f &_d)
set the diffuse color.
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode)
drawing the primitive
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
static void disable(GLenum _cap)
replaces glDisable, but supports locking
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat)
Add the objects to the given renderer.
std::string name() const
Returns: name of node (needs not be unique)
Definition: MeshNode2T.cc:446
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1022
void pick_set_name(unsigned int _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1057
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:428
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
Definition: Vector11T.hh:408
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:69
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:534
Interface class between scenegraph and renderer.
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
picks faces (should be implemented for all nodes)
Definition: BaseNode.hh:104
double get_size(int _idx=0) const
get size
ShaderGenDesc shaderDesc
Drawmode and other shader params.
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking