RenderState.cpp 22 KB

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