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