Developer Documentation
Loading...
Searching...
No Matches
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
63namespace ACG {
64namespace SceneGraph {
65
66
67//== IMPLEMENTATION ==========================================================
68
69GlutPrimitiveNode::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
83GlutPrimitiveNode::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
100void
101GlutPrimitiveNode::
102set_position(const Vec3d& _p, int _idx)
103{
104 if (_idx > -1 && _idx < (int)primitives_.size())
105 primitives_[_idx].position = _p;
106}
107
108//----------------------------------------------------------------------------
109
110const Vec3d
111GlutPrimitiveNode::
112get_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
122void
123GlutPrimitiveNode::
124set_size(double _s, int _idx)
125{
126 if (_idx > -1 && _idx < (int)primitives_.size())
127 primitives_[_idx].size = _s;
128}
129
130//----------------------------------------------------------------------------
131
132double
133GlutPrimitiveNode::
134get_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
143void
144GlutPrimitiveNode::
145boundingBox(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
158GlutPrimitiveNode::
159availableDrawModes() const
160{
161 return ( DrawModes::POINTS |
162 DrawModes::WIREFRAME |
163 DrawModes::HIDDENLINE |
164 DrawModes::SOLID_FLAT_SHADED |
165 DrawModes::SOLID_SMOOTH_SHADED |
166 DrawModes::SOLID_FACES_COLORED );
167}
168
169//----------------------------------------------------------------------------
170
171void
172GlutPrimitiveNode::
173draw(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);
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);
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);
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);
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);
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
295size_t
296GlutPrimitiveNode::
297add_primitive(GlutPrimitiveType _type, Vec3d _pos, Vec3d _axis, ACG::Vec4f _color)
298{
299 Primitive p(_type, _pos, _axis, _color);
300 primitives_.push_back(p);
301 return primitives_.size() - 1;
302}
303
304//----------------------------------------------------------------------------
305
306void
307GlutPrimitiveNode::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
379void
380GlutPrimitiveNode::
381pick(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
413void
414GlutPrimitiveNode::
415getRenderObjects(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 j = 0; j < (int)primitives_.size(); ++j)
429 {
430
431 // Set the right position
432 _state.push_modelview_matrix();
433 _state.translate(primitives_[j].position);
434 ro.modelview = _state.modelview();
435 _state.pop_modelview_matrix();
436
437 Material localMaterial = *_mat;
438 if (setColor_)
439 {
440 //localMaterial.color(primitives_[j].color);
441 //localMaterial.ambientColor(primitives_[j].color);
442 localMaterial.diffuseColor(primitives_[j].color);
443 localMaterial.baseColor(primitives_[j].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 {
454 case DrawModes::LIGHTSTAGE_SMOOTH:
455 ro.shaderDesc.shadeMode = SG_SHADE_GOURAUD;
456 break;
457 case DrawModes::LIGHTSTAGE_PHONG:
458 ro.shaderDesc.shadeMode = SG_SHADE_PHONG;
459 break;
460 case DrawModes::LIGHTSTAGE_UNLIT:
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 set_ambient_color(const Vec4f &_col)
set ambient color
Definition GLState.cc:707
void pop_modelview_matrix()
pop modelview matrix
Definition GLState.cc:1026
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
const GLMatrixd & modelview() const
get modelview matrix
Definition GLState.hh:816
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition GLState.cc:1061
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition GLState.hh:951
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition GLState.cc:1051
void scale(double _s)
scale by (_s, _s, _s)
Definition GLState.hh:775
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition GLState.cc:533
void set_color(const Vec4f &_col)
set color
Definition GLState.cc:691
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition GLState.cc:1757
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition GLState.cc:1527
const Vec4f & ambient_color() const
get ambient color
Definition GLState.hh:956
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
const Vec4f & clear_color() const
get background color
Definition GLState.hh:946
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition GLState.cc:1729
const Vec4f & diffuse_color() const
get diffuse color
Definition GLState.hh:961
void push_modelview_matrix()
push modelview matrix
Definition GLState.cc:1010
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Definition GLState.cc:722
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition DrawModes.cc:525
size_t getNumLayers() const
returns the layer count
Definition DrawModes.cc:521
GlutPrimitiveType
Lists all available primivites.
void baseColor(const Vec4f &_c)
set the base color (Sets the baseColor which is the same as the emission(const Vec4f& _c) )
void diffuseColor(const Vec4f &_d)
set the diffuse color.
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition Vector11T.hh:588
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition Vector11T.hh:560
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM > >().norm())
Definition Vector11T.hh:454
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM > >().sqrnorm()))
compute euclidean norm
Definition Vector11T.hh:434
PickTarget
What target to use for picking.
Definition PickTarget.hh:74
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition PickTarget.hh:84
@ PICK_FACE
picks faces (should be implemented for all nodes)
Definition PickTarget.hh:78
Namespace providing different geometric functions concerning angles.
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
int priority
Priority to allow sorting of objects.
GLMatrixd modelview
Modelview transform.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.