RenderState.cpp 23 KB

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