Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Rendering/vtkOpenGLStateCache.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    $RCSfile: vtkOpenGLStateCache.h,v $
00005   Language:  C++
00006 
00007   Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen 
00008   All rights reserved.
00009   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00010 
00011      This software is distributed WITHOUT ANY WARRANTY; without even 
00012      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00013      PURPOSE.  See the above copyright notice for more information.
00014 
00015 =========================================================================*/
00016 //*************************************************************************
00017 /*
00018   GlStateCache_Cache============================================
00019   This simply checks for redundancies in state-change requests and
00020   only calls the real OpenGL call if there has in fact been a change.
00021   This cannot, however, fix problems with the ordering of calls.
00022 */
00023 
00024 #ifndef VTK_IMPLEMENT_MESA_CXX
00025 #if defined(__APPLE__) && (defined(VTK_USE_CARBON) || defined(VTK_USE_COCOA))
00026 #include <OpenGL/gl.h>
00027 #else
00028 #include <GL/gl.h>
00029 #endif
00030 #endif
00031 
00032 #define vtkOpenGLCall_glEnable vtkOpenGLStateCache::CurrentGLCache->glEnable
00033 #define vtkOpenGLCall_glDisable vtkOpenGLStateCache::CurrentGLCache->glDisable
00034 #define vtkOpenGLCall_glAlphaFunc vtkOpenGLStateCache::CurrentGLCache->glAlphaFunc
00035 #define vtkOpenGLCall_glBlendFunc vtkOpenGLStateCache::CurrentGLCache->glBlendFunc
00036 #define vtkOpenGLCall_glDepthFunc vtkOpenGLStateCache::CurrentGLCache->glDepthFunc
00037 #define vtkOpenGLCall_glTexEnvf vtkOpenGLStateCache::CurrentGLCache->glTexEnvf
00038 #define vtkOpenGLCall_glLightModeli vtkOpenGLStateCache::CurrentGLCache->glLightModeli
00039 #define vtkOpenGLCall_glLightModelfv vtkOpenGLStateCache::CurrentGLCache->glLightMOdelfv
00040 #define vtkOpenGLCall_glLightfv vtkOpenGLStateCache::CurrentGLCache->glLightfv
00041 #define vtkOpenGLCall_glLightf vtkOpenGLStateCache::CurrentGLCache->glLightf
00042 #define vtkOpenGLCall_glLighti vtkOpenGLStateCache::CurrentGLCache->glLighti
00043 #define vtkOpenGLCall_glMaterialfv vtkOpenGLStateCache::CurrentGLCache->glMaterialfv
00044 #define vtkOpenGLCall_glShadeModel vtkOpenGLStateCache::CurrentGLCache->glShadeModel
00045 #define vtkOpenGLCall_glClearColor vtkOpenGLStateCache::CurrentGLCache->glClearColor
00046 #define vtkOpenGLCall_glClearDepth vtkOpenGLStateCache::CurrentGLCache->glClearDepth
00047 #define vtkOpenGLCall_glDepthMask vtkOpenGLStateCache::CurrentGLCache->glDepthMask
00048 #define vtkOpenGLCall_glCullFace vtkOpenGLStateCache::CurrentGLCache->glCullFace
00049 #define vtkOpenGLCall_glClear vtkOpenGLStateCache::CurrentGLCache->glClear
00050 #define vtkOpenGLCall_glDrawBuffer vtkOpenGLStateCache::CurrentGLCache->glDrawBuffer
00051 #define vtkOpenGLCall_glMatrixMode vtkOpenGLStateCache::CurrentGLCache->glMatrixMode
00052 #define vtkOpenGLCall_glViewport vtkOpenGLStateCache::CurrentGLCache->glViewport
00053 #define vtkOpenGLCall_glScissor vtkOpenGLStateCache::CurrentGLCache->glScissor
00054 #define vtkOpenGLCall_glClipPlane vtkOpenGLStateCache::CurrentGLCache->glClipPlane
00055 #define vtkOpenGLCall_glColorMaterial vtkOpenGLStateCache::CurrentGLCache->glColorMaterial
00056 #define vtkOpenGLCall_glPointSize vtkOpenGLStateCache::CurrentGLCache->glPointSize
00057 #define vtkOpenGLCall_glLineWidth vtkOpenGLStateCache::CurrentGLCache->glLineWidth
00058 #define vtkOpenGLCall_glLineStipple vtkOpenGLStateCache::CurrentGLCache->glLineStipple
00059 #define vtkOpenGLCall_glDepthRange vtkOpenGLStateCache::CurrentGLCache->glDepthRange
00060 #define vtkOpenGLCall_glPolygonOffset vtkOpenGLStateCache::CurrentGLCache->glPolygonOffset
00061 
00062 #define vtkOpenGLCall_glPushMatrix glPushMatrix
00063 #define vtkOpenGLCall_glPopMatrix glPopMatrix
00064 #define vtkOpenGLCall_glMultMatrixd glMultMatrixd
00065 #define vtkOpenGLCall_glLoadMatrixd glLoadMatrixd
00066 #define vtkOpenGLCall_glLoadIdentity glLoadIdentity
00067 #define vtkOpenGLCall_glSelectBuffer glSelectBuffer
00068 #define vtkOpenGLCall_glRenderMode glRenderMode
00069 #define vtkOpenGLCall_glInitNames glInitNames
00070 #define vtkOpenGLCall_glPushName glPushName
00071 #define vtkOpenGLCall_glLoadName glLoadName
00072 #define vtkOpenGLCall_glGetIntegerv glGetIntegerv
00073 #define vtkOpenGLCall_glIsTexture glIsTexture
00074 #define vtkOpenGLCall_glDeleteTextures glDeleteTexture
00075 #define vtkOpenGLCall_glGenTextures glGenTextures
00076 #define vtkOpenGLCall_glBindTexture glBindTexture
00077 #define vtkOpenGLCall_glTexParameterf glTextParameterf
00078 #define vtkOpenGLCall_glTexCoord2fv glTexCoord2fv
00079 #define vtkOpenGLCall_glVertex3fv glVertex3fv
00080 #define vtkOpenGLCall_glNormal3fv glNormal3fv
00081 #define vtkOpenGLCall_glColor3f glColor3f
00082 #define vtkOpenGLCall_glColor4ubv glColor4ubv
00083 #define vtkOpenGLCall_glColor4fv glColor4fv
00084 #define vtkOpenGLCall_glBegin glBegin
00085 #define vtkOpenGLCall_glEnd glEnd
00086 #define vtkOpenGLCall_glTexImage2D glTextImage2D
00087 #define vtkOpenGLCall_glDeleteLists glDeleteLists
00088 #define vtkOpenGLCall_glIsList glIsList
00089 #define vtkOpenGLCall_glGenLists glGenLists
00090 #define vtkOpenGLCall_glCallList glCallList
00091 #define vtkOpenGLCall_glReadBuffer glReadBuffer
00092 #define vtkOpenGLCall_glPixelStorei glPixelStorei
00093 #define vtkOpenGLCall_glReadPixels glReadPixels
00094 #define vtkOpenGLCall_glRasterPos3f glRasterPos3f
00095 #define vtkOpenGLCall_glDrawPixels glDrawPixels
00096 #define vtkOpenGLCall_glRasterPos2f glRasterPos2f
00097 #define vtkOpenGLCall_glNewList glNewList
00098 #define vtkOpenGLCall_glEndList glEndList
00099 
00100 class vtkOpenGLStateCache  
00101 {
00102 public:
00103   static vtkOpenGLStateCache *CurrentGLCache; // recursive definition
00104 
00105   vtkOpenGLStateCache(); // set all members to initial values
00106   ~vtkOpenGLStateCache(); // delete any dynamic objects
00107   void Initialize();
00108 
00109   // GL_BLEND         = 0x0BE2
00110   // GL_POINT_SMOOTH  = 0x0B10
00111   // GL_LINE_SMOOTH   = 0x0B20
00112   // GL_POLYGON_SMOOTH= 0x0B41
00113   // GL_DEPTH_TEST    = 0x0B71
00114   // GL_ALPHA_TEST    = 0x0BC0
00115   // GL_TEXTURE_2D    = 0x0DE1
00116   // GL_CLIP_PLANE0+i = 0x3000
00117   // GL_LIGHTING      = 0x0B50
00118   // GL_COLOR_MATERIAL= 0x0B57
00119   // GL_NORMALIZE     = 0x0BA1
00120   // GL_CULL_FACE     = 0x0B44
00121   // GL_SCISSOR_TEST  = 0x0C11
00122   // GL_POLYGON_OFFSET_FILL = 0x8037
00123   // GL_LINE_STIPPLE  = 0x0B24
00124   // GL_LIGHT+i       = 0x4000
00125   char Enable_buckets[0xDE1-0xB10+1]; // 0xB10-0xDE1
00126   char Enable_GL_LIGHT_buckets[8]; // 0x4000 + i (0<i<8)
00127   char Enable_GL_CLIP_PLANE_buckets[8]; // 0x8000 + i (0<i<8)
00128   /* Need to have special handling for disabling and enabling the 
00129      GL_LIGHT's because they are disabling too many lights!
00130      need to propagate in how many lights are actually *on*
00131      and only apply the op to them.
00132    */
00133   inline void glEnable(GLenum e) 
00134     {
00135       register int ex;
00136       register char *val=0;
00137       if(e&0x4000)
00138         {
00139         ex=e-0x4000;
00140         if(ex<8) {val=Enable_GL_LIGHT_buckets+ex; }
00141         }    
00142       else 
00143         {
00144         if(e&0x8000)
00145           {
00146           ex=e-0x8000;
00147           if(ex<8) { val=Enable_GL_CLIP_PLANE_buckets+ex; }
00148           }
00149         else 
00150           {
00151           if(e>=0xB10 && e<=0xDE1)
00152             {
00153             ex=e-0xB10;
00154             val=Enable_buckets+ex;
00155             }
00156           else
00157             {
00158             printf("Error: glEnable of 0x%X failed\n",e);
00159             }
00160           }
00161         }
00162       if(val && *val!=1)
00163         {
00164         *val=1;
00165         ::glEnable(e);
00166         }
00167     }
00168   inline void glDisable(GLenum e) 
00169     {
00170       register int ex;
00171       register char *val=0;
00172       if(e&0x4000)
00173         {
00174         ex=e-0x4000;
00175         if(ex<8) { val=Enable_GL_LIGHT_buckets+ex; }
00176         }    
00177       else
00178         {
00179         if(e&0x8000)
00180           {
00181           ex=e-0x8000;
00182           if(ex<8) { val=Enable_GL_CLIP_PLANE_buckets+ex; }
00183           }
00184         else 
00185           {
00186           if(e>=0xB10 && e<=0xDE1)
00187             {
00188             ex=e-0xB10;
00189             val=Enable_buckets+ex;
00190             }
00191           else
00192             {
00193             printf("Error: glEnable of 0x%X failed\n",e);
00194             }
00195           }
00196         }
00197       if(val && *val!=0)
00198         {
00199         *val=0;
00200         ::glDisable(e);
00201         }
00202     }
00203   
00204   // GL_GREATER = 0x0204, (GLclampf) 0
00205   GLclampf AlphaFunc_bucket;
00206   inline void glAlphaFunc(GLenum e,GLclampf cf) 
00207     {
00208       if(e==GL_GREATER && cf!=AlphaFunc_bucket)
00209         {
00210         AlphaFunc_bucket=cf;
00211         ::glAlphaFunc(e,cf);
00212         }
00213     }
00214   
00215   // GL_SRC_ALPHA = 0x0302, GL_ONE_MINUS_SRC_ALPHA = 0x0303
00216   GLenum BlendFunc_bucket; // multibucket if any other blendfunc is used
00217   inline void glBlendFunc(GLenum e,GLenum e1) 
00218     {
00219       if(e==GL_SRC_ALPHA && e1!=BlendFunc_bucket)
00220         {
00221         BlendFunc_bucket=e1;
00222         ::glBlendFunc(e,e1);
00223         }
00224     }
00225   
00226   // GL_GREATER = 0x0204
00227   // GL_LESS    = 0x0201
00228   // GL_LEQUAL  = 0x0203
00229   GLenum DepthFunc_bucket;
00230   inline void glDepthFunc(GLenum e) 
00231     {
00232       if(e!=DepthFunc_bucket)
00233         {
00234         DepthFunc_bucket=e;
00235         ::glDepthFunc(e);
00236         }
00237     }
00238   
00239   // GL_TEXTURE_ENV = 0x2300, GL_TEXTURE_ENV_MODE = 0x2200, GL_MODULATE = 0x2100
00240   GLfloat TexEnvf_MODE_bucket; // total kludge right now
00241   inline void glTexEnvf(GLenum e,GLenum e1,GLfloat f) 
00242     {
00243       if(e==GL_TEXTURE_ENV && e1==GL_TEXTURE_ENV_MODE)
00244         {
00245         if(f!=TexEnvf_MODE_bucket)
00246           {
00247           TexEnvf_MODE_bucket=f;
00248           ::glTexEnvf(e,e1,f);
00249           }
00250         }
00251     }
00252   
00253   // GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE/FALSE
00254   // GL_LIGHT_MODEL_TWO_SIDE, 0
00255   GLint LightModeli_LIGHT_MODEL_TWO_SIDE_bucket; // shoudld check other modes
00256   inline void glLightModeli(GLenum e,GLint i) 
00257     {
00258       if(e==GL_LIGHT_MODEL_TWO_SIDE && i!=LightModeli_LIGHT_MODEL_TWO_SIDE_bucket){
00259       LightModeli_LIGHT_MODEL_TWO_SIDE_bucket=i;
00260       ::glLightModeli(e,i);
00261       }
00262     }
00263   
00264   // GL_LIGHT_MODEL_AMBIENT, fvect(amb color), A=1.0
00265   // GL_LIGHT_MODEL_AMBIENT = 0x0B53
00266   GLfloat LightModelfv_LIGHT_MODEL_AMBIENT_bucket[3];
00267   inline void glLightModelfv(GLenum e,GLfloat *fv) 
00268     {
00269       if(e==GL_LIGHT_MODEL_AMBIENT && 
00270          (fv[0]!=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[0] ||
00271           fv[1]!=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[1] ||
00272           fv[2]!=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[2])){
00273       fv[0]=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[0];
00274       fv[1]=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[1];
00275       fv[2]=LightModelfv_LIGHT_MODEL_AMBIENT_bucket[2]; 
00276       ::glLightModelfv(e,fv);
00277       }
00278     }
00279   
00280   // light=GL_LIGHT index
00281   // pname= lighting type
00282   //   GL_DIFFUSE        = 0x1201
00283   //   GL_SPECULAR       = 0x1202
00284   //   GL_POSITION       = 0x1203
00285   //   GL_SPOT_DIRECTION = 0x1204
00286   GLfloat Lightfv_buckets[8*4*8];
00287   inline void glLightfv( GLenum light, GLenum pname, const GLfloat *params) 
00288     {
00289       register GLfloat *val = Lightfv_buckets + ((((int)(pname-0x1201))|((int)(light-GL_LIGHT0)<<3))<<2);
00290       if(params[0]!=val[0] ||
00291          params[1]!=val[1] ||
00292          params[2]!=val[2] ||
00293          params[3]!=val[3])
00294         {
00295         val[0]=params[0];
00296         val[1]=params[1];
00297         val[2]=params[2];
00298         val[3]=params[3];
00299         ::glLightfv(light,pname,params);
00300         }
00301     } 
00302   
00303   // light=GL_LIGHT index
00304   // pname= lighting parameter
00305   //   GL_SPOT_EXPONENT        = 0x1205
00306   //   GL_SPOT_CUTOFF          = 0x1206
00307   //   GL_CONSTANT_ATTENUATION = 0x1207
00308   //   GL_LINEAR_ATTENUATION   = 0x1208
00309   //   GL_QUADRATIC_ATTENUATION= 0x1209
00310   GLfloat Lightf_buckets[8*8];
00311   GLint Lighti_SPOT_CUTOFF_buckets[8];
00312   inline void glLightf( GLenum light, GLenum pname, GLfloat f){
00313     register GLfloat *val=Lightf_buckets+(((int)(light-GL_LIGHT0)<<3)|((int)(pname-0x1205)));
00314     if(val[0]!=f)
00315       {
00316       val[0]=f;
00317       ::glLightf(light,pname,f);
00318       if(pname==GL_SPOT_CUTOFF) // invalidate integer spot cutoff
00319         Lighti_SPOT_CUTOFF_buckets[light-GL_LIGHT0]=-1;
00320       }
00321   }
00322   
00323   // light=GL_LIGHT index
00324   // pname=lighting parameter
00325   //   GL_SPOT_CUTOFF = 0x1206
00326   // needs to invalidate the float light cutoff
00327   inline void glLighti( GLenum light, GLenum pname, GLint f) 
00328     {
00329       if(pname==GL_SPOT_CUTOFF && f!=Lighti_SPOT_CUTOFF_buckets[light-GL_LIGHT0]){
00330       Lighti_SPOT_CUTOFF_buckets[light-GL_LIGHT0]=f;
00331       ::glLighti(light,pname,f);
00332       // need to invalidate the float cutoff
00333       Lightf_buckets[((int)(light-GL_LIGHT0)<<3)|0x02] = -1.0f;
00334       }
00335     }  
00336   
00337   // Face, GL_AMBIENT, float Info[4] 
00338   //   GL_FRONT          = 0x0404  
00339   //   GL_BACK           = 0x0405
00340   //   GL_FRONT_AND_BACK = 0x0408
00341   // GL_AMBIENT   = 0x1200
00342   // GL_DIFFUSE   = 0x1201
00343   // GL_SPECULAR  = 0x1202
00344   // GL_EMISSION  = 0x1600
00345   // GL_SHININESS = 0x1601
00346   // GL_AMBIENT_AND_DIFFUSE = 0x1602
00347   // GL_COLOR_INDEXES       = 0x1603
00348   GLfloat Materialfv_buckets[8*8*4]; 
00349   inline void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params ) 
00350     {
00351       register int idx;
00352       register GLfloat *val;
00353       if(pname>=0x1600) 
00354         {
00355         idx=pname-0x1600 + 4; // put it just past the 120x buckets
00356         }
00357       else 
00358         {
00359         idx=pname-0x1200;
00360         }
00361       // FRONT/BACK and FRONT_AND_BACK should do both.
00362       // or perhaps should be a separate state key?
00363       // For now, we will treat FRONT_AND_BACK independently
00364       // because from a practical standpoint, that's how 
00365       // it tends to get used.
00366       val = Materialfv_buckets + ((((face-0x0404)<<3)|idx)<<2);
00367       if(val[0]!=params[0] ||
00368          val[1]!=params[1] || 
00369          val[2]!=params[2] ||
00370          val[3]!=params[3])
00371         {
00372         val[0]=params[0];
00373         val[1]=params[1];
00374         val[2]=params[2];
00375         val[3]=params[3];
00376         ::glMaterialfv(face,pname,params);
00377         }
00378     }
00379 
00380   /*
00381     a=0;
00382     a|=(val[0]^params[0])
00383     a|=(val[1]^params[1])
00384     a|=(val[2]^params[2])
00385     a|=(val[3]^params[3])
00386    */
00387   // GL_FLAT   = 0x1D00
00388   // GL_SMOOTH = 0x1D01
00389   GLenum ShadeModel_bucket; 
00390   inline void glShadeModel(GLenum e)
00391     {
00392       if(ShadeModel_bucket!=e)
00393         {
00394         ShadeModel_bucket=e;
00395         ::glShadeModel(e);
00396         }
00397     }
00398   
00399   GLclampf ClearColor_buckets[4];
00400   inline void glClearColor(GLclampf r,GLclampf g,GLclampf b,GLclampf a)
00401     {
00402       register GLclampf *c=ClearColor_buckets;
00403       if(c[0]!=r ||
00404          c[1]!=g ||
00405          c[2]!=b ||
00406          c[3]!=a)
00407         {
00408         c[0]=r;
00409         c[1]=g;
00410         c[2]=b;
00411         c[3]=a;
00412         ::glClearColor(r,g,b,a);
00413         }
00414     }
00415   
00416   GLclampd ClearDepth_bucket;
00417   inline void glClearDepth(GLclampd d) 
00418     { 
00419       if(d!=ClearDepth_bucket)
00420         {
00421         ClearDepth_bucket=d;
00422         ::glClearDepth(d);
00423         }
00424     }
00425   
00426   GLclampf DepthMask_bucket;
00427   inline void glDepthMask(GLenum e)
00428     {
00429       if(DepthMask_bucket!=e)
00430         {
00431         DepthMask_bucket=e;
00432         ::glDepthMask(e);
00433         }
00434     }
00435   
00436   // GL_FRONT = 0x0404
00437   // GL_BACK  = 0x0405
00438   GLenum CullFace_bucket;
00439   inline void glCullFace(GLenum e)
00440     {
00441       if(CullFace_bucket!=e)
00442         {
00443         CullFace_bucket=e;
00444         ::glCullFace(e);
00445         }
00446     }
00447   
00448   // well, lets go ahead and let it clear when it wants to
00449   inline void glClear(GLbitfield b) { ::glClear(b);}
00450   // GL_BACK_LEFT  = 0x0402
00451   // GL_BACK_RIGHT = 0x0403
00452   // GL_FRONT      = 0x0404
00453   // GL_BACK       = 0x0405
00454   GLenum DrawBuffer_bucket;
00455   inline void glDrawBuffer(GLenum e) {
00456     if(e!=DrawBuffer_bucket){
00457       DrawBuffer_bucket=e;
00458       ::glDrawBuffer(e);
00459     }
00460   }
00461   //============Matrix Ops (behave different for deferred ops)===
00462   // GL_MODELVIEW=0x1700
00463   // GL_PROJECTION=0x1701
00464   GLenum  MatrixMode_bucket;
00465   inline void glMatrixMode(GLenum e) {
00466     if(e!=MatrixMode_bucket){
00467       MatrixMode_bucket=e;
00468       ::glMatrixMode(e);
00469     }
00470   }
00471 
00472   GLint Viewport_bucket[4];
00473   inline void glViewport(GLint llx,GLint lly,GLint u,GLint v){
00474     register GLint *val=Viewport_bucket;
00475     if(val[0]!=llx ||
00476        val[1]!=lly ||
00477        val[2]!=u ||
00478        val[3]!=v){
00479       val[0]=llx;
00480       val[1]=lly;
00481       val[2]=u;
00482       val[3]=v;
00483       ::glViewport(llx,lly,u,v);
00484     }
00485   }
00486   // only needs to be called if scissor changes (and it usually won't)
00487   GLint Scissor_bucket[4];
00488   inline void glScissor(GLint llx,GLint lly,GLint u,GLint v){
00489     register GLint *val=Scissor_bucket;
00490     if(val[0]!=llx ||
00491        val[1]!=lly ||
00492        val[2]!=u ||
00493        val[3]!=v){
00494       val[0]=llx;
00495       val[1]=lly;
00496       val[2]=u;
00497       val[3]=v;
00498       ::glScissor(llx,lly,u,v);
00499     }
00500   }
00501   
00502   // what is the order of the clip plane eqn???
00503   // GL_CLIP_PLANE0 = 0x3000
00504   GLdouble ClipPlane_bucket[4*GL_MAX_CLIP_PLANES];
00505   inline void glClipPlane(GLenum e,const GLdouble *eqn){
00506     register GLdouble *val=ClipPlane_bucket + ((e-0x3000)<<2);
00507     if(val[0]!=eqn[0] ||
00508        val[1]!=eqn[1] ||
00509        val[2]!=eqn[2] ||
00510        val[3]!=eqn[3]){
00511       val[0]=eqn[0];
00512       val[1]=eqn[1];
00513       val[2]=eqn[2];
00514       val[3]=eqn[3];
00515       ::glClipPlane(e,eqn);
00516     }
00517   }
00518 
00519   // face= 
00520   //   GL_FRONT          = 0x0404  
00521   //   GL_BACK           = 0x0405
00522   //   GL_FRONT_AND_BACK = 0x0408
00523   GLenum ColorMaterial_bucket[8];
00524   inline void glColorMaterial(GLenum face,GLenum mode ){
00525     register GLenum *val= ColorMaterial_bucket + (face-0x0404);
00526     if(*val!=mode){
00527       *val=mode;
00528       ::glColorMaterial(face,mode);
00529     }
00530   }
00531   GLfloat PointSize_bucket;
00532   inline void glPointSize(GLfloat f) {
00533     if(f!=PointSize_bucket){
00534       PointSize_bucket=f;
00535       ::glPointSize(f);
00536     }
00537   }
00538   GLfloat LineWidth_bucket;
00539   inline void glLineWidth(GLfloat f){
00540     if(f!=LineWidth_bucket){
00541       LineWidth_bucket=f;
00542       ::glPointSize(f);
00543     }
00544   }
00545   GLint LineStipple_FACTOR_bucket;
00546   GLushort LineStipple_PATTERN_bucket;
00547   inline void glLineStipple(GLint factor, GLushort pattern )
00548     {
00549       if(factor!=LineStipple_FACTOR_bucket ||
00550          pattern!=LineStipple_PATTERN_bucket)
00551         {
00552         LineStipple_FACTOR_bucket=factor;
00553         LineStipple_PATTERN_bucket=pattern;
00554         ::glLineStipple(factor,pattern);
00555         }
00556     }
00557 
00558   GLclampd DepthRange_NEAR_bucket;
00559   GLclampd DepthRange_FAR_bucket;
00560   inline void glDepthRange(GLclampd nearval,GLclampd farval )
00561     {
00562       if(DepthRange_NEAR_bucket!=nearval ||
00563          DepthRange_FAR_bucket!=farval)
00564         {
00565         DepthRange_NEAR_bucket=nearval;
00566         DepthRange_FAR_bucket=farval;
00567         ::glDepthRange(nearval,farval);
00568         }
00569     }
00570   
00571 #ifdef GL_VERSION_1_1
00572   // enable GL_POLYGON_OFFSET_FILL = 0x8037
00573   GLfloat PolygonOffset_bucket[2];
00574   inline void glPolygonOffset( GLfloat f,GLfloat u) {
00575     if(PolygonOffset_bucket[0]!=f ||
00576        PolygonOffset_bucket[1]!=u){
00577       PolygonOffset_bucket[0]=f;
00578       PolygonOffset_bucket[1]=u;
00579       ::glPolygonOffset(f,u);
00580     }
00581   }
00582 #endif
00583 };
00584 
00585 
00586 //#ifdef vtkOpenGLStateCache_Cache
00587 //#undef vtkOpenGLStateCache_Cache
00588 //#endif