RenderState.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879
  1. #include "Base.h"
  2. #include "RenderState.h"
  3. #include "Node.h"
  4. #include "Pass.h"
  5. #include "Technique.h"
  6. #include "Node.h"
  7. #include "Scene.h"
  8. // Render state override bits
  9. #define RS_BLEND 1
  10. #define RS_BLEND_FUNC 2
  11. #define RS_CULL_FACE 4
  12. #define RS_DEPTH_TEST 8
  13. #define RS_DEPTH_WRITE 16
  14. #define RS_DEPTH_FUNC 32
  15. namespace gameplay
  16. {
  17. RenderState::StateBlock* RenderState::StateBlock::_defaultState = NULL;
  18. std::vector<RenderState::ResolveAutoBindingCallback> RenderState::_customAutoBindingResolvers;
  19. RenderState::RenderState()
  20. : _nodeBinding(NULL), _state(NULL), _parent(NULL)
  21. {
  22. }
  23. RenderState::~RenderState()
  24. {
  25. SAFE_RELEASE(_state);
  26. // Destroy all the material parameters
  27. for (size_t i = 0, count = _parameters.size(); i < count; ++i)
  28. {
  29. SAFE_RELEASE(_parameters[i]);
  30. }
  31. }
  32. void RenderState::initialize()
  33. {
  34. if (StateBlock::_defaultState == NULL)
  35. {
  36. StateBlock::_defaultState = StateBlock::create();
  37. }
  38. }
  39. void RenderState::finalize()
  40. {
  41. SAFE_RELEASE(StateBlock::_defaultState);
  42. }
  43. void RenderState::registerAutoBindingResolver(ResolveAutoBindingCallback callback)
  44. {
  45. _customAutoBindingResolvers.push_back(callback);
  46. }
  47. MaterialParameter* RenderState::getParameter(const char* name) const
  48. {
  49. GP_ASSERT(name);
  50. // Search for an existing parameter with this name.
  51. MaterialParameter* param;
  52. for (size_t i = 0, count = _parameters.size(); i < count; ++i)
  53. {
  54. param = _parameters[i];
  55. GP_ASSERT(param);
  56. if (strcmp(param->getName(), name) == 0)
  57. {
  58. return param;
  59. }
  60. }
  61. // Create a new parameter and store it in our list.
  62. param = new MaterialParameter(name);
  63. _parameters.push_back(param);
  64. return param;
  65. }
  66. void RenderState::clearParameter(const char* name)
  67. {
  68. for (size_t i = 0, count = _parameters.size(); i < count; ++i)
  69. {
  70. MaterialParameter* p = _parameters[i];
  71. if (p->_name == name)
  72. {
  73. _parameters.erase(_parameters.begin() + i);
  74. SAFE_RELEASE(p);
  75. break;
  76. }
  77. }
  78. }
  79. /**
  80. * @script{ignore}
  81. */
  82. const char* autoBindingToString(RenderState::AutoBinding autoBinding)
  83. {
  84. // NOTE: As new AutoBinding values are added, this switch statement must be updatd.
  85. switch (autoBinding)
  86. {
  87. case RenderState::NONE:
  88. return NULL;
  89. case RenderState::VIEW_MATRIX:
  90. return "VIEW_MATRIX";
  91. case RenderState::PROJECTION_MATRIX:
  92. return "PROJECTION_MATRIX";
  93. case RenderState::WORLD_VIEW_MATRIX:
  94. return "WORLD_VIEW_MATRIX";
  95. case RenderState::VIEW_PROJECTION_MATRIX:
  96. return "VIEW_PROJECTION_MATRIX";
  97. case RenderState::WORLD_VIEW_PROJECTION_MATRIX:
  98. return "WORLD_VIEW_PROJECTION_MATRIX";
  99. case RenderState::INVERSE_TRANSPOSE_WORLD_MATRIX:
  100. return "INVERSE_TRANSPOSE_WORLD_MATRIX";
  101. case RenderState::INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX:
  102. return "INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX";
  103. case RenderState::CAMERA_WORLD_POSITION:
  104. return "CAMERA_WORLD_POSITION";
  105. case RenderState::CAMERA_VIEW_POSITION:
  106. return "CAMERA_VIEW_POSITION";
  107. case RenderState::MATRIX_PALETTE:
  108. return "MATRIX_PALETTE";
  109. case RenderState::SCENE_AMBIENT_COLOR:
  110. return "SCENE_AMBIENT_COLOR";
  111. case RenderState::SCENE_LIGHT_COLOR:
  112. return "SCENE_LIGHT_COLOR";
  113. case RenderState::SCENE_LIGHT_DIRECTION:
  114. return "SCENE_LIGHT_DIRECTION";
  115. default:
  116. return "";
  117. }
  118. }
  119. void RenderState::setParameterAutoBinding(const char* name, AutoBinding autoBinding)
  120. {
  121. setParameterAutoBinding(name, autoBindingToString(autoBinding));
  122. }
  123. void RenderState::setParameterAutoBinding(const char* name, const char* autoBinding)
  124. {
  125. GP_ASSERT(name);
  126. GP_ASSERT(autoBinding);
  127. if (autoBinding == NULL)
  128. {
  129. // Remove an existing auto-binding
  130. std::map<std::string, std::string>::iterator itr = _autoBindings.find(name);
  131. if (itr != _autoBindings.end())
  132. _autoBindings.erase(itr);
  133. }
  134. else
  135. {
  136. // Add/update an auto-binding
  137. _autoBindings[name] = autoBinding;
  138. }
  139. // If we already have a node binding set, pass it to our handler now
  140. if (_nodeBinding)
  141. {
  142. applyAutoBinding(name, autoBinding);
  143. }
  144. }
  145. void RenderState::setStateBlock(StateBlock* state)
  146. {
  147. if (_state != state)
  148. {
  149. SAFE_RELEASE(_state);
  150. _state = state;
  151. if (_state)
  152. {
  153. _state->addRef();
  154. }
  155. }
  156. }
  157. RenderState::StateBlock* RenderState::getStateBlock() const
  158. {
  159. if (_state == NULL)
  160. {
  161. _state = StateBlock::create();
  162. }
  163. return _state;
  164. }
  165. void RenderState::setNodeBinding(Node* node)
  166. {
  167. if (_nodeBinding != node)
  168. {
  169. _nodeBinding = node;
  170. if (_nodeBinding)
  171. {
  172. // Apply all existing auto-bindings using this node.
  173. std::map<std::string, std::string>::const_iterator itr = _autoBindings.begin();
  174. while (itr != _autoBindings.end())
  175. {
  176. applyAutoBinding(itr->first.c_str(), itr->second.c_str());
  177. ++itr;
  178. }
  179. }
  180. }
  181. }
  182. void RenderState::applyAutoBinding(const char* uniformName, const char* autoBinding)
  183. {
  184. GP_ASSERT(_nodeBinding);
  185. MaterialParameter* param = getParameter(uniformName);
  186. GP_ASSERT(param);
  187. bool bound = false;
  188. // First attempt to resolve the binding using custom registered resolvers.
  189. if (_customAutoBindingResolvers.size() > 0)
  190. {
  191. for (size_t i = 0, count = _customAutoBindingResolvers.size(); i < count; ++i)
  192. {
  193. if (_customAutoBindingResolvers[i](autoBinding, _nodeBinding, param))
  194. {
  195. // Handled by custom auto binding resolver
  196. bound = true;
  197. break;
  198. }
  199. }
  200. }
  201. // Perform built-in resolution
  202. if (!bound)
  203. {
  204. bound = true;
  205. if (strcmp(autoBinding, "WORLD_MATRIX") == 0)
  206. {
  207. param->bindValue(this, &RenderState::autoBindingGetWorldMatrix);
  208. }
  209. else if (strcmp(autoBinding, "VIEW_MATRIX") == 0)
  210. {
  211. param->bindValue(this, &RenderState::autoBindingGetViewMatrix);
  212. }
  213. else if (strcmp(autoBinding, "PROJECTION_MATRIX") == 0)
  214. {
  215. param->bindValue(this, &RenderState::autoBindingGetProjectionMatrix);
  216. }
  217. else if (strcmp(autoBinding, "WORLD_VIEW_MATRIX") == 0)
  218. {
  219. param->bindValue(this, &RenderState::autoBindingGetWorldViewMatrix);
  220. }
  221. else if (strcmp(autoBinding, "VIEW_PROJECTION_MATRIX") == 0)
  222. {
  223. param->bindValue(this, &RenderState::autoBindingGetViewProjectionMatrix);
  224. }
  225. else if (strcmp(autoBinding, "WORLD_VIEW_PROJECTION_MATRIX") == 0)
  226. {
  227. param->bindValue(this, &RenderState::autoBindingGetWorldViewProjectionMatrix);
  228. }
  229. else if (strcmp(autoBinding, "INVERSE_TRANSPOSE_WORLD_MATRIX") == 0)
  230. {
  231. param->bindValue(this, &RenderState::autoBindingGetInverseTransposeWorldMatrix);
  232. }
  233. else if (strcmp(autoBinding, "INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX") == 0)
  234. {
  235. param->bindValue(this, &RenderState::autoBindingGetInverseTransposeWorldViewMatrix);
  236. }
  237. else if (strcmp(autoBinding, "CAMERA_WORLD_POSITION") == 0)
  238. {
  239. param->bindValue(this, &RenderState::autoBindingGetCameraWorldPosition);
  240. }
  241. else if (strcmp(autoBinding, "CAMERA_VIEW_POSITION") == 0)
  242. {
  243. param->bindValue(this, &RenderState::autoBindingGetCameraViewPosition);
  244. }
  245. else if (strcmp(autoBinding, "MATRIX_PALETTE") == 0)
  246. {
  247. param->bindValue(this, &RenderState::autoBindingGetMatrixPalette, &RenderState::autoBindingGetMatrixPaletteSize);
  248. }
  249. else if (strcmp(autoBinding, "SCENE_AMBIENT_COLOR") == 0)
  250. {
  251. param->bindValue(this, &RenderState::autoBindingGetAmbientColor);
  252. }
  253. else if (strcmp(autoBinding, "SCENE_LIGHT_COLOR") == 0)
  254. {
  255. param->bindValue(this, &RenderState::autoBindingGetLightColor);
  256. }
  257. else if (strcmp(autoBinding, "SCENE_LIGHT_DIRECTION") == 0)
  258. {
  259. param->bindValue(this, &RenderState::autoBindingGetLightDirection);
  260. }
  261. else
  262. {
  263. bound = false;
  264. GP_WARN("Unsupported auto binding type (%d).", autoBinding);
  265. }
  266. }
  267. if (bound)
  268. {
  269. // Mark parameter as an auto binding
  270. if (param->_type == MaterialParameter::METHOD && param->_value.method)
  271. param->_value.method->_autoBinding = true;
  272. }
  273. }
  274. const Matrix& RenderState::autoBindingGetWorldMatrix() const
  275. {
  276. return _nodeBinding ? _nodeBinding->getWorldMatrix() : Matrix::identity();
  277. }
  278. const Matrix& RenderState::autoBindingGetViewMatrix() const
  279. {
  280. return _nodeBinding ? _nodeBinding->getViewMatrix() : Matrix::identity();
  281. }
  282. const Matrix& RenderState::autoBindingGetProjectionMatrix() const
  283. {
  284. return _nodeBinding ? _nodeBinding->getProjectionMatrix() : Matrix::identity();
  285. }
  286. const Matrix& RenderState::autoBindingGetWorldViewMatrix() const
  287. {
  288. return _nodeBinding ? _nodeBinding->getWorldViewMatrix() : Matrix::identity();
  289. }
  290. const Matrix& RenderState::autoBindingGetViewProjectionMatrix() const
  291. {
  292. return _nodeBinding ? _nodeBinding->getViewProjectionMatrix() : Matrix::identity();
  293. }
  294. const Matrix& RenderState::autoBindingGetWorldViewProjectionMatrix() const
  295. {
  296. return _nodeBinding ? _nodeBinding->getWorldViewProjectionMatrix() : Matrix::identity();
  297. }
  298. const Matrix& RenderState::autoBindingGetInverseTransposeWorldMatrix() const
  299. {
  300. return _nodeBinding ? _nodeBinding->getInverseTransposeWorldMatrix() : Matrix::identity();
  301. }
  302. const Matrix& RenderState::autoBindingGetInverseTransposeWorldViewMatrix() const
  303. {
  304. return _nodeBinding ? _nodeBinding->getInverseTransposeWorldViewMatrix() : Matrix::identity();
  305. }
  306. Vector3 RenderState::autoBindingGetCameraWorldPosition() const
  307. {
  308. return _nodeBinding ? _nodeBinding->getActiveCameraTranslationWorld() : Vector3::zero();
  309. }
  310. Vector3 RenderState::autoBindingGetCameraViewPosition() const
  311. {
  312. return _nodeBinding ? _nodeBinding->getActiveCameraTranslationView() : Vector3::zero();
  313. }
  314. const Vector4* RenderState::autoBindingGetMatrixPalette() const
  315. {
  316. Model* model = _nodeBinding ? _nodeBinding->getModel() : NULL;
  317. MeshSkin* skin = model ? model->getSkin() : NULL;
  318. return skin ? skin->getMatrixPalette() : NULL;
  319. }
  320. unsigned int RenderState::autoBindingGetMatrixPaletteSize() const
  321. {
  322. Model* model = _nodeBinding ? _nodeBinding->getModel() : NULL;
  323. MeshSkin* skin = model ? model->getSkin() : NULL;
  324. return skin ? skin->getMatrixPaletteSize() : 0;
  325. }
  326. const Vector3& RenderState::autoBindingGetAmbientColor() const
  327. {
  328. Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
  329. return scene ? scene->getAmbientColor() : Vector3::zero();
  330. }
  331. const Vector3& RenderState::autoBindingGetLightColor() const
  332. {
  333. Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
  334. return scene ? scene->getLightColor() : Vector3::one();
  335. }
  336. const Vector3& RenderState::autoBindingGetLightDirection() const
  337. {
  338. static Vector3 down(0, -1, 0);
  339. Scene* scene = _nodeBinding ? _nodeBinding->getScene() : NULL;
  340. return scene ? scene->getLightDirection() : down;
  341. }
  342. void RenderState::bind(Pass* pass)
  343. {
  344. GP_ASSERT(pass);
  345. // Get the combined modified state bits for our RenderState hierarchy.
  346. long stateOverrideBits = _state ? _state->_bits : 0;
  347. RenderState* rs = _parent;
  348. while (rs)
  349. {
  350. if (rs->_state)
  351. {
  352. stateOverrideBits |= rs->_state->_bits;
  353. }
  354. rs = rs->_parent;
  355. }
  356. // Restore renderer state to its default, except for explicitly specified states
  357. StateBlock::restore(stateOverrideBits);
  358. // Apply parameter bindings and renderer state for the entire hierarchy, top-down.
  359. rs = NULL;
  360. Effect* effect = pass->getEffect();
  361. while ((rs = getTopmost(rs)))
  362. {
  363. for (size_t i = 0, count = rs->_parameters.size(); i < count; ++i)
  364. {
  365. GP_ASSERT(rs->_parameters[i]);
  366. rs->_parameters[i]->bind(effect);
  367. }
  368. if (rs->_state)
  369. {
  370. rs->_state->bindNoRestore();
  371. }
  372. }
  373. }
  374. RenderState* RenderState::getTopmost(RenderState* below)
  375. {
  376. RenderState* rs = this;
  377. if (rs == below)
  378. {
  379. // Nothing below ourself.
  380. return NULL;
  381. }
  382. while (rs)
  383. {
  384. if (rs->_parent == below || rs->_parent == NULL)
  385. {
  386. // Stop traversing up here.
  387. return rs;
  388. }
  389. rs = rs->_parent;
  390. }
  391. return NULL;
  392. }
  393. void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context) const
  394. {
  395. GP_ASSERT(renderState);
  396. // Clone parameters
  397. for (std::map<std::string, std::string>::const_iterator it = _autoBindings.begin(); it != _autoBindings.end(); ++it)
  398. {
  399. renderState->setParameterAutoBinding(it->first.c_str(), it->second.c_str());
  400. }
  401. for (std::vector<MaterialParameter*>::const_iterator it = _parameters.begin(); it != _parameters.end(); ++it)
  402. {
  403. const MaterialParameter* param = *it;
  404. GP_ASSERT(param);
  405. // If this parameter is a method binding auto binding, don't clone it - it will get setup automatically
  406. // via the cloned auto bindings instead.
  407. if (param->_type == MaterialParameter::METHOD && param->_value.method && param->_value.method->_autoBinding)
  408. continue;
  409. MaterialParameter* paramCopy = new MaterialParameter(param->getName());
  410. param->cloneInto(paramCopy);
  411. renderState->_parameters.push_back(paramCopy);
  412. }
  413. // Clone our state block
  414. if (_state)
  415. {
  416. _state->cloneInto(renderState->getStateBlock());
  417. }
  418. // Notes:
  419. // 1. _nodeBinding should not be set here, it should be set by the caller.
  420. // 2. _parent should not be set here, since it's set in the constructor of Technique and Pass.
  421. }
  422. RenderState::StateBlock::StateBlock()
  423. : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(true), _depthFunction(RenderState::DEPTH_LESS),
  424. _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
  425. _bits(0L)
  426. {
  427. }
  428. RenderState::StateBlock::StateBlock(const StateBlock& copy)
  429. {
  430. // Hidden
  431. }
  432. RenderState::StateBlock::~StateBlock()
  433. {
  434. }
  435. RenderState::StateBlock* RenderState::StateBlock::create()
  436. {
  437. return new RenderState::StateBlock();
  438. }
  439. void RenderState::StateBlock::bind()
  440. {
  441. // When the public bind() is called with no RenderState object passed in,
  442. // we assume we are being called to bind the state of a single StateBlock,
  443. // irrespective of whether it belongs to a hierarchy of RenderStates.
  444. // Therefore, we call restore() here with only this StateBlock's override
  445. // bits to restore state before applying the new state.
  446. StateBlock::restore(_bits);
  447. bindNoRestore();
  448. }
  449. void RenderState::StateBlock::bindNoRestore()
  450. {
  451. GP_ASSERT(_defaultState);
  452. // Update any state that differs from _defaultState and flip _defaultState bits
  453. if ((_bits & RS_BLEND) && (_blendEnabled != _defaultState->_blendEnabled))
  454. {
  455. if (_blendEnabled)
  456. GL_ASSERT( glEnable(GL_BLEND) );
  457. else
  458. GL_ASSERT( glDisable(GL_BLEND) );
  459. _defaultState->_blendEnabled = _blendEnabled;
  460. }
  461. if ((_bits & RS_BLEND_FUNC) && (_blendSrc != _defaultState->_blendSrc || _blendDst != _defaultState->_blendDst))
  462. {
  463. GL_ASSERT( glBlendFunc((GLenum)_blendSrc, (GLenum)_blendDst) );
  464. _defaultState->_blendSrc = _blendSrc;
  465. _defaultState->_blendDst = _blendDst;
  466. }
  467. if ((_bits & RS_CULL_FACE) && (_cullFaceEnabled != _defaultState->_cullFaceEnabled))
  468. {
  469. if (_cullFaceEnabled)
  470. GL_ASSERT( glEnable(GL_CULL_FACE) );
  471. else
  472. GL_ASSERT( glDisable(GL_CULL_FACE) );
  473. _defaultState->_cullFaceEnabled = _cullFaceEnabled;
  474. }
  475. if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
  476. {
  477. if (_depthTestEnabled)
  478. GL_ASSERT( glEnable(GL_DEPTH_TEST) );
  479. else
  480. GL_ASSERT( glDisable(GL_DEPTH_TEST) );
  481. _defaultState->_depthTestEnabled = _depthTestEnabled;
  482. }
  483. if ((_bits & RS_DEPTH_WRITE) && (_depthWriteEnabled != _defaultState->_depthWriteEnabled))
  484. {
  485. GL_ASSERT( glDepthMask(_depthWriteEnabled ? GL_TRUE : GL_FALSE) );
  486. _defaultState->_depthWriteEnabled = _depthWriteEnabled;
  487. }
  488. if ((_bits & RS_DEPTH_FUNC) && (_depthFunction != _defaultState->_depthFunction))
  489. {
  490. GL_ASSERT( glDepthFunc((GLenum)_depthFunction) );
  491. _defaultState->_depthFunction = _depthFunction;
  492. }
  493. _defaultState->_bits |= _bits;
  494. }
  495. void RenderState::StateBlock::restore(long stateOverrideBits)
  496. {
  497. GP_ASSERT(_defaultState);
  498. // If there is no state to restore (i.e. no non-default state), do nothing.
  499. if (_defaultState->_bits == 0)
  500. {
  501. return;
  502. }
  503. // Restore any state that is not overridden and is not default
  504. if (!(stateOverrideBits & RS_BLEND) && (_defaultState->_bits & RS_BLEND))
  505. {
  506. GL_ASSERT( glDisable(GL_BLEND) );
  507. _defaultState->_bits &= ~RS_BLEND;
  508. _defaultState->_blendEnabled = false;
  509. }
  510. if (!(stateOverrideBits & RS_BLEND_FUNC) && (_defaultState->_bits & RS_BLEND_FUNC))
  511. {
  512. GL_ASSERT( glBlendFunc(GL_ONE, GL_ZERO) );
  513. _defaultState->_bits &= ~RS_BLEND_FUNC;
  514. _defaultState->_blendSrc = RenderState::BLEND_ONE;
  515. _defaultState->_blendDst = RenderState::BLEND_ZERO;
  516. }
  517. if (!(stateOverrideBits & RS_CULL_FACE) && (_defaultState->_bits & RS_CULL_FACE))
  518. {
  519. GL_ASSERT( glDisable(GL_CULL_FACE) );
  520. _defaultState->_bits &= ~RS_CULL_FACE;
  521. _defaultState->_cullFaceEnabled = false;
  522. }
  523. if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState->_bits & RS_DEPTH_TEST))
  524. {
  525. GL_ASSERT( glDisable(GL_DEPTH_TEST) );
  526. _defaultState->_bits &= ~RS_DEPTH_TEST;
  527. _defaultState->_depthTestEnabled = false;
  528. }
  529. if (!(stateOverrideBits & RS_DEPTH_WRITE) && (_defaultState->_bits & RS_DEPTH_WRITE))
  530. {
  531. GL_ASSERT( glDepthMask(GL_TRUE) );
  532. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  533. _defaultState->_depthWriteEnabled = true;
  534. }
  535. if (!(stateOverrideBits & RS_DEPTH_FUNC) && (_defaultState->_bits & RS_DEPTH_FUNC))
  536. {
  537. GL_ASSERT( glDepthFunc((GLenum)GL_LESS) );
  538. _defaultState->_bits &= ~RS_DEPTH_FUNC;
  539. _defaultState->_depthFunction = RenderState::DEPTH_LESS;
  540. }
  541. }
  542. void RenderState::StateBlock::enableDepthWrite()
  543. {
  544. GP_ASSERT(_defaultState);
  545. // Internal method used by Game::clear() to restore depth writing before a
  546. // clear operation. This is necessary if the last code to draw before the
  547. // next frame leaves depth writing disabled.
  548. if (!_defaultState->_depthWriteEnabled)
  549. {
  550. GL_ASSERT( glDepthMask(GL_TRUE) );
  551. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  552. _defaultState->_depthWriteEnabled = true;
  553. }
  554. }
  555. void RenderState::StateBlock::cloneInto(StateBlock* state)
  556. {
  557. GP_ASSERT(state);
  558. state->_cullFaceEnabled = _cullFaceEnabled;
  559. state->_depthTestEnabled = _depthTestEnabled;
  560. state->_depthWriteEnabled = _depthWriteEnabled;
  561. state->_depthFunction = _depthFunction;
  562. state->_blendEnabled = _blendEnabled;
  563. state->_blendSrc = _blendSrc;
  564. state->_blendDst = _blendDst;
  565. state->_bits = _bits;
  566. }
  567. static bool parseBoolean(const char* value)
  568. {
  569. GP_ASSERT(value);
  570. if (strlen(value) == 4)
  571. {
  572. return (
  573. tolower(value[0]) == 't' &&
  574. tolower(value[1]) == 'r' &&
  575. tolower(value[2]) == 'u' &&
  576. tolower(value[3]) == 'e' );
  577. }
  578. return false;
  579. }
  580. static RenderState::Blend parseBlend(const char* value)
  581. {
  582. GP_ASSERT(value);
  583. // Convert the string to uppercase for comparison.
  584. std::string upper(value);
  585. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  586. if (upper == "ZERO")
  587. return RenderState::BLEND_ZERO;
  588. else if (upper == "ONE")
  589. return RenderState::BLEND_ONE;
  590. else if (upper == "SRC_COLOR")
  591. return RenderState::BLEND_SRC_COLOR;
  592. else if (upper == "ONE_MINUS_SRC_COLOR")
  593. return RenderState::BLEND_ONE_MINUS_SRC_COLOR;
  594. else if (upper == "DST_COLOR")
  595. return RenderState::BLEND_DST_COLOR;
  596. else if (upper == "ONE_MINUS_DST_COLOR")
  597. return RenderState::BLEND_ONE_MINUS_DST_COLOR;
  598. else if (upper == "SRC_ALPHA")
  599. return RenderState::BLEND_SRC_ALPHA;
  600. else if (upper == "ONE_MINUS_SRC_ALPHA")
  601. return RenderState::BLEND_ONE_MINUS_SRC_ALPHA;
  602. else if (upper == "DST_ALPHA")
  603. return RenderState::BLEND_DST_ALPHA;
  604. else if (upper == "ONE_MINUS_DST_ALPHA")
  605. return RenderState::BLEND_ONE_MINUS_DST_ALPHA;
  606. else if (upper == "CONSTANT_ALPHA")
  607. return RenderState::BLEND_CONSTANT_ALPHA;
  608. else if (upper == "ONE_MINUS_CONSTANT_ALPHA")
  609. return RenderState::BLEND_ONE_MINUS_CONSTANT_ALPHA;
  610. else if (upper == "SRC_ALPHA_SATURATE")
  611. return RenderState::BLEND_SRC_ALPHA_SATURATE;
  612. else
  613. {
  614. GP_ERROR("Unsupported blend value (%s). (Will default to BLEND_ONE if errors are treated as warnings)", value);
  615. return RenderState::BLEND_ONE;
  616. }
  617. }
  618. static RenderState::DepthFunction parseDepthFunc(const char* value)
  619. {
  620. GP_ASSERT(value);
  621. // Convert string to uppercase for comparison
  622. std::string upper(value);
  623. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  624. if (upper == "NEVER")
  625. return RenderState::DEPTH_NEVER;
  626. else if (upper == "LESS")
  627. return RenderState::DEPTH_LESS;
  628. else if (upper == "EQUAL")
  629. return RenderState::DEPTH_EQUAL;
  630. else if (upper == "LEQUAL")
  631. return RenderState::DEPTH_LEQUAL;
  632. else if (upper == "GREATER")
  633. return RenderState::DEPTH_GREATER;
  634. else if (upper == "NOTEQUAL")
  635. return RenderState::DEPTH_NOTEQUAL;
  636. else if (upper == "GEQUAL")
  637. return RenderState::DEPTH_GEQUAL;
  638. else if (upper == "ALWAYS")
  639. return RenderState::DEPTH_ALWAYS;
  640. else
  641. {
  642. GP_ERROR("Unsupported depth function value (%s). Will default to DEPTH_LESS if errors are treated as warnings)", value);
  643. return RenderState::DEPTH_LESS;
  644. }
  645. }
  646. void RenderState::StateBlock::setState(const char* name, const char* value)
  647. {
  648. GP_ASSERT(name);
  649. if (strcmp(name, "blend") == 0)
  650. {
  651. setBlend(parseBoolean(value));
  652. }
  653. else if (strcmp(name, "blendSrc") == 0 || strcmp(name, "srcBlend") == 0 ) // Leaving srcBlend for backward compat.
  654. {
  655. setBlendSrc(parseBlend(value));
  656. }
  657. else if (strcmp(name, "blendDst") == 0 || strcmp(name, "dstBlend") == 0) // // Leaving dstBlend for backward compat.
  658. {
  659. setBlendDst(parseBlend(value));
  660. }
  661. else if (strcmp(name, "cullFace") == 0)
  662. {
  663. setCullFace(parseBoolean(value));
  664. }
  665. else if (strcmp(name, "depthTest") == 0)
  666. {
  667. setDepthTest(parseBoolean(value));
  668. }
  669. else if (strcmp(name, "depthWrite") == 0)
  670. {
  671. setDepthWrite(parseBoolean(value));
  672. }
  673. else if (strcmp(name, "depthFunc") == 0)
  674. {
  675. setDepthFunction(parseDepthFunc(value));
  676. }
  677. else
  678. {
  679. GP_ERROR("Unsupported render state string '%s'.", name);
  680. }
  681. }
  682. void RenderState::StateBlock::setBlend(bool enabled)
  683. {
  684. _blendEnabled = enabled;
  685. if (!enabled)
  686. {
  687. _bits &= ~RS_BLEND;
  688. }
  689. else
  690. {
  691. _bits |= RS_BLEND;
  692. }
  693. }
  694. void RenderState::StateBlock::setBlendSrc(Blend blend)
  695. {
  696. _blendSrc = blend;
  697. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  698. {
  699. // Default blend func
  700. _bits &= ~RS_BLEND_FUNC;
  701. }
  702. else
  703. {
  704. _bits |= RS_BLEND_FUNC;
  705. }
  706. }
  707. void RenderState::StateBlock::setBlendDst(Blend blend)
  708. {
  709. _blendDst = blend;
  710. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  711. {
  712. // Default blend func
  713. _bits &= ~RS_BLEND_FUNC;
  714. }
  715. else
  716. {
  717. _bits |= RS_BLEND_FUNC;
  718. }
  719. }
  720. void RenderState::StateBlock::setCullFace(bool enabled)
  721. {
  722. _cullFaceEnabled = enabled;
  723. if (!enabled)
  724. {
  725. _bits &= ~RS_CULL_FACE;
  726. }
  727. else
  728. {
  729. _bits |= RS_CULL_FACE;
  730. }
  731. }
  732. void RenderState::StateBlock::setDepthTest(bool enabled)
  733. {
  734. _depthTestEnabled = enabled;
  735. if (!enabled)
  736. {
  737. _bits &= ~RS_DEPTH_TEST;
  738. }
  739. else
  740. {
  741. _bits |= RS_DEPTH_TEST;
  742. }
  743. }
  744. void RenderState::StateBlock::setDepthWrite(bool enabled)
  745. {
  746. _depthWriteEnabled = enabled;
  747. if (enabled)
  748. {
  749. _bits &= ~RS_DEPTH_WRITE;
  750. }
  751. else
  752. {
  753. _bits |= RS_DEPTH_WRITE;
  754. }
  755. }
  756. void RenderState::StateBlock::setDepthFunction(DepthFunction func)
  757. {
  758. _depthFunction = func;
  759. if (_depthFunction == DEPTH_LESS)
  760. {
  761. // Default depth function
  762. _bits &= ~RS_DEPTH_FUNC;
  763. }
  764. else
  765. {
  766. _bits |= RS_DEPTH_FUNC;
  767. }
  768. }
  769. }