RenderState.cpp 21 KB

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