00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00041 #define FORCE_STATE_CHANGE false
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 ¶m1, 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 ¶m1, 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 ¶m1, 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 ¶m1, 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 ¶m1) 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 ¶m1, 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 ¶m1, 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 ¶m1, 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
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
00519 GLenum blend_sourceRGB;
00520 GLenum blend_destinationRGB;
00521 GLenum blend_sourceA;
00522 GLenum blend_destinationA;
00523
00524
00525 GLint pixelUnpackAlignment;
00526 bool pixelUnpackSwapBytes;
00527
00528
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
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
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
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 )
00714 {
00715 const int currentUnit = currentContext->currentImageUnit;
00716 return currentContext->boundtexture[currentUnit];
00717 }
00718 GLuint GetTexture (GLenum , 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__