00001
00002
00003
00004
00005
00006 #pragma once
00007 #ifndef STATESET_H
00008 #define STATESET_H
00009
00010 #include "Types.h"
00011 #include "Util.h"
00012 #include "RelationalNode.h"
00013 #include "AbstractPropertyContainer.h"
00014 #include "XMLNode.h"
00015 #include "BindingInterface.h"
00016
00017 using namespace std;
00018
00019 namespace RenderTools {
00020
00021 class Stateset : public BindingInterface, public AbstractPropertyContainer {
00022 public:
00023 typedef unsigned int StateMask;
00024 enum StateComponents {
00025 NONE = 0x0000,
00026 CURRENT_COLOR = 0x0001,
00027 CLEAR_COLOR = 0x0002,
00028 COLOR_MASK = 0x0004,
00029 TEXTURE = 0x0008,
00030 BLEND = 0x0010,
00031 ALPHA_TEST = 0x0020,
00032 #ifdef GL_ALPHA_TEST_FUNC
00033 ALPHA_FUNCTION = 0x0040,
00034 #endif
00035 DEPTH_TEST = 0x0080,
00036 #ifdef GL_DEPTH_FUNC
00037 DEPTH_FUNCTION = 0x0100,
00038 #endif
00039 DEPTH_MASK = 0x0200,
00040 #ifdef GL_CULL_FACE
00041 CULL_FACE = 0x0400,
00042 CULL_MODE = 0x0800,
00043 #endif
00044 #ifdef GL_POLYGON_MODE
00045 POLYGON_MODE = 0x1000,
00046 #endif
00047 LINE_WIDTH = 0x2000,
00048 POINT_SIZE = 0x4000,
00049 ALL = 0xFFFFF
00050 };
00051
00052 Stateset( void );
00053
00054 static PropertyPtr create( const XMLNodePtr & xml = XMLNodePtr() );
00055 virtual void createProperties( void );
00056 virtual const string getTypeName( bool ofComponent = false ) const;
00057
00058 virtual void onInitialize( void );
00059 virtual void onBind( int unit );
00060 virtual void onUnbind( int unit );
00061
00062 Stateset& operator = ( const Stateset &other ){
00063 this->mask = other.mask;
00064 this->currentColor = other.currentColor;
00065 this->clearColor = other.clearColor;
00066 this->texture = other.texture;
00067 this->blend = other.blend;
00068 #ifdef GL_BLEND_SRC
00069 this->blendSrc = other.blendSrc;
00070 this->blendDst = other.blendDst;
00071 #endif
00072 this->redMask = other.redMask;
00073 this->greenMask = other.greenMask;
00074 this->blueMask = other.blueMask;
00075 this->alphaMask = other.alphaMask;
00076 this->alphaTest = other.alphaTest;
00077 #ifdef GL_ALPHA_TEST_FUNC
00078 this->alphaFunc = other.alphaFunc;
00079 this->alphaRef = other.alphaRef;
00080 #endif
00081 this->depthMask = other.depthMask;
00082 this->depthTest = other.depthTest;
00083 #ifdef GL_DEPTH_FUNC
00084 this->depthFunc = other.depthFunc;
00085 #endif
00086 #ifdef GL_CULL_FACE
00087 this->cullFace = other.cullFace;
00088 this->cullMode = other.cullMode;
00089 #endif
00090 #ifdef GL_POLYGON_MODE
00091 this->polygonFrontMode = other.polygonFrontMode;
00092 this->polygonBackMode = other.polygonBackMode;
00093 #endif
00094 this->lineWidth = other.lineWidth;
00095 this->pointSize = other.pointSize;
00096 return * this;
00097 }
00098
00099 Stateset & operator |= ( const Stateset & other ){
00100 this->mask |= other.mask;
00101 this->currentColor = other.currentColor;
00102 this->clearColor = other.clearColor;
00103 this->texture = other.texture;
00104 this->blend = other.blend;
00105 #ifdef GL_BLEND_SRC
00106 this->blendSrc = other.blendSrc;
00107 this->blendDst = other.blendDst;
00108 #endif
00109 this->redMask |= other.redMask;
00110 this->greenMask |= other.greenMask;
00111 this->blueMask |= other.blueMask;
00112 this->alphaMask |= other.alphaMask;
00113 this->alphaTest |= other.alphaTest;
00114 #ifdef GL_ALPHA_TEST_FUNC
00115 this->alphaFunc |= other.alphaFunc;
00116 this->alphaRef = other.alphaRef;
00117 #endif
00118 this->depthMask |= other.depthMask;
00119 this->depthTest |= other.depthTest;
00120 #ifdef GL_DEPTH_FUNC
00121 this->depthFunc = other.depthFunc;
00122 #endif
00123 #ifdef GL_CULL_FACE
00124 this->cullFace |= other.cullFace;
00125 this->cullMode = other.cullMode;
00126 #endif
00127 #ifdef GL_POLYGON_MODE
00128 this->polygonFrontMode = other.polygonFrontMode;
00129 this->polygonBackMode = other.polygonBackMode;
00130 #endif
00131 this->lineWidth = other.lineWidth;
00132 this->pointSize = other.pointSize;
00133 return * this;
00134 }
00135
00136 Stateset & operator &= ( const Stateset & other ){
00137 this->mask &= other.mask;
00138 this->currentColor = other.currentColor;
00139 this->clearColor = other.clearColor;
00140 this->texture = other.texture;
00141 this->blend = other.blend;
00142 #ifdef GL_BLEND_SRC
00143 this->blendSrc = other.blendSrc;
00144 this->blendDst = other.blendDst;
00145 #endif
00146 this->redMask &= other.redMask;
00147 this->greenMask &= other.greenMask;
00148 this->blueMask &= other.blueMask;
00149 this->alphaMask &= other.alphaMask;
00150 this->alphaTest &= other.alphaTest;
00151 #ifdef GL_ALPHA_TEST_FUNC
00152 this->alphaFunc &= other.alphaFunc;
00153 this->alphaRef = other.alphaRef;
00154 #endif
00155 this->depthMask &= other.depthMask;
00156 this->depthTest &= other.depthTest;
00157 #ifdef GL_DEPTH_FUNC
00158 this->depthFunc = other.depthFunc;
00159 #endif
00160 #ifdef GL_CULL_FACE
00161 this->cullFace &= other.cullFace;
00162 this->cullMode = other.cullMode;
00163 #endif
00164 #ifdef GL_POLYGON_MODE
00165 this->polygonFrontMode = other.polygonFrontMode;
00166 this->polygonBackMode = other.polygonBackMode;
00167 #endif
00168 this->lineWidth = other.lineWidth;
00169 this->pointSize = other.pointSize;
00170 return * this;
00171 }
00172
00173 void setCurrentColor( GLfloat * currentColor ){
00174 this->mask |= CURRENT_COLOR;
00175 this->currentColor[0] = currentColor[0];
00176 this->currentColor[1] = currentColor[1];
00177 this->currentColor[2] = currentColor[2];
00178 this->currentColor[3] = currentColor[3];
00179 }
00180 void setCurrentColor( Vec4 currentColor = Vec4( 0.0f, 0.0f, 0.0f, 0.0f ) ){
00181 this->mask |= CURRENT_COLOR;
00182 this->currentColor = currentColor;
00183 }
00184 void setClearColor( GLfloat * clearColor ){
00185 this->mask |= CLEAR_COLOR;
00186 this->clearColor[0] = clearColor[0];
00187 this->clearColor[1] = clearColor[1];
00188 this->clearColor[2] = clearColor[2];
00189 this->clearColor[3] = clearColor[3];
00190 }
00191 void setClearColor( Vec4 clearColor = Vec4( 0.0f, 0.0f, 0.0f, 0.0f ) ){
00192 this->mask |= CLEAR_COLOR;
00193 this->clearColor = clearColor;
00194 }
00195 void setTexture( GLboolean texture = GL_TRUE ){
00196 this->mask |= TEXTURE;
00197 this->texture = texture;
00198 }
00199 void setBlend( GLboolean blend = GL_TRUE ){
00200 this->mask |= BLEND;
00201 this->blend = blend;
00202 }
00203 #ifdef GL_BLEND_SRC
00204 void setBlendFunc( GLenum src = GL_SRC_ALPHA, GLenum dst = GL_ONE_MINUS_SRC_ALPHA ){
00205 this->mask |= BLEND;
00206 this->blendSrc = src;
00207 this->blendDst = dst;
00208 }
00209 #endif
00210 void setColorMask( GLboolean redMask = GL_TRUE, GLboolean greenMask = GL_TRUE, GLboolean blueMask = GL_TRUE, GLboolean alphaMask = GL_TRUE ){
00211 this->mask |= COLOR_MASK;
00212 this->redMask = redMask;
00213 this->greenMask = greenMask;
00214 this->blueMask = blueMask;
00215 this->alphaMask = alphaMask;
00216 }
00217 void setAlphaTest( GLboolean alphaTest = GL_FALSE ){
00218 this->mask |= ALPHA_TEST;
00219 this->alphaTest = alphaTest;
00220 }
00221 #ifdef GL_ALPHA_TEST_FUNC
00222 void setAlphaFunc( GLenum alphaFunc = GL_ALWAYS, GLfloat alphaRef = 1.0f ){
00223 this->mask |= ALPHA_FUNCTION;
00224 this->alphaFunc = alphaFunc;
00225 this->alphaRef = alphaRef;
00226 }
00227 #endif
00228 void setDepthTest( GLboolean depthTest = GL_TRUE ){
00229 this->mask |= DEPTH_TEST;
00230 this->depthTest = depthTest;
00231 }
00232 #ifdef GL_DEPTH_FUNC
00233 void setDepthFunc( GLenum depthFunc = GL_LEQUAL ){
00234 this->mask |= DEPTH_FUNCTION;
00235 this->depthFunc = depthFunc;
00236 }
00237 #endif
00238 void setDepthMask( GLboolean depthMask = GL_TRUE ){
00239 this->mask |= DEPTH_MASK;
00240 this->depthMask = depthMask;
00241 }
00242 #ifdef GL_CULL_FACE
00243 void setCullFace( GLboolean cullFace = GL_TRUE ){
00244 this->mask |= CULL_FACE;
00245 this->cullFace = cullFace;
00246 }
00247 void setCullMode( GLenum cullMode = GL_BACK ){
00248 this->mask |= CULL_MODE;
00249 this->cullMode = cullMode;
00250 }
00251 #endif
00252 #ifdef GL_POLYGON_MODE
00253 void setPolygonMode( GLenum front = GL_FILL, GLenum back = GL_FILL ){
00254 this->mask |= POLYGON_MODE;
00255 this->polygonFrontMode = front;
00256 this->polygonBackMode = back;
00257 }
00258 #endif
00259 void setLineWidth( GLfloat width = 1.0f ){
00260 this->mask |= LINE_WIDTH;
00261 this->lineWidth = width;
00262 }
00263 void setPointSize( GLfloat size = 1.0f ){
00264 this->mask |= POINT_SIZE;
00265 this->pointSize = size;
00266 }
00267
00268 public:
00269 StateMask mask;
00270 Vec4 currentColor;
00271 Vec4 clearColor;
00272 GLboolean texture;
00273 GLboolean blend;
00274 #ifdef GL_BLEND_SRC
00275 GLenum blendSrc;
00276 GLenum blendDst;
00277 #endif
00278 GLboolean redMask;
00279 GLboolean greenMask;
00280 GLboolean blueMask;
00281 GLboolean alphaMask;
00282 GLboolean alphaTest;
00283 #ifdef GL_ALPHA_TEST_FUNC
00284 GLenum alphaFunc;
00285 GLfloat alphaRef;
00286 #endif
00287 GLboolean depthMask;
00288 GLboolean depthTest;
00289 #ifdef GL_DEPTH_FUNC
00290 GLenum depthFunc;
00291 #endif
00292 #ifdef GL_CULL_FACE
00293 GLboolean cullFace;
00294 GLenum cullMode;
00295 #endif
00296 #ifdef GL_POLYGON_MODE
00297 GLenum polygonFrontMode;
00298 GLenum polygonBackMode;
00299 #endif
00300 GLfloat lineWidth;
00301 GLfloat pointSize;
00302 };
00303
00304 struct StateComponentMaskStruct {
00305 StateComponentMaskStruct( Stateset::StateMask * e = 0 ):
00306 m_value( e ){
00307 }
00308
00309 bool operator == ( StateComponentMaskStruct & v2 ){
00310 return( m_value == v2.m_value );
00311 }
00312 bool operator != ( StateComponentMaskStruct & v2 ){
00313 return( ! ( m_value == v2.m_value ) );
00314 }
00315 Stateset::StateMask operator [] ( const unsigned int i ){
00316 return( * m_value );
00317 }
00318
00319 Stateset::StateMask * m_value;
00320 };
00321
00322 inline EnumList getStateComponentsEnums( void ){
00323 EnumList r;
00324 r.push_back( "NONE" );
00325 r.push_back( "CURRENT_COLOR" );
00326 r.push_back( "CLEAR_COLOR" );
00327 r.push_back( "COLOR_MASK" );
00328 r.push_back( "TEXTURE" );
00329 r.push_back( "BLEND" );
00330 r.push_back( "ALPHA_TEST" );
00331 #ifdef GL_ALPHA_TEST_FUNC
00332 r.push_back( "ALPHA_FUNCTION" );
00333 #endif
00334 r.push_back( "DEPTH_TEST" );
00335 #ifdef GL_DEPTH_FUNC
00336 r.push_back( "DEPTH_FUNCTION" );
00337 #endif
00338 r.push_back( "DEPTH_MASK" );
00339 #ifdef GL_CULL_FACE
00340 r.push_back( "CULL_FACE" );
00341 r.push_back( "CULL_MODE" );
00342 #endif
00343 #ifdef GL_POLYGON_MODE
00344 r.push_back( "POLYGON_MODE" );
00345 #endif
00346 r.push_back( "LINE_WIDTH" );
00347 r.push_back( "POINT_SIZE" );
00348 r.push_back( "ALL" );
00349 return( r );
00350 }
00351
00352 inline ostream & operator << ( ostream & s, const StateComponentMaskStruct & v ){
00353 if( ( * v.m_value ) == Stateset::NONE ){
00354 s << string( "NONE" );
00355 }
00356 else{
00357 if( ( * v.m_value ) & Stateset::CURRENT_COLOR ) s << string( "CURRENT_COLOR " );
00358 if( ( * v.m_value ) & Stateset::CLEAR_COLOR ) s << string( "CLEAR_COLOR " );
00359 if( ( * v.m_value ) & Stateset::COLOR_MASK ) s << string( "COLOR_MASK " );
00360 if( ( * v.m_value ) & Stateset::BLEND ) s << string( "BLEND " );
00361 if( ( * v.m_value ) & Stateset::TEXTURE ) s << string( "TEXTURE " );
00362 if( ( * v.m_value ) & Stateset::ALPHA_TEST ) s << string( "ALPHA_TEST " );
00363 #ifdef GL_ALPHA_TEST_FUNC
00364 if( ( * v.m_value ) & Stateset::ALPHA_FUNCTION ) s << string( "ALPHA_FUNCTION " );
00365 #endif
00366 if( ( * v.m_value ) & Stateset::DEPTH_TEST ) s << string( "DEPTH_TEST " );
00367 #ifdef GL_DEPTH_FUNC
00368 if( ( * v.m_value ) & Stateset::DEPTH_FUNCTION ) s << string( "DEPTH_FUNCTION " );
00369 #endif
00370 if( ( * v.m_value ) & Stateset::DEPTH_MASK ) s << string( "DEPTH_MASK " );
00371 #ifdef GL_CULL_FACE
00372 if( ( * v.m_value ) & Stateset::CULL_MODE ) s << string( "CULL_MODE " );
00373 #endif
00374 #ifdef GL_POLYGON_MODE
00375 if( ( * v.m_value ) & Stateset::POLYGON_MODE ) s << string( "POLYGON_MODE " );
00376 #endif
00377 if( ( * v.m_value ) & Stateset::LINE_WIDTH ) s << string( "LINE_WIDTH " );
00378 if( ( * v.m_value ) & Stateset::LINE_WIDTH ) s << string( "POINT_SIZE " );
00379 }
00380 return( s );
00381 }
00382
00383 inline istream & operator >> ( istream & s, StateComponentMaskStruct & v ){
00384 ( * v.m_value ) = Stateset::NONE;
00385 string value;
00386 while( ! s.fail() ){
00387 s >> value;
00388
00389 if( value == "NONE" ){
00390 ( * v.m_value ) = Stateset::NONE;
00391 }
00392 else if( value == "CURRENT_COLOR" ){
00393 ( * v.m_value ) |= Stateset::CURRENT_COLOR;
00394 }
00395 else if( value == "CLEAR_COLOR" ){
00396 ( * v.m_value ) |= Stateset::CLEAR_COLOR;
00397 }
00398 else if( value == "COLOR_MASK" ){
00399 ( * v.m_value ) |= Stateset::COLOR_MASK;
00400 }
00401 else if( value == "TEXTURE" ){
00402 ( * v.m_value ) |= Stateset::TEXTURE;
00403 }
00404 else if( value == "BLEND" ){
00405 ( * v.m_value ) |= Stateset::BLEND;
00406 }
00407 else if( value == "ALPHA_TEST" ){
00408 ( * v.m_value ) |= Stateset::ALPHA_TEST;
00409 }
00410 #ifdef GL_ALPHA_TEST_FUNC
00411 else if( value == "ALPHA_FUNCTION" ){
00412 ( * v.m_value ) |= Stateset::ALPHA_FUNCTION;
00413 }
00414 #endif
00415 else if( value == "DEPTH_TEST" ){
00416 ( * v.m_value ) |= Stateset::DEPTH_TEST;
00417 }
00418 #ifdef GL_DEPTH_FUNC
00419 else if( value == "DEPTH_FUNCTION" ){
00420 ( * v.m_value ) |= Stateset::DEPTH_FUNCTION;
00421 }
00422 #endif
00423 else if( value == "DEPTH_MASK" ){
00424 ( * v.m_value ) |= Stateset::DEPTH_MASK;
00425 }
00426 #ifdef GL_CULL_FACE
00427 else if( value == "CULL_FACE" ){
00428 ( * v.m_value ) |= Stateset::CULL_FACE;
00429 }
00430 else if( value == "CULL_MODE" ){
00431 ( * v.m_value ) |= Stateset::CULL_MODE;
00432 }
00433 #endif
00434 #ifdef GL_POLYGON_MODE
00435 else if( value == "POLYGON_MODE" ){
00436 ( * v.m_value ) |= Stateset::POLYGON_MODE;
00437 }
00438 #endif
00439 else if( value == "LINE_WIDTH" ){
00440 ( * v.m_value ) |= Stateset::LINE_WIDTH;
00441 }
00442 else if( value == "POINT_SIZE" ){
00443 ( * v.m_value ) |= Stateset::POINT_SIZE;
00444 }
00445 else if( value == "ALL" ){
00446 ( * v.m_value ) |= Stateset::ALL;
00447 }
00448 }
00449 return( s );
00450 }
00451
00452 inline ostream & operator << ( ostream & s, Stateset & set ){
00453 s << string( "mask : " ) << StateComponentMaskStruct( & set.mask ) << endl;
00454 if( set.mask & Stateset::CURRENT_COLOR ){
00455 s << string( "color : " ) << set.currentColor << endl;
00456 }
00457 if( set.mask & Stateset::CLEAR_COLOR ){
00458 s << string( "clearcolor : " ) << set.clearColor << endl;
00459 }
00460 if( set.mask & Stateset::COLOR_MASK ){
00461 #if GLbooleanStruct
00462 s << string( "colormask : " ) << GLbooleanStruct( & set.redMask ) << " " << GLbooleanStruct( & set.greenMask ) << " " << GLbooleanStruct( & set.blueMask ) << " " << GLbooleanStruct( & set.alphaMask ) << endl;
00463 #endif
00464 }
00465 if( set.mask & Stateset::TEXTURE ){
00466 if( set.texture ){
00467 s << string( "texture : GL_TRUE" ) << endl;
00468 }
00469 else{
00470 s << string( "texture : GL_FALSE" ) << endl;
00471 }
00472 }
00473 if( set.mask & Stateset::BLEND ){
00474 if( set.blend ){
00475 s << string( "blending : GL_TRUE" ) << endl;
00476 #ifdef GL_BLEND_SRC
00477 # if GLenumStruct
00478 s << string( "source : " ) << GLenumStruct( & set.blendSrc ) << endl;
00479 s << string( "dest : " ) << GLenumStruct( & set.blendDst ) << endl;
00480 # endif
00481 #endif
00482 }
00483 else{
00484 s << string( "blending : GL_FALSE" ) << endl;
00485 }
00486 }
00487 if( set.mask & Stateset::ALPHA_TEST ){
00488 if( set.alphaTest ){
00489 s << string( "alphaTest : GL_TRUE" ) << endl;
00490 }
00491 else{
00492 s << string( "alphaTest : GL_FALSE" ) << endl;
00493 }
00494 }
00495 #ifdef GL_ALPHA_TEST_FUNC
00496 if( set.mask & Stateset::ALPHA_FUNCTION ){
00497 s << string( "alphaFunc : " ) << GLenumStruct( & set.alphaFunc ) << string( " " ) << toString( set.alphaRef ) << endl;
00498 }
00499 #endif
00500 if( set.mask & Stateset::DEPTH_TEST ){
00501 if( set.alphaTest ){
00502 s << string( "depthTest : GL_TRUE" ) << endl;
00503 }
00504 else{
00505 s << string( "depthTest : GL_FALSE" ) << endl;
00506 }
00507 }
00508 #ifdef GL_DEPTH_FUNC
00509 if( set.mask & Stateset::DEPTH_FUNCTION ){
00510 s << string( "depthFunc : " ) << GLenumStruct( & set.depthFunc ) << endl;
00511 }
00512 #endif
00513 if( set.mask & Stateset::DEPTH_MASK ){
00514 if( set.depthMask ){
00515 s << string( "depthMask : GL_TRUE" ) << endl;
00516 }
00517 else{
00518 s << string( "depthMask : GL_FALSE" ) << endl;
00519 }
00520 }
00521 #ifdef GL_CULL_FACE
00522 if( set.mask & Stateset::CULL_FACE ){
00523 if( set.cullFace ){
00524 s << string( "cullFace : GL_TRUE" ) << endl;
00525 }
00526 else{
00527 s << string( "cullFace : GL_FALSE" ) << endl;
00528 }
00529 }
00530 if( set.mask & Stateset::CULL_MODE ){
00531 s << string( "cullMode : " ) << GLenumStruct( & set.cullMode ) << endl;
00532 }
00533 #endif
00534 #ifdef GL_POLYGON_MODE
00535 if( set.mask & Stateset::POLYGON_MODE ){
00536 s << string( "frontMode : " ) << GLenumStruct( & set.polygonFrontMode ) << endl;
00537 s << string( "backMode : " ) << GLenumStruct( & set.polygonBackMode ) << endl;
00538 }
00539 #endif
00540 if( set.mask & Stateset::LINE_WIDTH ){
00541 s << string( "lineWidth : " ) << toString( set.lineWidth ) << endl;
00542 }
00543 if( set.mask & Stateset::POINT_SIZE ){
00544 s << string( "pointSize : " ) << toString( set.pointSize ) << endl;
00545 }
00546 return s;
00547 }
00548
00549 };
00550
00551 #endif