CCRenderState.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /****************************************************************************
  2. Copyright (c) 2015-2017 Chukong Technologies Inc.
  3. Copyright (c) 2014 GamePlay3D team
  4. http://www.cocos2d-x.org
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. Ideas taken from:
  15. - GamePlay3D: http://gameplay3d.org/
  16. - OGRE3D: http://www.ogre3d.org/
  17. - Qt3D: http://qt-project.org/
  18. ****************************************************************************/
  19. #include "renderer/CCRenderState.h"
  20. #include <string>
  21. #include "renderer/CCTexture2D.h"
  22. #include "renderer/CCPass.h"
  23. #include "renderer/ccGLStateCache.h"
  24. NS_CC_BEGIN
  25. RenderState::StateBlock* RenderState::StateBlock::_defaultState = nullptr;
  26. RenderState::RenderState()
  27. : _hash(0)
  28. , _hashDirty(true)
  29. , _parent(nullptr)
  30. , _texture(nullptr)
  31. {
  32. _state = StateBlock::create();
  33. CC_SAFE_RETAIN(_state);
  34. }
  35. RenderState::~RenderState()
  36. {
  37. CC_SAFE_RELEASE(_texture);
  38. CC_SAFE_RELEASE(_state);
  39. }
  40. void RenderState::initialize()
  41. {
  42. if (StateBlock::_defaultState == nullptr)
  43. {
  44. StateBlock::_defaultState = StateBlock::create();
  45. CC_SAFE_RETAIN(StateBlock::_defaultState);
  46. }
  47. }
  48. void RenderState::finalize()
  49. {
  50. CC_SAFE_RELEASE_NULL(StateBlock::_defaultState);
  51. }
  52. bool RenderState::init(RenderState* parent)
  53. {
  54. CCASSERT(!_parent, "Cannot reinitialize Render State");
  55. CCASSERT(parent, "parent must be non-null");
  56. // Weak reference
  57. _parent = parent;
  58. return true;
  59. }
  60. std::string RenderState::getName() const
  61. {
  62. return _name;
  63. }
  64. void RenderState::setTexture(Texture2D* texture)
  65. {
  66. if (_texture != texture)
  67. {
  68. CC_SAFE_RELEASE(_texture);
  69. _texture = texture;
  70. CC_SAFE_RETAIN(_texture);
  71. }
  72. }
  73. Texture2D* RenderState::getTexture() const
  74. {
  75. return _texture;
  76. }
  77. void RenderState::bind(Pass* pass)
  78. {
  79. CC_ASSERT(pass);
  80. if (_texture)
  81. GL::bindTexture2D(_texture->getName());
  82. // Get the combined modified state bits for our RenderState hierarchy.
  83. long stateOverrideBits = _state ? _state->_bits : 0;
  84. RenderState* rs = _parent;
  85. while (rs)
  86. {
  87. if (rs->_state)
  88. {
  89. stateOverrideBits |= rs->_state->_bits;
  90. }
  91. rs = rs->_parent;
  92. }
  93. // Restore renderer state to its default, except for explicitly specified states
  94. StateBlock::restore(stateOverrideBits);
  95. // Apply renderer state for the entire hierarchy, top-down.
  96. rs = nullptr;
  97. while ((rs = getTopmost(rs)))
  98. {
  99. if (rs->_state)
  100. {
  101. rs->_state->bindNoRestore();
  102. }
  103. }
  104. }
  105. RenderState* RenderState::getTopmost(RenderState* below)
  106. {
  107. RenderState* rs = this;
  108. if (rs == below)
  109. {
  110. // Nothing below ourself.
  111. return nullptr;
  112. }
  113. while (rs)
  114. {
  115. if (rs->_parent == below || rs->_parent == nullptr)
  116. {
  117. // Stop traversing up here.
  118. return rs;
  119. }
  120. rs = rs->_parent;
  121. }
  122. return nullptr;
  123. }
  124. RenderState::StateBlock* RenderState::getStateBlock() const
  125. {
  126. return _state;
  127. }
  128. void RenderState::setStateBlock(RenderState::StateBlock* state)
  129. {
  130. CC_SAFE_RETAIN(state);
  131. CC_SAFE_RELEASE(_state);
  132. _state = state;
  133. }
  134. void RenderState::cloneInto(RenderState* renderState) const
  135. {
  136. CCASSERT(renderState, "must be non null");
  137. // Clone our state block
  138. if (_state)
  139. {
  140. _state->cloneInto(renderState->getStateBlock());
  141. }
  142. renderState->_name = _name;
  143. renderState->_texture = _texture;
  144. CC_SAFE_RETAIN(renderState->_texture);
  145. // weak ref. don't retain
  146. renderState->_parent = _parent;
  147. }
  148. //
  149. // StateBlock
  150. //
  151. RenderState::StateBlock* RenderState::StateBlock::create()
  152. {
  153. auto state = new (std::nothrow) RenderState::StateBlock();
  154. if (state)
  155. {
  156. state->autorelease();
  157. }
  158. return state;
  159. }
  160. //
  161. // The defaults are based on GamePlay3D defaults, with the following changes
  162. // _depthWriteEnabled is FALSE
  163. // _depthTestEnabled is TRUE
  164. // _blendEnabled is TRUE
  165. RenderState::StateBlock::StateBlock()
  166. : _cullFaceEnabled(false)
  167. , _depthTestEnabled(true), _depthWriteEnabled(false), _depthFunction(RenderState::DEPTH_LESS)
  168. , _blendEnabled(true), _blendSrc(RenderState::BLEND_ONE), _blendDst(RenderState::BLEND_ZERO)
  169. , _cullFaceSide(CULL_FACE_SIDE_BACK), _frontFace(FRONT_FACE_CCW)
  170. , _stencilTestEnabled(false), _stencilWrite(RS_ALL_ONES)
  171. , _stencilFunction(RenderState::STENCIL_ALWAYS), _stencilFunctionRef(0), _stencilFunctionMask(RS_ALL_ONES)
  172. , _stencilOpSfail(RenderState::STENCIL_OP_KEEP), _stencilOpDpfail(RenderState::STENCIL_OP_KEEP), _stencilOpDppass(RenderState::STENCIL_OP_KEEP)
  173. , _bits(0L)
  174. {
  175. }
  176. RenderState::StateBlock::~StateBlock()
  177. {
  178. }
  179. void RenderState::StateBlock::bind()
  180. {
  181. // When the public bind() is called with no RenderState object passed in,
  182. // we assume we are being called to bind the state of a single StateBlock,
  183. // irrespective of whether it belongs to a hierarchy of RenderStates.
  184. // Therefore, we call restore() here with only this StateBlock's override
  185. // bits to restore state before applying the new state.
  186. StateBlock::restore(_bits);
  187. bindNoRestore();
  188. }
  189. void RenderState::StateBlock::bindNoRestore()
  190. {
  191. CC_ASSERT(_defaultState);
  192. // Update any state that differs from _defaultState and flip _defaultState bits
  193. if ((_bits & RS_BLEND) && (_blendEnabled != _defaultState->_blendEnabled))
  194. {
  195. if (_blendEnabled)
  196. glEnable(GL_BLEND);
  197. else
  198. glDisable(GL_BLEND);
  199. _defaultState->_blendEnabled = _blendEnabled;
  200. }
  201. if ((_bits & RS_BLEND_FUNC) && (_blendSrc != _defaultState->_blendSrc || _blendDst != _defaultState->_blendDst))
  202. {
  203. GL::blendFunc((GLenum)_blendSrc, (GLenum)_blendDst);
  204. _defaultState->_blendSrc = _blendSrc;
  205. _defaultState->_blendDst = _blendDst;
  206. }
  207. if ((_bits & RS_CULL_FACE) && (_cullFaceEnabled != _defaultState->_cullFaceEnabled))
  208. {
  209. if (_cullFaceEnabled)
  210. glEnable(GL_CULL_FACE);
  211. else
  212. glDisable(GL_CULL_FACE);
  213. _defaultState->_cullFaceEnabled = _cullFaceEnabled;
  214. }
  215. if ((_bits & RS_CULL_FACE_SIDE) && (_cullFaceSide != _defaultState->_cullFaceSide))
  216. {
  217. glCullFace((GLenum)_cullFaceSide);
  218. _defaultState->_cullFaceSide = _cullFaceSide;
  219. }
  220. if ((_bits & RS_FRONT_FACE) && (_frontFace != _defaultState->_frontFace))
  221. {
  222. glFrontFace((GLenum)_frontFace);
  223. _defaultState->_frontFace = _frontFace;
  224. }
  225. if ((_bits & RS_DEPTH_TEST) && (_depthTestEnabled != _defaultState->_depthTestEnabled))
  226. {
  227. if (_depthTestEnabled)
  228. glEnable(GL_DEPTH_TEST);
  229. else
  230. glDisable(GL_DEPTH_TEST);
  231. _defaultState->_depthTestEnabled = _depthTestEnabled;
  232. }
  233. if ((_bits & RS_DEPTH_WRITE) && (_depthWriteEnabled != _defaultState->_depthWriteEnabled))
  234. {
  235. glDepthMask(_depthWriteEnabled ? GL_TRUE : GL_FALSE);
  236. _defaultState->_depthWriteEnabled = _depthWriteEnabled;
  237. }
  238. if ((_bits & RS_DEPTH_FUNC) && (_depthFunction != _defaultState->_depthFunction))
  239. {
  240. glDepthFunc((GLenum)_depthFunction);
  241. _defaultState->_depthFunction = _depthFunction;
  242. }
  243. // if ((_bits & RS_STENCIL_TEST) && (_stencilTestEnabled != _defaultState->_stencilTestEnabled))
  244. // {
  245. // if (_stencilTestEnabled)
  246. // glEnable(GL_STENCIL_TEST);
  247. // else
  248. // glDisable(GL_STENCIL_TEST);
  249. // _defaultState->_stencilTestEnabled = _stencilTestEnabled;
  250. // }
  251. // if ((_bits & RS_STENCIL_WRITE) && (_stencilWrite != _defaultState->_stencilWrite))
  252. // {
  253. // glStencilMask(_stencilWrite);
  254. // _defaultState->_stencilWrite = _stencilWrite;
  255. // }
  256. // if ((_bits & RS_STENCIL_FUNC) && (_stencilFunction != _defaultState->_stencilFunction ||
  257. // _stencilFunctionRef != _defaultState->_stencilFunctionRef ||
  258. // _stencilFunctionMask != _defaultState->_stencilFunctionMask))
  259. // {
  260. // glStencilFunc((GLenum)_stencilFunction, _stencilFunctionRef, _stencilFunctionMask);
  261. // _defaultState->_stencilFunction = _stencilFunction;
  262. // _defaultState->_stencilFunctionRef = _stencilFunctionRef;
  263. // _defaultState->_stencilFunctionMask = _stencilFunctionMask;
  264. // }
  265. // if ((_bits & RS_STENCIL_OP) && (_stencilOpSfail != _defaultState->_stencilOpSfail ||
  266. // _stencilOpDpfail != _defaultState->_stencilOpDpfail ||
  267. // _stencilOpDppass != _defaultState->_stencilOpDppass))
  268. // {
  269. // glStencilOp((GLenum)_stencilOpSfail, (GLenum)_stencilOpDpfail, (GLenum)_stencilOpDppass);
  270. // _defaultState->_stencilOpSfail = _stencilOpSfail;
  271. // _defaultState->_stencilOpDpfail = _stencilOpDpfail;
  272. // _defaultState->_stencilOpDppass = _stencilOpDppass;
  273. // }
  274. _defaultState->_bits |= _bits;
  275. }
  276. void RenderState::StateBlock::restore(long stateOverrideBits)
  277. {
  278. CC_ASSERT(_defaultState);
  279. // If there is no state to restore (i.e. no non-default state), do nothing.
  280. // if (_defaultState->_bits == 0)
  281. if ( (stateOverrideBits | _defaultState->_bits) == stateOverrideBits)
  282. {
  283. return;
  284. }
  285. // Restore any state that is not overridden and is not default
  286. if (!(stateOverrideBits & RS_BLEND) && (_defaultState->_bits & RS_BLEND))
  287. {
  288. glEnable(GL_BLEND);
  289. _defaultState->_bits &= ~RS_BLEND;
  290. _defaultState->_blendEnabled = true;
  291. }
  292. if (!(stateOverrideBits & RS_BLEND_FUNC) && (_defaultState->_bits & RS_BLEND_FUNC))
  293. {
  294. GL::blendFunc(GL_ONE, GL_ZERO);
  295. _defaultState->_bits &= ~RS_BLEND_FUNC;
  296. _defaultState->_blendSrc = RenderState::BLEND_ONE;
  297. _defaultState->_blendDst = RenderState::BLEND_ZERO;
  298. }
  299. if (!(stateOverrideBits & RS_CULL_FACE) && (_defaultState->_bits & RS_CULL_FACE))
  300. {
  301. glDisable(GL_CULL_FACE);
  302. _defaultState->_bits &= ~RS_CULL_FACE;
  303. _defaultState->_cullFaceEnabled = false;
  304. }
  305. if (!(stateOverrideBits & RS_CULL_FACE_SIDE) && (_defaultState->_bits & RS_CULL_FACE_SIDE))
  306. {
  307. glCullFace((GLenum)GL_BACK);
  308. _defaultState->_bits &= ~RS_CULL_FACE_SIDE;
  309. _defaultState->_cullFaceSide = RenderState::CULL_FACE_SIDE_BACK;
  310. }
  311. if (!(stateOverrideBits & RS_FRONT_FACE) && (_defaultState->_bits & RS_FRONT_FACE))
  312. {
  313. glFrontFace((GLenum)GL_CCW);
  314. _defaultState->_bits &= ~RS_FRONT_FACE;
  315. _defaultState->_frontFace = RenderState::FRONT_FACE_CCW;
  316. }
  317. if (!(stateOverrideBits & RS_DEPTH_TEST) && (_defaultState->_bits & RS_DEPTH_TEST))
  318. {
  319. glEnable(GL_DEPTH_TEST);
  320. _defaultState->_bits &= ~RS_DEPTH_TEST;
  321. _defaultState->_depthTestEnabled = true;
  322. }
  323. if (!(stateOverrideBits & RS_DEPTH_WRITE) && (_defaultState->_bits & RS_DEPTH_WRITE))
  324. {
  325. glDepthMask(GL_FALSE);
  326. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  327. _defaultState->_depthWriteEnabled = false;
  328. }
  329. if (!(stateOverrideBits & RS_DEPTH_FUNC) && (_defaultState->_bits & RS_DEPTH_FUNC))
  330. {
  331. glDepthFunc((GLenum)GL_LESS);
  332. _defaultState->_bits &= ~RS_DEPTH_FUNC;
  333. _defaultState->_depthFunction = RenderState::DEPTH_LESS;
  334. }
  335. // if (!(stateOverrideBits & RS_STENCIL_TEST) && (_defaultState->_bits & RS_STENCIL_TEST))
  336. // {
  337. // glDisable(GL_STENCIL_TEST);
  338. // _defaultState->_bits &= ~RS_STENCIL_TEST;
  339. // _defaultState->_stencilTestEnabled = false;
  340. // }
  341. // if (!(stateOverrideBits & RS_STENCIL_WRITE) && (_defaultState->_bits & RS_STENCIL_WRITE))
  342. // {
  343. // glStencilMask(RS_ALL_ONES);
  344. // _defaultState->_bits &= ~RS_STENCIL_WRITE;
  345. // _defaultState->_stencilWrite = RS_ALL_ONES;
  346. // }
  347. // if (!(stateOverrideBits & RS_STENCIL_FUNC) && (_defaultState->_bits & RS_STENCIL_FUNC))
  348. // {
  349. // glStencilFunc((GLenum)RenderState::STENCIL_ALWAYS, 0, RS_ALL_ONES);
  350. // _defaultState->_bits &= ~RS_STENCIL_FUNC;
  351. // _defaultState->_stencilFunction = RenderState::STENCIL_ALWAYS;
  352. // _defaultState->_stencilFunctionRef = 0;
  353. // _defaultState->_stencilFunctionMask = RS_ALL_ONES;
  354. // }
  355. // if (!(stateOverrideBits & RS_STENCIL_OP) && (_defaultState->_bits & RS_STENCIL_OP))
  356. // {
  357. // glStencilOp((GLenum)RenderState::STENCIL_OP_KEEP, (GLenum)RenderState::STENCIL_OP_KEEP, (GLenum)RenderState::STENCIL_OP_KEEP);
  358. // _defaultState->_bits &= ~RS_STENCIL_OP;
  359. // _defaultState->_stencilOpSfail = RenderState::STENCIL_OP_KEEP;
  360. // _defaultState->_stencilOpDpfail = RenderState::STENCIL_OP_KEEP;
  361. // _defaultState->_stencilOpDppass = RenderState::STENCIL_OP_KEEP;
  362. // }
  363. }
  364. void RenderState::StateBlock::enableDepthWrite()
  365. {
  366. CC_ASSERT(_defaultState);
  367. // Internal method used to restore depth writing before a
  368. // clear operation. This is necessary if the last code to draw before the
  369. // next frame leaves depth writing disabled.
  370. if (!_defaultState->_depthWriteEnabled)
  371. {
  372. glDepthMask(GL_TRUE);
  373. _defaultState->_bits &= ~RS_DEPTH_WRITE;
  374. _defaultState->_depthWriteEnabled = true;
  375. }
  376. }
  377. void RenderState::StateBlock::cloneInto(StateBlock* state) const
  378. {
  379. CC_ASSERT(state);
  380. state->_cullFaceEnabled = _cullFaceEnabled;
  381. state->_depthTestEnabled = _depthTestEnabled;
  382. state->_depthWriteEnabled = _depthWriteEnabled;
  383. state->_depthFunction = _depthFunction;
  384. state->_blendEnabled = _blendEnabled;
  385. state->_blendSrc = _blendSrc;
  386. state->_blendDst = _blendDst;
  387. state->_cullFaceSide = _cullFaceSide;
  388. state->_frontFace = _frontFace;
  389. state->_stencilTestEnabled = _stencilTestEnabled;
  390. state->_stencilWrite = _stencilWrite;
  391. state->_stencilFunction = _stencilFunction;
  392. state->_stencilFunctionRef = _stencilFunctionRef;
  393. state->_stencilFunctionMask = _stencilFunctionMask;
  394. state->_stencilOpSfail = _stencilOpSfail;
  395. state->_stencilOpDpfail = _stencilOpDpfail;
  396. state->_stencilOpDppass = _stencilOpDppass;
  397. state->_bits = _bits;
  398. }
  399. static bool parseBoolean(const std::string& value)
  400. {
  401. return (value.compare("true")==0);
  402. }
  403. static int parseInt(const std::string& value)
  404. {
  405. // Android NDK 10 doesn't support std::stoi a/ std::stoul
  406. #if CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
  407. return std::stoi(value);
  408. #else
  409. return atoi(value.c_str());
  410. #endif
  411. }
  412. static unsigned int parseUInt(const std::string& value)
  413. {
  414. // Android NDK 10 doesn't support std::stoi a/ std::stoul
  415. #if CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
  416. return (unsigned int)std::stoul(value);
  417. #else
  418. return (unsigned int)atoi(value.c_str());
  419. #endif
  420. }
  421. static RenderState::Blend parseBlend(const std::string& value)
  422. {
  423. // Convert the string to uppercase for comparison.
  424. std::string upper(value);
  425. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  426. if (upper == "ZERO")
  427. return RenderState::BLEND_ZERO;
  428. else if (upper == "ONE")
  429. return RenderState::BLEND_ONE;
  430. else if (upper == "SRC_COLOR")
  431. return RenderState::BLEND_SRC_COLOR;
  432. else if (upper == "ONE_MINUS_SRC_COLOR")
  433. return RenderState::BLEND_ONE_MINUS_SRC_COLOR;
  434. else if (upper == "DST_COLOR")
  435. return RenderState::BLEND_DST_COLOR;
  436. else if (upper == "ONE_MINUS_DST_COLOR")
  437. return RenderState::BLEND_ONE_MINUS_DST_COLOR;
  438. else if (upper == "SRC_ALPHA")
  439. return RenderState::BLEND_SRC_ALPHA;
  440. else if (upper == "ONE_MINUS_SRC_ALPHA")
  441. return RenderState::BLEND_ONE_MINUS_SRC_ALPHA;
  442. else if (upper == "DST_ALPHA")
  443. return RenderState::BLEND_DST_ALPHA;
  444. else if (upper == "ONE_MINUS_DST_ALPHA")
  445. return RenderState::BLEND_ONE_MINUS_DST_ALPHA;
  446. else if (upper == "CONSTANT_ALPHA")
  447. return RenderState::BLEND_CONSTANT_ALPHA;
  448. else if (upper == "ONE_MINUS_CONSTANT_ALPHA")
  449. return RenderState::BLEND_ONE_MINUS_CONSTANT_ALPHA;
  450. else if (upper == "SRC_ALPHA_SATURATE")
  451. return RenderState::BLEND_SRC_ALPHA_SATURATE;
  452. else
  453. {
  454. CCLOG("Unsupported blend value (%s). (Will default to BLEND_ONE if errors are treated as warnings)", value.c_str());
  455. return RenderState::BLEND_ONE;
  456. }
  457. }
  458. static RenderState::DepthFunction parseDepthFunc(const std::string& value)
  459. {
  460. // Convert string to uppercase for comparison
  461. std::string upper(value);
  462. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  463. if (upper == "NEVER")
  464. return RenderState::DEPTH_NEVER;
  465. else if (upper == "LESS")
  466. return RenderState::DEPTH_LESS;
  467. else if (upper == "EQUAL")
  468. return RenderState::DEPTH_EQUAL;
  469. else if (upper == "LEQUAL")
  470. return RenderState::DEPTH_LEQUAL;
  471. else if (upper == "GREATER")
  472. return RenderState::DEPTH_GREATER;
  473. else if (upper == "NOTEQUAL")
  474. return RenderState::DEPTH_NOTEQUAL;
  475. else if (upper == "GEQUAL")
  476. return RenderState::DEPTH_GEQUAL;
  477. else if (upper == "ALWAYS")
  478. return RenderState::DEPTH_ALWAYS;
  479. else
  480. {
  481. CCLOG("Unsupported depth function value (%s). Will default to DEPTH_LESS if errors are treated as warnings)", value.c_str());
  482. return RenderState::DEPTH_LESS;
  483. }
  484. }
  485. static RenderState::CullFaceSide parseCullFaceSide(const std::string& value)
  486. {
  487. // Convert string to uppercase for comparison
  488. std::string upper(value);
  489. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  490. if (upper == "BACK")
  491. return RenderState::CULL_FACE_SIDE_BACK;
  492. else if (upper == "FRONT")
  493. return RenderState::CULL_FACE_SIDE_FRONT;
  494. else if (upper == "FRONT_AND_BACK")
  495. return RenderState::CULL_FACE_SIDE_FRONT_AND_BACK;
  496. else
  497. {
  498. CCLOG("Unsupported cull face side value (%s). Will default to BACK if errors are treated as warnings.", value.c_str());
  499. return RenderState::CULL_FACE_SIDE_BACK;
  500. }
  501. }
  502. static RenderState::FrontFace parseFrontFace(const std::string& value)
  503. {
  504. // Convert string to uppercase for comparison
  505. std::string upper(value);
  506. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  507. if (upper == "CCW")
  508. return RenderState::FRONT_FACE_CCW;
  509. else if (upper == "CW")
  510. return RenderState::FRONT_FACE_CW;
  511. else
  512. {
  513. CCLOG("Unsupported front face side value (%s). Will default to CCW if errors are treated as warnings.", value.c_str());
  514. return RenderState::FRONT_FACE_CCW;
  515. }
  516. }
  517. static RenderState::StencilFunction parseStencilFunc(const std::string& value)
  518. {
  519. // Convert string to uppercase for comparison
  520. std::string upper(value);
  521. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  522. if (upper == "NEVER")
  523. return RenderState::STENCIL_NEVER;
  524. else if (upper == "LESS")
  525. return RenderState::STENCIL_LESS;
  526. else if (upper == "EQUAL")
  527. return RenderState::STENCIL_EQUAL;
  528. else if (upper == "LEQUAL")
  529. return RenderState::STENCIL_LEQUAL;
  530. else if (upper == "GREATER")
  531. return RenderState::STENCIL_GREATER;
  532. else if (upper == "NOTEQUAL")
  533. return RenderState::STENCIL_NOTEQUAL;
  534. else if (upper == "GEQUAL")
  535. return RenderState::STENCIL_GEQUAL;
  536. else if (upper == "ALWAYS")
  537. return RenderState::STENCIL_ALWAYS;
  538. else
  539. {
  540. CCLOG("Unsupported stencil function value (%s). Will default to STENCIL_ALWAYS if errors are treated as warnings)", value.c_str());
  541. return RenderState::STENCIL_ALWAYS;
  542. }
  543. }
  544. static RenderState::StencilOperation parseStencilOp(const std::string& value)
  545. {
  546. // Convert string to uppercase for comparison
  547. std::string upper(value);
  548. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  549. if (upper == "KEEP")
  550. return RenderState::STENCIL_OP_KEEP;
  551. else if (upper == "ZERO")
  552. return RenderState::STENCIL_OP_ZERO;
  553. else if (upper == "REPLACE")
  554. return RenderState::STENCIL_OP_REPLACE;
  555. else if (upper == "INCR")
  556. return RenderState::STENCIL_OP_INCR;
  557. else if (upper == "DECR")
  558. return RenderState::STENCIL_OP_DECR;
  559. else if (upper == "INVERT")
  560. return RenderState::STENCIL_OP_INVERT;
  561. else if (upper == "INCR_WRAP")
  562. return RenderState::STENCIL_OP_INCR_WRAP;
  563. else if (upper == "DECR_WRAP")
  564. return RenderState::STENCIL_OP_DECR_WRAP;
  565. else
  566. {
  567. CCLOG("Unsupported stencil operation value (%s). Will default to STENCIL_OP_KEEP if errors are treated as warnings)", value.c_str());
  568. return RenderState::STENCIL_OP_KEEP;
  569. }
  570. }
  571. void RenderState::StateBlock::setState(const std::string& name, const std::string& value)
  572. {
  573. if (name.compare("blend") == 0)
  574. {
  575. setBlend(parseBoolean(value));
  576. }
  577. else if (name.compare("blendSrc") == 0)
  578. {
  579. setBlendSrc(parseBlend(value));
  580. }
  581. else if (name.compare("blendDst") == 0)
  582. {
  583. setBlendDst(parseBlend(value));
  584. }
  585. else if (name.compare("cullFace") == 0)
  586. {
  587. setCullFace(parseBoolean(value));
  588. }
  589. else if (name.compare("cullFaceSide") == 0)
  590. {
  591. setCullFaceSide(parseCullFaceSide(value));
  592. }
  593. else if (name.compare("frontFace") == 0)
  594. {
  595. setFrontFace(parseFrontFace(value));
  596. }
  597. else if (name.compare("depthTest") == 0)
  598. {
  599. setDepthTest(parseBoolean(value));
  600. }
  601. else if (name.compare("depthWrite") == 0)
  602. {
  603. setDepthWrite(parseBoolean(value));
  604. }
  605. else if (name.compare("depthFunc") == 0)
  606. {
  607. setDepthFunction(parseDepthFunc(value));
  608. }
  609. // else if (name.compare("stencilTest") == 0)
  610. // {
  611. // setStencilTest(parseBoolean(value));
  612. // }
  613. // else if (name.compare("stencilWrite") == 0)
  614. // {
  615. // setStencilWrite(parseUInt(value));
  616. // }
  617. // else if (name.compare("stencilFunc") == 0)
  618. // {
  619. // setStencilFunction(parseStencilFunc(value), _stencilFunctionRef, _stencilFunctionMask);
  620. // }
  621. // else if (name.compare("stencilFuncRef") == 0)
  622. // {
  623. // setStencilFunction(_stencilFunction, parseInt(value), _stencilFunctionMask);
  624. // }
  625. // else if (name.compare("stencilFuncMask") == 0)
  626. // {
  627. // setStencilFunction(_stencilFunction, _stencilFunctionRef, parseUInt(value));
  628. // }
  629. // else if (name.compare("stencilOpSfail") == 0)
  630. // {
  631. // setStencilOperation(parseStencilOp(value), _stencilOpDpfail, _stencilOpDppass);
  632. // }
  633. // else if (name.compare("stencilOpDpfail") == 0)
  634. // {
  635. // setStencilOperation(_stencilOpSfail, parseStencilOp(value), _stencilOpDppass);
  636. // }
  637. // else if (name.compare("stencilOpDppass") == 0)
  638. // {
  639. // setStencilOperation(_stencilOpSfail, _stencilOpDpfail, parseStencilOp(value));
  640. // }
  641. else
  642. {
  643. CCLOG("Unsupported render state string '%s'.", name.c_str());
  644. }
  645. }
  646. bool RenderState::StateBlock::isDirty() const
  647. {
  648. // XXX
  649. return true;
  650. }
  651. uint32_t RenderState::StateBlock::getHash() const
  652. {
  653. // XXX
  654. return 0x12345678;
  655. }
  656. void RenderState::StateBlock::invalidate(long stateBits)
  657. {
  658. CCASSERT(_defaultState, "_default state not created yet. Cannot be invalidated");
  659. _defaultState->_bits = stateBits;
  660. _defaultState->restore(0);
  661. }
  662. void RenderState::StateBlock::setBlend(bool enabled)
  663. {
  664. _blendEnabled = enabled;
  665. if (enabled)
  666. {
  667. _bits &= ~RS_BLEND;
  668. }
  669. else
  670. {
  671. _bits |= RS_BLEND;
  672. }
  673. }
  674. void RenderState::StateBlock::setBlendFunc(const BlendFunc& blendFunc)
  675. {
  676. setBlendSrc((RenderState::Blend)blendFunc.src);
  677. setBlendDst((RenderState::Blend)blendFunc.dst);
  678. }
  679. void RenderState::StateBlock::setBlendSrc(Blend blend)
  680. {
  681. _blendSrc = blend;
  682. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  683. {
  684. // Default blend func
  685. _bits &= ~RS_BLEND_FUNC;
  686. }
  687. else
  688. {
  689. _bits |= RS_BLEND_FUNC;
  690. }
  691. }
  692. void RenderState::StateBlock::setBlendDst(Blend blend)
  693. {
  694. _blendDst = blend;
  695. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  696. {
  697. // Default blend func
  698. _bits &= ~RS_BLEND_FUNC;
  699. }
  700. else
  701. {
  702. _bits |= RS_BLEND_FUNC;
  703. }
  704. }
  705. void RenderState::StateBlock::setCullFace(bool enabled)
  706. {
  707. _cullFaceEnabled = enabled;
  708. if (!enabled)
  709. {
  710. _bits &= ~RS_CULL_FACE;
  711. }
  712. else
  713. {
  714. _bits |= RS_CULL_FACE;
  715. }
  716. }
  717. void RenderState::StateBlock::setCullFaceSide(CullFaceSide side)
  718. {
  719. _cullFaceSide = side;
  720. if (_cullFaceSide == CULL_FACE_SIDE_BACK)
  721. {
  722. // Default cull side
  723. _bits &= ~RS_CULL_FACE_SIDE;
  724. }
  725. else
  726. {
  727. _bits |= RS_CULL_FACE_SIDE;
  728. }
  729. }
  730. void RenderState::StateBlock::setFrontFace(FrontFace winding)
  731. {
  732. _frontFace = winding;
  733. if (_frontFace == FRONT_FACE_CCW)
  734. {
  735. // Default front face
  736. _bits &= ~RS_FRONT_FACE;
  737. }
  738. else
  739. {
  740. _bits |= RS_FRONT_FACE;
  741. }
  742. }
  743. void RenderState::StateBlock::setDepthTest(bool enabled)
  744. {
  745. _depthTestEnabled = enabled;
  746. if (enabled)
  747. {
  748. _bits &= ~RS_DEPTH_TEST;
  749. }
  750. else
  751. {
  752. _bits |= RS_DEPTH_TEST;
  753. }
  754. }
  755. void RenderState::StateBlock::setDepthWrite(bool enabled)
  756. {
  757. _depthWriteEnabled = enabled;
  758. if (!enabled)
  759. {
  760. _bits &= ~RS_DEPTH_WRITE;
  761. }
  762. else
  763. {
  764. _bits |= RS_DEPTH_WRITE;
  765. }
  766. }
  767. void RenderState::StateBlock::setDepthFunction(DepthFunction func)
  768. {
  769. _depthFunction = func;
  770. if (_depthFunction == DEPTH_LESS)
  771. {
  772. // Default depth function
  773. _bits &= ~RS_DEPTH_FUNC;
  774. }
  775. else
  776. {
  777. _bits |= RS_DEPTH_FUNC;
  778. }
  779. }
  780. //void RenderState::StateBlock::setStencilTest(bool enabled)
  781. //{
  782. // _stencilTestEnabled = enabled;
  783. // if (!enabled)
  784. // {
  785. // _bits &= ~RS_STENCIL_TEST;
  786. // }
  787. // else
  788. // {
  789. // _bits |= RS_STENCIL_TEST;
  790. // }
  791. //}
  792. //
  793. //void RenderState::StateBlock::setStencilWrite(unsigned int mask)
  794. //{
  795. // _stencilWrite = mask;
  796. // if (mask == RS_ALL_ONES)
  797. // {
  798. // // Default stencil write
  799. // _bits &= ~RS_STENCIL_WRITE;
  800. // }
  801. // else
  802. // {
  803. // _bits |= RS_STENCIL_WRITE;
  804. // }
  805. //}
  806. //
  807. //void RenderState::StateBlock::setStencilFunction(StencilFunction func, int ref, unsigned int mask)
  808. //{
  809. // _stencilFunction = func;
  810. // _stencilFunctionRef = ref;
  811. // _stencilFunctionMask = mask;
  812. // if (func == STENCIL_ALWAYS && ref == 0 && mask == RS_ALL_ONES)
  813. // {
  814. // // Default stencil function
  815. // _bits &= ~RS_STENCIL_FUNC;
  816. // }
  817. // else
  818. // {
  819. // _bits |= RS_STENCIL_FUNC;
  820. // }
  821. //}
  822. //
  823. //void RenderState::StateBlock::setStencilOperation(StencilOperation sfail, StencilOperation dpfail, StencilOperation dppass)
  824. //{
  825. // _stencilOpSfail = sfail;
  826. // _stencilOpDpfail = dpfail;
  827. // _stencilOpDppass = dppass;
  828. // if (sfail == STENCIL_OP_KEEP && dpfail == STENCIL_OP_KEEP && dppass == STENCIL_OP_KEEP)
  829. // {
  830. // // Default stencil operation
  831. // _bits &= ~RS_STENCIL_OP;
  832. // }
  833. // else
  834. // {
  835. // _bits |= RS_STENCIL_OP;
  836. // }
  837. //}
  838. NS_CC_END