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