csplugincommon/opengl/glstates.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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__