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