Developer Documentation

BSplineSurfaceNodeT_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
44
45 //=============================================================================
46 //
47 // CLASS BSplineSurfaceNodeT - IMPLEMENTATION
48 // Author: Ellen Dekkers <dekkers@cs.rwth-aachen.de>
49 //
50 //=============================================================================
51
52 #define ACG_BSPLINESURFACENODET_C
53
54 //== INCLUDES =================================================================
55
56 #include "BSplineSurfaceNodeT.hh"
57 #include <ACG/GL/gl.hh>
58 #include <ACG/GL/GLError.hh>
59 #include <ACG/GL/IRenderer.hh>
60 #include <ACG/Utils/VSToolsT.hh>
61 #include <vector>
62
63
64
65 //== NAMESPACES ===============================================================
66
67 namespace ACG {
68 namespace SceneGraph {
69
70 //== IMPLEMENTATION ==========================================================
71
72
73 template <class BSplineSurfaceType>
74 void
75 BSplineSurfaceNodeT<BSplineSurfaceType>::
76 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
77 {
78 for (unsigned int i = 0; i < bsplineSurface_.n_control_points_m(); ++i)
79 {
80 for (unsigned int j = 0; j < bsplineSurface_.n_control_points_n(); ++j)
81 {
82 _bbMin.minimize(bsplineSurface_(i,j));
83 _bbMax.maximize(bsplineSurface_(i,j));
84 }
85 }
86 }
87
88 //----------------------------------------------------------------------------
89
90 template <class BSplineSurfaceType>
91 DrawModes::DrawMode
92 BSplineSurfaceNodeT<BSplineSurfaceType>::
93 availableDrawModes() const
94 {
95 DrawModes::DrawMode drawModes(0);
96
97 drawModes |= DrawModes::POINTS;
98 drawModes |= DrawModes::WIREFRAME;
99 drawModes |= DrawModes::HIDDENLINE;
100 drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
101 drawModes |= DrawModes::SOLID_FLAT_SHADED;
102 drawModes |= DrawModes::SOLID_PHONG_SHADED;
103 drawModes |= DrawModes::SOLID_SHADER;
104 drawModes |= DrawModes::SOLID_TEXTURED;
105 drawModes |= DrawModes::SOLID_1DTEXTURED;
106
107 return drawModes;
108 }
109
110
111 //----------------------------------------------------------------------------
112
113 template <class BSplineSurfaceType>
114 void
115 BSplineSurfaceNodeT<BSplineSurfaceType>::
116 getRenderObjects(IRenderer* _renderer, GLState& _state, const DrawModes::DrawMode& _drawMode, const Material* _mat)
117 {
118 // check if textures are still valid
119 if ( bspline_selection_draw_mode_ == CONTROLPOINT
120 && controlPointSelectionTexture_valid_ == false)
121 updateControlPointSelectionTexture(_state);
122 if ( bspline_selection_draw_mode_ == KNOTVECTOR
123 && knotVectorSelectionTexture_valid_ == false)
124 updateKnotVectorSelectionTexture(_state);
125
126
127 for (size_t i = 0; i < _drawMode.getNumLayers(); ++i)
128 {
129 const DrawModes::DrawModeProperties* props = _drawMode.getLayer(i);
130
131
132 RenderObject ro;
133 ro.initFromState(&_state);
134 ro.setupShaderGenFromDrawmode(props);
135 ro.depthTest = true;
136
137 // generated texcoords for environment mapping should be computed in fragment shader,
138 // because normals aren't available in the vertex shader
139 ro.shaderDesc.texGenPerFragment = true;
140
141 if ( props->textured() && arb_texture_idx_)
142 ro.addTexture(ACG::RenderObject::Texture(arb_texture_idx_), 0);
143
144 if (props->primitive() == DrawModes::PRIMITIVE_POLYGON || props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
145 {
146 updateSurfaceMesh();
147
148 ro.vertexBuffer = surfaceVBO_.id();
149 ro.indexBuffer = surfaceIBO_.id();
150 ro.vertexDecl = &surfaceDecl_;
151
152 if (props->primitive() == DrawModes::PRIMITIVE_WIREFRAME)
153 ro.fillMode = GL_LINE;
154 else
155 ro.fillMode = GL_FILL;
156
157 GLenum roPrimitives = GL_TRIANGLES;
158
159 #ifdef GL_ARB_tessellation_shader
160 bool tessellationMode = ACG::openGLVersion(4, 0) && Texture::supportsTextureBuffer();
161
162 if (tessellationMode)
163 {
164 // dynamic lod tessellation and spline evaluation on gpu
165
166 if (!controlPointTex_.is_valid())
167 updateTexBuffers();
168
169 ro.shaderDesc.tessControlTemplateFile = "BSpline/tesscontrol_lod.glsl";
170 ro.shaderDesc.tessEvaluationTemplateFile = "BSpline/tesseval_lod.glsl";
171
172
173 QString shaderMacro;
174
175 shaderMacro.sprintf("#define BSPLINE_DEGREE_U %i", bsplineSurface_.degree_m());
176 ro.shaderDesc.macros.push_back(shaderMacro);
177
178 shaderMacro.sprintf("#define BSPLINE_DEGREE_V %i", bsplineSurface_.degree_n());
179 ro.shaderDesc.macros.push_back(shaderMacro);
180
181 shaderMacro.sprintf("#define BSPLINE_KNOTVEC_U %i", bsplineSurface_.degree_m() * 2 + 1);
182 ro.shaderDesc.macros.push_back(shaderMacro);
183
184 shaderMacro.sprintf("#define BSPLINE_KNOTVEC_V %i", bsplineSurface_.degree_n() * 2 + 1);
185 ro.shaderDesc.macros.push_back(shaderMacro);
186
187
188 ro.setUniform("controlPointTex", int(1));
189 ro.setUniform("knotBufferU", int(2));
190 ro.setUniform("knotBufferV", int(3));
191
192 ro.setUniform("uvRange", Vec4f(bsplineSurface_.loweru(), bsplineSurface_.upperu(),
193 bsplineSurface_.lowerv(), bsplineSurface_.upperv()));
194
195 ro.addTexture(RenderObject::Texture(controlPointTex_.id(), GL_TEXTURE_2D), 1, false);
196 ro.addTexture(RenderObject::Texture(knotTexBufferU_.id(), GL_TEXTURE_BUFFER), 2, false);
197 ro.addTexture(RenderObject::Texture(knotTexBufferV_.id(), GL_TEXTURE_BUFFER), 3, false);
198
199 roPrimitives = GL_PATCHES;
200 }
201
202 if (tessellationMode)
203 ro.patchVertices = 3;
204 #endif
205
206 ro.glDrawElements(roPrimitives, surfaceIndexCount_, GL_UNSIGNED_INT, 0);
207
208 _renderer->addRenderObject(&ro);
209
210 }
211 }
212
213 // draw the control net (includes selection on the net)
214 if (render_control_net_)
215 {
216 // update if necessary
217 updateControlNetMesh();
218 updateControlNetMeshSel();
219
220 // setup base renderobject for unlit point and line rendering
221 RenderObject ro;
222 ro.initFromState(&_state);
223 ro.depthTest = true;
224 ro.shaderDesc.shadeMode = SG_SHADE_UNLIT;
225
226 ro.vertexBuffer = controlNetVBO_.id();
227 ro.vertexDecl = &controlNetDecl_;
228
229 Vec2f screenSize = Vec2f(_state.viewport_width(), _state.viewport_height());
230
231 // selected control points
232 if (controlNetSelIndices_)
233 {
234 ro.name = "BSplineSurface_ControlPointSel";
235
236 ro.setupPointRendering(10.0f, screenSize);
237
238 Vec4f selColor = generateHighlightColor(controlnet_color_);
239 ro.emissive = Vec3f(selColor[0], selColor[1], selColor[2]);
240
241 ro.indexBuffer = controlNetSelIBO_.id();
242
243 ro.glDrawElements(GL_POINTS, controlNetSelIndices_, GL_UNSIGNED_INT, 0);
244
245 _renderer->addRenderObject(&ro);
246 }
247
248 // all control points
249 {
250 ro.name = "BSplineSurface_ControlPoint";
251 ro.setupPointRendering(_state.point_size() + 4.0f, screenSize);
252
253 ro.emissive = Vec3f(controlnet_color_[0], controlnet_color_[1], controlnet_color_[2]);
254
255 GLsizei numPoints = bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n();
256 ro.glDrawArrays(GL_POINTS, 0, numPoints);
257
258 _renderer->addRenderObject(&ro);
259 }
260
261 ro.resetPointRendering();
262
263 // all line segments
264 {
265 ro.name = "BSplineSurface_ControlNetLines";
266 ro.setupLineRendering(_state.line_width() + 2.0f, screenSize);
267
268 ro.indexBuffer = controlNetLineIBO_.id();
269
270 ro.glDrawElements(GL_LINES, controlNetLineIndices_, GL_UNSIGNED_INT, 0);
271
272 _renderer->addRenderObject(&ro);
273 }
274 }
275 }
276
277
278 //----------------------------------------------------------------------------
279
280 template <class BSplineSurfaceType>
281 void
282 BSplineSurfaceNodeT<BSplineSurfaceType>::
283 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
284 {
285 GLenum prev_depth = _state.depthFunc();
286
287 glPushAttrib(GL_ENABLE_BIT);
288
289 // check if textures are still valid
290 if ( bspline_selection_draw_mode_ == CONTROLPOINT
291 && controlPointSelectionTexture_valid_ == false)
292 updateControlPointSelectionTexture(_state);
293 if ( bspline_selection_draw_mode_ == KNOTVECTOR
294 && knotVectorSelectionTexture_valid_ == false)
295 updateKnotVectorSelectionTexture(_state);
296
297
298 if (_drawMode & DrawModes::POINTS)
299 {
300 ACG::GLState::disable(GL_LIGHTING);
301 ACG::GLState::shadeModel(GL_FLAT);
302 render( _state, false);
303 }
304
305 if (_drawMode & DrawModes::WIREFRAME)
306 {
307 glPushAttrib(GL_ENABLE_BIT);
308
309 ACG::GLState::disable( GL_CULL_FACE );
310 ACG::GLState::disable(GL_LIGHTING);
311 ACG::GLState::shadeModel(GL_FLAT);
312 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
313
314 render( _state, false);
315
316 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
317 glPopAttrib();
318 }
319
320
321 if (_drawMode & DrawModes::HIDDENLINE)
322 {
323 Vec4f clear_color = _state.clear_color();
324 Vec4f base_color = _state.base_color();
325 clear_color[3] = 1.0;
326
327 ACG::GLState::enable(GL_DEPTH_TEST);
328 ACG::GLState::disable(GL_LIGHTING);
329 ACG::GLState::shadeModel(GL_FLAT);
330 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
331 _state.set_base_color(clear_color);
332
333 ACG::GLState::depthRange(0.01, 1.0);
334
335 render( _state, true);
336
337 ACG::GLState::depthRange(0.0, 1.0);
338
339 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
340 ACG::GLState::depthFunc(GL_LEQUAL);
341 _state.set_base_color(base_color);
342
343 render( _state, false);
344
345 ACG::GLState::depthFunc(prev_depth);
346 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
347 }
348
349
350 if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ))
351 {
352 ACG::GLState::enable(GL_LIGHTING);
353 ACG::GLState::shadeModel(GL_FLAT);
354
355 ACG::GLState::enable(GL_AUTO_NORMAL);
356 ACG::GLState::enable(GL_NORMALIZE);
357
358 ACG::GLState::depthRange(0.01, 1.0);
359
360 render( _state, true);
361
362 ACG::GLState::depthRange(0.0, 1.0);
363 }
364
365
366 if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) )
367 {
368 ACG::GLState::enable(GL_AUTO_NORMAL);
369 ACG::GLState::enable(GL_NORMALIZE);
370
371 ACG::GLState::enable(GL_LIGHTING);
372 ACG::GLState::shadeModel(GL_SMOOTH);
373 ACG::GLState::depthRange(0.01, 1.0);
374
375 render( _state, true);
376
377 ACG::GLState::depthRange(0.0, 1.0);
378 }
379
380 if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) )
381 {
382 ACG::GLState::enable(GL_AUTO_NORMAL);
383 ACG::GLState::enable(GL_NORMALIZE);
384
385 ACG::GLState::enable(GL_LIGHTING);
386 ACG::GLState::shadeModel(GL_SMOOTH);
387 ACG::GLState::depthRange(0.01, 1.0);
388
389 render( _state, true);
390
391 ACG::GLState::depthRange(0.0, 1.0);
392 }
393
394
395 // If in shader mode, just draw, as the shader has to be set by a shadernode above this node
396 if ( (_drawMode & DrawModes::SOLID_SHADER ) ) {
397 ACG::GLState::enable(GL_AUTO_NORMAL);
398 ACG::GLState::enable(GL_NORMALIZE);
399
400 ACG::GLState::enable(GL_LIGHTING);
401 ACG::GLState::shadeModel(GL_SMOOTH);
402 ACG::GLState::depthRange(0.01, 1.0);
403
404 // draw_faces(PER_VERTEX);
405 render( _state, true);
406
407 ACG::GLState::depthRange(0.0, 1.0);
408 }
409
410
411 if ((_drawMode & DrawModes::SOLID_TEXTURED) || (_drawMode & DrawModes::SOLID_ENV_MAPPED)) {
412 ACG::GLState::enable(GL_AUTO_NORMAL);
413 ACG::GLState::enable(GL_NORMALIZE);
414 // ACG::GLState::enable (GL_BLEND);
415 // ACG::GLState::blendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
416 ACG::GLState::enable(GL_LIGHTING);
417 ACG::GLState::shadeModel(GL_SMOOTH);
418 ACG::GLState::depthRange(0.01, 1.0);
419
420 arb_texture_used_ = true;
421 drawTexturedSurface(_state, arb_texture_idx_ );
422 arb_texture_used_ = false;
423
424 ACG::GLState::depthRange(0.0, 1.0);
425 // ACG::GLState::disable(GL_BLEND);
426 }
427
428 glPopAttrib();
429 }
430
431 //----------------------------------------------------------------------------
432
433 template <class BSplineSurfaceType>
434 void
435 BSplineSurfaceNodeT<BSplineSurfaceType>::
436 render(GLState& _state, bool _fill)
437 {
438 // draw the control net (includes selection on the net)
439 if (render_control_net_)
440 {
441 if (bspline_draw_mode_ == NORMAL)
442 drawControlNet(_state);
443 else if (bspline_draw_mode_ == FANCY)
444 drawFancyControlNet(_state);
445 }
446
447 // draw the spline curve itself, depending on the type of visualization
448 if (render_bspline_surface_)
449 {
450 if (bspline_selection_draw_mode_ == NONE)
451 drawSurface(_state, _fill);
452 else if (bspline_selection_draw_mode_ == CONTROLPOINT)
453 drawTexturedSurface(_state, cp_selection_texture_idx_);
454 else if (bspline_selection_draw_mode_ == KNOTVECTOR)
455 drawTexturedSurface(_state, knot_selection_texture_idx_);
456 }
457 }
458
459 //----------------------------------------------------------------------------
460
461 template <class BSplineSurfaceType>
462 void
463 BSplineSurfaceNodeT<BSplineSurfaceType>::
464 drawSurface(GLState& _state, bool _fill)
465 {
466 updateSurfaceMesh();
467
468 surfaceVBO_.bind();
469 surfaceIBO_.bind();
470
471 surfaceDecl_.activateFixedFunction();
472
473 // draw
474 glDrawElements(GL_TRIANGLES, surfaceIndexCount_, GL_UNSIGNED_INT, 0);
475
476 surfaceDecl_.deactivateFixedFunction();
477
478 surfaceIBO_.unbind();
479 surfaceVBO_.unbind();
480 }
481
482 //----------------------------------------------------------------------------
483
484 template <class BSplineSurfaceType>
485 void
486 BSplineSurfaceNodeT<BSplineSurfaceType>::
487 drawTexturedSurface(GLState& _state, GLuint _texture_idx)
488 {
489 glPushAttrib(GL_ALL_ATTRIB_BITS);
490 // ACG::GLState::enable( GL_COLOR_MATERIAL );
491 // glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
492
493 ACG::GLState::enable(GL_TEXTURE_2D);
494
495 // blend colors (otherwise lighting does not affect the texture)
496 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
497 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
498 // avoid aliasing at patch boundaries
499 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
500 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
501
502 // repeat if arbitrary texture mode
503 if( arb_texture_used_ )
504 {
505 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
506 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
507 }
508
509 // GL_MODULATE to include lighting effects
510 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
511
512 ACG::GLState::bindTexture( GL_TEXTURE_2D, _texture_idx);
513
514 drawSurface( _state);
515
516 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
517 ACG::GLState::disable(GL_TEXTURE_2D);
518 // ACG::GLState::disable( GL_COLOR_MATERIAL );
519 glPopAttrib( );
520 }
521
522 //----------------------------------------------------------------------------
523
524 template <class BSplineSurfaceType>
525 void
526 BSplineSurfaceNodeT<BSplineSurfaceType>::
527 drawControlNet(GLState& _state)
528 {
529 // remember old color
530 Vec4f base_color_old = _state.base_color();
531
532 // draw control net
533 // glPushAttrib(GL_ENABLE_BIT);
534 glPushAttrib(GL_ALL_ATTRIB_BITS);
535
536 ACG::GLState::disable( GL_CULL_FACE );
537 ACG::GLState::disable(GL_LIGHTING);
538 ACG::GLState::shadeModel(GL_FLAT);
539
540
541 // update controlnet buffers
542 updateControlNetMesh();
543 updateControlNetMeshSel();
544
545 // bind vbo containing all control points
546 controlNetVBO_.bind();
547 controlNetDecl_.activateFixedFunction();
548
549 // draw points
550
551 // draw selection
552 if (controlNetSelIndices_)
553 {
554 glColor(generateHighlightColor(controlnet_color_));
555 glPointSize(10);
556
557 // selected points are in index buffer
558 controlNetSelIBO_.bind();
559 glDrawElements(GL_POINTS, controlNetSelIndices_, GL_UNSIGNED_INT, 0);
560 }
561
562 // draw all points
563 glColor(controlnet_color_);
564
565 float point_size_old = _state.point_size();
566 glPointSize(point_size_old + 4);
567
568 GLsizei numControlPoints = bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n();
569 glDrawArrays(GL_POINTS, 0, numControlPoints);
570
571 glPointSize((int)point_size_old);
572
573
574 // draw line segments
575
576 /*
577 // draw selection
578 if( bsplineSurface_.edge_selections_available())
579 {
580 // save old values
581 Vec4f base_color_old = _state.base_color();
582 float line_width_old = _state.line_width();
583
584 glColor(controlnet_highlight_color_);
585 glLineWidth(2*line_width_old);
586
587 glBegin(GL_LINES);
588 // draw bspline control net
589 int num_edges_m = (int)(bsplineSurface_.n_control_points_m()) - 1;
590 int num_edges_n = (int)(bsplineSurface_.n_control_points_n()) - 1;
591 for (int i = 0; i < num_edges_m; ++i) // #edges
592 {
593 for (int j = 0; j < num_edges_n; ++j) // #edges
594 {
595 if( bsplineSurface_.edge_selection(i, j))
596 {
597 glVertex(bsplineSurface_(i,j));
598 glVertex(bsplineSurface_(i+1, j));
599 }
600 }
601 }
602 glEnd();
603
604 glLineWidth(line_width_old);
605 glColor( base_color_old );
606 }
607 */
608 // draw all line segments
609 glColor(controlnet_color_);
610
611 float line_width_old = _state.line_width();
612 glLineWidth(line_width_old+2.0);
613
614 controlNetLineIBO_.bind();
615 glDrawElements(GL_LINES, controlNetLineIndices_, GL_UNSIGNED_INT, 0);
616
617
618 // restore gl states
619 controlNetDecl_.deactivateFixedFunction();
620 controlNetLineIBO_.unbind();
621 controlNetVBO_.unbind();
622
623 glColor( base_color_old );
624 glLineWidth(line_width_old);
625
626 glPopAttrib();
627 }
628
629 //----------------------------------------------------------------------------
630
631 template <class BSplineSurfaceType>
632 void
633 BSplineSurfaceNodeT<BSplineSurfaceType>::
634 drawFancyControlNet(GLState& _state)
635 {
636 // remember old color
637 Vec4f base_color_old = _state.base_color();
638
639 // draw control net
640 // glPushAttrib(GL_ENABLE_BIT);
641 glPushAttrib(GL_ALL_ATTRIB_BITS);
642
643 ACG::GLState::disable( GL_CULL_FACE );
644
645 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
646 ACG::GLState::enable( GL_COLOR_MATERIAL );
647 ACG::GLState::enable(GL_LIGHTING);
648 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
649 ACG::GLState::shadeModel(GL_SMOOTH);
650
651
652 // draw points
653 double sphereRadius = _state.point_size() * 0.05;
654
655 // draw selection
656 if( bsplineSurface_.controlpoint_selections_available())
657 {
658 // save old values
659 float point_size_old = _state.point_size();
660
661 // save old values
662 // glColor(controlnet_highlight_color_);
663 glColor(generateHighlightColor(controlnet_color_));
664
665 // draw control polygon
666 for (unsigned int i = 0; i < bsplineSurface_.n_control_points_m(); ++i)
667 {
668 for (unsigned int j = 0; j < bsplineSurface_.n_control_points_n(); ++j)
669 {
670 if( bsplineSurface_.controlpoint_selection(i, j))
671 draw_sphere(bsplineSurface_(i, j), sphereRadius, _state, fancySphere_);
672 }
673 }
674
675 glPointSize(point_size_old);
676 }
677
678 // draw all points
679 glColor(controlnet_color_);
680
681 for (unsigned int i = 0; i < bsplineSurface_.n_control_points_m(); ++i)
682 for (unsigned int j = 0; j < bsplineSurface_.n_control_points_n(); ++j)
683 draw_sphere(bsplineSurface_(i, j), sphereRadius, _state, fancySphere_);
684
685
686 // draw line segments
687
688 double cylinderRadius = _state.line_width() * 0.05;
689
690 glColor(controlnet_color_);
691
692 // draw bspline control net
693 for (unsigned int i = 0; i < bsplineSurface_.n_control_points_m(); ++i)
694 {
695 for (int j = 0; j < (int)bsplineSurface_.n_control_points_n() - 1; ++j)
696 {
697 Vec3d p = bsplineSurface_(i, j);
698 Vec3d p_next = bsplineSurface_(i, j+1);
699 draw_cylinder(p, p_next - p, cylinderRadius, _state);
700 }
701 }
702
703 for (int j = 0; j < (int)bsplineSurface_.n_control_points_n(); ++j)
704 {
705 for (int i = 0; i < (int)bsplineSurface_.n_control_points_m() - 1; ++i)
706 {
707 Vec3d p = bsplineSurface_(i, j);
708 Vec3d p_next = bsplineSurface_(i+1,j);
709 draw_cylinder(p, p_next - p, cylinderRadius, _state);
710 }
711 }
712
713 // reset old color
714 glColor( base_color_old );
715
716 glPopAttrib();
717 }
718
719 //----------------------------------------------------------------------------
720
721 template <class BSplineSurfaceType>
722 void
723 BSplineSurfaceNodeT<BSplineSurfaceType>::
724 updateGeometry()
725 {
726 invalidateSurfaceMesh_ = true;
727 invalidateControlNetMesh_ = true;
728 }
729
730 //----------------------------------------------------------------------------
731
732 template <class BSplineSurfaceType>
733 void
734 BSplineSurfaceNodeT<BSplineSurfaceType>::
735 pick(GLState& _state, PickTarget _target)
736 {
737 if(pick_texture_idx_ == 0)
738 pick_init_texturing();
739
740 ACG::GLState::disable(GL_COLOR_MATERIAL);
741
742 switch (_target)
743 {
744 case PICK_VERTEX:
745 {
746 if(render_control_net_)
747 {
748 _state.pick_set_maximum (bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n());
749 pick_vertices(_state);
750 }
751 break;
752 }
753
754 case PICK_FACE:
755 {
756 _state.pick_set_maximum (1);
757 pick_surface(_state, 0);
758 break;
759 }
760
761 case PICK_SPLINE:
762 {
763 _state.pick_set_maximum( pick_texture_res_ * pick_texture_res_);
764 pick_spline(_state);
765 break;
766 }
767
768 case PICK_ANYTHING:
769 {
770 _state.pick_set_maximum (bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n() + 1);
771 pick_vertices(_state);
772 pick_surface(_state, bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n());
773 break;
774 }
775
776 default:
777 break;
778 }
779 }
780
781 //----------------------------------------------------------------------------
782
783 template <class BSplineSurfaceType>
784 void
785 BSplineSurfaceNodeT<BSplineSurfaceType>::
786 pick_vertices( GLState& _state )
787 {
788 // radius in pixels
789 int psize = 7;
790
791 _state.pick_set_name (0);
792
793 for (unsigned int i = 0; i < bsplineSurface_.n_control_points_m(); ++i)
794 {
795 for (unsigned int j = 0; j < bsplineSurface_.n_control_points_n(); ++j)
796 {
797 _state.pick_set_name (i * bsplineSurface_.n_control_points_n() + j);
798
799 // compute 3d radius of sphere
800 Vec3d window_pos = _state.project( (Vec3d)bsplineSurface_(i,j) );
801 int px = round( window_pos[0]);
802 int py = round( window_pos[1]);
803 double angle = acos(_state.viewing_direction(px, py).normalize()|_state.viewing_direction(px+psize, py).normalize());
804 double l = (_state.eye() - (Vec3d)bsplineSurface_(i,j)).norm();
805 double r = l*tan(angle);
806
807 // draw 3d sphere
808 draw_sphere( bsplineSurface_(i,j), r, _state, sphere_);
809 }
810 }
811 }
812
813 //----------------------------------------------------------------------------
814
815 template <class BSplineSurfaceType>
816 void
817 BSplineSurfaceNodeT<BSplineSurfaceType>::
818 pick_spline( GLState& _state )
819 {
820 glPushAttrib(GL_ALL_ATTRIB_BITS);
821
822 ACG::GLState::enable(GL_TEXTURE_2D);
823
824 ACG::GLState::disable(GL_COLOR_MATERIAL);
825 ACG::GLState::disable(GL_LIGHTING);
826 ACG::GLState::shadeModel(GL_FLAT);
827
828 std::cout << "[BSplineSurface] pick_spline: \n"
829 << "pick_texture_baseidx_ = " << pick_texture_baseidx_
830 << ", _state.pick_current_index () = " << _state.pick_current_index ()
831 << ", pick_texture_idx_ = " << pick_texture_idx_
832 << std::endl;
833
834 if( _state.pick_current_index () != pick_texture_baseidx_)
835 {
836 pick_texture_baseidx_ = _state.pick_current_index();
837 pick_create_texture( _state);
838 }
839 else
840 {
841 // do not blend colors (else color picking breaks!)
842 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
843 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
844 // avoid aliasing at patch boundaries
845 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
846 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
847 // GL_REPLACE to avoid smearing colors (else color picking breaks!)
848 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
849
850 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_);
851 }
852
853 drawSurface(_state);
854
855 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
856 ACG::GLState::disable(GL_TEXTURE_2D);
857 glPopAttrib( );
858 }
859
860 //----------------------------------------------------------------------------
861
862 template <class BSplineSurfaceType>
863 void
864 BSplineSurfaceNodeT<BSplineSurfaceType>::
865 pick_surface( GLState& _state, unsigned int _offset )
866 {
867 bool sampling_mode_backup = adaptive_sampling_;
868 adaptive_sampling_ = false;
869
870 // pick the whole surface
871 _state.pick_set_name ( _offset );
872 drawSurface( _state);
873
874 adaptive_sampling_ = sampling_mode_backup;
875 }
876
877 //----------------------------------------------------------------------------
878
879 template <class BSplineSurfaceType>
880 void
881 BSplineSurfaceNodeT<BSplineSurfaceType>::
882 draw_sphere( const Point& _p0, double _r, GLState& _state, GLSphere* _sphere)
883 {
884 // draw 3d sphere
885 _state.push_modelview_matrix();
886 _state.translate( _p0[0], _p0[1], _p0[2]);
887
888 _sphere->draw(_state,_r);
889
890 _state.pop_modelview_matrix();
891 }
892
893 //----------------------------------------------------------------------------
894
895 template <class BSplineSurfaceType>
896 void
897 BSplineSurfaceNodeT<BSplineSurfaceType>::
898 draw_cylinder( const Point& _p0, const Point& _axis, double _r, GLState& _state)
899 {
900 _state.push_modelview_matrix();
901 _state.translate(_p0[0], _p0[1], _p0[2]);
902
903 Point direction = _axis;
904 Point z_axis(0,0,1);
905 Point rot_normal;
906 double rot_angle;
907
908 direction.normalize();
909 rot_angle = acos((z_axis | direction))*180/M_PI;
910 rot_normal = ((z_axis % direction).normalize());
911
912 if( fabs( rot_angle ) > 0.0001 && fabs( 180 - rot_angle ) > 0.0001)
913 _state.rotate(rot_angle,rot_normal[0], rot_normal[1], rot_normal[2]);
914 else
915 _state.rotate(rot_angle,1,0,0);
916
917 cylinder_->setBottomRadius(_r);
918 cylinder_->setTopRadius(_r);
919 cylinder_->draw(_state,_axis.norm());
920
921 _state.pop_modelview_matrix();
922 }
923
924 //----------------------------------------------------------------------------
925
926 template <class BSplineSurfaceType>
927 void
928 BSplineSurfaceNodeT<BSplineSurfaceType>::
929 updateControlPointSelectionTexture(GLState& _state)
930 {
931 create_cp_selection_texture(_state);
932 controlPointSelectionTexture_valid_ = true;
933
934 // also update index buffer for rendering selections
935 invalidateControlNetMeshSel_ = true;
936 }
937
938 //----------------------------------------------------------------------------
939
940 template <class BSplineSurfaceType>
941 void
942 BSplineSurfaceNodeT<BSplineSurfaceType>::
943 updateKnotVectorSelectionTexture(GLState& _state)
944 {
945 create_knot_selection_texture(_state);
946 knotVectorSelectionTexture_valid_ = true;
947 }
948
949 //----------------------------------------------------------------------------
950
951 template <class BSplineSurfaceType>
952 void
953 BSplineSurfaceNodeT<BSplineSurfaceType>::
954 selection_init_texturing(GLuint & _texture_idx )
955 {
956 // generate texture index
957 glGenTextures( 1, &_texture_idx );
958 // bind texture as current
959 ACG::GLState::bindTexture( GL_TEXTURE_2D, _texture_idx );
960 // blend colors (otherwise lighting does not affect the texture)
961 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
962 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
963 // avoid aliasing at patch boundaries
964 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
965 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
966 // GL_MODULATE to include lighting effects
967 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
968 // unbind current texture
969 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
970 }
971
972 //----------------------------------------------------------------------------
973
974 template <class BSplineSurfaceType>
975 void
976 BSplineSurfaceNodeT<BSplineSurfaceType>::
977 create_cp_selection_texture(GLState& /*_state*/)
978 {
979 if (bsplineSurface_.n_knots_m() == 0 || bsplineSurface_.n_knots_n() == 0)
980 return;
981
982 if(cp_selection_texture_idx_ == 0)
983 selection_init_texturing(cp_selection_texture_idx_);
984
985 QImage b(cp_selection_texture_res_, cp_selection_texture_res_, QImage::Format_ARGB32);
986
987 int degree_m = bsplineSurface_.degree_m();
988 int degree_n = bsplineSurface_.degree_n();
989
990 int numKnots_m = bsplineSurface_.n_knots_m();
991 int numKnots_n = bsplineSurface_.n_knots_n();
992
993 Knotvector knotvec_m = bsplineSurface_.get_knotvector_m();
994 Knotvector knotvec_n = bsplineSurface_.get_knotvector_n();
995
996 double minu = bsplineSurface_.get_knot_m( degree_m );
997 double maxu = bsplineSurface_.get_knot_m( numKnots_m - degree_m -1 );
998 double diffu = maxu - minu;
999
1000 double minv = bsplineSurface_.get_knot_n( degree_n );
1001 double maxv = bsplineSurface_.get_knot_n( numKnots_n - degree_n -1 );
1002 double diffv = maxv - minv;
1003
1004 if (diffu == 0.0 || diffv == 0.0 )
1005 return;
1006
1007 int texelIdx_u = 0;
1008
1009 for ( int m = 0; m < cp_selection_texture_res_; ++m)
1010 {
1011 double step_m = (double)m / (double)cp_selection_texture_res_;
1012 double u = step_m * diffu;
1013
1014 // get the span and check which knots are selected
1015 ACG::Vec2i span_u = bsplineSurface_.spanm(u);
1016 // check for incomplete spline
1017 if (span_u[0] < 0 || span_u[1] < 0)
1018 return;
1019
1020 // reset texture v coord for every new u coord
1021 int texelIdx_v = 0;
1022
1023 // iterate over n direction
1024 for ( int n = 0; n < cp_selection_texture_res_; ++n)
1025 {
1026 double step_n = double(n) / (double)cp_selection_texture_res_;
1027 double v = step_n * diffv;
1028
1029 // get the span and check which knots are selected
1030 ACG::Vec2i span_v = bsplineSurface_.spann(v);
1031 // check for incomplete spline
1032 if (span_v[0] < 0 || span_v[1] < 0)
1033 return;
1034
1035 float alpha = 0.0; // blends between curve and highlight colors
1036 for (int i = 0; i < degree_m+1; ++i) // degree+1 basis functions (those in the span) contribute
1037 {
1038 int idx_m = span_u[0] + i;
1039
1040 for (int j = 0; j < degree_n+1; ++j) // degree+1 basis functions (those in the span) contribute
1041 {
1042 int idx_n = span_v[0] + j;
1043
1044 // basis functions sum up to 1. hence, we only have to sum up those with selected control point to get the blending weight
1045 if (bsplineSurface_.controlpoint_selection(idx_m, idx_n))
1046 alpha += bsplineSurface_.basisFunction( knotvec_m, idx_m, degree_m, u)
1047 * bsplineSurface_.basisFunction( knotvec_n, idx_n, degree_n, v);
1048 }
1049 }
1050
1051 // compute color
1052 Vec4f color = surface_color_ * (1.0 - alpha) + surface_highlight_color_ * alpha;
1053
1054 // fill texture (switch v coord due to axis of texture image)
1055 b.setPixel (texelIdx_u, 255-texelIdx_v, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
1056
1057 ++texelIdx_v;
1058 } // end of n direction iter
1059
1060 ++texelIdx_u;
1061 } // end of u direction iter
1062
1063
1064 // debug, output image
1065 // b.save("surfaceCPSelectionTexture.png", "PNG");
1066
1067 cp_selection_texture_image_ = QGLWidget::convertToGLFormat( b );
1068
1069 // bind texture
1070 ACG::GLState::bindTexture( GL_TEXTURE_2D, cp_selection_texture_idx_ );
1071 glTexImage2D( GL_TEXTURE_2D,
1072 0, GL_RGBA, cp_selection_texture_image_.width(), cp_selection_texture_image_.height(),
1073 0, GL_RGBA, GL_UNSIGNED_BYTE, cp_selection_texture_image_.bits() );
1074 }
1075
1076 //----------------------------------------------------------------------------
1077
1078 template <class BSplineSurfaceType>
1079 void
1080 BSplineSurfaceNodeT<BSplineSurfaceType>::
1081 create_knot_selection_texture(GLState& _state)
1082 {
1083 if (bsplineSurface_.n_knots_m() == 0 ||bsplineSurface_.n_knots_n() == 0)
1084 return;
1085
1086 if(knot_selection_texture_idx_ == 0)
1087 selection_init_texturing(knot_selection_texture_idx_);
1088
1089 QImage b(knot_selection_texture_res_, knot_selection_texture_res_, QImage::Format_ARGB32);
1090
1091 int degree_m = bsplineSurface_.degree_m();
1092 int degree_n = bsplineSurface_.degree_n();
1093
1094 int numKnots_m = bsplineSurface_.n_knots_m();
1095 int numKnots_n = bsplineSurface_.n_knots_n();
1096
1097 Knotvector knotvec_m = bsplineSurface_.get_knotvector_m();
1098 Knotvector knotvec_n = bsplineSurface_.get_knotvector_n();
1099
1100 double minu = bsplineSurface_.get_knot_m( degree_m );
1101 double maxu = bsplineSurface_.get_knot_m( numKnots_m - degree_m -1 );
1102 double diffu = maxu - minu;
1103
1104 double minv = bsplineSurface_.get_knot_n( degree_n );
1105 double maxv = bsplineSurface_.get_knot_n( numKnots_n - degree_n -1 );
1106 double diffv = maxv - minv;
1107
1108 if (diffu == 0.0 || diffv == 0.0 )
1109 return;
1110
1111 int texelIdx_u = 0;
1112
1113 // if a knot is selected, select all knots in the span of this knot, too
1114 std::vector<bool> selectedKnotSpans_m(numKnots_m, false);
1115 for (int i = 0; i < numKnots_m; ++i)
1116 {
1117 if (bsplineSurface_.get_knotvector_m_ref()->selection(i))
1118 {
1119 // get the span and check which knots are selected
1120 ACG::Vec2i span = bsplineSurface_.spanm(bsplineSurface_.get_knot_m(i));
1121 // check for incomple spline
1122 if (span[0] < 0 || span[1] < 0)
1123 return;
1124
1125 for(int j = span[0]; j <= span[1]+degree_m; ++j)
1126 selectedKnotSpans_m[j] = true;
1127 }
1128 }
1129 // std::cout << "selectedKnotSpans_m: " << std::flush;
1130 // for (unsigned int i = 0; i < selectedKnotSpans_m.size(); ++i)
1131 // std::cout << selectedKnotSpans_m[i] << ", " << std::flush;
1132 // std::cout << std::endl;
1133
1134
1135 std::vector<bool> selectedKnotSpans_n(numKnots_n, false);
1136 for (int i = 0; i < numKnots_n; ++i)
1137 {
1138 if (bsplineSurface_.get_knotvector_n_ref()->selection(i))
1139 {
1140 // get the span and check which knots are selected
1141 ACG::Vec2i span = bsplineSurface_.spann(bsplineSurface_.get_knot_n(i));
1142 // check for incomple spline
1143 if (span[0] < 0 || span[1] < 0)
1144 return;
1145
1146 for(int j = span[0]; j <= span[1]+degree_n; ++j)
1147 selectedKnotSpans_n[j] = true;
1148 }
1149 }
1150 // std::cout << "selectedKnotSpans_n: " << std::flush;
1151 // for (unsigned int i = 0; i < selectedKnotSpans_n.size(); ++i)
1152 // std::cout << selectedKnotSpans_n[i] << ", " << std::flush;
1153 // std::cout << std::endl;
1154
1155
1156 for ( int m = 0; m < knot_selection_texture_res_; ++m)
1157 {
1158 double step_m = (double)m / (double)knot_selection_texture_res_;
1159 double u = step_m * diffu;
1160
1161 Vec2i interval_m = bsplineSurface_.interval_m(u);
1162
1163 // reset texture v coord for every new u coord
1164 int texelIdx_v = 0;
1165
1166 for ( int n = 0; n < knot_selection_texture_res_; ++n)
1167 {
1168 double step_n = (double)n / (double)knot_selection_texture_res_;
1169 double v = step_n * diffv;
1170
1171 Vec2i interval_n = bsplineSurface_.interval_n(v);
1172
1173 // check if highlighted
1174 bool selected_m = (selectedKnotSpans_m[interval_m[0]] && selectedKnotSpans_m[interval_m[1]]);
1175 bool selected_n = (selectedKnotSpans_n[interval_n[0]] && selectedKnotSpans_n[interval_n[1]]);
1176
1177 Vec4f color;
1178 if (selected_m && selected_n)
1179 // color = _state.specular_color();
1180 // color = _state.base_color();
1181 color = surface_highlight_color_;
1182 else if ((selected_m && !selected_n) || (!selected_m && selected_n) )
1183 // color = _state.ambient_color() *0.5 + _state.specular_color() * 0.5;
1184 // color = _state.base_color() *0.5 + _state.specular_color() * 0.5;
1185 color = surface_highlight_color_ * 0.5 + surface_color_ * 0.5;
1186 else
1187 // color = _state.ambient_color() *0.5 + _state.diffuse_color() * 0.5;
1188 // color = _state.base_color() *0.5 + _state.diffuse_color() * 0.5;
1189 color = surface_color_;
1190
1191
1192 // fill texture
1193 b.setPixel (texelIdx_u, 255-texelIdx_v, qRgba((int)(color[0]*255.0), (int)(color[1]*255.0), (int)(color[2]*255.0), 255));
1194
1195 ++texelIdx_v;
1196 } // end of v direction
1197
1198 ++texelIdx_u;
1199 } // end of u direction
1200
1201 // debug, output image
1202 // b.save("surfaceKnotSelectionTexture.png", "PNG");
1203
1204 knot_selection_texture_image_ = QGLWidget::convertToGLFormat( b );
1205
1206 // bind texture
1207 ACG::GLState::bindTexture( GL_TEXTURE_2D, knot_selection_texture_idx_ );
1208 glTexImage2D( GL_TEXTURE_2D,
1209 0, GL_RGBA, knot_selection_texture_image_.width(), knot_selection_texture_image_.height(),
1210 0, GL_RGBA, GL_UNSIGNED_BYTE, knot_selection_texture_image_.bits() );
1211 }
1212
1213 //----------------------------------------------------------------------------
1214
1215 template <class BSplineSurfaceType>
1216 void
1217 BSplineSurfaceNodeT<BSplineSurfaceType>::
1218 pick_init_texturing( )
1219 {
1220 std::cout << "[BSplineSurface] pick_init_texturing()" << std::endl;
1221
1222 pick_texture_res_ = 256;
1223 pick_texture_baseidx_ = 0;
1224
1225 // generate texture index
1226 glGenTextures( 1, &pick_texture_idx_ );
1227 // bind texture as current
1228 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_ );
1229 // do not blend colors (else color picking breaks!)
1230 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1231 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1232 // avoid aliasing at patch boundaries
1233 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
1234 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
1235 // GL_REPLACE to avoid smearing colors (else color picking breaks!)
1236 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1237 // unbind current texture
1238 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
1239 }
1240
1241 //----------------------------------------------------------------------------
1242
1243 template <class BSplineSurfaceType>
1244 void
1245 BSplineSurfaceNodeT<BSplineSurfaceType>::
1246 pick_create_texture( GLState& _state)
1247 {
1248 std::cout << "[BSplineSurface] pick_create_texture()" << std::endl;
1249
1250 QImage b(pick_texture_res_, pick_texture_res_, QImage::Format_ARGB32);
1251 QImage texture(pick_texture_res_, pick_texture_res_, QImage::Format_ARGB32);
1252
1253 // fill with colors
1254 int cur_idx=0;
1255 for( int i = 0; i < pick_texture_res_; ++i)
1256 {
1257 for( int j = pick_texture_res_ - 1; j >= 0; j--)
1258 {
1259 Vec4uc cur_col( _state.pick_get_name_color (cur_idx) );
1260 b.setPixel ( i,j, qRgba((int)cur_col[0], (int)cur_col[1], (int)cur_col[2], (int)cur_col[3]));
1261
1262 Vec4f testcol = Vec4f((float)cur_col[0], (float)cur_col[1], (float)cur_col[2], (float)cur_col[3]);
1263 texture.setPixel ( i,j, qRgba((int)(testcol[0]*255.0), (int)(testcol[1]*255.0), (int)(testcol[2]*255.0), 255));
1264 cur_idx++;
1265 }
1266 }
1267
1268 /*
1269 // creates checkerboard texture for debugging purposes
1270
1271 bool odd_row = true;
1272 bool odd_col = true;
1273 bool green = true;
1274 for( int i = 0; i < pick_texture_res_; ++i)
1275 {
1276 if (i % 20 == 0)
1277 odd_row = !odd_row;
1278
1279 odd_col = true;
1280 for( int j = 0; j < pick_texture_res_; ++j)
1281 {
1282 if (j % 20 == 0)
1283 odd_col = !odd_col;
1284
1285 green = (odd_row && odd_col) || (!odd_row && !odd_col);
1286
1287 if (green)
1288 b.setPixel (i, j, qRgba(0, 255, 0, 255));
1289 else
1290 b.setPixel (i, j, qRgba(255, 0, 255, 255));
1291 }
1292 }
1293 */
1294
1295 // debug, output image
1296 // b.save("surfacePickingTexture.png", "PNG");
1297 texture.save("surfacePickingTexture.png", "PNG");
1298
1299 pick_texture_image_ = QGLWidget::convertToGLFormat( b );
1300
1301 // bind texture
1302 ACG::GLState::bindTexture( GL_TEXTURE_2D, pick_texture_idx_ );
1303 glTexImage2D( GL_TEXTURE_2D,
1304 0, GL_RGBA, pick_texture_image_.width(), pick_texture_image_.height(),
1305 0, GL_RGBA, GL_UNSIGNED_BYTE, pick_texture_image_.bits() );
1306 }
1307
1308 //----------------------------------------------------------------------------
1309
1310 template <class BSplineSurfaceType>
1311 void
1312 BSplineSurfaceNodeT<BSplineSurfaceType>::
1313 set_arb_texture( const QImage& _texture, bool _repeat, float _u_repeat, float _v_repeat )
1314 {
1315 if(arb_texture_idx_ == 0)
1316 selection_init_texturing(arb_texture_idx_);
1317
1318 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
1319
1320 arb_texture_repeat_ = _repeat;
1321 arb_texture_repeat_u_ = _u_repeat;
1322 arb_texture_repeat_v_ = _v_repeat;
1323
1324 arb_texture_image_ = QGLWidget::convertToGLFormat( _texture );
1325 int u_res = arb_texture_image_.width();
1326 int v_res = arb_texture_image_.height();
1327
1328 // bind texture as current
1329 ACG::GLState::bindTexture( GL_TEXTURE_2D, arb_texture_idx_ );
1330
1331 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1332 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1333
1334 glTexImage2D( GL_TEXTURE_2D,
1335 0, GL_RGBA, u_res, v_res,
1336 0, GL_RGBA, GL_UNSIGNED_BYTE, arb_texture_image_.bits() );
1337
1338 // unbind current texture
1339 ACG::GLState::bindTexture( GL_TEXTURE_2D, 0);
1340 }
1341
1342 //----------------------------------------------------------------------------
1343
1344 template <class BSplineSurfaceType>
1345 ACG::Vec4f
1346 BSplineSurfaceNodeT<BSplineSurfaceType>::
1347 generateHighlightColor(ACG::Vec4f _color)
1348 {
1349 float c1 = _color[0]*1.5;
1350 c1 = c1 > 255.0 ? 255 : c1;
1351
1352 float c2 = _color[1]*1.5;
1353 c2 = c2 > 255.0 ? 255 : c2;
1354
1355 float c3 = _color[2]*1.5;
1356 c3 = c3 > 255.0 ? 255 : c3;
1357
1358 return Vec4f( c1, c2, c3, _color[3]);
1359 }
1360
1361 //----------------------------------------------------------------------------
1362
1363 template <class BSplineSurfaceType>
1364 void
1365 BSplineSurfaceNodeT<BSplineSurfaceType>::
1366 updateSurfaceMesh(int _vertexCountU, int _vertexCountV)
1367 {
1368 if (!invalidateSurfaceMesh_)
1369 return;
1370
1371 surfaceVBO_.del();
1372 surfaceIBO_.del();
1373
1374 // vertex layout:
1375 // float3 pos
1376 // float3 normal
1377 // float2 texcoord
1378 // + debug info (optional)
1379
1380 // provide expected values of bspline evaluation steps for debugging in shader
1381 const bool provideDebugInfo = false;
1382
1383 if (!surfaceDecl_.getNumElements())
1384 {
1385 surfaceDecl_.addElement(GL_FLOAT, 3, VERTEX_USAGE_POSITION);
1386 surfaceDecl_.addElement(GL_FLOAT, 3, VERTEX_USAGE_NORMAL);
1387 surfaceDecl_.addElement(GL_FLOAT, 2, VERTEX_USAGE_TEXCOORD);
1388
1389 if (provideDebugInfo)
1390 {
1391 surfaceDecl_.addElement(GL_FLOAT, 2, VERTEX_USAGE_SHADER_INPUT, size_t(0), "a2v_span");
1392 surfaceDecl_.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, size_t(0), "a2v_bvu");
1393 surfaceDecl_.addElement(GL_FLOAT, 4, VERTEX_USAGE_SHADER_INPUT, size_t(0), "a2v_bvv");
1394 }
1395 }
1396
1397 // create vertex buffer
1398
1399 int numU = _vertexCountU,
1400 numV = _vertexCountV;
1401
1402 GLsizeiptr vboSize = numU * numV * surfaceDecl_.getVertexStride(); // bytes
1403 std::vector<float> vboData(vboSize / 4); // float: 4 bytes
1404
1405 // write counter
1406 int elementOffset = 0;
1407
1408 for (int i = 0; i < numU; ++i)
1409 {
1410 // param in [0, 1]
1411 float u01 = float(i) / float(numU - 1);
1412
1413 // map to actual range
1414 float u = (1 - u01) * bsplineSurface_.loweru() + u01 * bsplineSurface_.upperu();
1415
1416 for (int k = 0; k < numV; ++k)
1417 {
1418 // param in [0, 1]
1419 float v01 = float(k) / float(numV - 1);
1420
1421 // map to actual range
1422 float v = (1 - v01) * bsplineSurface_.lowerv() + v01 * bsplineSurface_.upperv();
1423
1424 // evaluate
1425 Point pos, normal;
1426 bsplineSurface_.surfacePointNormal(pos, normal, u, v);
1427
1428 // store pos
1429 for (int m = 0; m < 3; ++m)
1430 vboData[elementOffset++] = float(pos[m]);
1431
1432 // store normal
1433 for (int m = 0; m < 3; ++m)
1434 vboData[elementOffset++] = float(normal[m]);
1435
1436 // store texcoord
1437 vboData[elementOffset++] = u01;
1438 vboData[elementOffset++] = v01;
1439
1440
1441 if (provideDebugInfo)
1442 {
1443 // debug elements
1444 Vec2i span_u = bsplineSurface_.spanm(u);
1445 Vec2i span_v = bsplineSurface_.spann(u);
1446 vboData[elementOffset++] = span_u[1];
1447 vboData[elementOffset++] = span_v[1];
1448
1449 std::vector<typename Point::value_type> bvu(std::max(4, bsplineSurface_.degree_m() + 1), 0);
1450 std::vector<typename Point::value_type> bvv(std::max(4, bsplineSurface_.degree_n() + 1), 0);
1451 bsplineBasisFunctions<typename Point::value_type>(bvu, span_u, u, bsplineSurface_.get_knotvector_m().getKnotvector());
1452 bsplineBasisFunctions<typename Point::value_type>(bvv, span_v, v, bsplineSurface_.get_knotvector_n().getKnotvector());
1453
1454 for (int m = 0; m < 4; ++m) vboData[elementOffset++] = bvu[m];
1455 for (int m = 0; m < 4; ++m) vboData[elementOffset++] = bvv[m];
1456 }
1457 }
1458 }
1459
1460 if (vboSize)
1461 surfaceVBO_.upload(vboSize, &vboData[0], GL_STATIC_DRAW);
1462
1463 vboData.clear();
1464
1465
1466
1467 // create index buffer
1468 int numIndices = (numU - 1) * (numV - 1) * 6;
1469 std::vector<int> iboData(numIndices);
1470
1471 // index counter
1472 int idxOffset = 0;
1473
1474 for (int k = 0; k < numV - 1; ++k)
1475 {
1476 for (int i = 0; i < numU - 1; ++i)
1477 {
1478 /*
1479 ccw quad tessellation:
1480 c---d
1481 | / |
1482 |/ |
1483 a---b
1484 */
1485
1486 iboData[idxOffset++] = k * numU + i;
1487 iboData[idxOffset++] = (k+1) * numU + i;
1488 iboData[idxOffset++] = (k+1) * numU + i + 1;
1489
1490 iboData[idxOffset++] = k * numU + i;
1491 iboData[idxOffset++] = (k+1) * numU + i+1;
1492 iboData[idxOffset++] = k * numU + i + 1;
1493 }
1494 }
1495
1496 if (numIndices)
1497 surfaceIBO_.upload(numIndices * 4, &iboData[0], GL_STATIC_DRAW);
1498
1499
1500 surfaceIndexCount_ = numIndices;
1501
1502
1503 invalidateSurfaceMesh_ = false;
1504 }
1505
1506 //----------------------------------------------------------------------------
1507
1508 template <class BSplineSurfaceType>
1509 void
1510 BSplineSurfaceNodeT<BSplineSurfaceType>::
1511 updateControlNetMesh()
1512 {
1513 if (!invalidateControlNetMesh_)
1514 return;
1515
1516 // vertex layout:
1517 // float3 pos
1518
1519 if (!controlNetDecl_.getNumElements())
1520 controlNetDecl_.addElement(GL_FLOAT, 3, VERTEX_USAGE_POSITION);
1521
1522 int numU = bsplineSurface_.n_control_points_m(),
1523 numV = bsplineSurface_.n_control_points_n();
1524
1525 // create vertex buffer
1526 GLsizeiptr vboSize = bsplineSurface_.n_control_points_m() * bsplineSurface_.n_control_points_n() * controlNetDecl_.getVertexStride(); // bytes
1527 std::vector<float> vboData(vboSize / 4); // float: 4 bytes
1528
1529 // write counter
1530 int elementOffset = 0;
1531
1532 for (int k = 0; k < numV; ++k)
1533 {
1534 for (int i = 0; i < numU; ++i)
1535 {
1536 Point pt = bsplineSurface_.get_control_point(i, k);
1537 for (int m = 0; m < 3; ++m)
1538 vboData[elementOffset++] = pt[m];
1539 }
1540 }
1541
1542 if (vboSize)
1543 controlNetVBO_.upload(vboSize, &vboData[0], GL_STATIC_DRAW);
1544
1545 vboData.clear();
1546
1547
1548
1549 // create index buffer for line segments
1550 // horizontal + vertical cross lines, 2 indices per segment
1551 int numIndices = 2 *( (numU - 1) * (numV) + (numU) * (numV - 1) );
1552 std::vector<int> iboData(numIndices);
1553
1554 // index counter
1555 int idxOffset = 0;
1556
1557 // horizontal lines
1558 for (int k = 0; k < numV; ++k)
1559 {
1560 for (int i = 0; i < numU - 1; ++i)
1561 {
1562 iboData[idxOffset++] = k * numU + i;
1563 iboData[idxOffset++] = k * numU + i + 1;
1564 }
1565 }
1566
1567 // vertical lines
1568 for (int k = 0; k < numV - 1; ++k)
1569 {
1570 for (int i = 0; i < numU; ++i)
1571 {
1572 iboData[idxOffset++] = k * numU + i;
1573 iboData[idxOffset++] = (k+1) * numU + i;
1574 }
1575 }
1576
1577 if (numIndices)
1578 controlNetLineIBO_.upload(numIndices * 4, &iboData[0], GL_STATIC_DRAW);
1579
1580
1581 controlNetLineIndices_ = numIndices;
1582
1583
1584 invalidateControlNetMesh_ = false;
1585 }
1586
1587 //----------------------------------------------------------------------------
1588
1589
1590 template <class BSplineSurfaceType>
1591 void
1592 BSplineSurfaceNodeT<BSplineSurfaceType>::
1593 updateControlNetMeshSel()
1594 {
1595 if (!invalidateControlNetMeshSel_)
1596 return;
1597
1598 controlNetSelIBO_.del();
1599
1600 if (bsplineSurface_.controlpoint_selections_available())
1601 {
1602 int numU = bsplineSurface_.n_control_points_m(),
1603 numV = bsplineSurface_.n_control_points_n();
1604
1605 // count # selected points
1606 int numSel = 0;
1607 for (int k = 0; k < numV; ++k)
1608 {
1609 for (int i = 0; i < numU; ++i)
1610 {
1611 if (bsplineSurface_.controlpoint_selection(i, k))
1612 ++numSel;
1613 }
1614 }
1615
1616 // save count for draw call
1617 controlNetSelIndices_ = numSel;
1618
1619
1620 if (numSel)
1621 {
1622 // create array
1623 std::vector<int> iboData(numSel);
1624 numSel = 0;
1625 for (int k = 0; k < numV; ++k)
1626 {
1627 for (int i = 0; i < numU; ++i)
1628 {
1629 if (bsplineSurface_.controlpoint_selection(i, k))
1630 {
1631 // see vertex indexing of vbo in updateControlNetMesh()
1632 // they are in "row-mayor" order
1633 iboData[numSel++] = k * numU + i;
1634 }
1635 }
1636 }
1637
1638 controlNetSelIBO_.upload(numSel * 4, &iboData[0], GL_STATIC_DRAW);
1639 }
1640 }
1641
1642 invalidateControlNetMeshSel_ = false;
1643 }
1644
1645 //----------------------------------------------------------------------------
1646
1647 template <class BSplineSurfaceType>
1648 void
1649 BSplineSurfaceNodeT<BSplineSurfaceType>::
1650 updateTexBuffers()
1651 {
1652 const size_t knotBufSizeU = bsplineSurface_.get_knots_m().size();
1653 const size_t knotBufSizeV = bsplineSurface_.get_knots_n().size();
1654
1655
1656
1657
1658 if (knotBufSizeU)
1659 {
1660 std::vector<float> knotBufU(knotBufSizeU);
1661
1662 for (size_t i = 0; i < knotBufSizeU; ++i)
1663 knotBufU[i] = float(bsplineSurface_.get_knot_m(i));
1664
1665 knotTexBufferU_.setBufferData(knotBufSizeU * 4, &knotBufU[0], GL_R32F);
1666 }
1667
1668 if (knotBufSizeV)
1669 {
1670 std::vector<float> knotBufV(knotBufSizeV);
1671
1672 for (size_t i = 0; i < knotBufSizeV; ++i)
1673 knotBufV[i] = float(bsplineSurface_.get_knot_n(i));
1674
1675 knotTexBufferV_.setBufferData(knotBufSizeV * 4, &knotBufV[0], GL_R32F);
1676 }
1677
1678
1679 #ifdef GL_VERSION_3_0
1680
1681 const size_t numControlPointsU = bsplineSurface_.n_control_points_m();
1682 const size_t numControlPointsV = bsplineSurface_.n_control_points_n();
1683 const size_t controlPointBufSize = numControlPointsU * numControlPointsV;
1684
1685 if (controlPointBufSize)
1686 {
1687 std::vector<float> controlPointBuf(controlPointBufSize * 3);
1688
1689 for (size_t y = 0; y < numControlPointsV; ++y)
1690 {
1691 for (size_t x = 0; x < numControlPointsU; ++x)
1692 {
1693 Point cp = bsplineSurface_.get_control_point(x, y);
1694 controlPointBuf[(y * numControlPointsU + x) * 3 + 0] = cp[0];
1695 controlPointBuf[(y * numControlPointsU + x) * 3 + 1] = cp[1];
1696 controlPointBuf[(y * numControlPointsU + x) * 3 + 2] = cp[2];
1697 }
1698 }
1699
1700 controlPointTex_.bind();
1701 controlPointTex_.parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); // disable filtering
1702 controlPointTex_.parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1703 controlPointTex_.setData(0, GL_RGB32F, numControlPointsU, numControlPointsV, GL_RGB, GL_FLOAT, &controlPointBuf[0]);
1704 }
1705 #endif
1706 }
1707
1708
1709 //=============================================================================
1710 } // namespace SceneGraph
1711 } // namespace ACG
1712 //=============================================================================
ACG::glColor
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:144
ACG::RenderObject::initFromState
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
Definition: RenderObject.cc:61
ACG::SceneGraph::BSplineSurfaceNodeT::pick_init_texturing
void pick_init_texturing()
generate index and setup texture parameters
Definition: BSplineSurfaceNodeT_impl.hh:1218
ACG::GLState::viewing_direction
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:848
ACG::GLState::pop_modelview_matrix
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
ACG::RenderObject::setUniform
void setUniform(const char *_name, GLint _value)
set values for int uniforms
Definition: RenderObject.cc:413
ACG::VERTEX_USAGE_SHADER_INPUT
defined by user via VertexElement::shaderInputName_
Definition: VertexDeclaration.hh:71
ACG::GLState
Definition: GLState.hh:213
ACG::GLState::point_size
float point_size() const
get point size
Definition: GLState.hh:970
ACG::RenderObject::Texture
Texture to be used.
Definition: RenderObject.hh:313
ACG::SceneGraph::PICK_FACE
picks faces (should be implemented for all nodes)
Definition: PickTarget.hh:78
ACG::SceneGraph::BSplineSurfaceNodeT::availableDrawModes
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
Definition: BSplineSurfaceNodeT_impl.hh:93
ACG::SceneGraph::DrawModes::SOLID_ENV_MAPPED
DrawMode SOLID_ENV_MAPPED
draw environment mapped
Definition: DrawModes.cc:87
ACG::GLState::viewport_width
int viewport_width() const
get viewport width
Definition: GLState.hh:822
ACG::RenderObject::addTexture
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
Definition: RenderObject.hh:326
ACG::Vec2f
VectorT< float, 2 > Vec2f
Definition: VectorT.hh:102
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::SceneGraph::BSplineSurfaceNodeT::updateTexBuffers
void updateTexBuffers()
update texture resources for gpu-based spline evaluation
Definition: BSplineSurfaceNodeT_impl.hh:1650
pybind11
Definition: PythonTypeConversions.hh:49
ACG::GLState::project
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
ACG::SceneGraph::BSplineSurfaceNodeT::boundingBox
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
Definition: BSplineSurfaceNodeT_impl.hh:76
ACG::Vec4f
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
ACG::SceneGraph::BSplineSurfaceNodeT::updateControlNetMesh
void updateControlNetMesh()
update vertex + index buffer of control net mesh
Definition: BSplineSurfaceNodeT_impl.hh:1511
ACG::SceneGraph::ACG::GLState::disable
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
ACG::GLState::base_color
const Vec4f & base_color() const
get base color (used when lighting is off)
Definition: GLState.hh:926
ACG::RenderObject::shaderDesc
ShaderGenDesc shaderDesc
Drawmode and other shader params.
Definition: RenderObject.hh:225
ACG::GLState::pick_current_index
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::SceneGraph::BSplineSurfaceNodeT::create_knot_selection_texture
void create_knot_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of knotvector selection ...
Definition: BSplineSurfaceNodeT_impl.hh:1081
ACG::SceneGraph::BSplineSurfaceNodeT::pick
void pick(GLState &_state, PickTarget _target) override
picking
Definition: BSplineSurfaceNodeT_impl.hh:735
ACG::SceneGraph::DrawModes::HIDDENLINE
DrawMode HIDDENLINE
draw hidden line (2 rendering passes needed)
Definition: DrawModes.cc:80
ACG::SceneGraph::BSplineSurfaceNodeT::updateGeometry
void updateGeometry()
update vertex buffer for rendering
Definition: BSplineSurfaceNodeT_impl.hh:724
OpenMesh::VectorT::maximize
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:568
ACG::RenderObject::name
std::string name
Name for logging.
Definition: RenderObject.hh:121
ACG::RenderObject::vertexBuffer
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
Definition: RenderObject.hh:162
ACG::GLState::depthFunc
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
ACG::GLState::pick_get_name_color
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
ACG::SceneGraph::DrawModes::SOLID_SMOOTH_SHADED
DrawMode SOLID_SMOOTH_SHADED
draw smooth shaded (Gouraud shaded) faces (requires halfedge normals)
Definition: DrawModes.cc:82
ACG::IRenderer
Definition: IRenderer.hh:78
ACG::RenderObject::setupLineRendering
void setupLineRendering(float _lineWidth, const Vec2f &_screenSize)
Setup rendering of thick lines.
Definition: RenderObject.cc:464
SceneGraph
Definition: QtPrincipalAxisDialog.hh:67
ACG::VERTEX_USAGE_NORMAL
"inNormal"
Definition: VertexDeclaration.hh:66
ACG::RenderObject::resetPointRendering
void resetPointRendering()
Reset shader template names blocked by point rendering.
Definition: RenderObject.cc:499
ACG::VERTEX_USAGE_TEXCOORD
"inTexCoord"
Definition: VertexDeclaration.hh:67
ACG::SceneGraph::PickTarget
PickTarget
What target to use for picking.
Definition: PickTarget.hh:73
ACG::GLState::push_modelview_matrix
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
ACG::SceneGraph::DrawModes::SOLID_PHONG_SHADED
DrawMode SOLID_PHONG_SHADED
draw phong shaded faces
Definition: DrawModes.cc:83
ACG::SceneGraph::DrawModes::DrawModeProperties::textured
bool textured() const
Is texturing enabled?
Definition: DrawModes.hh:219
ACG::SceneGraph::DrawModes::SOLID_1DTEXTURED
DrawMode SOLID_1DTEXTURED
draw textured faces
Definition: DrawModes.cc:90
ACG::Vec3f
VectorT< float, 3 > Vec3f
Definition: VectorT.hh:119
ACG::VERTEX_USAGE_POSITION
"inPosition"
Definition: VertexDeclaration.hh:65
ACG::RenderObject::setupPointRendering
void setupPointRendering(float _pointSize, const Vec2f &_screenSize)
Setup rendering of circle points.
Definition: RenderObject.cc:484
ACG::RenderObject::patchVertices
unsigned int patchVertices
patch size if primitiveMode is GL_PATCHES for rendering with tessellation shaders ...
Definition: RenderObject.hh:185
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
ACG::GLState::pick_set_maximum
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
ACG::SceneGraph::DrawModes::SOLID_TEXTURED
DrawMode SOLID_TEXTURED
draw textured faces
Definition: DrawModes.cc:88
ACG::SceneGraph::PICK_VERTEX
picks verices (may not be implemented for all nodes)
Definition: PickTarget.hh:82
ACG::RenderObject::indexBuffer
GLuint indexBuffer
Use vertex array object.
Definition: RenderObject.hh:162
ACG::GLState::viewport_height
int viewport_height() const
get viewport height
Definition: GLState.hh:824
OpenMesh::VectorT::minimize
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:540
ACG::openGLVersion
bool openGLVersion(const int _major, const int _minor, bool _verbose)
Definition: gl.cc:129
ACG::SceneGraph::BSplineSurfaceNodeT::pick_create_texture
void pick_create_texture(GLState &_state)
create texture image
Definition: BSplineSurfaceNodeT_impl.hh:1246
ACG::RenderObject::vertexDecl
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Definition: RenderObject.hh:208
ACG::GLSphere
Definition: GLPrimitives.hh:139
ACG::SceneGraph::DrawModes::POINTS
DrawMode POINTS
draw unlighted points using the default base color
Definition: DrawModes.cc:73
ACG::SceneGraph::DrawModes::SOLID_SHADER
DrawMode SOLID_SHADER
Definition: DrawModes.cc:98
ACG::SceneGraph::DrawModes::DrawModeProperties
DrawModeProperties stores a set of properties that defines, how to render an object.
Definition: DrawModes.hh:177
ACG::GLState::rotate
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
ACG::IRenderer::addRenderObject
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
Definition: IRenderer.cc:104
ACG::SceneGraph::DrawModes::SOLID_FLAT_SHADED
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Definition: DrawModes.cc:81
ACG::SceneGraph::BSplineSurfaceNodeT::selection_init_texturing
void selection_init_texturing(GLuint &_texture_idx)
generate index and setup texture parameters for selection visualization
Definition: BSplineSurfaceNodeT_impl.hh:954
ACG::SceneGraph::DrawModes::DrawMode
Specifies a DrawMode.
Definition: DrawModes.hh:288
ACG::SceneGraph::BSplineSurfaceNodeT::draw
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw lines and normals
Definition: BSplineSurfaceNodeT_impl.hh:283
ACG::SceneGraph::DrawModes::WIREFRAME
DrawMode WIREFRAME
draw wireframe
Definition: DrawModes.cc:78
ACG::SceneGraph::BSplineSurfaceNodeT::create_cp_selection_texture
void create_cp_selection_texture(GLState &_state)
creates texture to put onto nurbs curve for visualization of control point selection ...
Definition: BSplineSurfaceNodeT_impl.hh:977
ACG::SceneGraph::BSplineSurfaceNodeT::getRenderObjects
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const Material *_mat) override
create render objects
Definition: BSplineSurfaceNodeT_impl.hh:116
ACG::GLState::pick_set_name
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1061
ACG::GLState::set_base_color
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Definition: GLState.cc:677
ACG::SceneGraph::ACG::GLState::enable
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
ACG::SceneGraph::BSplineSurfaceNodeT::set_arb_texture
void set_arb_texture(const QImage &_texture, bool _repeat=false, float _u_repeat=1.0f, float _v_repeat=1.0f)
use arbitrary texture (in SOLID_TEXTURED mode)
Definition: BSplineSurfaceNodeT_impl.hh:1313
ACG::SceneGraph::PICK_SPLINE
Pick spline curve or surface (picks u or u,v coords respectively)
Definition: PickTarget.hh:92
ACG::RenderObject::setupShaderGenFromDrawmode
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
Definition: RenderObject.cc:137
ACG::SceneGraph::BSplineSurfaceNodeT::updateControlNetMeshSel
void updateControlNetMeshSel()
update index buffer of selected control points
Definition: BSplineSurfaceNodeT_impl.hh:1593
ACG::SceneGraph::ACG::GLState::depthRange
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
ACG::GLState::line_width
float line_width() const
get line width
Definition: GLState.hh:975
ACG::SceneGraph::DrawModes::DrawMode::getLayer
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
Definition: DrawModes.cc:535
ACG::KnotvectorT< double >
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:434
ACG::RenderObject
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
ACG::SceneGraph::ACG::GLState::bindTexture
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
ACG::SceneGraph::DrawModes::DrawMode::getNumLayers
size_t getNumLayers() const
returns the layer count
Definition: DrawModes.cc:531
ACG::GLState::clear_color
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:921
ACG::SceneGraph::ACG::GLState::shadeModel
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
ACG::SceneGraph::Material
Definition: MaterialNode.hh:79
ACG::GLState::eye
Vec3d eye() const
get eye point
Definition: GLState.cc:886
ACG::GLState::translate
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
ACG::SceneGraph::BSplineSurfaceNodeT
Definition: BSplineSurfaceNodeT.hh:88
ACG::SceneGraph::ACG::GLState::depthFunc
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
ACG::SceneGraph::BSplineSurfaceNodeT::updateSurfaceMesh
void updateSurfaceMesh(int _vertexCountU=50, int _vertexCountV=50)
update vertex + index buffer of surface mesh
Definition: BSplineSurfaceNodeT_impl.hh:1366