CrystalSpace

Public API Reference

csplugincommon/opengl/glstates.h
Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2002 by Anders Stenberg
00003     Written by Anders Stenberg
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 #ifndef __CS_GLSTATES_H__
00021 #define __CS_GLSTATES_H__
00022 
00027 #if defined(CS_OPENGL_PATH)
00028 #include CS_HEADER_GLOBAL(CS_OPENGL_PATH,gl.h)
00029 #else
00030 #include <GL/gl.h>
00031 #endif
00032 
00033 #include "csextern_gl.h"
00034 #include "csgeom/math.h"
00035 #include "glextmanager.h"
00036 
00040 // Set to 'true' to force state changing commands. For debugging.
00041 #define FORCE_STATE_CHANGE                        false/*true*/
00042 
00043 #define DECLARE_CACHED_BOOL(name) \
00044   bool enabled_##name;
00045 
00046 #define IMPLEMENT_CACHED_BOOL(name) \
00047   void Enable_##name () \
00048   { \
00049     if (!currentContext->enabled_##name || FORCE_STATE_CHANGE) \
00050     { \
00051       currentContext->enabled_##name = true;  \
00052       glEnable (name); \
00053     } \
00054   } \
00055   void Disable_##name () \
00056   { \
00057     if (currentContext->enabled_##name || FORCE_STATE_CHANGE) { \
00058       currentContext->enabled_##name = false;  \
00059       glDisable (name); \
00060     } \
00061   } \
00062   bool IsEnabled_##name () const \
00063   { \
00064     return currentContext->enabled_##name; \
00065   }
00066 
00067 #define DECLARE_CACHED_BOOL_IMAGEUNIT(name) \
00068   AutoArray<bool> enabled_##name;
00069 
00070 #define IMPLEMENT_CACHED_BOOL_IMAGEUNIT(name)                       \
00071   void Enable_##name ()                                                       \
00072   {                                                                           \
00073     const int currentUnit = currentContext->currentImageUnit;                 \
00074     if (!currentContext->enabled_##name[currentUnit] || FORCE_STATE_CHANGE)   \
00075     {                                                                         \
00076       ActivateImageUnit ();                                                   \
00077       currentContext->enabled_##name[currentUnit] = true;                     \
00078       glEnable (name);                                                        \
00079     }                                                                         \
00080   }                                                                           \
00081   void Disable_##name ()                                                      \
00082   {                                                                           \
00083     const int currentUnit = currentContext->currentImageUnit;                 \
00084     if (currentContext->enabled_##name[currentUnit] || FORCE_STATE_CHANGE)    \
00085     {                                                                         \
00086       ActivateImageUnit ();                                                   \
00087       currentContext->enabled_##name[currentUnit] = false;                    \
00088       glDisable (name);                                                       \
00089     }                                                                         \
00090   }                                                                           \
00091   bool IsEnabled_##name () const                                              \
00092   {                                                                           \
00093     const int currentUnit = currentContext->currentImageUnit;                 \
00094     return currentContext->enabled_##name[currentUnit];                       \
00095   }
00096 
00097 #define DECLARE_CACHED_PARAMETER_1(func, name, type1, param1) \
00098   type1 parameter_##param1;
00099 
00100 #define IMPLEMENT_CACHED_PARAMETER_1(func, name, type1, param1) \
00101   void Set##name (type1 param1, bool forced = false) \
00102   { \
00103     if (forced || (param1 != currentContext->parameter_##param1) || FORCE_STATE_CHANGE) \
00104     { \
00105       currentContext->parameter_##param1 = param1;  \
00106       func (param1); \
00107     } \
00108   } \
00109   void Get##name (type1 & param1) const\
00110   { \
00111     param1 = currentContext->parameter_##param1;  \
00112   }
00113 
00114 #define DECLARE_CACHED_PARAMETER_2(func, name, type1, param1, type2, param2) \
00115   type1 parameter_##param1; \
00116   type2 parameter_##param2;
00117 
00118 #define IMPLEMENT_CACHED_PARAMETER_2(func, name, type1, param1, type2, param2) \
00119   void Set##name (type1 param1, type2 param2, bool forced = false) \
00120   { \
00121     if (forced || (param1 != currentContext->parameter_##param1) || \
00122         (param2 != currentContext->parameter_##param2) || FORCE_STATE_CHANGE) \
00123     { \
00124       currentContext->parameter_##param1 = param1;  \
00125       currentContext->parameter_##param2 = param2;  \
00126       func (param1, param2); \
00127     } \
00128   } \
00129   void Get##name (type1 & param1, type2 & param2) const\
00130   { \
00131     param1 = currentContext->parameter_##param1;  \
00132     param2 = currentContext->parameter_##param2;  \
00133   }
00134 
00135 #define DECLARE_CACHED_PARAMETER_3(func, name, type1, param1, type2, param2, type3, param3) \
00136   type1 parameter_##param1; \
00137   type2 parameter_##param2; \
00138   type3 parameter_##param3;
00139 
00140 #define IMPLEMENT_CACHED_PARAMETER_3(func, name, type1, param1, type2, param2, type3, param3) \
00141   void Set##name (type1 param1, type2 param2, type3 param3, bool forced = false) \
00142   { \
00143     if (forced || (param1 != currentContext->parameter_##param1) \
00144         || (param2 != currentContext->parameter_##param2) \
00145         || (param3 != currentContext->parameter_##param3) || FORCE_STATE_CHANGE) \
00146     { \
00147       currentContext->parameter_##param1 = param1;  \
00148       currentContext->parameter_##param2 = param2;  \
00149       currentContext->parameter_##param3 = param3;  \
00150       func (param1, param2, param3); \
00151     } \
00152   } \
00153   void Get##name (type1 &param1, type2 & param2, type3 & param3) const\
00154   { \
00155     param1 = currentContext->parameter_##param1;  \
00156     param2 = currentContext->parameter_##param2;  \
00157     param3 = currentContext->parameter_##param3;  \
00158   }
00159 
00160 #define DECLARE_CACHED_PARAMETER_3_BUF(func, name, type1, param1, type2, param2, type3, param3, vbo) \
00161   type1 parameter_##param1; \
00162   type2 parameter_##param2; \
00163   type3 parameter_##param3; \
00164   GLuint parameter_##vbo;
00165 
00166 #define IMPLEMENT_CACHED_PARAMETER_3_BUF(func, name, type1, param1, type2, param2, type3, param3, vbo) \
00167   void Set##name (type1 param1, type2 param2, type3 param3, bool forced = false) \
00168   { \
00169     if (forced || (param1 != currentContext->parameter_##param1) \
00170         || (param2 != currentContext->parameter_##param2) \
00171         || (param3 != currentContext->parameter_##param3) \
00172         || (currentContext->currentBufferID[csGLStateCacheContext::boElementArray] \
00173           != currentContext->parameter_##vbo) \
00174         || FORCE_STATE_CHANGE) \
00175     { \
00176       currentContext->parameter_##param1 = param1;  \
00177       currentContext->parameter_##param2 = param2;  \
00178       currentContext->parameter_##param3 = param3;  \
00179       if (extmgr->CS_GL_ARB_vertex_buffer_object)                             \
00180       {                                                                       \
00181         ApplyBufferBinding (csGLStateCacheContext::boElementArray);           \
00182         currentContext->parameter_##vbo                                       \
00183          = currentContext->currentBufferID[csGLStateCacheContext::boElementArray];\
00184       }                                                                       \
00185       func (param1, param2, param3); \
00186     } \
00187   } \
00188   void Get##name (type1 &param1, type2 & param2, type3 & param3) const\
00189   { \
00190     param1 = currentContext->parameter_##param1;  \
00191     param2 = currentContext->parameter_##param2;  \
00192     param3 = currentContext->parameter_##param3;  \
00193   }
00194 
00195 #define DECLARE_CACHED_PARAMETER_4(func, name, type1, param1, \
00196   type2, param2, type3, param3, type4, param4) \
00197   type1 parameter_##param1; \
00198   type2 parameter_##param2; \
00199   type3 parameter_##param3; \
00200   type4 parameter_##param4;
00201 
00202 #define IMPLEMENT_CACHED_PARAMETER_4(func, name, type1, param1, \
00203     type2, param2, type3, param3, type4, param4) \
00204   void Set##name (type1 param1, type2 param2, type3 param3, type4 param4, \
00205     bool forced = false) \
00206   { \
00207     if (forced || (param1 != currentContext->parameter_##param1) || \
00208       (param2 != currentContext->parameter_##param2) || \
00209       (param3 != currentContext->parameter_##param3) || \
00210       (param4 != currentContext->parameter_##param4) || FORCE_STATE_CHANGE) \
00211     { \
00212       currentContext->parameter_##param1 = param1;  \
00213       currentContext->parameter_##param2 = param2;  \
00214       currentContext->parameter_##param3 = param3;  \
00215       currentContext->parameter_##param4 = param4;  \
00216       func (param1, param2, param3, param4); \
00217     } \
00218   } \
00219   void Get##name (type1 &param1, type2 & param2, type3 & param3, type4& param4) const\
00220   { \
00221     param1 = currentContext->parameter_##param1;  \
00222     param2 = currentContext->parameter_##param2;  \
00223     param3 = currentContext->parameter_##param3;  \
00224     param4 = currentContext->parameter_##param4;  \
00225   }
00226 
00227 #define DECLARE_CACHED_PARAMETER_4_BUF(func, name, type1, param1, \
00228   type2, param2, type3, param3, type4, param4, vbo) \
00229   type1 parameter_##param1; \
00230   type2 parameter_##param2; \
00231   type3 parameter_##param3; \
00232   type4 parameter_##param4; \
00233   GLuint parameter_##vbo;
00234 
00235 #define IMPLEMENT_CACHED_PARAMETER_4_BUF(func, name, type1, param1, \
00236     type2, param2, type3, param3, type4, param4, vbo) \
00237   void Set##name (type1 param1, type2 param2, type3 param3, type4 param4, \
00238     bool forced = false) \
00239   { \
00240     if (forced || (param1 != currentContext->parameter_##param1) || \
00241       (param2 != currentContext->parameter_##param2) || \
00242       (param3 != currentContext->parameter_##param3) || \
00243       (param4 != currentContext->parameter_##param4) \
00244       || (currentContext->currentBufferID[csGLStateCacheContext::boElementArray] \
00245         != currentContext->parameter_##vbo) \
00246       || FORCE_STATE_CHANGE) \
00247     { \
00248       currentContext->parameter_##param1 = param1;  \
00249       currentContext->parameter_##param2 = param2;  \
00250       currentContext->parameter_##param3 = param3;  \
00251       currentContext->parameter_##param4 = param4;  \
00252       if (extmgr->CS_GL_ARB_vertex_buffer_object)                             \
00253       {                                                                       \
00254         ApplyBufferBinding (csGLStateCacheContext::boElementArray);           \
00255         currentContext->parameter_##vbo =                                     \
00256           currentContext->currentBufferID[csGLStateCacheContext::boElementArray];\
00257       }                                                                       \
00258       func (param1, param2, param3, param4); \
00259     } \
00260   } \
00261   void Get##name (type1 &param1, type2 & param2, type3 & param3, type4& param4) const\
00262   { \
00263     param1 = currentContext->parameter_##param1;  \
00264     param2 = currentContext->parameter_##param2;  \
00265     param3 = currentContext->parameter_##param3;  \
00266     param4 = currentContext->parameter_##param4;  \
00267   }
00268 
00269 #define DECLARE_CACHED_CLIENT_STATE(name)             \
00270   bool enabled_##name;
00271 
00272 #define IMPLEMENT_CACHED_CLIENT_STATE(name)           \
00273   void Enable_##name () \
00274   { \
00275     if (!currentContext->enabled_##name || FORCE_STATE_CHANGE) \
00276     { \
00277       currentContext->enabled_##name = true;  \
00278       glEnableClientState (name); \
00279     } \
00280   } \
00281     void Disable_##name () \
00282   { \
00283     if (currentContext->enabled_##name || FORCE_STATE_CHANGE) { \
00284       currentContext->enabled_##name = false;  \
00285       glDisableClientState (name); \
00286     } \
00287   } \
00288   bool IsEnabled_##name () const \
00289   { \
00290     return currentContext->enabled_##name; \
00291   }
00292 
00293 #define DECLARE_CACHED_CLIENT_STATE_TCS(name)                                 \
00294   AutoArray<bool> enabled_##name;
00295 
00296 #define IMPLEMENT_CACHED_CLIENT_STATE_TCS(name)                      \
00297   void Enable_##name ()                                                       \
00298   {                                                                           \
00299     const int currentUnit = currentContext->currentTCUnit;                    \
00300     if (!currentContext->enabled_##name[currentUnit] || FORCE_STATE_CHANGE)   \
00301     {                                                                         \
00302       ActivateTCUnit (activateTexCoord);                                      \
00303       currentContext->enabled_##name[currentUnit] = true;                     \
00304       glEnableClientState (name);                                             \
00305     }                                                                         \
00306   }                                                                           \
00307   void Disable_##name ()                                                      \
00308   {                                                                           \
00309     const int currentUnit = currentContext->currentTCUnit;                    \
00310     if (currentContext->enabled_##name[currentUnit] || FORCE_STATE_CHANGE)    \
00311     {                                                                         \
00312       ActivateTCUnit (activateTexCoord);                                      \
00313       currentContext->enabled_##name[currentUnit] = false;                    \
00314       glDisableClientState (name);                                            \
00315     }                                                                         \
00316   }                                                                           \
00317   bool IsEnabled_##name () const                                              \
00318   {                                                                           \
00319     const int currentUnit = currentContext->currentTCUnit;                    \
00320     return currentContext->enabled_##name[currentUnit];                       \
00321   }
00322 
00323 #define DECLARE_CACHED_PARAMETER_1_LAYER(func, name, type1, param1) \
00324   AutoArray<type1> parameter_##param1;
00325 
00326 #define IMPLEMENT_CACHED_PARAMETER_1_LAYER(func, name, type1, param1, limit) \
00327   void Set##name (type1 param1, bool forced = false) \
00328   { \
00329     const int currentUnit = currentContext->currentUnit;                      \
00330     if (forced || \
00331         (param1 != currentContext->parameter_##param1[currentUnit] \
00332         || FORCE_STATE_CHANGE)) \
00333     { \
00334       ActivateTU (); \
00335       currentContext->parameter_##param1[currentUnit] = param1;  \
00336       func (param1); \
00337     } \
00338   } \
00339   void Get##name (type1 &param1) const\
00340   { \
00341     const int currentUnit = currentContext->currentUnit;                      \
00342     param1 = currentContext->parameter_##param1[currentUnit];  \
00343   }
00344 
00345 #define DECLARE_CACHED_PARAMETER_2_LAYER(func, name, type1, param1, \
00346   type2, param2) \
00347   AutoArray<type1> parameter_##param1; \
00348   AutoArray<type2> parameter_##param2;
00349 
00350 #define IMPLEMENT_CACHED_PARAMETER_2_LAYER(func, name, type1, param1, \
00351   type2, param2, limit) \
00352   void Set##name (type1 param1, type2 param2, bool forced = false) \
00353   { \
00354     const int currentUnit = currentContext->currentUnit;                      \
00355     if (forced || (param1 != currentContext->parameter_##param1[ \
00356                     currentUnit]) || \
00357                   (param2 != currentContext->parameter_##param2[ \
00358                     currentUnit]) \
00359                || FORCE_STATE_CHANGE) \
00360     { \
00361       ActivateTU (); \
00362       currentContext->parameter_##param1[currentUnit] = param1;  \
00363       currentContext->parameter_##param2[currentUnit] = param2;  \
00364       func (param1, param2); \
00365     } \
00366   } \
00367   void Get##name (type1 &param1, type2 & param2) const\
00368   { \
00369     const int currentUnit = currentContext->currentUnit;                      \
00370     param1 = currentContext->parameter_##param1[currentUnit];  \
00371     param2 = currentContext->parameter_##param2[currentUnit];  \
00372   }
00373 
00374 #define DECLARE_CACHED_PARAMETER_3_LAYER(func, name, type1, param1, \
00375   type2, param2, type3, param3) \
00376   AutoArray<type1> parameter_##param1; \
00377   AutoArray<type2> parameter_##param2; \
00378   AutoArray<type3> parameter_##param3;
00379 
00380 
00381 #define IMPLEMENT_CACHED_PARAMETER_3_LAYER(func, name, type1, param1, \
00382   type2, param2, type3, param3, limit) \
00383   void Set##name (type1 param1, type2 param2, type3 param3,\
00384     bool forced = false) \
00385   { \
00386     const int currentUnit = currentContext->currentUnit;                      \
00387     if (forced || (param1 != currentContext->parameter_##param1[ \
00388                     currentUnit]) || \
00389                   (param2 != currentContext->parameter_##param2[ \
00390                     currentUnit]) || \
00391                   (param3 != currentContext->parameter_##param3[ \
00392                     currentUnit]) \
00393                || FORCE_STATE_CHANGE) \
00394     { \
00395       ActivateTU (); \
00396       currentContext->parameter_##param1[currentUnit] = param1;  \
00397       currentContext->parameter_##param2[currentUnit] = param2;  \
00398       currentContext->parameter_##param3[currentUnit] = param3;  \
00399       func (param1, param2, param3); \
00400     } \
00401   } \
00402   void Get##name (type1 &param1, type2 & param2, type3 & param3) const\
00403   { \
00404     const int currentUnit = currentContext->currentUnit;                      \
00405     param1 = currentContext->parameter_##param1[currentUnit];  \
00406     param2 = currentContext->parameter_##param2[currentUnit];  \
00407     param3 = currentContext->parameter_##param3[currentUnit];  \
00408   }
00409 
00410 
00411 #define DECLARE_CACHED_PARAMETER_4_BUF_TCS(func, name, type1, param1,       \
00412   type2, param2, type3, param3, type4, param4, vbo)                           \
00413   AutoArray<type1> parameter_##param1;                                        \
00414   AutoArray<type2> parameter_##param2;                                        \
00415   AutoArray<type3> parameter_##param3;                                        \
00416   AutoArray<type4> parameter_##param4;                                        \
00417   AutoArray<GLuint> parameter_##vbo;
00418 
00419 #define IMPLEMENT_CACHED_PARAMETER_4_BUF_TCS(func, name, type1, param1,     \
00420     type2, param2, type3, param3, type4, param4, vbo)                  \
00421   void Set##name (type1 param1, type2 param2, type3 param3, type4 param4,     \
00422     bool forced = false)                                                      \
00423   {                                                                           \
00424     const int currentUnit = currentContext->currentTCUnit;                    \
00425     if (forced                                                                \
00426       || (param1 != currentContext->parameter_##param1[currentUnit])          \
00427       || (param2 != currentContext->parameter_##param2[currentUnit])          \
00428       || (param3 != currentContext->parameter_##param3[currentUnit])          \
00429       || (param4 != currentContext->parameter_##param4[currentUnit])          \
00430       || (currentContext->currentBufferID[csGLStateCacheContext::boElementArray]\
00431         != currentContext->parameter_##vbo[currentUnit])                      \
00432       || FORCE_STATE_CHANGE)                                                  \
00433     {                                                                         \
00434       ActivateTCUnit (activateTexCoord);                                      \
00435       currentContext->parameter_##param1[currentUnit] = param1;               \
00436       currentContext->parameter_##param2[currentUnit] = param2;               \
00437       currentContext->parameter_##param3[currentUnit] = param3;               \
00438       currentContext->parameter_##param4[currentUnit] = param4;               \
00439       if (extmgr->CS_GL_ARB_vertex_buffer_object)                             \
00440       {                                                                       \
00441         ApplyBufferBinding (csGLStateCacheContext::boElementArray);           \
00442         currentContext->parameter_##vbo[currentUnit] =                        \
00443           currentContext->currentBufferID[csGLStateCacheContext::boElementArray];\
00444       }                                                                       \
00445       func (param1, param2, param3, param4);                                  \
00446     }                                                                         \
00447   }                                                                           \
00448   void Get##name (type1 &param1, type2 & param2, type3 & param3,              \
00449     type4& param4) const                                                      \
00450   {                                                                           \
00451     const int currentUnit = currentContext->currentTCUnit;                    \
00452     param1 = currentContext->parameter_##param1[currentUnit];                 \
00453     param2 = currentContext->parameter_##param2[currentUnit];                 \
00454     param3 = currentContext->parameter_##param3[currentUnit];                 \
00455     param4 = currentContext->parameter_##param4[currentUnit];                 \
00456   }
00457 
00458 
00459 class CS_CSPLUGINCOMMON_GL_EXPORT csGLStateCacheContext
00460 {
00461   template<typename T>
00462   struct AutoArray
00463   {
00464     T* p;
00465     
00466     AutoArray() : p (0) {}
00467     ~AutoArray()
00468     {
00469       delete[] p;
00470     }
00471     void Setup (size_t n)
00472     {
00473       CS_ASSERT (p == 0);
00474       p = new T[n];
00475     }
00476     
00477     T& operator[] (size_t idx)
00478     {
00479       return p[idx];
00480     }
00481   };
00482 public:
00483   csGLExtensionManager* extmgr;
00484 
00485   // Special caches
00486   AutoArray<GLuint> boundtexture;
00487   GLint numImageUnits;
00488   GLint numTexCoords;
00489   int currentImageUnit, currentTCUnit;
00490   int activeUnit[2];
00491   enum
00492   {
00493     boElementArray = 0, boIndexArray, boPixelPack, boPixelUnpack,
00494     
00495     boCount
00496   };
00497   GLuint currentBufferID[boCount];
00498   GLuint activeBufferID[boCount];
00499   static int GLBufferTargetToCacheIndex (GLenum target)
00500   {
00501     switch (target)
00502     {
00503     case GL_ARRAY_BUFFER_ARB:         return boElementArray;
00504     case GL_ELEMENT_ARRAY_BUFFER_ARB: return boIndexArray;
00505     case GL_PIXEL_PACK_BUFFER_ARB:    return boPixelPack;
00506     case GL_PIXEL_UNPACK_BUFFER_ARB:  return boPixelUnpack;
00507     default: return -1;      
00508     }
00509   }
00510   static GLenum CacheIndexToGLBufferTarget (int index)
00511   {
00512     static const GLenum localIndexToGLBufferTarget[boCount] =
00513     { GL_ARRAY_BUFFER_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB, 
00514       GL_PIXEL_PACK_BUFFER_ARB, GL_PIXEL_UNPACK_BUFFER_ARB };
00515     return localIndexToGLBufferTarget[index];
00516   }
00517 
00518   // BlendFunc/BlendFuncSeparate
00519   GLenum blend_sourceRGB;
00520   GLenum blend_destinationRGB;
00521   GLenum blend_sourceA;
00522   GLenum blend_destinationA;
00523   
00524   // Pixel storage
00525   GLint pixelUnpackAlignment;
00526   bool pixelUnpackSwapBytes;
00527   
00528   // Color clamp control
00529   enum
00530   {
00531     clampVertex = 0, clampFragment = 1, clampRead = 2,
00532     clampCount
00533   };
00534   GLenum clampState[clampCount];
00535   static int GLClampTargetToCacheIndex (GLenum target)
00536   {
00537     switch (target)
00538     {
00539     case GL_CLAMP_VERTEX_COLOR_ARB:         return clampVertex;
00540     case GL_CLAMP_FRAGMENT_COLOR_ARB:         return clampFragment;
00541     case GL_CLAMP_READ_COLOR_ARB:         return clampRead;
00542     default: return -1;      
00543     }
00544   }
00545 
00546   // Standardized caches
00547   DECLARE_CACHED_BOOL (GL_DEPTH_TEST)
00548   DECLARE_CACHED_BOOL (GL_BLEND)
00549   DECLARE_CACHED_BOOL (GL_DITHER)
00550   DECLARE_CACHED_BOOL (GL_STENCIL_TEST)
00551   DECLARE_CACHED_BOOL (GL_CULL_FACE)
00552   DECLARE_CACHED_BOOL (GL_POLYGON_OFFSET_FILL)
00553   DECLARE_CACHED_BOOL (GL_LIGHTING)
00554   DECLARE_CACHED_BOOL (GL_ALPHA_TEST)
00555   DECLARE_CACHED_BOOL (GL_SCISSOR_TEST)
00556   DECLARE_CACHED_BOOL (GL_TEXTURE_GEN_S)
00557   DECLARE_CACHED_BOOL (GL_TEXTURE_GEN_T)
00558   DECLARE_CACHED_BOOL (GL_TEXTURE_GEN_R)
00559   DECLARE_CACHED_BOOL (GL_TEXTURE_GEN_Q)
00560   DECLARE_CACHED_BOOL (GL_FOG)
00561   DECLARE_CACHED_BOOL (GL_COLOR_SUM_EXT)
00562   DECLARE_CACHED_BOOL (GL_VERTEX_PROGRAM_POINT_SIZE_ARB)
00563   DECLARE_CACHED_BOOL (GL_POINT_SPRITE_ARB)
00564   DECLARE_CACHED_BOOL (GL_TEXTURE_CUBE_MAP_SEAMLESS)
00565   DECLARE_CACHED_BOOL (GL_SAMPLE_ALPHA_TO_COVERAGE_ARB)
00566   DECLARE_CACHED_BOOL (GL_SAMPLE_ALPHA_TO_ONE_ARB)
00567   DECLARE_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_1D)
00568   DECLARE_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_2D)
00569   DECLARE_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_3D)
00570   DECLARE_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_CUBE_MAP)
00571   DECLARE_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_RECTANGLE_ARB)
00572   DECLARE_CACHED_PARAMETER_2 (glAlphaFunc, AlphaFunc, GLenum, alpha_func, GLclampf, alpha_ref)
00573   DECLARE_CACHED_PARAMETER_1 (glCullFace, CullFace, GLenum, cull_mode)
00574   DECLARE_CACHED_PARAMETER_1 (glDepthFunc, DepthFunc, GLenum, depth_func)
00575   DECLARE_CACHED_PARAMETER_1 (glDepthMask, DepthMask, GLboolean, depth_mask)
00576   DECLARE_CACHED_PARAMETER_1 (glShadeModel, ShadeModel, GLenum, shade_model)
00577   DECLARE_CACHED_PARAMETER_3 (glStencilFunc, StencilFunc, GLenum, stencil_func, GLint, stencil_ref, GLuint, stencil_mask)
00578   DECLARE_CACHED_PARAMETER_3 (glStencilOp, StencilOp, GLenum, stencil_fail, GLenum, stencil_zfail, GLenum, stencil_zpass)
00579   DECLARE_CACHED_PARAMETER_1 (glStencilMask, StencilMask, GLuint, maskl)
00580   DECLARE_CACHED_PARAMETER_4 (glColorMask, ColorMask, GLboolean, wmRed, \
00581     GLboolean, wmGreen, GLboolean, wmBlue, GLboolean, wmAlpha)
00582 
00583   DECLARE_CACHED_CLIENT_STATE (GL_VERTEX_ARRAY)
00584   DECLARE_CACHED_CLIENT_STATE (GL_COLOR_ARRAY)
00585   DECLARE_CACHED_CLIENT_STATE (GL_SECONDARY_COLOR_ARRAY_EXT)
00586   DECLARE_CACHED_CLIENT_STATE (GL_NORMAL_ARRAY)
00587   DECLARE_CACHED_CLIENT_STATE_TCS (GL_TEXTURE_COORD_ARRAY)
00588 
00589   DECLARE_CACHED_PARAMETER_1 (glMatrixMode, MatrixMode, GLenum, matrixMode)
00590   
00591   DECLARE_CACHED_PARAMETER_4_BUF (glVertexPointer, VertexPointer, GLint, vsize,
00592     GLenum, vtype, GLsizei, vstride, GLvoid*, vpointer, vvbo)
00593   DECLARE_CACHED_PARAMETER_3_BUF (glNormalPointer, NormalPointer, GLenum, ntype,
00594     GLsizei, nstride, GLvoid*, npointer, nvbo)
00595   DECLARE_CACHED_PARAMETER_4_BUF (glColorPointer, ColorPointer, GLint, csize,
00596     GLenum, ctype, GLsizei, cstride, GLvoid*, cpointer, cvbo)
00597   DECLARE_CACHED_PARAMETER_4_BUF (extmgr->glSecondaryColorPointerEXT, 
00598     SecondaryColorPointerEXT, GLint, scsize, GLenum, sctype, GLsizei, scstride, 
00599     GLvoid*, scpointer, scvbo);
00600   DECLARE_CACHED_PARAMETER_4_BUF_TCS (glTexCoordPointer, TexCoordPointer, GLint, tsize,
00601     GLenum, ttype, GLsizei, tstride, GLvoid*, tpointer, tvbo)
00602   
00603   csGLStateCacheContext (csGLExtensionManager* extmgr);
00604 
00609   void InitCache();
00610 };
00611 
00612 
00623 class csGLStateCache
00624 {
00625   enum
00626   {
00627     texServer = 0,
00628     texClient = 1
00629   };
00630 public:
00631   csGLExtensionManager* extmgr;
00632   csGLStateCacheContext* currentContext;
00633 
00634   csGLStateCache (csGLExtensionManager* extmgr)
00635   {
00636     csGLStateCache::extmgr = extmgr;
00637     currentContext = 0;
00638   }
00639 
00640   void SetContext (csGLStateCacheContext *context)
00641   {
00642     currentContext = context;
00643   }
00644 
00645   // Standardized caches
00646   IMPLEMENT_CACHED_BOOL (GL_DEPTH_TEST)
00647   IMPLEMENT_CACHED_BOOL (GL_BLEND)
00648   IMPLEMENT_CACHED_BOOL (GL_DITHER)
00649   IMPLEMENT_CACHED_BOOL (GL_STENCIL_TEST)
00650   IMPLEMENT_CACHED_BOOL (GL_CULL_FACE)
00651   IMPLEMENT_CACHED_BOOL (GL_POLYGON_OFFSET_FILL)
00652   IMPLEMENT_CACHED_BOOL (GL_LIGHTING)
00653   IMPLEMENT_CACHED_BOOL (GL_ALPHA_TEST)
00654   IMPLEMENT_CACHED_BOOL (GL_SCISSOR_TEST)
00655   IMPLEMENT_CACHED_BOOL (GL_TEXTURE_GEN_S)
00656   IMPLEMENT_CACHED_BOOL (GL_TEXTURE_GEN_T)
00657   IMPLEMENT_CACHED_BOOL (GL_TEXTURE_GEN_R)
00658   IMPLEMENT_CACHED_BOOL (GL_TEXTURE_GEN_Q)
00659   IMPLEMENT_CACHED_BOOL (GL_FOG)
00660   IMPLEMENT_CACHED_BOOL (GL_COLOR_SUM_EXT)
00661   IMPLEMENT_CACHED_BOOL (GL_VERTEX_PROGRAM_POINT_SIZE_ARB)
00662   IMPLEMENT_CACHED_BOOL (GL_POINT_SPRITE_ARB)
00663   IMPLEMENT_CACHED_BOOL (GL_TEXTURE_CUBE_MAP_SEAMLESS)
00664   IMPLEMENT_CACHED_BOOL (GL_SAMPLE_ALPHA_TO_COVERAGE_ARB)
00665   IMPLEMENT_CACHED_BOOL (GL_SAMPLE_ALPHA_TO_ONE_ARB)
00666   IMPLEMENT_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_1D)
00667   IMPLEMENT_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_2D)
00668   IMPLEMENT_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_3D)
00669   IMPLEMENT_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_CUBE_MAP)
00670   IMPLEMENT_CACHED_BOOL_IMAGEUNIT (GL_TEXTURE_RECTANGLE_ARB)
00671   IMPLEMENT_CACHED_PARAMETER_2 (glAlphaFunc, AlphaFunc, GLenum, alpha_func, GLclampf, alpha_ref)
00672   IMPLEMENT_CACHED_PARAMETER_1 (glCullFace, CullFace, GLenum, cull_mode)
00673   IMPLEMENT_CACHED_PARAMETER_1 (glDepthFunc, DepthFunc, GLenum, depth_func)
00674   IMPLEMENT_CACHED_PARAMETER_1 (glDepthMask, DepthMask, GLboolean, depth_mask)
00675   IMPLEMENT_CACHED_PARAMETER_1 (glShadeModel, ShadeModel, GLenum, shade_model)
00676   IMPLEMENT_CACHED_PARAMETER_3 (glStencilFunc, StencilFunc, GLenum, stencil_func, GLint, stencil_ref, GLuint, stencil_mask)
00677   IMPLEMENT_CACHED_PARAMETER_3 (glStencilOp, StencilOp, GLenum, stencil_fail, GLenum, stencil_zfail, GLenum, stencil_zpass)
00678   IMPLEMENT_CACHED_PARAMETER_1 (glStencilMask, StencilMask, GLuint, maskl)
00679   IMPLEMENT_CACHED_PARAMETER_4 (glColorMask, ColorMask, GLboolean, wmRed, \
00680     GLboolean, wmGreen, GLboolean, wmBlue, GLboolean, wmAlpha)
00681 
00682   IMPLEMENT_CACHED_CLIENT_STATE (GL_VERTEX_ARRAY)
00683   IMPLEMENT_CACHED_CLIENT_STATE (GL_COLOR_ARRAY)
00684   IMPLEMENT_CACHED_CLIENT_STATE (GL_SECONDARY_COLOR_ARRAY_EXT)
00685   IMPLEMENT_CACHED_CLIENT_STATE (GL_NORMAL_ARRAY)
00686   IMPLEMENT_CACHED_CLIENT_STATE_TCS (GL_TEXTURE_COORD_ARRAY)
00687 
00688   IMPLEMENT_CACHED_PARAMETER_1 (glMatrixMode, MatrixMode, GLenum, matrixMode)
00689   
00690   IMPLEMENT_CACHED_PARAMETER_4_BUF (glVertexPointer, VertexPointer, GLint, vsize,
00691     GLenum, vtype, GLsizei, vstride, GLvoid*, vpointer, vvbo);
00692   IMPLEMENT_CACHED_PARAMETER_3_BUF (glNormalPointer, NormalPointer, GLenum, ntype,
00693     GLsizei, nstride, GLvoid*, npointer, nvbo);
00694   IMPLEMENT_CACHED_PARAMETER_4_BUF (glColorPointer, ColorPointer, GLint, csize,
00695     GLenum, ctype, GLsizei, cstride, GLvoid*, cpointer, cvbo);
00696   IMPLEMENT_CACHED_PARAMETER_4_BUF (extmgr->glSecondaryColorPointerEXT, 
00697     SecondaryColorPointerExt, GLint, scsize, GLenum, sctype, GLsizei, scstride, 
00698     GLvoid*, scpointer, scvbo);
00699   IMPLEMENT_CACHED_PARAMETER_4_BUF_TCS (glTexCoordPointer, TexCoordPointer, GLint, tsize,
00700     GLenum, ttype, GLsizei, tstride, GLvoid*, tpointer, tvbo);
00701   
00702   // Special caches
00703   void SetTexture (GLenum target, GLuint texture)
00704   {
00705     const int currentUnit = currentContext->currentImageUnit;
00706     if (texture != currentContext->boundtexture[currentUnit])
00707     {
00708       ActivateImageUnit ();
00709       currentContext->boundtexture[currentUnit] = texture;
00710       glBindTexture (target, texture);
00711     }
00712   }
00713   GLuint GetTexture (GLenum /*target*/)
00714   {
00715     const int currentUnit = currentContext->currentImageUnit;
00716     return currentContext->boundtexture[currentUnit];
00717   }
00718   GLuint GetTexture (GLenum /*target*/, int unit)
00719   {
00720     return currentContext->boundtexture[unit];
00721   }
00722   
00728   void SetCurrentImageUnit (int unit)
00729   {
00730     CS_ASSERT(unit < currentContext->numImageUnits);
00731     currentContext->currentImageUnit = unit;   
00732   }
00734   int GetCurrentImageUnit ()
00735   {
00736     return currentContext->currentImageUnit;
00737   }
00744   void ActivateImageUnit ()
00745   {
00746     int currentUnit = currentContext->currentImageUnit;
00747     if (currentContext->activeUnit[texServer] != currentUnit)
00748     {
00749       GLuint tu = GL_TEXTURE0_ARB + currentUnit;
00750       extmgr->glActiveTextureARB (tu);
00751       currentContext->activeUnit[texServer] = currentUnit;
00752     }
00753   }
00754   
00763   void SetCurrentTCUnit (int unit)
00764   {
00765     CS_ASSERT(unit < currentContext->numTexCoords);
00766     currentContext->currentTCUnit = unit;   
00767   }
00769   int GetCurrentTCUnit ()
00770   {
00771     return currentContext->currentTCUnit;
00772   }
00774   static const int activateTexCoord = 1 << texClient;
00776   static const int activateMatrix = 1 << texServer;
00778   static const int activateTexEnv = 1 << texServer;
00783   static const int activateTexGen = 1 << texServer;
00789   void ActivateTCUnit (uint usage)
00790   {
00791     int currentUnit = currentContext->currentTCUnit;
00792     for (int i = 0; i < 2; i++)
00793     {
00794       if (currentContext->activeUnit[i] != currentUnit)
00795       {
00796         GLuint tu = GL_TEXTURE0_ARB + currentUnit;
00797         if (usage & (1 << i))
00798         {
00799           if (i == texClient)
00800             extmgr->glClientActiveTextureARB (tu);
00801           else
00802             extmgr->glActiveTextureARB (tu);
00803           currentContext->activeUnit[i] = currentUnit;
00804         }
00805       }
00806     }
00807   }
00808   
00809   void ApplyBufferBinding (int index)
00810   {
00811     GLuint id = currentContext->currentBufferID[index];
00812     if (currentContext->activeBufferID[index] != id)
00813     {
00814       extmgr->glBindBufferARB (
00815         csGLStateCacheContext::CacheIndexToGLBufferTarget (index), id);
00816       currentContext->activeBufferID[index] = id;
00817     }
00818   }
00819 
00825   void SetBufferARB (GLenum target, GLuint id, bool applyNow = false)
00826   {
00827     int index = csGLStateCacheContext::GLBufferTargetToCacheIndex (target);
00828     CS_ASSERT (index >= 0);
00829     currentContext->currentBufferID[index] = id;
00830     if (applyNow) ApplyBufferBinding (index);
00831   }
00832 
00838   GLuint GetBufferARB (GLenum target)
00839   {
00840     int index = csGLStateCacheContext::GLBufferTargetToCacheIndex (target);
00841     CS_ASSERT (index >= 0);
00842     return currentContext->currentBufferID[index];
00843   }
00844 
00847   void SetBlendFunc (GLenum blend_source, GLenum blend_destination, 
00848                       bool forced = false)
00849   {
00850     if (forced 
00851       || (blend_source != currentContext->blend_sourceRGB)
00852       || (blend_source != currentContext->blend_sourceA)
00853       || (blend_destination != currentContext->blend_destinationRGB) 
00854       || (blend_destination != currentContext->blend_destinationA) 
00855       || FORCE_STATE_CHANGE)
00856     {
00857       currentContext->blend_sourceRGB = blend_source;
00858       currentContext->blend_sourceA = blend_source;
00859       currentContext->blend_destinationRGB = blend_destination;
00860       currentContext->blend_destinationA = blend_destination;
00861       glBlendFunc (blend_source, blend_destination);
00862     }
00863   }
00864   void GetBlendFunc (GLenum& blend_source, GLenum& blend_destination) const
00865   {
00866     blend_source = currentContext->blend_sourceRGB;
00867     blend_destination = currentContext->blend_destinationRGB;
00868   }
00869   void SetBlendFuncSeparate (GLenum blend_sourceRGB, 
00870                               GLenum blend_destinationRGB, 
00871                               GLenum blend_sourceA, 
00872                               GLenum blend_destinationA, 
00873                               bool forced = false)
00874   {
00875     if (forced 
00876       || (blend_sourceRGB != currentContext->blend_sourceRGB)
00877       || (blend_sourceA != currentContext->blend_sourceA)
00878       || (blend_destinationRGB != currentContext->blend_destinationRGB) 
00879       || (blend_destinationA != currentContext->blend_destinationA) 
00880       || FORCE_STATE_CHANGE)
00881     {
00882       currentContext->blend_sourceRGB = blend_sourceRGB;
00883       currentContext->blend_sourceA = blend_sourceA;
00884       currentContext->blend_destinationRGB = blend_destinationRGB;
00885       currentContext->blend_destinationA = blend_destinationA;
00886       extmgr->glBlendFuncSeparateEXT (blend_sourceRGB, blend_destinationRGB, 
00887         blend_sourceA, blend_destinationA);
00888     }
00889   }
00890   void GetBlendFuncSeparate (GLenum& blend_sourceRGB, 
00891                               GLenum& blend_destinationRGB,
00892                               GLenum& blend_sourceA, 
00893                               GLenum& blend_destinationA) const
00894   {
00895     blend_sourceRGB = currentContext->blend_sourceRGB;
00896     blend_destinationRGB = currentContext->blend_destinationRGB;
00897     blend_sourceA = currentContext->blend_sourceA;
00898     blend_destinationA = currentContext->blend_destinationA;
00899   }
00904   GLint GetPixelUnpackAlignment ()
00905   { return currentContext->pixelUnpackAlignment; }
00906   void SetPixelUnpackAlignment (GLint alignment)
00907   {
00908     if (alignment != currentContext->pixelUnpackAlignment)
00909     {
00910       glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
00911       currentContext->pixelUnpackAlignment = alignment;
00912     }
00913   }
00914   bool GetPixelUnpackSwapBytes ()
00915   { return currentContext->pixelUnpackSwapBytes; }
00916   void SetPixelUnpackSwapBytes (GLint swap)
00917   {
00918     bool swapAsbool = (swap != 0);
00919     if (swapAsbool != currentContext->pixelUnpackSwapBytes)
00920     {
00921       glPixelStorei (GL_UNPACK_SWAP_BYTES, (GLint)swap);
00922       currentContext->pixelUnpackSwapBytes = swapAsbool;
00923     }
00924   }
00929   void SetClampColor (GLenum target, GLenum clamp)
00930   {
00931     int index = csGLStateCacheContext::GLClampTargetToCacheIndex (target);
00932     CS_ASSERT (index >= 0);
00933     if (clamp != currentContext->clampState[index])
00934     {
00935       extmgr->glClampColorARB (target, clamp);
00936       currentContext->clampState[index] = clamp;
00937     }
00938   }
00939   GLenum GetClampColor (GLenum target) const
00940   {
00941     int index = csGLStateCacheContext::GLClampTargetToCacheIndex (target);
00942     CS_ASSERT (index >= 0);
00943     return currentContext->clampState[index];
00944   }
00947 
00948   GLint GetNumImageUnits() const { return currentContext->numImageUnits; }
00950   GLint GetNumTexCoords() const { return currentContext->numTexCoords; }
00951 };
00952 
00953 #undef IMPLEMENT_CACHED_BOOL
00954 #undef IMPLEMENT_CACHED_BOOL_IMAGEUNIT
00955 #undef IMPLEMENT_CACHED_PARAMETER_1
00956 #undef IMPLEMENT_CACHED_PARAMETER_2
00957 #undef IMPLEMENT_CACHED_PARAMETER_3
00958 #undef IMPLEMENT_CACHED_PARAMETER_4
00959 #undef IMPLEMENT_CACHED_PARAMETER_1_LAYER
00960 #undef IMPLEMENT_CACHED_PARAMETER_2_LAYER
00961 #undef IMPLEMENT_CACHED_PARAMETER_3_LAYER
00962 #undef IMPLEMENT_CACHED_PARAMETER_4_LAYER
00963 #undef IMPLEMENT_CACHED_CLIENT_STATE
00964 #undef IMPLEMENT_CACHED_CLIENT_STATE_LAYER
00965 
00966 #undef DECLARE_CACHED_BOOL
00967 #undef DECLARE_CACHED_BOOL_IMAGEUNIT
00968 #undef DECLARE_CACHED_PARAMETER_1
00969 #undef DECLARE_CACHED_PARAMETER_2
00970 #undef DECLARE_CACHED_PARAMETER_3
00971 #undef DECLARE_CACHED_PARAMETER_4
00972 #undef DECLARE_CACHED_PARAMETER_1_LAYER
00973 #undef DECLARE_CACHED_PARAMETER_2_LAYER
00974 #undef DECLARE_CACHED_PARAMETER_3_LAYER
00975 #undef DECLARE_CACHED_PARAMETER_4_LAYER
00976 #undef DECLARE_CACHED_CLIENT_STATE
00977 #undef DECLARE_CACHED_CLIENT_STATE_LAYER
00978 
00979 #undef FORCE_STATE_CHANGE
00980 
00983 #endif // __CS_GLSTATES_H__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1