Developer Documentation
GLState.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 // CLASS GLState - IMPLEMENTATION
46 //
47 //=============================================================================
48 
49 //== INCLUDES =================================================================
50 
51 #include <ACG/GL/acg_glew.hh>
52 #include "GLState.hh"
53 #include <ACG/GL/removedEnums.hh>
54 
55 #include <OpenMesh/Core/Utils/vector_cast.hh>
56 #include <cstring>
57 
58 
59 //== NAMESPACES ===============================================================
60 
61 
62 namespace ACG {
63 
64 
65 //== IMPLEMENTATION ==========================================================
66 
67 //#define GLSTATE_AVOID_REDUNDANT_GLCALLS
68 
69 const Vec4f GLState::default_clear_color(0.f, 0.f, 0.f, 1.f);
70 const Vec4f GLState::default_base_color(0.f, 0.f, 0.f, 1.f);
71 const Vec4f GLState::default_ambient_color(0.2f, 0.2f, 0.2f, 1.f);
72 const Vec4f GLState::default_diffuse_color(0.5f, 0.53f, 0.6f, 1.f);
73 const Vec4f GLState::default_specular_color(0.75f, 0.8f, 0.85f, 1.f);
74 const Vec4f GLState::default_overlay_color(0.f, 0.f, 0.f, 1.f);
75 const float GLState::default_shininess(100.f);
76 
77 
78 //-----------------------------------------------------------------------------
79 
80 bool GLState::depthFuncLock_ = false;
81 bool GLState::depthRangeLock_ = false;
82 bool GLState::blendFuncSeparateLock_[] = { false };
83 bool GLState::blendEquationLock_ = false;
84 bool GLState::blendColorLock_ = false;
85 bool GLState::alphaFuncLock_ = false;
86 bool GLState::shadeModelLock_ = false;
87 bool GLState::cullFaceLock_ = false;
88 bool GLState::vertexPointerLock_ = false;
89 bool GLState::normalPointerLock_ = false;
90 bool GLState::texcoordPointerLock_ = false;
91 bool GLState::colorPointerLock_ = false;
92 bool GLState::drawBufferLock_ = false;
93 bool GLState::programLock_ = false;
94 
95 std::deque <GLStateContext> GLState::stateStack_;
96 std::bitset<0xFFFF+1> GLState::glStateLock_;
97 int GLState::glBufferTargetLock_[] = {0};
98 int GLState::glTextureStageLock_[] = {0};
99 bool GLState::framebufferLock_[] = {false};
100 int GLState::maxTextureCoords_ = 0;
101 int GLState::maxCombinedTextureImageUnits_ = 0;
102 int GLState::maxDrawBuffers_ = 0;
103 
104 int GLState::num_texture_units_ = 0;
105 
106 GLStateContext::GLStateContext() :
107  activeTexture_(GL_TEXTURE0),
108  drawBufferSingle_(GL_BACK),
109  activeDrawBuffer_(0),
110  program_(0)
111 {
112  framebuffers_[0] = framebuffers_[1] = 0;
113  memset(drawBufferState_, GL_BACK, sizeof(drawBufferState_));
114  blendFuncState_[0] = GL_SRC_ALPHA;
115  blendFuncState_[1] = GL_ONE_MINUS_SRC_ALPHA;
116  blendFuncState_[2] = GL_SRC_ALPHA;
117  blendFuncState_[3] = GL_ONE_MINUS_SRC_ALPHA;
118  texGenMode_ = GL_EYE_LINEAR;
119 }
120 
121 GLState::GLState(bool _updateGL, bool _compatibilityProfile)
122  : compatibilityProfile_(_compatibilityProfile),
123  render_pass_(1),
124  max_render_passes_(1),
125  bb_min_(ACG::Vec3d(0.0,0.0,0.0)),
126  bb_max_(ACG::Vec3d(0.0,0.0,0.0)),
127  left_(-1),
128  bottom_(1),
129  width_(2),
130  height_(2),
131  glwidth_(2),
132  glheight_(2),
133  near_plane_(1.0),
134  far_plane_(100.0),
135  multisampling_(false),
136  allow_multisampling_(true),
137  mipmapping_(true),
138  updateGL_(_updateGL),
139  blending_(false),
140  msSinceLastRedraw_ (1),
141  colorPicking_(true)
142 {
143 
144  if ( stateStack_.empty() )
145  {
146  stateStack_.push_back(GLStateContext());
147 
148  memset(glBufferTargetLock_, 0, sizeof(glBufferTargetLock_));
149 
150  framebufferLock_[0] = framebufferLock_[1] = false;
151 
152  glStateLock_.reset();
153  }
154 
155  initialize();
156  ACG::compatibilityProfile(compatibilityProfile_);
157 }
158 
159 //-----------------------------------------------------------------------------
160 
161 
163 {
164  // clear matrix stacks
165  while (!stack_projection_.empty())
166  stack_projection_.pop();
167  while (!stack_modelview_.empty())
168  stack_modelview_.pop();
169  while (!stack_inverse_projection_.empty())
170  stack_inverse_projection_.pop();
171  while (!stack_inverse_modelview_.empty())
172  stack_inverse_modelview_.pop();
173 
174 
175  // load identity matrix
177  reset_modelview();
178 
179 
180  // colors
188 
189 
190  // thickness
191  set_point_size(1.0f);
192  set_line_width(1.0f);
193 
194  // multisampling
195  set_multisampling(true);
196 
197  // Get max number of texture units
198  GLint value;
199  glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &value);
200 
201  num_texture_units_ = value;
202 
203  // lighting
204  set_twosided_lighting(true);
205 }
206 
207 //-----------------------------------------------------------------------------
208 
210 {
211  makeCurrent();
212 
213  if (compatibilityProfile_ ) {
214 
215  // projection matrix
216  glMatrixMode(GL_PROJECTION);
217  glLoadMatrixd(projection_.get_raw_data());
218  glMatrixMode(GL_MODELVIEW);
219 
220  // modelview matrix
221  glLoadMatrixd(modelview_.get_raw_data());
222 
223  }
224 
225  // clear color
226  glClearColor(clear_color_[0], clear_color_[1], clear_color_[2], clear_color_[3]);
227 
228  if (compatibilityProfile_ ) {
229  // base color
230  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, base_color_.data());
231 
232  // ambient color
233  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT , ambient_color_.data());
234 
235  // diffuse color
236  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE , diffuse_color_.data());
237 
238  // specular color
239  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_color_.data());
240 
241  // shininess
242  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess_);
243  }
244 
245  // point size
246  glPointSize(point_size_);
247 
248  // line width
249  glLineWidth(line_width_);
250 
251  if ( compatibilityProfile_ ) {
252  // two sided lighting
253  if (twosided_lighting_ )
254  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
255  else
256  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
257  }
258 
259  // viewport
260  glViewport(left_, bottom_, width_, height_);
261 }
262 
263 
264 //-----------------------------------------------------------------------------
265 
267 {
268 
269  if ( compatibilityProfile_ ) {
270  glPushAttrib (GL_ALL_ATTRIB_BITS);
271  }
272 
273  GLState::disable(GL_DEPTH_TEST);
274  GLState::disable(GL_DITHER);
275 
276  if ( compatibilityProfile_ ) {
277  glShadeModel(GL_FLAT);
278 
279  GLState::disable(GL_LIGHTING);
280  glMatrixMode(GL_PROJECTION);
281  glPushMatrix();
282  glLoadIdentity ();
283 
284  glMatrixMode(GL_MODELVIEW);
285  glPushMatrix();
286  glLoadIdentity ();
287  }
288 
289 
290  // GetoriginalScissor settings
291  GLboolean scissor = glIsEnabled(GL_SCISSOR_TEST);
292 
293  GLint origBox[4];
294  glGetIntegerv(GL_SCISSOR_BOX,&origBox[0]);
295 
296  //Enable scissor
297  if (!scissor)
298  GLState::enable(GL_SCISSOR_TEST);
299 
300  // Restrict to our current viewport
301  glScissor( left_,bottom_,width_,height_ );
302 
303  // Clear restricted region
304  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
305 
306  // Reset to originalsettings
307  glScissor( origBox[0], origBox[1], origBox[2], origBox[3] );
308 
309  if (!scissor)
310  GLState::disable(GL_SCISSOR_TEST);
311 
312  if ( compatibilityProfile_ ) {
313  glPopMatrix ();
314  glMatrixMode(GL_PROJECTION);
315  glPopMatrix();
316  glMatrixMode(GL_MODELVIEW);
317  glPopAttrib ();
318  }
319 }
320 
321 //-----------------------------------------------------------------------------
322 
323 void GLState::setCompatibilityProfile( bool _compatibility ) {
324  compatibilityProfile_ = _compatibility;
325  ACG::compatibilityProfile(_compatibility);
326 }
327 
328 bool GLState::compatibilityProfile() const {
329  return compatibilityProfile_;
330 }
331 
332 //-----------------------------------------------------------------------------
333 
335 {
336  projection_.identity();
337  inverse_projection_.identity();
338 
339  if (updateGL_ && compatibilityProfile_ )
340  {
341  makeCurrent();
342  glMatrixMode(GL_PROJECTION);
343  glLoadIdentity();
344  glMatrixMode(GL_MODELVIEW);
345  }
346 }
347 
348 
349 //-----------------------------------------------------------------------------
350 
351 
352 void GLState::set_projection(const GLMatrixd& _m, const GLMatrixd& _inv_m)
353 {
354  projection_ = _m;
355  inverse_projection_ = _inv_m;
356 
357  if (updateGL_ && compatibilityProfile_)
358  {
359  makeCurrent();
360  glMatrixMode(GL_PROJECTION);
361  glLoadMatrixd(projection_.get_raw_data());
362  glMatrixMode(GL_MODELVIEW);
363  }
364 }
365 
366 
367 //-----------------------------------------------------------------------------
368 
369 
371 {
372  modelview_.identity();
373  inverse_modelview_.identity();
374 
375  if (updateGL_ && compatibilityProfile_ )
376  {
377  makeCurrent();
378  glLoadIdentity();
379  }
380 }
381 
382 
383 //-----------------------------------------------------------------------------
384 
385 
386 void GLState::set_modelview(const GLMatrixd& _m, const GLMatrixd& _inv_m)
387 {
388  modelview_ = _m;
389  inverse_modelview_ = _inv_m;
390 
391  if (updateGL_ && compatibilityProfile_)
392  {
393  makeCurrent();
394  glLoadMatrixd(modelview_.get_raw_data());
395  }
396 }
397 
398 
399 //-----------------------------------------------------------------------------
400 
401 
402 void GLState::ortho( double _left, double _right,
403  double _bottom, double _top,
404  double _n, double _f )
405 {
406  near_plane_ = _n;
407  far_plane_ = _f;
408 
409  projection_.ortho(_left, _right, _bottom, _top, _n, _f);
410  inverse_projection_.inverse_ortho(_left,_right,_bottom,_top,_n,_f);
411 
412  if (updateGL_ && compatibilityProfile_ )
413  {
414  makeCurrent();
415  glMatrixMode(GL_PROJECTION);
416  glOrtho(_left, _right, _bottom, _top, _n, _f);
417  glMatrixMode(GL_MODELVIEW);
418  }
419 }
420 
421 
422 //-----------------------------------------------------------------------------
423 
424 
425 void GLState::frustum( double _left, double _right,
426  double _bottom, double _top,
427  double _n, double _f )
428 {
429  near_plane_ = _n;
430  far_plane_ = _f;
431 
432  projection_.frustum(_left, _right, _bottom, _top, _n, _f);
433  inverse_projection_.inverse_frustum(_left,_right,_bottom,_top,_n,_f);
434 
435  if (updateGL_ && compatibilityProfile_)
436  {
437  makeCurrent();
438  glMatrixMode(GL_PROJECTION);
439  glFrustum(_left, _right, _bottom, _top, _n, _f);
440  glMatrixMode(GL_MODELVIEW);
441  }
442 }
443 
444 
445 //-----------------------------------------------------------------------------
446 
447 
448 void GLState::perspective( double _fovY, double _aspect,
449  double _n, double _f )
450 {
451  near_plane_ = _n;
452  far_plane_ = _f;
453 
454  projection_.perspective(_fovY, _aspect, _n, _f);
455  inverse_projection_.inverse_perspective(_fovY, _aspect, _n, _f);
456 
457  if (updateGL_ && compatibilityProfile_)
458  {
459  makeCurrent();
460  glMatrixMode(GL_PROJECTION);
461  glLoadMatrixd(projection_.data());
462  glMatrixMode(GL_MODELVIEW);
463  }
464 }
465 
466 
467 //-----------------------------------------------------------------------------
468 
469 
470 void GLState::viewport( int _left, int _bottom,
471  int _width, int _height,
472  int _glwidth, int _glheight)
473 {
474  left_ = _left;
475  bottom_ = _bottom;
476  width_ = _width;
477  height_ = _height;
478 
479  if (_glwidth < _width || _glheight < _height)
480  {
481  glwidth_ = _width;
482  glheight_ = _height;
483  } else {
484  glwidth_ = _glwidth;
485  glheight_ = _glheight;
486  }
487 
488  window2viewport_.identity();
489  window2viewport_(0,0) = 0.5f * width_;
490  window2viewport_(0,3) = 0.5f * width_ + left_;
491  window2viewport_(1,1) = 0.5f * height_;
492  window2viewport_(1,3) = 0.5f * height_ + bottom_;
493  window2viewport_(2,2) = 0.5f;
494  window2viewport_(2,3) = 0.5f;
495 
496  inverse_window2viewport_.identity();
497  inverse_window2viewport_(0,0) = 2.0f / width_;
498  inverse_window2viewport_(0,3) = -(2.0*left_ + width_) / width_;
499  inverse_window2viewport_(1,1) = 2.0f / height_;
500  inverse_window2viewport_(1,3) = -(2.0*bottom_ + height_) / height_;
501  inverse_window2viewport_(2,2) = 2.0f;
502  inverse_window2viewport_(2,3) = -1.0f;
503 
504  if (updateGL_)
505  {
506  makeCurrent();
507  glViewport(_left, _bottom, _width, _height);
508  }
509 }
510 
511 
512 //-----------------------------------------------------------------------------
513 
514 
515 void GLState::lookAt( const Vec3d& _eye,
516  const Vec3d& _center,
517  const Vec3d& _up )
518 {
519  modelview_.lookAt(_eye, _center, _up);
520  inverse_modelview_.inverse_lookAt(_eye, _center, _up);
521 
522  if (updateGL_ && compatibilityProfile_)
523  {
524  makeCurrent();
525  glLoadMatrixd(modelview_.data());
526  }
527 }
528 
529 
530 //-----------------------------------------------------------------------------
531 
532 
533 void GLState::translate( double _x, double _y, double _z,
534  MultiplyFrom _mult_from )
535 {
536  if (_mult_from == MULT_FROM_RIGHT)
537  {
538  modelview_.translate(_x, _y, _z);
539  inverse_modelview_.translate(-_x, -_y, -_z, MULT_FROM_LEFT);
540  }
541  else
542  {
543  modelview_.translate(_x, _y, _z, MULT_FROM_LEFT);
544  inverse_modelview_.translate(-_x, -_y, -_z);
545  }
546 
547  if (updateGL_ && compatibilityProfile_)
548  {
549  makeCurrent();
550  glLoadMatrixd(modelview_.get_raw_data());
551  }
552 }
553 
554 //-----------------------------------------------------------------------------
555 
556 void GLState::translate( Vec3d _vector,
557  MultiplyFrom _mult_from ) {
558  translate( _vector[0] , _vector[1] , _vector[2] ,_mult_from);
559 }
560 
561 //-----------------------------------------------------------------------------
562 
563 
564 void GLState::rotate( double _angle, double _x, double _y, double _z,
565  MultiplyFrom _mult_from )
566 {
567  if (_mult_from == MULT_FROM_RIGHT)
568  {
569  modelview_.rotate(_angle, _x, _y, _z);
570  inverse_modelview_.rotate(-_angle, _x, _y, _z, MULT_FROM_LEFT);
571  }
572  else
573  {
574  modelview_.rotate(_angle, _x, _y, _z, MULT_FROM_LEFT);
575  inverse_modelview_.rotate(-_angle, _x, _y, _z);
576  }
577 
578  if (updateGL_ && compatibilityProfile_)
579  {
580  makeCurrent();
581  glLoadMatrixd(modelview_.get_raw_data());
582  }
583 }
584 
585 
586 //-----------------------------------------------------------------------------
587 
588 
589 void GLState::scale( double _sx, double _sy, double _sz,
590  MultiplyFrom _mult_from )
591 {
592  if (_mult_from == MULT_FROM_RIGHT)
593  {
594  modelview_.scale(_sx, _sy, _sz, MULT_FROM_RIGHT);
595  inverse_modelview_.scale(1.0f/_sx, 1.0f/_sy, 1.0f/_sz, MULT_FROM_LEFT);
596  }
597  else
598  {
599  modelview_.scale(_sx, _sy, _sz, MULT_FROM_LEFT);
600  inverse_modelview_.scale(1.0f/_sx, 1.0f/_sy, 1.0f/_sz, MULT_FROM_RIGHT);
601  }
602 
603  if (updateGL_ && compatibilityProfile_)
604  {
605  makeCurrent();
606  glLoadMatrixd(modelview_.get_raw_data());
607  }
608 }
609 
610 
611 //-----------------------------------------------------------------------------
612 
613 
614 void GLState::mult_matrix( const GLMatrixd& _m, const GLMatrixd& _inv_m,
615  MultiplyFrom _mult_from )
616 {
617  if (_mult_from == MULT_FROM_RIGHT)
618  {
619  modelview_ *= _m;
620  inverse_modelview_.leftMult(_inv_m);
621  }
622  else
623  {
624  modelview_.leftMult(_m);
625  inverse_modelview_ *= _inv_m;
626  }
627 
628  if (updateGL_ && compatibilityProfile_)
629  {
630  makeCurrent();
631  glLoadMatrixd(modelview_.get_raw_data());
632  }
633 }
634 
635 
636 
637 //-----------------------------------------------------------------------------
638 
639 
640 Vec3d GLState::project(const Vec3d& _point) const
641 {
642  Vec3d t = modelview_.transform_point(_point);
643  t = projection_.transform_point(t);
644  return window2viewport_.transform_point(t);
645 }
646 
647 
648 //-----------------------------------------------------------------------------
649 
650 
651 Vec3d GLState::unproject(const Vec3d& _winPoint) const
652 {
653  Vec3d t = inverse_window2viewport_.transform_point(_winPoint);
654  t = inverse_projection_.transform_point(t);
655  return inverse_modelview_.transform_point(t);
656 }
657 
658 
659 //-----------------------------------------------------------------------------
660 
661 
663 {
664  clear_color_ = _col;
665 
666  if (updateGL_)
667  {
668  makeCurrent();
669  glClearColor(_col[0], _col[1], _col[2], _col[3]);
670  }
671 }
672 
673 
674 //-----------------------------------------------------------------------------
675 
676 
678 {
679  base_color_ = _col;
680 
681  if (updateGL_ && compatibilityProfile_ )
682  {
683  makeCurrent();
684  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, _col.data());
685  }
686 }
687 
688 //-----------------------------------------------------------------------------
689 
690 
691 void GLState::set_color(const Vec4f& _col)
692 {
693  color_ = _col;
694 
695  if (updateGL_)
696  {
697  makeCurrent();
698  glColor(color_);
699  }
700 }
701 
702 
703 
704 //-----------------------------------------------------------------------------
705 
706 
708 {
709  ambient_color_ = _col;
710 
711  if (updateGL_ && compatibilityProfile_)
712  {
713  makeCurrent();
714  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, _col.data());
715  }
716 }
717 
718 
719 //-----------------------------------------------------------------------------
720 
721 
723 {
724  diffuse_color_ = _col;
725 
726  if (updateGL_ && compatibilityProfile_)
727  {
728  makeCurrent();
729  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, _col.data());
730  }
731 }
732 
733 
734 //-----------------------------------------------------------------------------
735 
736 
738 {
739  specular_color_ = _col;
740 
741  if (updateGL_ && compatibilityProfile_)
742  {
743  makeCurrent();
744  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, _col.data());
745  }
746 
747 }
748 
749 //-----------------------------------------------------------------------------
750 
751 
753 {
754  overlay_color_ = _col;
755 }
756 
757 
758 //-----------------------------------------------------------------------------
759 
760 
761 void GLState::set_shininess(float _shininess)
762 {
763  shininess_ = _shininess;
764 
765  if (updateGL_ && compatibilityProfile_)
766  {
767  makeCurrent();
768  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, std::min(128.f, _shininess));
769  }
770 }
771 
772 
773 //-----------------------------------------------------------------------------
774 
775 
777 {
778  point_size_ = _f;
779 
780  if (updateGL_)
781  {
782  makeCurrent();
783  glPointSize(point_size_);
784  }
785 }
786 
787 
788 //-----------------------------------------------------------------------------
789 
790 
792 {
793  line_width_ = _f;
794 if(compatibilityProfile())
795 {
796  if (updateGL_)
797  {
798  makeCurrent();
799  glLineWidth(line_width_);
800  }
801 }
802 }
803 
804 //-----------------------------------------------------------------------------
805 
807  bb_min_ = _min;
808  bb_max_ = _max;
809 }
810 
811 //-----------------------------------------------------------------------------
812 
814  _min = bb_min_;
815  _max = bb_max_;
816 }
817 
818 
819 //-----------------------------------------------------------------------------
820 
821 
823 {
824  twosided_lighting_ = _b;
825 
826  if (updateGL_ && compatibilityProfile_ )
827  {
828  makeCurrent();
829  if (twosided_lighting_)
830  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
831  else
832  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
833  }
834 }
835 
836 
837 //-----------------------------------------------------------------------------
838 
840 {
841 
842  multisampling_ = _b;
843 
844  if (updateGL_)
845  {
846  makeCurrent();
847  if ( allow_multisampling_ ) {
848 
849  if ( _b )
850  GLState::enable( GL_MULTISAMPLE );
851  else
852  GLState::disable( GL_MULTISAMPLE );
853 
854  } else {
855 
856  multisampling_ = false;
857 
858  if ( glIsEnabled( GL_MULTISAMPLE ) )
859  GLState::disable( GL_MULTISAMPLE );
860 
861  }
862  }
863 
864 }
865 
866 //-----------------------------------------------------------------------------
867 
868 double GLState::fovy() const
869 {
870  assert(projection_(1,1) != 0.0);
871 
872  return atan(1.0/projection_(1,1))*2.0;
873 }
874 
875 //-----------------------------------------------------------------------------
876 
877 double GLState::aspect() const
878 {
879  assert(projection_(0,0) != 0.0);
880 
881  return projection_(1,1) / projection_(0,0);
882 }
883 
884 //-----------------------------------------------------------------------------
885 
887 {
888  return inverse_modelview_.transform_point(Vec3d(0.0, 0.0, 0.0));
889 }
890 
891 //-----------------------------------------------------------------------------
892 
893 
894 Vec3d GLState::viewing_direction(int _x, int _y) const
895 {
896  Vec3d dir = ( unproject(Vec3d(_x, _y, 1.0)) -
897  unproject(Vec3d(_x, _y, 0.0)) );
898  dir.normalize();
899  return dir;
900 }
901 
902 
903 //-----------------------------------------------------------------------------
904 
905 
907 {
908  Vec3d dir( unproject(Vec3d(0.5*width_, height_-1, 0.0)) -
909  unproject(Vec3d(0.5*width_, 0.5*height_, 0.0)) );
910  dir.normalize();
911  return dir;
912 }
913 
914 
915 //-----------------------------------------------------------------------------
916 
917 
919 {
920  Vec3d dir( unproject(Vec3d(width_-1, 0.5*height_, 0.0)) -
921  unproject(Vec3d(0.5*width_, 0.5*height_, 0.0)) );
922  dir.normalize();
923  return dir;
924 }
925 
926 
927 //-----------------------------------------------------------------------------
928 
929 
930 void GLState::viewing_ray( int _x, int _y,
931  Vec3d& _origin, Vec3d& _direction) const
932 {
933  _origin = unproject(Vec3d(_x, _y, 0.0));
934  _direction = unproject(Vec3d(_x, _y, 1.0)) - _origin;
935  _direction.normalize();
936 }
937 
938 
939 //-----------------------------------------------------------------------------
940 
941 const GLenum& GLState::depthFunc() const
942 {
943  return stateStack_.back().depthFunc_;
944 }
945 
946 //-----------------------------------------------------------------------------
947 
948 void GLState:: set_depthFunc(const GLenum& _depth_func)
949 {
950  depthFunc(_depth_func);
951 }
952 
953 //-----------------------------------------------------------------------------
954 
955 void GLState::depthFunc(GLenum _depthFunc)
956 {
957  if (!depthFuncLock_)
958  {
959 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
960  if (stateStack_.back().depthFunc_ != _depthFunc)
961 #endif
962  {
963  glDepthFunc(_depthFunc);
964  stateStack_.back().depthFunc_ = _depthFunc;
965  }
966  }
967 }
968 
969 //-----------------------------------------------------------------------------
970 
972 {
973  stack_projection_.push(projection_);
974  stack_inverse_projection_.push(inverse_projection_);
975 
976  if (updateGL_ && compatibilityProfile_)
977  {
978  makeCurrent();
979  glMatrixMode(GL_PROJECTION);
980  glPushMatrix();
981  glMatrixMode(GL_MODELVIEW);
982  }
983 }
984 
985 
986 //-----------------------------------------------------------------------------
987 
988 
990 {
991  projection_ = stack_projection_.top();
992  inverse_projection_ = stack_inverse_projection_.top();
993 
994  stack_projection_.pop();
995  stack_inverse_projection_.pop();
996 
997  if (updateGL_ && compatibilityProfile_)
998  {
999  makeCurrent();
1000  glMatrixMode(GL_PROJECTION);
1001  glPopMatrix();
1002  glMatrixMode(GL_MODELVIEW);
1003  }
1004 }
1005 
1006 
1007 //-----------------------------------------------------------------------------
1008 
1009 
1011 {
1012  stack_modelview_.push(modelview_);
1013  stack_inverse_modelview_.push(inverse_modelview_);
1014 
1015  if (updateGL_ && compatibilityProfile_)
1016  {
1017  makeCurrent();
1018  glPushMatrix();
1019  }
1020 }
1021 
1022 
1023 //-----------------------------------------------------------------------------
1024 
1025 
1027 {
1028  modelview_ = stack_modelview_.top();
1029  inverse_modelview_ = stack_inverse_modelview_.top();
1030 
1031  stack_modelview_.pop();
1032  stack_inverse_modelview_.pop();
1033 
1034  if (updateGL_ && compatibilityProfile_)
1035  {
1036  makeCurrent();
1037  glPopMatrix();
1038  }
1039 }
1040 
1041 //-----------------------------------------------------------------------------
1042 
1043 void GLState::pick_init (bool _color)
1044 {
1045  colorPicking_ = _color;
1046  colorStack_.initialize ( this);
1047 }
1048 
1049 //-----------------------------------------------------------------------------
1050 
1051 bool GLState::pick_set_maximum (size_t _idx)
1052 {
1053  bool rv = colorStack_.setMaximumIndex (_idx);
1054  if (colorPicking_)
1055  return rv;
1056  return true;
1057 }
1058 
1059 //-----------------------------------------------------------------------------
1060 
1061 void GLState::pick_set_name (size_t _idx)
1062 {
1063  colorStack_.setIndex (_idx);
1064 }
1065 
1066 //-----------------------------------------------------------------------------
1067 
1069 {
1070  if (colorPicking_)
1071  return colorStack_.getIndexColor (_idx);
1072  return Vec4uc (0, 0, 0, 0);
1073 }
1074 
1075 //-----------------------------------------------------------------------------
1076 
1078 {
1079  Vec4f rv(0.0f, 0.0f, 0.0f, 0.0f);
1080  if (colorPicking_)
1081  {
1082  Vec4uc color_abs = colorStack_.getIndexColor(_idx);
1083  rv = OpenMesh::vector_cast<Vec4f, Vec4uc>(color_abs) / 255.0f;
1084  }
1085  return rv;
1086 }
1087 
1088 //-----------------------------------------------------------------------------
1089 
1090 void GLState::pick_push_name (size_t _idx)
1091 {
1092  colorStack_.pushIndex (_idx);
1093 }
1094 
1095 //-----------------------------------------------------------------------------
1096 
1098 {
1099  colorStack_.popIndex ();
1100 }
1101 
1102 //-----------------------------------------------------------------------------
1103 
1104 std::vector<size_t> GLState::pick_color_to_stack (Vec4uc _rgba) const
1105 {
1106  if (colorPicking_ && colorStack_.initialized ())
1107  return colorStack_.colorToStack (_rgba);
1108  return std::vector<size_t> ();
1109 }
1110 
1111 //-----------------------------------------------------------------------------
1112 
1114 {
1115  if (colorPicking_ && colorStack_.initialized ())
1116  return colorStack_.freeIndicies ();
1117  return -1;
1118 }
1119 
1120 //-----------------------------------------------------------------------------
1121 
1122 bool GLState::pick_error () const
1123 {
1124  if (colorPicking_)
1125  return colorStack_.error ();
1126  return false;
1127 }
1128 
1129 //-----------------------------------------------------------------------------
1130 
1132 {
1133  if (colorPicking_)
1134  return colorStack_.currentIndex ();
1135  else
1136  return 0;
1137 }
1138 
1139 //-----------------------------------------------------------------------------
1140 
1142 {
1143  return colorPicking_;
1144 }
1145 
1146 //-----------------------------------------------------------------------------
1147 
1148 GLenum GLState::glStateCaps[] = {GL_ALPHA_TEST,
1149 GL_AUTO_NORMAL,
1150 GL_MAP2_VERTEX_3,
1151 GL_MAP2_VERTEX_4,
1152 GL_BLEND,
1153 GL_CLIP_PLANE0,
1154 GL_CLIP_PLANE1,
1155 GL_CLIP_PLANE2,
1156 GL_CLIP_PLANE3,
1157 GL_CLIP_PLANE4,
1158 GL_CLIP_PLANE5,
1159 GL_COLOR_LOGIC_OP,
1160 GL_COLOR_MATERIAL,
1161 GL_COLOR_SUM,
1162 GL_COLOR_TABLE,
1163 GL_CONVOLUTION_1D,
1164 GL_CONVOLUTION_2D,
1165 GL_CULL_FACE,
1166 GL_DEPTH_TEST,
1167 GL_DITHER,
1168 GL_FOG,
1169 GL_HISTOGRAM,
1170 GL_INDEX_LOGIC_OP,
1171 GL_LIGHT0,
1172 GL_LIGHT1,
1173 GL_LIGHT2,
1174 GL_LIGHT3,
1175 GL_LIGHT4,
1176 GL_LIGHT5,
1177 GL_LIGHT6,
1178 GL_LIGHT7,
1179 GL_LIGHTING,
1180 GL_LINE_SMOOTH,
1181 GL_LINE_STIPPLE,
1182 GL_MAP1_COLOR_4,
1183 GL_MAP1_INDEX,
1184 GL_MAP1_NORMAL,
1185 GL_MAP1_TEXTURE_COORD_1,
1186 GL_MAP1_TEXTURE_COORD_2,
1187 GL_MAP1_TEXTURE_COORD_3,
1188 GL_MAP1_TEXTURE_COORD_4,
1189 GL_MAP1_VERTEX_3,
1190 GL_MAP1_VERTEX_4,
1191 GL_MAP2_COLOR_4,
1192 GL_MAP2_INDEX,
1193 GL_MAP2_NORMAL,
1194 GL_MAP2_TEXTURE_COORD_1,
1195 GL_MAP2_TEXTURE_COORD_2,
1196 GL_MAP2_TEXTURE_COORD_3,
1197 GL_MAP2_TEXTURE_COORD_4,
1198 GL_MAP2_VERTEX_3,
1199 GL_MAP2_VERTEX_4,
1200 GL_MINMAX,
1201 GL_MULTISAMPLE,
1202 GL_NORMALIZE,
1203 GL_RESCALE_NORMAL,
1204 GL_POINT_SMOOTH,
1205 GL_POINT_SPRITE,
1206 GL_POLYGON_OFFSET_FILL,
1207 GL_FILL,
1208 GL_POLYGON_OFFSET_LINE,
1209 GL_LINE,
1210 GL_POLYGON_OFFSET_POINT,
1211 GL_POINT,
1212 GL_POLYGON_SMOOTH,
1213 GL_POLYGON_STIPPLE,
1214 GL_POST_COLOR_MATRIX_COLOR_TABLE,
1215 GL_POST_CONVOLUTION_COLOR_TABLE,
1216 GL_RESCALE_NORMAL,
1217 GL_NORMALIZE,
1218 GL_SAMPLE_ALPHA_TO_COVERAGE,
1219 GL_SAMPLE_ALPHA_TO_ONE,
1220 GL_SAMPLE_COVERAGE,
1221 GL_SAMPLE_COVERAGE_INVERT,
1222 GL_SEPARABLE_2D,
1223 GL_SCISSOR_TEST,
1224 GL_STENCIL_TEST,
1225 GL_TEXTURE_1D,
1226 GL_TEXTURE_2D,
1227 GL_TEXTURE_3D,
1228 GL_TEXTURE_CUBE_MAP,
1229 GL_TEXTURE_GEN_Q,
1230 GL_TEXTURE_GEN_R,
1231 GL_TEXTURE_GEN_S,
1232 GL_TEXTURE_GEN_T,
1233 GL_VERTEX_PROGRAM_POINT_SIZE,
1234 GL_VERTEX_PROGRAM_TWO_SIDE,
1235 GL_COLOR_ARRAY,
1236 GL_EDGE_FLAG_ARRAY,
1237 GL_FOG_COORD_ARRAY,
1238 GL_INDEX_ARRAY,
1239 GL_NORMAL_ARRAY,
1240 GL_SECONDARY_COLOR_ARRAY,
1241 GL_TEXTURE_COORD_ARRAY,
1242 GL_VERTEX_ARRAY};
1243 
1245 {
1246  // get enabled states
1247  GLenum caps[] = {GL_ALPHA_TEST,
1248  GL_AUTO_NORMAL,
1249  GL_MAP2_VERTEX_3,
1250  GL_MAP2_VERTEX_4,
1251  GL_BLEND,
1252  GL_CLIP_PLANE0,
1253  GL_CLIP_PLANE1,
1254  GL_CLIP_PLANE2,
1255  GL_CLIP_PLANE3,
1256  GL_CLIP_PLANE4,
1257  GL_CLIP_PLANE5,
1258  GL_COLOR_LOGIC_OP,
1259  GL_COLOR_MATERIAL,
1260  GL_COLOR_SUM,
1261  GL_COLOR_TABLE,
1262  GL_CONVOLUTION_1D,
1263  GL_CONVOLUTION_2D,
1264  GL_CULL_FACE,
1265  GL_DEPTH_TEST,
1266  GL_DITHER,
1267  GL_FOG,
1268  GL_HISTOGRAM,
1269  GL_INDEX_LOGIC_OP,
1270  GL_LIGHT0,
1271  GL_LIGHT1,
1272  GL_LIGHT2,
1273  GL_LIGHT3,
1274  GL_LIGHT4,
1275  GL_LIGHT5,
1276  GL_LIGHT6,
1277  GL_LIGHT7,
1278  GL_LIGHTING,
1279  GL_LINE_SMOOTH,
1280  GL_LINE_STIPPLE,
1281  GL_MAP1_COLOR_4,
1282  GL_MAP1_INDEX,
1283  GL_MAP1_NORMAL,
1284  GL_MAP1_TEXTURE_COORD_1,
1285  GL_MAP1_TEXTURE_COORD_2,
1286  GL_MAP1_TEXTURE_COORD_3,
1287  GL_MAP1_TEXTURE_COORD_4,
1288  GL_MAP1_VERTEX_3,
1289  GL_MAP1_VERTEX_4,
1290  GL_MAP2_COLOR_4,
1291  GL_MAP2_INDEX,
1292  GL_MAP2_NORMAL,
1293  GL_MAP2_TEXTURE_COORD_1,
1294  GL_MAP2_TEXTURE_COORD_2,
1295  GL_MAP2_TEXTURE_COORD_3,
1296  GL_MAP2_TEXTURE_COORD_4,
1297  GL_MAP2_VERTEX_3,
1298  GL_MAP2_VERTEX_4,
1299  GL_MINMAX,
1300  GL_MULTISAMPLE,
1301  GL_NORMALIZE,
1302  GL_RESCALE_NORMAL,
1303  GL_POINT_SMOOTH,
1304  GL_POINT_SPRITE,
1305  GL_POLYGON_OFFSET_FILL,
1306  GL_POLYGON_OFFSET_LINE,
1307  GL_POLYGON_OFFSET_POINT,
1308  GL_POLYGON_SMOOTH,
1309  GL_POLYGON_STIPPLE,
1310  GL_POST_COLOR_MATRIX_COLOR_TABLE,
1311  GL_POST_CONVOLUTION_COLOR_TABLE,
1312  GL_RESCALE_NORMAL,
1313  GL_NORMALIZE,
1314  GL_SAMPLE_ALPHA_TO_COVERAGE,
1315  GL_SAMPLE_ALPHA_TO_ONE,
1316  GL_SAMPLE_COVERAGE,
1317  GL_SEPARABLE_2D,
1318  GL_SCISSOR_TEST,
1319  GL_STENCIL_TEST,
1320  GL_TEXTURE_1D,
1321  GL_TEXTURE_2D,
1322  GL_TEXTURE_3D,
1323  GL_TEXTURE_CUBE_MAP,
1324  GL_TEXTURE_GEN_Q,
1325  GL_TEXTURE_GEN_R,
1326  GL_TEXTURE_GEN_S,
1327  GL_TEXTURE_GEN_T,
1328  GL_VERTEX_PROGRAM_POINT_SIZE,
1329  GL_VERTEX_PROGRAM_TWO_SIDE,
1330  GL_COLOR_ARRAY,
1331  GL_EDGE_FLAG_ARRAY,
1332  GL_FOG_COORD_ARRAY,
1333  GL_INDEX_ARRAY,
1334  GL_NORMAL_ARRAY,
1335  GL_SECONDARY_COLOR_ARRAY,
1336  GL_TEXTURE_COORD_ARRAY,
1337  GL_VERTEX_ARRAY};
1338 
1339  for (unsigned int i = 0; i < sizeof(caps) / sizeof(GLenum); ++i)
1340  {
1341  if (glIsEnabled(caps[i])) stateStack_.back().glStateEnabled_.set(caps[i]);
1342  else stateStack_.back().glStateEnabled_.reset(caps[i]);
1343  }
1344 
1345  GLint getparam;
1346 
1347 #ifdef GL_VERSION_1_4
1348  glGetIntegerv(GL_BLEND_SRC_RGB, &getparam);
1349  stateStack_.back().blendFuncState_[0] = getparam;
1350 
1351  glGetIntegerv(GL_BLEND_DST_ALPHA, &getparam);
1352  stateStack_.back().blendFuncState_[1] = getparam;
1353 
1354  glGetIntegerv(GL_BLEND_SRC_ALPHA, &getparam);
1355  stateStack_.back().blendFuncState_[2] = getparam;
1356 
1357  glGetIntegerv(GL_BLEND_DST_ALPHA, &getparam);
1358  stateStack_.back().blendFuncState_[3] = getparam;
1359 #else
1360  glGetIntegerv(GL_BLEND_SRC, &getparam);
1361  stateStack_.back().blendFuncState_[0] = getparam;
1362 
1363  glGetIntegerv(GL_BLEND_DST, &getparam);
1364  stateStack_.back().blendFuncState_[1] = getparam;
1365 #endif
1366 
1367 
1368  glGetIntegerv(GL_BLEND_EQUATION_RGB, &getparam);
1369  stateStack_.back().blendEquationState_ = getparam;
1370 
1371  glGetFloatv(GL_BLEND_COLOR, stateStack_.back().blendColorState_);
1372 
1373  glGetIntegerv(GL_ALPHA_TEST_FUNC, &getparam);
1374  stateStack_.back().alphaFuncState_ = getparam;
1375 
1376  glGetFloatv(GL_ALPHA_TEST_REF, &stateStack_.back().alphaRefState_);
1377 
1378  glGetIntegerv(GL_DEPTH_FUNC, &getparam);
1379  stateStack_.back().depthFunc_ = getparam;
1380 
1381  glGetDoublev(GL_DEPTH_RANGE, stateStack_.back().depthRange_);
1382 
1383  // bound buffers
1384 
1385  GLenum bufGets[8] = {
1386  GL_ARRAY_BUFFER_BINDING, GL_ARRAY_BUFFER,
1387  GL_ELEMENT_ARRAY_BUFFER_BINDING, GL_ELEMENT_ARRAY_BUFFER,
1388  GL_PIXEL_PACK_BUFFER_BINDING, GL_PIXEL_PACK_BUFFER,
1389  GL_PIXEL_UNPACK_BUFFER_BINDING, GL_PIXEL_UNPACK_BUFFER};
1390 
1391  for (int i = 0; i < 4; ++i)
1392  glGetIntegerv(bufGets[i*2], (GLint*)stateStack_.back().glBufferTargetState_ + getBufferTargetIndex(bufGets[i*2+1]));
1393 
1394 
1395  // bound textures
1396  glGetIntegerv(GL_ACTIVE_TEXTURE, &getparam);
1397  stateStack_.back().activeTexture_ = getparam;
1398 
1399  GLenum texBufGets[] = {
1400  GL_TEXTURE_BINDING_1D, GL_TEXTURE_1D,
1401  GL_TEXTURE_BINDING_2D, GL_TEXTURE_2D,
1402  GL_TEXTURE_BINDING_3D, GL_TEXTURE_3D,
1403  GL_TEXTURE_BINDING_CUBE_MAP, GL_TEXTURE_CUBE_MAP
1404  , GL_TEXTURE_BINDING_RECTANGLE_ARB, GL_TEXTURE_RECTANGLE_ARB
1405  };
1406 
1407  glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxTextureCoords_);
1408  glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxCombinedTextureImageUnits_);
1409 
1410  // safe clamp
1411  if (maxTextureCoords_ > 16) maxTextureCoords_ = 16;
1412  if (maxCombinedTextureImageUnits_ > 16) maxCombinedTextureImageUnits_ = 16;
1413 
1414  int numTexUnits = maxTextureCoords_;
1415  if (numTexUnits < maxCombinedTextureImageUnits_) numTexUnits = maxCombinedTextureImageUnits_;
1416 
1417  for (int i = 0; i < numTexUnits; ++i)
1418  {
1419  glActiveTexture(GL_TEXTURE0 + i);
1420 
1421  getparam = 0;
1422  // for each texture stage query 5 texture types: 1D, 2D, 3D, Cube, Rect
1423  for (int k = 0; k < 5 && !getparam; ++k)
1424  {
1425  glGetIntegerv(texBufGets[k*2], &getparam);
1426  if (getparam)
1427  {
1428  stateStack_.back().glTextureStage_[i].buf_ = getparam;
1429  stateStack_.back().glTextureStage_[i].target_ = texBufGets[k*2+1];
1430  }
1431  }
1432  }
1433 
1434  // restore active texture unit
1435  if (numTexUnits > 0)
1436  glActiveTexture(stateStack_.back().activeTexture_);
1437 
1438 
1439  // shade model
1440  glGetIntegerv(GL_SHADE_MODEL, &getparam);
1441  stateStack_.back().shadeModel_ = getparam;
1442 
1443  // cull face
1444  glGetIntegerv(GL_CULL_FACE_MODE, &getparam);
1445  stateStack_.back().cullFace_ = getparam;
1446 
1447 
1448  // vertex pointers
1449  {
1450  GLenum ptrEnums[] = {
1451  GL_VERTEX_ARRAY_SIZE, GL_VERTEX_ARRAY_TYPE,
1452  GL_VERTEX_ARRAY_STRIDE, GL_VERTEX_ARRAY_POINTER,
1453  GL_COLOR_ARRAY_SIZE, GL_COLOR_ARRAY_TYPE,
1454  GL_COLOR_ARRAY_STRIDE, GL_COLOR_ARRAY_POINTER,
1455  GL_TEXTURE_COORD_ARRAY_SIZE, GL_TEXTURE_COORD_ARRAY_TYPE,
1456  GL_TEXTURE_COORD_ARRAY_STRIDE, GL_TEXTURE_COORD_ARRAY_POINTER};
1457 
1458  GLStateContext::GLVertexPointer* ptrs[] = {&stateStack_.back().vertexPointer_,
1459  &stateStack_.back().colorPointer_, &stateStack_.back().texcoordPointer_};
1460 
1461  for (int i = 0; i < 3 ; ++i)
1462  {
1463  glGetIntegerv(ptrEnums[i*4], &getparam);
1464  ptrs[i]->size = getparam;
1465  glGetIntegerv(ptrEnums[i*4+1], &getparam);
1466  ptrs[i]->type = getparam;
1467  glGetIntegerv(ptrEnums[i*4+2], &getparam);
1468  ptrs[i]->stride = getparam;
1469  glGetPointerv(ptrEnums[i*4+3], (GLvoid**)&ptrs[i]->pointer);
1470  }
1471 
1472  glGetIntegerv(GL_NORMAL_ARRAY_STRIDE, &getparam);
1473  stateStack_.back().normalPointer_.size = getparam;
1474  glGetIntegerv(GL_NORMAL_ARRAY_TYPE, &getparam);
1475  stateStack_.back().normalPointer_.type = getparam;
1476  glGetPointerv(GL_NORMAL_ARRAY_POINTER, (GLvoid**)&stateStack_.back().normalPointer_.pointer);
1477  }
1478 
1479 
1480  // draw buffer state
1481  glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers_);
1482  if (maxDrawBuffers_ > 16) maxDrawBuffers_ = 16;
1483 
1484  for (int i = 0; i < maxDrawBuffers_; ++i)
1485  {
1486  glGetIntegerv(GL_DRAW_BUFFER0 + i, &getparam);
1487  stateStack_.back().drawBufferState_[i] = getparam;
1488  }
1489 
1490  glGetIntegerv(GL_DRAW_BUFFER, &getparam);
1491  stateStack_.back().drawBufferSingle_ = getparam;
1492 
1493  // framebuffer
1494  glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &getparam);
1495  stateStack_.back().framebuffers_[0] = getparam;
1496  glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &getparam);
1497  stateStack_.back().framebuffers_[1] = getparam;
1498 
1499  // shader program
1500  glGetIntegerv(GL_CURRENT_PROGRAM, &getparam);
1501  stateStack_.back().program_ = getparam;
1502 }
1503 
1504 //-----------------------------------------------------------------------------
1505 
1506 
1507 void GLState::enable(GLenum _cap, bool _warn)
1508 {
1509  if (!glStateLock_.test(_cap))
1510  {
1511 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1512  if (!stateStack_.back().glStateEnabled_.test(_cap))
1513 #endif
1514  {
1515  if (ACG::compatibilityProfile() || removedEnums.find(_cap) == removedEnums.end())
1516  glEnable(_cap);
1517  else
1518  {
1519  if(_warn)
1520  std::cerr << "OpenGL Warning:You are trying to use a GLenum that has been removed for OpenGL core profiles." << std::endl;
1521  }
1522  stateStack_.back().glStateEnabled_.set(_cap);
1523  }
1524  }
1525 }
1526 
1527 void GLState::disable(GLenum _cap, bool _warn)
1528 {
1529  if (!glStateLock_.test(_cap))
1530  {
1531 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1532  if (stateStack_.back().glStateEnabled_.test(_cap))
1533 #endif
1534  {
1535  if (ACG::compatibilityProfile() || removedEnums.find(_cap) == removedEnums.end())
1536  glDisable(_cap);
1537  else
1538  {
1539  if (_warn)
1540  std::cerr << "OpenGL Warning:You are trying to use a GLenum that has been removed for OpenGL core profiles." << std::endl;
1541  }
1542  stateStack_.back().glStateEnabled_.reset(_cap);
1543  }
1544  }
1545 }
1546 
1547 void GLState::lockState(GLenum _cap)
1548 {
1549  glStateLock_.set(_cap);
1550 }
1551 
1552 void GLState::unlockState(GLenum _cap)
1553 {
1554  glStateLock_.reset(_cap);
1555 }
1556 
1557 bool GLState::isStateLocked(GLenum _cap)
1558 {
1559  return glStateLock_.test(_cap);
1560 }
1561 
1562 bool GLState::isStateEnabled(GLenum _cap)
1563 {
1564  return stateStack_.back().glStateEnabled_.test(_cap);
1565 }
1566 
1567 //-----------------------------------------------------------------------------
1568 // client state functions
1569 
1571 {
1572  if (!glStateLock_.test(_cap))
1573  {
1574 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1575  if (!stateStack_.back().glStateEnabled_.test(_cap))
1576 #endif
1577  {
1578  glEnableClientState(_cap);
1579  stateStack_.back().glStateEnabled_.set(_cap);
1580  }
1581  }
1582 }
1583 
1585 {
1586  if (!glStateLock_.test(_cap))
1587  {
1588 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1589  if (stateStack_.back().glStateEnabled_.test(_cap))
1590 #endif
1591  {
1592  glDisableClientState(_cap);
1593  stateStack_.back().glStateEnabled_.reset(_cap);
1594  }
1595  }
1596 }
1597 
1598 void GLState::lockClientState(GLenum _cap)
1599 {
1600  glStateLock_.set(_cap);
1601 }
1602 
1604 {
1605  glStateLock_.reset(_cap);
1606 }
1607 
1609 {
1610  return glStateLock_.test(_cap);
1611 }
1612 
1614 {
1615  return stateStack_.back().glStateEnabled_.test(_cap);
1616 }
1617 
1618 //-----------------------------------------------------------------------------
1619 // blending functions
1620 
1621 void GLState::blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
1622 {
1623  // fix parameters according to lock status
1624  if (blendFuncSeparateLock_[0])
1625  {
1626  _srcRGB = stateStack_.back().blendFuncState_[0];
1627  _dstRGB = stateStack_.back().blendFuncState_[1];
1628  }
1629 
1630  if (blendFuncSeparateLock_[1])
1631  {
1632  _srcAlpha = stateStack_.back().blendFuncState_[2];
1633  _dstAlpha = stateStack_.back().blendFuncState_[3];
1634  }
1635 
1636  if (!blendFuncSeparateLock_[0] || !blendFuncSeparateLock_[1])
1637  {
1638 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1639  if (stateStack_.back().blendFuncState_[0] != _srcRGB || stateStack_.back().blendFuncState_[1] != _dstRGB ||
1640  stateStack_.back().blendFuncState_[2] != _srcAlpha || stateStack_.back().blendFuncState_[3] != _dstAlpha)
1641 #endif
1642  {
1643 #ifdef GL_VERSION_1_4
1644  // check if glew has loaded glBlendFuncSeparate already
1645  if (glBlendFuncSeparate)
1646  glBlendFuncSeparate(_srcRGB, _dstRGB, _srcAlpha, _dstAlpha);
1647  else
1648  glBlendFunc(_srcRGB, _dstRGB);
1649  stateStack_.back().blendFuncState_[0] = _srcRGB;
1650  stateStack_.back().blendFuncState_[1] = _dstRGB;
1651  stateStack_.back().blendFuncState_[2] = _srcAlpha;
1652  stateStack_.back().blendFuncState_[3] = _dstAlpha;
1653 #else
1654  glBlendFunc(_srcRGB, _dstRGB);
1655  stateStack_.back().blendFuncState_[0] = _srcRGB;
1656  stateStack_.back().blendFuncState_[1] = _dstRGB;
1657  stateStack_.back().blendFuncState_[2] = _srcRGB;
1658  stateStack_.back().blendFuncState_[3] = _dstRGB;
1659 #endif
1660  }
1661  }
1662 }
1663 
1664 void GLState::getBlendFuncSeparate(GLenum* _srcRGB, GLenum* _dstRGB, GLenum* _srcAlpha, GLenum* _dstAlpha)
1665 {
1666  if (_srcRGB) *_srcRGB = stateStack_.back().blendFuncState_[0];
1667  if (_dstRGB) *_dstRGB = stateStack_.back().blendFuncState_[1];
1668  if (_srcAlpha) *_srcAlpha = stateStack_.back().blendFuncState_[2];
1669  if (_dstAlpha) *_dstAlpha = stateStack_.back().blendFuncState_[3];
1670 }
1671 
1672 void GLState::blendEquation(GLenum _mode)
1673 {
1674  if (!blendEquationLock_)
1675  {
1676 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1677  if (stateStack_.back().blendEquationState_ != _mode)
1678 #endif
1679  {
1680  glBlendEquation(_mode);
1681  stateStack_.back().blendEquationState_ = _mode;
1682  }
1683  }
1684 }
1685 
1686 void GLState::blendColor(GLclampf _red, GLclampf _green, GLclampf _blue, GLclampf _alpha)
1687 {
1688  if (!blendColorLock_)
1689  {
1690 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1691  if (stateStack_.back().blendColorState_[0] != _red || stateStack_.back().blendColorState_[1] != _green ||
1692  stateStack_.back().blendColorState_[2] != _blue || stateStack_.back().blendColorState_[3] != _alpha)
1693 #endif
1694  {
1695  glBlendColor(_red, _green, _blue, _alpha);
1696  stateStack_.back().blendColorState_[0] = _red; stateStack_.back().blendColorState_[1] = _green;
1697  stateStack_.back().blendColorState_[2] = _blue; stateStack_.back().blendColorState_[3] = _alpha;
1698  }
1699  }
1700 }
1701 
1702 void GLState::getBlendColor(GLclampf* _col)
1703 {
1704  for (int i = 0; i < 4; ++i) _col[i] = stateStack_.back().blendColorState_[i];
1705 }
1706 
1707 
1708 void GLState::alphaFunc(GLenum _func, GLclampf _ref)
1709 {
1710  if (!alphaFuncLock_)
1711  {
1712 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1713  if (stateStack_.back().alphaFuncState_ != _func || stateStack_.back().alphaRefState_ != _ref)
1714 #endif
1715  {
1716  glAlphaFunc(_func, _ref);
1717  stateStack_.back().alphaFuncState_ = _func;
1718  stateStack_.back().alphaRefState_ = _ref;
1719  }
1720  }
1721 }
1722 
1723 void GLState::getAlphaFunc(GLenum* _func, GLclampf* _ref)
1724 {
1725  if (_func) *_func = stateStack_.back().alphaFuncState_;
1726  if (_ref) *_ref = stateStack_.back().alphaRefState_;
1727 }
1728 
1729 void GLState::shadeModel(GLenum _mode)
1730 {
1731  if (!shadeModelLock_)
1732  {
1733 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1734  if (stateStack_.back().shadeModel_ != _mode)
1735 #endif
1736  {
1737  glShadeModel(_mode);
1738  stateStack_.back().shadeModel_ = _mode;
1739  }
1740  }
1741 }
1742 
1743 void GLState::cullFace(GLenum _mode)
1744 {
1745  if (!cullFaceLock_)
1746  {
1747 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1748  if (stateStack_.back().cullFace_ != _mode)
1749 #endif
1750  {
1751  glCullFace(_mode);
1752  stateStack_.back().cullFace_ = _mode;
1753  }
1754  }
1755 }
1756 
1757 void GLState::depthRange(GLclampd _zNear, GLclampd _zFar)
1758 {
1759  if (!depthRangeLock_)
1760  {
1761  #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1762  if (abs(_zNear - stateStack_.back().depthRange_[0]) > 1e-6 ||
1763  abs(_zFar - stateStack_.back().depthRange_[1]) > 1e-6)
1764  #endif
1765  {
1766  glDepthRange(_zNear, _zFar);
1767  stateStack_.back().depthRange_[0] = _zNear;
1768  stateStack_.back().depthRange_[1] = _zFar;
1769  }
1770  }
1771 }
1772 
1773 void GLState::getDepthRange(GLclampd* _zNearOut, GLclampd* _zFarOut)
1774 {
1775  if (_zNearOut) *_zNearOut = stateStack_.back().depthRange_[0];
1776  if (_zFarOut) *_zFarOut = stateStack_.back().depthRange_[1];
1777 }
1778 
1779 //-----------------------------------------------------------------------------
1780 
1782 {
1783  switch (_target)
1784  {
1785  case GL_ARRAY_BUFFER: return 0;
1786  case GL_ELEMENT_ARRAY_BUFFER: return 1;
1787  case GL_PIXEL_PACK_BUFFER: return 2;
1788  case GL_PIXEL_UNPACK_BUFFER: return 3;
1789 #ifdef GL_ARB_uniform_buffer_object
1790  case GL_UNIFORM_BUFFER: return 4;
1791 #endif
1792 #ifdef GL_ARB_shader_storage_buffer_object
1793  case GL_SHADER_STORAGE_BUFFER: return 5;
1794 #endif
1795 #ifdef GL_ARB_shader_atomic_counters
1796  case GL_ATOMIC_COUNTER_BUFFER: return 6;
1797 #endif
1798 #ifdef GL_ARB_copy_buffer
1799  case GL_COPY_READ_BUFFER: return 7;
1800  case GL_COPY_WRITE_BUFFER: return 8;
1801 #endif
1802 #ifdef GL_ARB_compute_shader
1803  case GL_DISPATCH_INDIRECT_BUFFER: return 9;
1804 #endif
1805 #ifdef GL_ARB_draw_indirect
1806  case GL_DRAW_INDIRECT_BUFFER: return 10;
1807 #endif
1808 #ifdef GL_ARB_query_buffer_object
1809  case GL_QUERY_BUFFER: return 11;
1810 #endif
1811  case GL_TEXTURE_BUFFER: return 12;
1812 #ifdef GL_VERSION_3_0
1813  case GL_TRANSFORM_FEEDBACK_BUFFER: return 13;
1814 #endif
1815  }
1816  std::cerr << "error : GLState::bindBuffer - unknown buffer target type" << _target << std::endl;
1817  return -1;
1818 }
1819 
1820 void GLState::bindBuffer(GLenum _target, GLuint _buffer)
1821 {
1822  int idx = getBufferTargetIndex(_target);
1823  if (idx >= 0 && !glBufferTargetLock_[idx])
1824  {
1825 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1826  if (stateStack_.back().glBufferTargetState_[idx] != _buffer)
1827 #endif
1828  {
1829  glBindBuffer(_target, _buffer);
1830  stateStack_.back().glBufferTargetState_[idx] = _buffer;
1831  }
1832  }
1833 }
1834 
1835 void GLState::lockBufferTarget(GLenum _target)
1836 {
1837  glBufferTargetLock_[getBufferTargetIndex(_target)] = 1;
1838 }
1839 
1840 void GLState::unlockBufferTarget(GLenum _target)
1841 {
1842  glBufferTargetLock_[getBufferTargetIndex(_target)] = 0;
1843 }
1844 
1845 bool GLState::isBufferTargetLocked(GLenum _target)
1846 {
1847  return glBufferTargetLock_[getBufferTargetIndex(_target)] != 0;
1848 }
1849 
1850 GLuint GLState::getBoundBuf(GLenum _target)
1851 {
1852  return stateStack_.back().glBufferTargetState_[getBufferTargetIndex(_target)];
1853 }
1854 
1855 //-----------------------------------------------------------------------------
1856 
1857 void GLState::activeTexture(GLenum _texunit)
1858 {
1859 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1860  if (stateStack_.back().activeTexture_ != _texunit)
1861 #endif
1862  {
1863  glActiveTexture(_texunit);
1864  stateStack_.back().activeTexture_ = _texunit;
1865  }
1866 }
1867 
1868 void GLState::bindTexture(GLenum _target, GLuint _buffer)
1869 {
1870  int activeTex = getActiveTextureIndex();
1871 
1872  assert(activeTex >= 0);
1873 
1874  GLStateContext::TextureStage* stage = stateStack_.back().glTextureStage_ + activeTex;
1875 
1876  if (!glTextureStageLock_[activeTex])
1877  {
1878 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1879  if (_buffer != stage->buf_ || _target != stage->target_)
1880 #endif
1881  {
1882  glBindTexture(_target, _buffer);
1883 
1884  stage->target_ = _target;
1885  stage->buf_ = _buffer;
1886  }
1887  }
1888 }
1889 
1891 {
1892  glTextureStageLock_[getActiveTextureIndex()] = 1;
1893 }
1894 
1896 {
1897  glTextureStageLock_[getActiveTextureIndex()] = 0;
1898 }
1899 
1901 {
1902  return glTextureStageLock_[getActiveTextureIndex()] != 0;
1903 }
1904 
1906 {
1907  return stateStack_.back().glTextureStage_[getActiveTextureIndex()].buf_;
1908 }
1909 
1911 {
1912  return stateStack_.back().glTextureStage_[getActiveTextureIndex()].target_;
1913 }
1914 
1915 //----------------------------------------------------------
1916 // vertex pointers
1917 
1918 void GLState::vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid* _pointer)
1919 {
1920  if (!vertexPointerLock_)
1921  {
1922 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1923  if (!stateStack_.back().vertexPointer_.equals(_size, _type, _stride, _pointer))
1924 #endif
1925  {
1926  glVertexPointer(_size, _type, _stride, _pointer);
1927  stateStack_.back().vertexPointer_.set(_size, _type, _stride, _pointer);
1928  }
1929  }
1930 }
1931 
1932 void GLState::getVertexPointer(GLint* _size, GLenum* _type, GLsizei* _stride, const GLvoid** _pointer)
1933 {
1934  if (_size) *_size = stateStack_.back().vertexPointer_.size;
1935  if (_stride) *_stride = stateStack_.back().vertexPointer_.stride;
1936  if (_type) *_type = stateStack_.back().vertexPointer_.type;
1937  if (_pointer) *_pointer = stateStack_.back().vertexPointer_.pointer;
1938 }
1939 
1940 void GLState::normalPointer(GLenum _type, GLsizei _stride, const GLvoid* _pointer)
1941 {
1942  if (!normalPointerLock_)
1943  {
1944 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1945  if (!stateStack_.back().normalPointer_.equals(stateStack_.back().normalPointer_.size, _type, _stride, _pointer))
1946 #endif
1947  {
1948  glNormalPointer(_type, _stride, _pointer);
1949  stateStack_.back().normalPointer_.set(3, _type, _stride, _pointer);
1950  }
1951  }
1952 }
1953 
1954 void GLState::getNormalPointer(GLenum* _type, GLsizei* _stride, const GLvoid** _pointer)
1955 {
1956  if (_type) *_type = stateStack_.back().normalPointer_.type;
1957  if (_stride) *_stride = stateStack_.back().normalPointer_.stride;
1958  if (_pointer) *_pointer = stateStack_.back().normalPointer_.pointer;
1959 }
1960 
1961 
1962 void GLState::colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid* _pointer)
1963 {
1964  if (!colorPointerLock_)
1965  {
1966 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1967  if (!stateStack_.back().colorPointer_.equals(_size, _type, _stride, _pointer))
1968 #endif
1969  {
1970  glColorPointer(_size, _type, _stride, _pointer);
1971  stateStack_.back().colorPointer_.set(_size, _type, _stride, _pointer);
1972  }
1973  }
1974 }
1975 
1976 void GLState::getColorPointer(GLint* _size, GLenum* _type, GLsizei* _stride, const GLvoid** _pointer)
1977 {
1978  if (_size) *_size = stateStack_.back().colorPointer_.size;
1979  if (_stride) *_stride = stateStack_.back().colorPointer_.stride;
1980  if (_type) *_type = stateStack_.back().colorPointer_.type;
1981  if (_pointer) *_pointer = stateStack_.back().colorPointer_.pointer;
1982 }
1983 
1984 void GLState::texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid* _pointer)
1985 {
1986  if (!texcoordPointerLock_)
1987  {
1988 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
1989  if (!stateStack_.back().texcoordPointer_.equals(_size, _type, _stride, _pointer))
1990 #endif
1991  {
1992  glTexCoordPointer(_size, _type, _stride, _pointer);
1993  stateStack_.back().texcoordPointer_.set(_size, _type, _stride, _pointer);
1994  }
1995  }
1996 }
1997 
1998 void GLState::getTexcoordPointer(GLint* _size, GLenum* _type, GLsizei* _stride, const GLvoid** _pointer)
1999 {
2000  if (_size) *_size = stateStack_.back().texcoordPointer_.size;
2001  if (_stride) *_stride = stateStack_.back().texcoordPointer_.stride;
2002  if (_type) *_type = stateStack_.back().texcoordPointer_.type;
2003  if (_pointer) *_pointer = stateStack_.back().texcoordPointer_.pointer;
2004 }
2005 
2006 void GLState::setTexGenMode(GLenum _coord, GLenum _name, GLint _param)
2007 {
2009  {
2010  glTexGeni(_coord, _name, _param);
2011  }
2012  else
2013  {
2014  stateStack_.back().texGenMode_ = _param;
2015  }
2016 }
2017 
2018 void GLState::getTexGenMode(GLenum _coord, GLenum _name, GLint* _param)
2019 {
2021  {
2022  glGetTexGeniv(_coord, _name, _param);
2023  }
2024  else
2025  {
2026  *_param = stateStack_.back().texGenMode_;
2027  }
2028 }
2029 
2030 //---------------------------------------------------------------------
2031 // draw buffer functions
2032 
2033 void GLState::drawBuffer(GLenum _mode)
2034 {
2035  if (!drawBufferLock_)
2036  {
2037 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
2038  if (stateStack_.back().drawBufferSingle_ != _mode || stateStack_.back().activeDrawBuffer_)
2039 #endif
2040  {
2041  glDrawBuffer(_mode);
2042  stateStack_.back().drawBufferSingle_ = _mode;
2043  stateStack_.back().activeDrawBuffer_ = 0;
2044  }
2045  }
2046 }
2047 
2048 void GLState::drawBuffers(GLsizei _n, const GLenum* _bufs)
2049 {
2050  if (!drawBufferLock_)
2051  {
2052 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
2053  int bChange = !stateStack_.back().activeDrawBuffer_;
2054  for (int i = 0; i < _n && (!bChange); ++i)
2055  {
2056  if (stateStack_.back().drawBufferState_[i] != _bufs[i])
2057  bChange = 1;
2058  }
2059 
2060  if (bChange)
2061 #endif
2062  {
2063  glDrawBuffers(_n, _bufs);
2064 
2065  for (int i = 0; i < _n; ++i)
2066  stateStack_.back().drawBufferState_[i] = _bufs[i];
2067 
2068  stateStack_.back().activeDrawBuffer_ = _n;
2069  }
2070  }
2071 }
2072 
2075 {
2076  GLint curfbo;
2077  glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curfbo);
2078  return curfbo;
2079 }
2080 
2083 {
2084  GLint curfbo;
2085  glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint*)&curfbo);
2086  return curfbo;
2087 }
2088 
2089 void GLState::bindFramebuffer(GLenum _target, GLuint _framebuffer)
2090 {
2091  int i = -1;
2092  switch (_target)
2093  {
2094  case GL_FRAMEBUFFER:
2095  {
2096  bindFramebuffer(GL_READ_FRAMEBUFFER, _framebuffer);
2097  bindFramebuffer(GL_DRAW_FRAMEBUFFER, _framebuffer);
2098  return;
2099  }
2100  case GL_DRAW_FRAMEBUFFER: i = 0; break;
2101  case GL_READ_FRAMEBUFFER: i = 1; break;
2102  }
2103 
2104  if (i >= 0 && !framebufferLock_[i])
2105  {
2106 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
2107  if (stateStack_.back().framebuffers_[i] != _framebuffer)
2108 #endif
2109  {
2110 #ifndef __APPLE__
2111  if (glBindFramebuffer == nullptr)
2112  glewInit();
2113 #endif
2114  glBindFramebuffer(_target, _framebuffer);
2115  stateStack_.back().framebuffers_[i] = _framebuffer;
2116  }
2117  }
2118 }
2119 
2120 void GLState::lockFramebuffer(GLenum _target)
2121 {
2122  switch (_target)
2123  {
2124  case GL_FRAMEBUFFER:
2125  framebufferLock_[0] = framebufferLock_[1] = true; break;
2126 
2127  case GL_DRAW_FRAMEBUFFER: framebufferLock_[0] = true; break;
2128  case GL_READ_FRAMEBUFFER: framebufferLock_[1] = true; break;
2129  }
2130 }
2131 
2132 void GLState::unlockFramebuffer(GLenum _target)
2133 {
2134  switch (_target)
2135  {
2136  case GL_FRAMEBUFFER:
2137  framebufferLock_[0] = framebufferLock_[1] = false; break;
2138 
2139  case GL_DRAW_FRAMEBUFFER: framebufferLock_[0] = false; break;
2140  case GL_READ_FRAMEBUFFER: framebufferLock_[1] = false; break;
2141  }
2142 }
2143 
2144 bool GLState::isFramebufferLocked(GLenum _target)
2145 {
2146  switch (_target)
2147  {
2148  case GL_FRAMEBUFFER:
2149  return framebufferLock_[0] && framebufferLock_[1];
2150 
2151  case GL_DRAW_FRAMEBUFFER: return framebufferLock_[0];
2152  case GL_READ_FRAMEBUFFER: return framebufferLock_[1];
2153  }
2154  return false;
2155 }
2156 
2157 void GLState::useProgram(GLuint _program)
2158 {
2159  if (!programLock_)
2160  {
2161 #ifdef GLSTATE_AVOID_REDUNDANT_GLCALLS
2162  if (stateStack_.back().program_ != _program)
2163 #endif
2164  {
2165  glUseProgram(_program);
2166  stateStack_.back().program_ = _program;
2167  }
2168  }
2169 }
2170 
2171 void GLState::genBuffersARB(GLsizei n, GLuint* buffers) {
2172  glGenBuffers(n, buffers);
2173 }
2174 
2175 void GLState::genBuffers(GLsizei n, GLuint* buffers) {
2176  glGenBuffers(n, buffers);
2177 }
2178 
2180  GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) {
2181  glBufferData(target, size, data, usage);
2182 }
2183 
2185  GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
2186  glBufferData(target, size, data, usage);
2187 }
2188 
2189 void GLState::deleteBuffers(GLsizei n, const GLuint* buffers) {
2190  glDeleteBuffers(n, buffers);
2191 }
2192 
2193 GLvoid* GLState::mapBuffer (GLenum target, GLenum access) {
2194  return glMapBuffer(target, access);
2195 }
2196 
2197 
2198 GLboolean GLState::unmapBuffer (GLenum target) {
2199  return glUnmapBuffer(target);
2200 }
2201 
2202 
2203 //---------------------------------------------------------------------
2204 
2205 
2206 
2207 
2208 //=============================================================================
2209 } // namespace ACG
2210 //=============================================================================
void set_bounding_box(ACG::Vec3d _min, ACG::Vec3d _max)
Definition: GLState.cc:806
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:81
void frustum(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition: GLState.cc:1757
Namespace providing different geometric functions concerning angles.
std::vector< size_t > colorToStack(Vec4uc _rgba) const
converts the given color to index values on the stack
Definition: ColorStack.cc:155
void inverse_perspective(Scalar fovY, Scalar aspect, Scalar near_plane, Scalar far_plane)
multiply self from left with inverse of perspective projection matrix
static int getBufferTargetIndex(GLenum _target)
bijective map from GLenum buffer_target to [0..3], -1 if unsupported
Definition: GLState.cc:1781
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
Definition: GLState.cc:1984
void makeCurrent()
does nothing
Definition: GLState.hh:224
static const Vec4f default_specular_color
default value for specular color
Definition: GLState.hh:905
Vec3d right() const
get right-vector w.r.t. camera coordinates
Definition: GLState.cc:918
void set_shininess(float _shininess)
set specular shininess (must be in [0, 128])
Definition: GLState.cc:761
void set_specular_color(const Vec4f &_col)
set specular color
Definition: GLState.cc:737
bool initialized() const
has it been initialized?
Definition: ColorStack.hh:85
Vec4f pick_get_name_color_norm(unsigned int _idx)
same as pick_get_name_color, but the resulting color channels are normalized in [0.0, 1.0] range
Definition: GLState.cc:1077
const GLMatrixd & viewport() const
get viewport matrix
Definition: GLState.hh:796
bool color_picking() const
Is color picking active?
Definition: GLState.cc:1141
std::vector< size_t > pick_color_to_stack(Vec4uc _rgba) const
Definition: GLState.cc:1104
static void alphaFunc(GLenum _func, GLclampf _ref)
replaces glAlphaFunc, supports locking
Definition: GLState.cc:1708
Vec4uc pick_get_name_color(size_t _idx)
Definition: GLState.cc:1068
static void blendColor(GLclampf _red, GLclampf _green, GLclampf _blue, GLclampf _alpha)
replaces glBlendColor, supports locking
Definition: GLState.cc:1686
void set_ambient_color(const Vec4f &_col)
set ambient color
Definition: GLState.cc:707
static bool isClientStateLocked(GLenum _cap)
returns true, if a client state is locked
Definition: GLState.cc:1608
static void deleteBuffers(GLsizei n, const GLuint *buffers)
Definition: GLState.cc:2189
VectorT< unsigned char, 4 > Vec4uc
Definition: VectorT.hh:128
static void blendEquation(GLenum _mode)
replaces glBlendEquation, supports locking
Definition: GLState.cc:1672
void set_diffuse_color(const Vec4f &_col)
set diffuse color
Definition: GLState.cc:722
static GLuint getFramebufferRead()
get current read framebuffer of a target
Definition: GLState.cc:2082
void push_modelview_matrix()
push modelview matrix
Definition: GLState.cc:1010
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
Definition: GLState.cc:1962
static bool isStateLocked(GLenum _cap)
returns true, if a cap state is locked
Definition: GLState.cc:1557
void pick_pop_name()
pops the current name from the stack (like glPopName())
Definition: GLState.cc:1097
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:941
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.cc:822
static bool isTextureTargetLocked()
get texture target locking state
Definition: GLState.cc:1900
void lookAt(const Vec3 &eye, const Vec3 &center, const Vec3 &up)
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:370
size_t currentIndex() const
returns the current color index
Definition: ColorStack.cc:181
static void lockClientState(GLenum _cap)
locks a client state
Definition: GLState.cc:1598
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
size_t freeIndicies() const
returns maximal available index count
Definition: ColorStack.cc:169
void inverse_lookAt(const Vec3 &eye, const Vec3 &center, const Vec3 &up)
multiply self from left with inverse lookAt matrix
void set_color(const Vec4f &_col)
set color
Definition: GLState.cc:691
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
size_t pick_free_indicies() const
returns the number of still available colors during color picking
Definition: GLState.cc:1113
MultiplyFrom
Definition: GLMatrixT.hh:73
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
Definition: GLState.cc:2074
static void unlockClientState(GLenum _cap)
unlocks a client state
Definition: GLState.cc:1603
size_t pick_current_index() const
Returns the current color picking index (can be used for caching)
Definition: GLState.cc:1131
static void getBlendFuncSeparate(GLenum *_srcRGB, GLenum *_dstRGB, GLenum *_srcAlpha, GLenum *_dstAlpha)
get blend function, null-ptr safe
Definition: GLState.cc:1664
void set_overlay_color(const Vec4f &_col)
set overlay color
Definition: GLState.cc:752
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429
void set_depthFunc(const GLenum &_depth_func)
Call glDepthFunc() to actually change the depth comparison function, and store the new value in this ...
Definition: GLState.cc:948
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x&#39;,y&#39;,z&#39;,1) = M * (x,y,z,1)
void clearBuffers()
clear buffers viewport rectangle
Definition: GLState.cc:266
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
Definition: GLState.cc:1621
Scalar * data()
access to Scalar array
Definition: Vector11T.hh:195
void popIndex()
pops the current node from the stack (like glPopName)
Definition: ColorStack.cc:147
static void lockState(GLenum _cap)
locks a specific cap state, such that enable() or disable() has no effect
Definition: GLState.cc:1547
void push_projection_matrix()
push projection matrix
Definition: GLState.cc:971
void pushIndex(size_t _idx)
creates a new node the stack (like glPushName)
Definition: ColorStack.cc:139
static void drawBuffers(GLsizei _n, const GLenum *_bufs)
replaces glDrawBuffers, supports locking
Definition: GLState.cc:2048
static void getDepthRange(GLclampd *_zNearOut, GLclampd *_zFarOut)
get current depth range
Definition: GLState.cc:1773
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
Definition: GLState.cc:2089
void compatibilityProfile(bool _enableCoreProfile)
Store opengl core profile setting.
Definition: gl.cc:166
ACG::Vec3d bb_min_
Definition: GLState.hh:1025
static void lockTextureStage()
locks the current texture stage (set by setActiveTexture)
Definition: GLState.cc:1890
static void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2184
void pick_push_name(size_t _idx)
creates a new name the stack (like glPushName())
Definition: GLState.cc:1090
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:448
static void bufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage)
Definition: GLState.cc:2179
ACG::Vec3d bb_max_
Definition: GLState.hh:1025
static GLvoid * mapBuffer(GLenum target, GLenum access)
Definition: GLState.cc:2193
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
static void unlockTextureStage()
unlocks the current texture target
Definition: GLState.cc:1895
static void getNormalPointer(GLenum *_type, GLsizei *_stride, const GLvoid **_pointer)
get normal pointer, null-ptr safe
Definition: GLState.cc:1954
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:402
static GLuint getBoundBuf(GLenum _target)
get currently bound buffer
Definition: GLState.cc:1850
static GLenum getBoundTextureTarget()
get bound texture target
Definition: GLState.cc:1910
Vec3d up() const
get up-vector w.r.t. camera coordinates
Definition: GLState.cc:906
static const Vec4f default_clear_color
default value for clear color
Definition: GLState.hh:897
void setIndex(size_t _idx)
sets the current color the given index (like glLoadName)
Definition: ColorStack.cc:112
void pick_init(bool _color)
initialize name/color picking stack (like glInitNames())
Definition: GLState.cc:1043
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
Definition: GLState.cc:2033
void set_multisampling(bool _b)
Enable or disable multisampling.
Definition: GLState.cc:839
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Definition: GLState.cc:1584
static void getVertexPointer(GLint *_size, GLenum *_type, GLsizei *_stride, const GLvoid **_pointer)
get vertex pointer, null-ptr safe
Definition: GLState.cc:1932
static const Vec4f default_base_color
default value for base color
Definition: GLState.hh:899
static void genBuffers(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2175
static void unlockFramebuffer(GLenum _target)
unlock a framebuffer target
Definition: GLState.cc:2132
void inverse_ortho(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self from left with inverse orthographic projection matrix
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:651
GLState(bool _updateGL=true, bool _compatibilityProfile=true)
Default constructor.
Definition: GLState.cc:121
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
Definition: GLState.cc:640
void mult_matrix(const GLMatrixd &_m, const GLMatrixd &_inv_m, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply by a given transformation matrix
Definition: GLState.cc:614
void set_point_size(float _f)
set point size
Definition: GLState.cc:776
static void useProgram(GLuint _program)
replaces glUseProgram, supports locking
Definition: GLState.cc:2157
static bool isFramebufferLocked(GLenum _target)
get framebuffer target lock state
Definition: GLState.cc:2144
void frustum(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:425
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
static const Vec4f default_diffuse_color
default value for diffuse color
Definition: GLState.hh:903
bool pick_error() const
Definition: GLState.cc:1122
static void syncFromGL()
synchronize this class with the OpenGL state machine
Definition: GLState.cc:1244
void set_line_width(float _f)
set line width
Definition: GLState.cc:791
void set_clear_color(const Vec4f &_col)
set background color
Definition: GLState.cc:662
double fovy() const
get field of view in y direction
Definition: GLState.cc:868
static int getActiveTextureIndex()
get active texture as zero based index
Definition: GLState.hh:659
static void getTexcoordPointer(GLint *_size, GLenum *_type, GLsizei *_stride, const GLvoid **_pointer)
get color pointer, null-ptr safe
Definition: GLState.cc:1998
double aspect() const
get aspect ratio
Definition: GLState.cc:877
const Scalar * get_raw_data() const
Definition: Matrix4x4T.hh:256
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1729
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
Definition: GLState.cc:1940
static const Vec4f default_overlay_color
default value for overlay color
Definition: GLState.hh:907
void viewing_ray(int _x, int _y, Vec3d &_origin, Vec3d &_direction) const
Definition: GLState.cc:930
void inverse_frustum(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self from left with inverse of perspective projection matrix
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:848
static void getAlphaFunc(GLenum *_func, GLclampf *_ref)
get alpha function, null-ptr safe
Definition: GLState.cc:1723
Vec3d eye() const
get eye point
Definition: GLState.cc:886
static void unlockBufferTarget(GLenum _target)
unlock buffer target
Definition: GLState.cc:1840
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:334
static bool isBufferTargetLocked(GLenum _target)
get buffer target locking state
Definition: GLState.cc:1845
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Definition: GLState.cc:1918
void ortho(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self with orthographic projection matrix
static void getBlendColor(GLclampf *_col)
get blend color, not null-ptr safe, 4 element color output: RGBA
Definition: GLState.cc:1702
void perspective(Scalar fovY, Scalar aspect, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
static void setTexGenMode(GLenum _coord, GLenum _name, GLint _param)
replaces glVertexPointer, supports locking
Definition: GLState.cc:2006
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
static bool isStateEnabled(GLenum _cap)
returns true, if a cpa state is enabled
Definition: GLState.cc:1562
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
Definition: GLState.cc:1857
void pop_modelview_matrix()
pop modelview matrix
Definition: GLState.cc:1026
void identity()
setup an identity matrix
static void getTexGenMode(GLenum _coord, GLenum _name, GLint *_param)
replaces glVertexPointer, supports locking
Definition: GLState.cc:2018
void pop_projection_matrix()
pop projection matrix
Definition: GLState.cc:989
static void cullFace(GLenum _mode)
replaces glCullFace, supports locking
Definition: GLState.cc:1743
void scale(double _s)
scale by (_s, _s, _s)
Definition: GLState.hh:750
bool setMaximumIndex(size_t _idx)
sets the maximum index number used in current node
Definition: ColorStack.cc:98
static GLuint getBoundTextureBuffer()
get bound texture
Definition: GLState.cc:1905
static const Vec4f default_ambient_color
default value for ambient color
Definition: GLState.hh:901
bool error() const
Did an error occur during picking.
Definition: ColorStack.hh:109
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
Vec4uc getIndexColor(size_t _idx)
gets the color instead of setting it directly
Definition: ColorStack.cc:123
static void getColorPointer(GLint *_size, GLenum *_type, GLsizei *_stride, const GLvoid **_pointer)
get color pointer, null-ptr safe
Definition: GLState.cc:1976
static void genBuffersARB(GLsizei n, GLuint *buffers)
Definition: GLState.cc:2171
static GLboolean unmapBuffer(GLenum target)
Definition: GLState.cc:2198
void initialize()
initialize all state variables (called by constructor)
Definition: GLState.cc:162
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:728
static bool isClientStateEnabled(GLenum _cap)
returns true, if a client state is enabled
Definition: GLState.cc:1613
static void lockFramebuffer(GLenum _target)
lock a framebuffer target
Definition: GLState.cc:2120
static void lockBufferTarget(GLenum _target)
lock buffer target
Definition: GLState.cc:1835
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
void set_base_color(const Vec4f &_col)
set base color (used when lighting is off)
Definition: GLState.cc:677
void setState()
set the whole stored gl state
Definition: GLState.cc:209
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
Definition: GLState.cc:1570
void get_bounding_box(ACG::Vec3d &_min, ACG::Vec3d &_max)
Definition: GLState.cc:813
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:134
static void unlockState(GLenum _cap)
unlocks a specific cap state
Definition: GLState.cc:1552
void initialize(ACG::GLState *)
init (takes current GL context/ like glInitNames (); glPushName (0))
Definition: ColorStack.cc:84
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
Definition: GLState.cc:515
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void set_projection(const GLMatrixd &_m)
set projection
Definition: GLState.hh:691
static const float default_shininess
default value for shininess
Definition: GLState.hh:909
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
Definition: GLState.cc:1051
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
Definition: GLState.cc:1061
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition: GLState.cc:1868