RenderState.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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. // Render state override bits
  8. #define RS_BLEND 1
  9. #define RS_BLEND_FUNC 2
  10. #define RS_CULL_FACE 4
  11. #define RS_DEPTH_TEST 8
  12. #define RS_DEPTH_WRITE 16
  13. namespace gameplay
  14. {
  15. RenderState::StateBlock* RenderState::StateBlock::_defaultState = NULL;
  16. std::vector<RenderState::ResolveAutoBindingCallback> RenderState::_customAutoBindingResolvers;
  17. RenderState::RenderState()
  18. : _nodeBinding(NULL), _state(NULL), _parent(NULL)
  19. {
  20. }
  21. RenderState::~RenderState()
  22. {
  23. SAFE_RELEASE(_state);
  24. // Destroy all the material parameters
  25. for (unsigned int i = 0, count = _parameters.size(); i < count; ++i)
  26. {
  27. SAFE_RELEASE(_parameters[i]);
  28. }
  29. }
  30. void RenderState::initialize()
  31. {
  32. if (StateBlock::_defaultState == NULL)
  33. {
  34. StateBlock::_defaultState = StateBlock::create();
  35. }
  36. }
  37. void RenderState::finalize()
  38. {
  39. SAFE_RELEASE(StateBlock::_defaultState);
  40. }
  41. void RenderState::registerAutoBindingResolver(ResolveAutoBindingCallback callback)
  42. {
  43. _customAutoBindingResolvers.push_back(callback);
  44. }
  45. MaterialParameter* RenderState::getParameter(const char* name) const
  46. {
  47. GP_ASSERT(name);
  48. // Search for an existing parameter with this name.
  49. MaterialParameter* param;
  50. for (unsigned int i = 0, count = _parameters.size(); i < count; ++i)
  51. {
  52. param = _parameters[i];
  53. GP_ASSERT(param);
  54. if (strcmp(param->getName(), name) == 0)
  55. {
  56. return param;
  57. }
  58. }
  59. // Create a new parameter and store it in our list.
  60. param = new MaterialParameter(name);
  61. _parameters.push_back(param);
  62. return param;
  63. }
  64. const char* autoBindingToString(RenderState::AutoBinding autoBinding)
  65. {
  66. // NOTE: As new AutoBinding values are added, this switch statement must be updatd.
  67. switch (autoBinding)
  68. {
  69. case RenderState::NONE:
  70. return NULL;
  71. case RenderState::VIEW_MATRIX:
  72. return "VIEW_MATRIX";
  73. case RenderState::PROJECTION_MATRIX:
  74. return "PROJECTION_MATRIX";
  75. case RenderState::WORLD_VIEW_MATRIX:
  76. return "WORLD_VIEW_MATRIX";
  77. case RenderState::VIEW_PROJECTION_MATRIX:
  78. return "VIEW_PROJECTION_MATRIX";
  79. case RenderState::WORLD_VIEW_PROJECTION_MATRIX:
  80. return "WORLD_VIEW_PROJECTION_MATRIX";
  81. case RenderState::INVERSE_TRANSPOSE_WORLD_MATRIX:
  82. return "INVERSE_TRANSPOSE_WORLD_MATRIX";
  83. case RenderState::INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX:
  84. return "INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX";
  85. case RenderState::CAMERA_WORLD_POSITION:
  86. return "CAMERA_WORLD_POSITION";
  87. case RenderState::CAMERA_VIEW_POSITION:
  88. return "CAMERA_VIEW_POSITION";
  89. case RenderState::MATRIX_PALETTE:
  90. return "MATRIX_PALETTE";
  91. }
  92. }
  93. void RenderState::setParameterAutoBinding(const char* name, AutoBinding autoBinding)
  94. {
  95. setParameterAutoBinding(name, autoBindingToString(autoBinding));
  96. }
  97. void RenderState::setParameterAutoBinding(const char* name, const char* autoBinding)
  98. {
  99. GP_ASSERT(name);
  100. GP_ASSERT(autoBinding);
  101. if (autoBinding == NULL)
  102. {
  103. // Remove an existing auto-binding
  104. std::map<std::string, std::string>::iterator itr = _autoBindings.find(name);
  105. if (itr != _autoBindings.end())
  106. _autoBindings.erase(itr);
  107. }
  108. else
  109. {
  110. // Add/update an auto-binding
  111. _autoBindings[name] = autoBinding;
  112. }
  113. // If we already have a node binding set, pass it to our handler now
  114. if (_nodeBinding)
  115. {
  116. applyAutoBinding(name, autoBinding);
  117. }
  118. }
  119. void RenderState::setStateBlock(StateBlock* state)
  120. {
  121. if (_state != state)
  122. {
  123. SAFE_RELEASE(_state);
  124. _state = state;
  125. if (_state)
  126. {
  127. _state->addRef();
  128. }
  129. }
  130. }
  131. RenderState::StateBlock* RenderState::getStateBlock() const
  132. {
  133. if (_state == NULL)
  134. {
  135. _state = StateBlock::create();
  136. }
  137. return _state;
  138. }
  139. void RenderState::setNodeBinding(Node* node)
  140. {
  141. if (_nodeBinding != node)
  142. {
  143. _nodeBinding = node;
  144. if (_nodeBinding)
  145. {
  146. // Apply all existing auto-bindings using this node.
  147. std::map<std::string, std::string>::const_iterator itr = _autoBindings.begin();
  148. while (itr != _autoBindings.end())
  149. {
  150. applyAutoBinding(itr->first.c_str(), itr->second.c_str());
  151. ++itr;
  152. }
  153. }
  154. }
  155. }
  156. void RenderState::applyAutoBinding(const char* uniformName, const char* autoBinding)
  157. {
  158. MaterialParameter* param = getParameter(uniformName);
  159. GP_ASSERT(param);
  160. // First attempt to resolve the binding using custom registered resolvers.
  161. if (_customAutoBindingResolvers.size() > 0)
  162. {
  163. for (size_t i = 0, count = _customAutoBindingResolvers.size(); i < count; ++i)
  164. {
  165. if (_customAutoBindingResolvers[i](autoBinding, _nodeBinding, param))
  166. return; // handled by custom resolver
  167. }
  168. }
  169. // Perform built-in resolution
  170. if (strcmp(autoBinding, "WORLD_MATRIX") == 0)
  171. {
  172. param->bindValue(_nodeBinding, &Node::getWorldMatrix);
  173. }
  174. else if (strcmp(autoBinding, "VIEW_MATRIX") == 0)
  175. {
  176. param->bindValue(_nodeBinding, &Node::getViewMatrix);
  177. }
  178. else if (strcmp(autoBinding, "PROJECTION_MATRIX") == 0)
  179. {
  180. param->bindValue(_nodeBinding, &Node::getProjectionMatrix);
  181. }
  182. else if (strcmp(autoBinding, "WORLD_VIEW_MATRIX") == 0)
  183. {
  184. param->bindValue(_nodeBinding, &Node::getWorldViewMatrix);
  185. }
  186. else if (strcmp(autoBinding, "VIEW_PROJECTION_MATRIX") == 0)
  187. {
  188. param->bindValue(_nodeBinding, &Node::getViewProjectionMatrix);
  189. }
  190. else if (strcmp(autoBinding, "WORLD_VIEW_PROJECTION_MATRIX") == 0)
  191. {
  192. param->bindValue(_nodeBinding, &Node::getWorldViewProjectionMatrix);
  193. }
  194. else if (strcmp(autoBinding, "INVERSE_TRANSPOSE_WORLD_MATRIX") == 0)
  195. {
  196. param->bindValue(_nodeBinding, &Node::getInverseTransposeWorldMatrix);
  197. }
  198. else if (strcmp(autoBinding, "INVERSE_TRANSPOSE_WORLD_VIEW_MATRIX") == 0)
  199. {
  200. param->bindValue(_nodeBinding, &Node::getInverseTransposeWorldViewMatrix);
  201. }
  202. else if (strcmp(autoBinding, "CAMERA_WORLD_POSITION") == 0)
  203. {
  204. param->bindValue(_nodeBinding, &Node::getActiveCameraTranslationWorld);
  205. }
  206. else if (strcmp(autoBinding, "CAMERA_VIEW_POSITION") == 0)
  207. {
  208. param->bindValue(_nodeBinding, &Node::getActiveCameraTranslationView);
  209. }
  210. else if (strcmp(autoBinding, "MATRIX_PALETTE") == 0)
  211. {
  212. Model* model = _nodeBinding->getModel();
  213. MeshSkin* skin = model ? model->getSkin() : NULL;
  214. if (skin)
  215. {
  216. GP_ASSERT(param);
  217. param->bindValue(skin, &MeshSkin::getMatrixPalette, &MeshSkin::getMatrixPaletteSize);
  218. }
  219. }
  220. else
  221. {
  222. GP_WARN("Unsupported auto binding type (%d).", autoBinding);
  223. }
  224. }
  225. void RenderState::bind(Pass* pass)
  226. {
  227. GP_ASSERT(pass);
  228. // Get the combined modified state bits for our RenderState hierarchy.
  229. long stateOverrideBits = _state ? _state->_bits : 0;
  230. RenderState* rs = _parent;
  231. while (rs)
  232. {
  233. if (rs->_state)
  234. {
  235. stateOverrideBits |= rs->_state->_bits;
  236. }
  237. rs = rs->_parent;
  238. }
  239. // Restore renderer state to its default, except for explicitly specified states
  240. StateBlock::restore(stateOverrideBits);
  241. // Apply parameter bindings and renderer state for the entire hierarchy, top-down.
  242. rs = NULL;
  243. Effect* effect = pass->getEffect();
  244. while ((rs = getTopmost(rs)))
  245. {
  246. for (unsigned int i = 0, count = rs->_parameters.size(); i < count; ++i)
  247. {
  248. GP_ASSERT(rs->_parameters[i]);
  249. rs->_parameters[i]->bind(effect);
  250. }
  251. if (rs->_state)
  252. {
  253. rs->_state->bindNoRestore();
  254. }
  255. }
  256. }
  257. RenderState* RenderState::getTopmost(RenderState* below)
  258. {
  259. RenderState* rs = this;
  260. if (rs == below)
  261. {
  262. // Nothing below ourself.
  263. return NULL;
  264. }
  265. while (rs)
  266. {
  267. if (rs->_parent == below || rs->_parent == NULL)
  268. {
  269. // Stop traversing up here.
  270. return rs;
  271. }
  272. rs = rs->_parent;
  273. }
  274. return NULL;
  275. }
  276. void RenderState::cloneInto(RenderState* renderState, NodeCloneContext& context) const
  277. {
  278. GP_ASSERT(renderState);
  279. for (std::map<std::string, std::string>::const_iterator it = _autoBindings.begin(); it != _autoBindings.end(); ++it)
  280. {
  281. renderState->setParameterAutoBinding(it->first.c_str(), it->second.c_str());
  282. }
  283. for (std::vector<MaterialParameter*>::const_iterator it = _parameters.begin(); it != _parameters.end(); ++it)
  284. {
  285. const MaterialParameter* param = *it;
  286. GP_ASSERT(param);
  287. MaterialParameter* paramCopy = new MaterialParameter(param->getName());
  288. param->cloneInto(paramCopy);
  289. renderState->_parameters.push_back(paramCopy);
  290. }
  291. renderState->_parent = _parent;
  292. if (Node* node = context.findClonedNode(_nodeBinding))
  293. {
  294. renderState->setNodeBinding(node);
  295. }
  296. if (_state)
  297. {
  298. renderState->setStateBlock(_state);
  299. }
  300. }
  301. RenderState::StateBlock::StateBlock()
  302. : _cullFaceEnabled(false), _depthTestEnabled(false), _depthWriteEnabled(false),
  303. _blendEnabled(false), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO),
  304. _bits(0L)
  305. {
  306. }
  307. RenderState::StateBlock::StateBlock(const StateBlock& copy)
  308. {
  309. // Hidden
  310. }
  311. RenderState::StateBlock::~StateBlock()
  312. {
  313. }
  314. RenderState::StateBlock* RenderState::StateBlock::create()
  315. {
  316. return new RenderState::StateBlock();
  317. }
  318. void RenderState::StateBlock::bind()
  319. {
  320. // When the public bind() is called with no RenderState object passed in,
  321. // we assume we are being called to bind the state of a single StateBlock,
  322. // irrespective of whether it belongs to a hierarchy of RenderStates.
  323. // Therefore, we call restore() here with only this StateBlock's override
  324. // bits to restore state before applying the new state.
  325. StateBlock::restore(_bits);
  326. bindNoRestore();
  327. }
  328. void RenderState::StateBlock::bindNoRestore()
  329. {
  330. GP_ASSERT(_defaultState);
  331. // Update any state that differs from _defaultState and flip _defaultState bits
  332. if ((_bits & RS_BLEND) && (_blendEnabled != _defaultState->_blendEnabled))
  333. {
  334. if (_blendEnabled)
  335. GL_ASSERT( glEnable(GL_BLEND) );
  336. else
  337. GL_ASSERT( glDisable(GL_BLEND) );
  338. _defaultState->_blendEnabled = _blendEnabled;
  339. }
  340. if ((_bits & RS_BLEND_FUNC) && (_blendSrc != _defaultState->_blendSrc || _blendDst != _defaultState->_blendDst))
  341. {
  342. GL_ASSERT( glBlendFunc((GLenum)_blendSrc, (GLenum)_blendDst) );
  343. _defaultState->_blendSrc = _blendSrc;
  344. _defaultState->_blendDst = _blendDst;
  345. }
  346. if ((_bits & RS_CULL_FACE) && (_cullFaceEnabled != _defaultState->_cullFaceEnabled))
  347. {
  348. if (_cullFaceEnabled)
  349. GL_ASSERT( glEnable(GL_CULL_FACE) );
  350. else
  351. GL_ASSERT( glDisable(GL_CULL_FACE) );
  352. _defaultState->_cullFaceEnabled = _cullFaceEnabled;
  353. }
  354. if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
  355. {
  356. if (_depthTestEnabled)
  357. GL_ASSERT( glEnable(GL_DEPTH_TEST) );
  358. else
  359. GL_ASSERT( glDisable(GL_DEPTH_TEST) );
  360. _defaultState->_depthTestEnabled = _depthTestEnabled;
  361. }
  362. if ((_bits & RS_DEPTH_WRITE) && (_depthWriteEnabled != _defaultState->_depthWriteEnabled))
  363. {
  364. GL_ASSERT( glDepthMask(_depthWriteEnabled ? GL_TRUE : GL_FALSE) );
  365. _defaultState->_depthWriteEnabled = _depthWriteEnabled;
  366. }
  367. _defaultState->_bits |= _bits;
  368. }
  369. void RenderState::StateBlock::restore(long stateOverrideBits)
  370. {
  371. GP_ASSERT(_defaultState);
  372. // If there is no state to restore (i.e. no non-default state), do nothing.
  373. if (_defaultState->_bits == 0)
  374. {
  375. return;
  376. }
  377. // Restore any state that is not overridden and is not default
  378. if (!(stateOverrideBits & RS_BLEND) && (_defaultState->_bits & RS_BLEND))
  379. {
  380. GL_ASSERT( glDisable(GL_BLEND) );
  381. _defaultState->_bits &= ~RS_BLEND;
  382. _defaultState->_blendEnabled = false;
  383. }
  384. if (!(stateOverrideBits & RS_BLEND_FUNC) && (_defaultState->_bits & RS_BLEND_FUNC))
  385. {
  386. GL_ASSERT( glBlendFunc(GL_ONE, GL_ZERO) );
  387. _defaultState->_bits &= ~RS_BLEND_FUNC;
  388. _defaultState->_blendSrc = RenderState::BLEND_ONE;
  389. _defaultState->_blendDst = RenderState::BLEND_ZERO;
  390. }
  391. if (!(stateOverrideBits & RS_CULL_FACE) && (_defaultState->_bits & RS_CULL_FACE))
  392. {
  393. GL_ASSERT( glDisable(GL_CULL_FACE) );
  394. _defaultState->_bits &= ~RS_CULL_FACE;
  395. _defaultState->_cullFaceEnabled = false;
  396. }
  397. if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState->_bits & RS_DEPTH_TEST))
  398. {
  399. GL_ASSERT( glDisable(GL_DEPTH_TEST) );
  400. _defaultState->_bits &= ~RS_DEPTH_TEST;
  401. _defaultState->_depthTestEnabled = false;
  402. }
  403. if (!(stateOverrideBits & RS_DEPTH_WRITE) && (_defaultState->_bits & RS_DEPTH_WRITE))
  404. {
  405. GL_ASSERT( glDepthMask(GL_TRUE) );
  406. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  407. _defaultState->_depthWriteEnabled = true;
  408. }
  409. }
  410. void RenderState::StateBlock::enableDepthWrite()
  411. {
  412. GP_ASSERT(_defaultState);
  413. // Internal method used by Game::clear() to restore depth writing before a
  414. // clear operation. This is necessary if the last code to draw before the
  415. // next frame leaves depth writing disabled.
  416. if (!_defaultState->_depthWriteEnabled)
  417. {
  418. GL_ASSERT( glDepthMask(GL_TRUE) );
  419. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  420. _defaultState->_depthWriteEnabled = true;
  421. }
  422. }
  423. static bool parseBoolean(const char* value)
  424. {
  425. GP_ASSERT(value);
  426. if (strlen(value) == 4)
  427. {
  428. return (
  429. tolower(value[0]) == 't' &&
  430. tolower(value[1]) == 'r' &&
  431. tolower(value[2]) == 'u' &&
  432. tolower(value[3]) == 'e' );
  433. }
  434. return false;
  435. }
  436. static RenderState::Blend parseBlend(const char* value)
  437. {
  438. GP_ASSERT(value);
  439. // Convert the string to uppercase for comparison.
  440. std::string upper(value);
  441. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  442. if (upper == "ZERO")
  443. return RenderState::BLEND_ZERO;
  444. else if (upper == "ONE")
  445. return RenderState::BLEND_ONE;
  446. else if (upper == "SRC_ALPHA")
  447. return RenderState::BLEND_SRC_ALPHA;
  448. else if (upper == "ONE_MINUS_SRC_ALPHA")
  449. return RenderState::BLEND_ONE_MINUS_SRC_ALPHA;
  450. else if (upper == "DST_ALPHA")
  451. return RenderState::BLEND_DST_ALPHA;
  452. else if (upper == "ONE_MINUS_DST_ALPHA")
  453. return RenderState::BLEND_ONE_MINUS_DST_ALPHA;
  454. else if (upper == "CONSTANT_ALPHA")
  455. return RenderState::BLEND_CONSTANT_ALPHA;
  456. else if (upper == "ONE_MINUS_CONSTANT_ALPHA")
  457. return RenderState::BLEND_ONE_MINUS_CONSTANT_ALPHA;
  458. else if (upper == "SRC_ALPHA_SATURATE")
  459. return RenderState::BLEND_SRC_ALPHA_SATURATE;
  460. else
  461. {
  462. GP_ERROR("Unsupported blend value (%s). (Will default to BLEND_ONE if errors are treated as warnings)", value);
  463. return RenderState::BLEND_ONE;
  464. }
  465. }
  466. void RenderState::StateBlock::setState(const char* name, const char* value)
  467. {
  468. GP_ASSERT(name);
  469. if (strcmp(name, "blend") == 0)
  470. {
  471. setBlend(parseBoolean(value));
  472. }
  473. else if (strcmp(name, "blendSrc") == 0 || strcmp(name, "srcBlend") == 0 ) // Leaving srcBlend for backward compat.
  474. {
  475. setBlendSrc(parseBlend(value));
  476. }
  477. else if (strcmp(name, "blendDst") == 0 || strcmp(name, "dstBlend") == 0) // // Leaving dstBlend for backward compat.
  478. {
  479. setBlendDst(parseBlend(value));
  480. }
  481. else if (strcmp(name, "cullFace") == 0)
  482. {
  483. setCullFace(parseBoolean(value));
  484. }
  485. else if (strcmp(name, "depthTest") == 0)
  486. {
  487. setDepthTest(parseBoolean(value));
  488. }
  489. else if (strcmp(name, "depthWrite") == 0)
  490. {
  491. setDepthWrite(parseBoolean(value));
  492. }
  493. else
  494. {
  495. GP_ERROR("Unsupported render state string '%s'.", name);
  496. }
  497. }
  498. void RenderState::StateBlock::setBlend(bool enabled)
  499. {
  500. _blendEnabled = enabled;
  501. if (!enabled)
  502. {
  503. _bits &= ~RS_BLEND;
  504. }
  505. else
  506. {
  507. _bits |= RS_BLEND;
  508. }
  509. }
  510. void RenderState::StateBlock::setBlendSrc(Blend blend)
  511. {
  512. _blendSrc = blend;
  513. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  514. {
  515. // Default blend func
  516. _bits &= ~RS_BLEND_FUNC;
  517. }
  518. else
  519. {
  520. _bits |= RS_BLEND_FUNC;
  521. }
  522. }
  523. void RenderState::StateBlock::setBlendDst(Blend blend)
  524. {
  525. _blendDst = blend;
  526. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  527. {
  528. // Default blend func
  529. _bits &= ~RS_BLEND_FUNC;
  530. }
  531. else
  532. {
  533. _bits |= RS_BLEND_FUNC;
  534. }
  535. }
  536. void RenderState::StateBlock::setCullFace(bool enabled)
  537. {
  538. _cullFaceEnabled = enabled;
  539. if (!enabled)
  540. {
  541. _bits &= ~RS_CULL_FACE;
  542. }
  543. else
  544. {
  545. _bits |= RS_CULL_FACE;
  546. }
  547. }
  548. void RenderState::StateBlock::setDepthTest(bool enabled)
  549. {
  550. _depthTestEnabled = enabled;
  551. if (!enabled)
  552. {
  553. _bits &= ~RS_DEPTH_TEST;
  554. }
  555. else
  556. {
  557. _bits |= RS_DEPTH_TEST;
  558. }
  559. }
  560. void RenderState::StateBlock::setDepthWrite(bool enabled)
  561. {
  562. _depthWriteEnabled = enabled;
  563. if (enabled)
  564. {
  565. _bits &= ~RS_DEPTH_WRITE;
  566. }
  567. else
  568. {
  569. _bits |= RS_DEPTH_WRITE;
  570. }
  571. }
  572. }