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. //
  413. //static unsigned int parseUInt(const std::string& value)
  414. //{
  415. // // Android NDK 10 doesn't support std::stoi a/ std::stoul
  416. //#if CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
  417. // return (unsigned int)std::stoul(value);
  418. //#else
  419. // return (unsigned int)atoi(value.c_str());
  420. //#endif
  421. //
  422. //}
  423. static RenderState::Blend parseBlend(const std::string& value)
  424. {
  425. // Convert the string to uppercase for comparison.
  426. std::string upper(value);
  427. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  428. if (upper == "ZERO")
  429. return RenderState::BLEND_ZERO;
  430. else if (upper == "ONE")
  431. return RenderState::BLEND_ONE;
  432. else if (upper == "SRC_COLOR")
  433. return RenderState::BLEND_SRC_COLOR;
  434. else if (upper == "ONE_MINUS_SRC_COLOR")
  435. return RenderState::BLEND_ONE_MINUS_SRC_COLOR;
  436. else if (upper == "DST_COLOR")
  437. return RenderState::BLEND_DST_COLOR;
  438. else if (upper == "ONE_MINUS_DST_COLOR")
  439. return RenderState::BLEND_ONE_MINUS_DST_COLOR;
  440. else if (upper == "SRC_ALPHA")
  441. return RenderState::BLEND_SRC_ALPHA;
  442. else if (upper == "ONE_MINUS_SRC_ALPHA")
  443. return RenderState::BLEND_ONE_MINUS_SRC_ALPHA;
  444. else if (upper == "DST_ALPHA")
  445. return RenderState::BLEND_DST_ALPHA;
  446. else if (upper == "ONE_MINUS_DST_ALPHA")
  447. return RenderState::BLEND_ONE_MINUS_DST_ALPHA;
  448. else if (upper == "CONSTANT_ALPHA")
  449. return RenderState::BLEND_CONSTANT_ALPHA;
  450. else if (upper == "ONE_MINUS_CONSTANT_ALPHA")
  451. return RenderState::BLEND_ONE_MINUS_CONSTANT_ALPHA;
  452. else if (upper == "SRC_ALPHA_SATURATE")
  453. return RenderState::BLEND_SRC_ALPHA_SATURATE;
  454. else
  455. {
  456. CCLOG("Unsupported blend value (%s). (Will default to BLEND_ONE if errors are treated as warnings)", value.c_str());
  457. return RenderState::BLEND_ONE;
  458. }
  459. }
  460. static RenderState::DepthFunction parseDepthFunc(const std::string& value)
  461. {
  462. // Convert string to uppercase for comparison
  463. std::string upper(value);
  464. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  465. if (upper == "NEVER")
  466. return RenderState::DEPTH_NEVER;
  467. else if (upper == "LESS")
  468. return RenderState::DEPTH_LESS;
  469. else if (upper == "EQUAL")
  470. return RenderState::DEPTH_EQUAL;
  471. else if (upper == "LEQUAL")
  472. return RenderState::DEPTH_LEQUAL;
  473. else if (upper == "GREATER")
  474. return RenderState::DEPTH_GREATER;
  475. else if (upper == "NOTEQUAL")
  476. return RenderState::DEPTH_NOTEQUAL;
  477. else if (upper == "GEQUAL")
  478. return RenderState::DEPTH_GEQUAL;
  479. else if (upper == "ALWAYS")
  480. return RenderState::DEPTH_ALWAYS;
  481. else
  482. {
  483. CCLOG("Unsupported depth function value (%s). Will default to DEPTH_LESS if errors are treated as warnings)", value.c_str());
  484. return RenderState::DEPTH_LESS;
  485. }
  486. }
  487. static RenderState::CullFaceSide parseCullFaceSide(const std::string& value)
  488. {
  489. // Convert string to uppercase for comparison
  490. std::string upper(value);
  491. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  492. if (upper == "BACK")
  493. return RenderState::CULL_FACE_SIDE_BACK;
  494. else if (upper == "FRONT")
  495. return RenderState::CULL_FACE_SIDE_FRONT;
  496. else if (upper == "FRONT_AND_BACK")
  497. return RenderState::CULL_FACE_SIDE_FRONT_AND_BACK;
  498. else
  499. {
  500. CCLOG("Unsupported cull face side value (%s). Will default to BACK if errors are treated as warnings.", value.c_str());
  501. return RenderState::CULL_FACE_SIDE_BACK;
  502. }
  503. }
  504. static RenderState::FrontFace parseFrontFace(const std::string& value)
  505. {
  506. // Convert string to uppercase for comparison
  507. std::string upper(value);
  508. std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  509. if (upper == "CCW")
  510. return RenderState::FRONT_FACE_CCW;
  511. else if (upper == "CW")
  512. return RenderState::FRONT_FACE_CW;
  513. else
  514. {
  515. CCLOG("Unsupported front face side value (%s). Will default to CCW if errors are treated as warnings.", value.c_str());
  516. return RenderState::FRONT_FACE_CCW;
  517. }
  518. }
  519. //static RenderState::StencilFunction parseStencilFunc(const std::string& value)
  520. //{
  521. // // Convert string to uppercase for comparison
  522. // std::string upper(value);
  523. // std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  524. // if (upper == "NEVER")
  525. // return RenderState::STENCIL_NEVER;
  526. // else if (upper == "LESS")
  527. // return RenderState::STENCIL_LESS;
  528. // else if (upper == "EQUAL")
  529. // return RenderState::STENCIL_EQUAL;
  530. // else if (upper == "LEQUAL")
  531. // return RenderState::STENCIL_LEQUAL;
  532. // else if (upper == "GREATER")
  533. // return RenderState::STENCIL_GREATER;
  534. // else if (upper == "NOTEQUAL")
  535. // return RenderState::STENCIL_NOTEQUAL;
  536. // else if (upper == "GEQUAL")
  537. // return RenderState::STENCIL_GEQUAL;
  538. // else if (upper == "ALWAYS")
  539. // return RenderState::STENCIL_ALWAYS;
  540. // else
  541. // {
  542. // CCLOG("Unsupported stencil function value (%s). Will default to STENCIL_ALWAYS if errors are treated as warnings)", value.c_str());
  543. // return RenderState::STENCIL_ALWAYS;
  544. // }
  545. //}
  546. //
  547. //static RenderState::StencilOperation parseStencilOp(const std::string& value)
  548. //{
  549. // // Convert string to uppercase for comparison
  550. // std::string upper(value);
  551. // std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
  552. // if (upper == "KEEP")
  553. // return RenderState::STENCIL_OP_KEEP;
  554. // else if (upper == "ZERO")
  555. // return RenderState::STENCIL_OP_ZERO;
  556. // else if (upper == "REPLACE")
  557. // return RenderState::STENCIL_OP_REPLACE;
  558. // else if (upper == "INCR")
  559. // return RenderState::STENCIL_OP_INCR;
  560. // else if (upper == "DECR")
  561. // return RenderState::STENCIL_OP_DECR;
  562. // else if (upper == "INVERT")
  563. // return RenderState::STENCIL_OP_INVERT;
  564. // else if (upper == "INCR_WRAP")
  565. // return RenderState::STENCIL_OP_INCR_WRAP;
  566. // else if (upper == "DECR_WRAP")
  567. // return RenderState::STENCIL_OP_DECR_WRAP;
  568. // else
  569. // {
  570. // CCLOG("Unsupported stencil operation value (%s). Will default to STENCIL_OP_KEEP if errors are treated as warnings)", value.c_str());
  571. // return RenderState::STENCIL_OP_KEEP;
  572. // }
  573. //}
  574. void RenderState::StateBlock::setState(const std::string& name, const std::string& value)
  575. {
  576. if (name.compare("blend") == 0)
  577. {
  578. setBlend(parseBoolean(value));
  579. }
  580. else if (name.compare("blendSrc") == 0)
  581. {
  582. setBlendSrc(parseBlend(value));
  583. }
  584. else if (name.compare("blendDst") == 0)
  585. {
  586. setBlendDst(parseBlend(value));
  587. }
  588. else if (name.compare("cullFace") == 0)
  589. {
  590. setCullFace(parseBoolean(value));
  591. }
  592. else if (name.compare("cullFaceSide") == 0)
  593. {
  594. setCullFaceSide(parseCullFaceSide(value));
  595. }
  596. else if (name.compare("frontFace") == 0)
  597. {
  598. setFrontFace(parseFrontFace(value));
  599. }
  600. else if (name.compare("depthTest") == 0)
  601. {
  602. setDepthTest(parseBoolean(value));
  603. }
  604. else if (name.compare("depthWrite") == 0)
  605. {
  606. setDepthWrite(parseBoolean(value));
  607. }
  608. else if (name.compare("depthFunc") == 0)
  609. {
  610. setDepthFunction(parseDepthFunc(value));
  611. }
  612. // else if (name.compare("stencilTest") == 0)
  613. // {
  614. // setStencilTest(parseBoolean(value));
  615. // }
  616. // else if (name.compare("stencilWrite") == 0)
  617. // {
  618. // setStencilWrite(parseUInt(value));
  619. // }
  620. // else if (name.compare("stencilFunc") == 0)
  621. // {
  622. // setStencilFunction(parseStencilFunc(value), _stencilFunctionRef, _stencilFunctionMask);
  623. // }
  624. // else if (name.compare("stencilFuncRef") == 0)
  625. // {
  626. // setStencilFunction(_stencilFunction, parseInt(value), _stencilFunctionMask);
  627. // }
  628. // else if (name.compare("stencilFuncMask") == 0)
  629. // {
  630. // setStencilFunction(_stencilFunction, _stencilFunctionRef, parseUInt(value));
  631. // }
  632. // else if (name.compare("stencilOpSfail") == 0)
  633. // {
  634. // setStencilOperation(parseStencilOp(value), _stencilOpDpfail, _stencilOpDppass);
  635. // }
  636. // else if (name.compare("stencilOpDpfail") == 0)
  637. // {
  638. // setStencilOperation(_stencilOpSfail, parseStencilOp(value), _stencilOpDppass);
  639. // }
  640. // else if (name.compare("stencilOpDppass") == 0)
  641. // {
  642. // setStencilOperation(_stencilOpSfail, _stencilOpDpfail, parseStencilOp(value));
  643. // }
  644. else
  645. {
  646. CCLOG("Unsupported render state string '%s'.", name.c_str());
  647. }
  648. }
  649. bool RenderState::StateBlock::isDirty() const
  650. {
  651. // XXX
  652. return true;
  653. }
  654. uint32_t RenderState::StateBlock::getHash() const
  655. {
  656. // XXX
  657. return 0x12345678;
  658. }
  659. void RenderState::StateBlock::invalidate(long stateBits)
  660. {
  661. CCASSERT(_defaultState, "_default state not created yet. Cannot be invalidated");
  662. _defaultState->_bits = stateBits;
  663. _defaultState->restore(0);
  664. }
  665. void RenderState::StateBlock::setBlend(bool enabled)
  666. {
  667. _blendEnabled = enabled;
  668. if (enabled)
  669. {
  670. _bits &= ~RS_BLEND;
  671. }
  672. else
  673. {
  674. _bits |= RS_BLEND;
  675. }
  676. }
  677. void RenderState::StateBlock::setBlendFunc(const BlendFunc& blendFunc)
  678. {
  679. setBlendSrc((RenderState::Blend)blendFunc.src);
  680. setBlendDst((RenderState::Blend)blendFunc.dst);
  681. }
  682. void RenderState::StateBlock::setBlendSrc(Blend blend)
  683. {
  684. _blendSrc = blend;
  685. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  686. {
  687. // Default blend func
  688. _bits &= ~RS_BLEND_FUNC;
  689. }
  690. else
  691. {
  692. _bits |= RS_BLEND_FUNC;
  693. }
  694. }
  695. void RenderState::StateBlock::setBlendDst(Blend blend)
  696. {
  697. _blendDst = blend;
  698. if (_blendSrc == BLEND_ONE && _blendDst == BLEND_ZERO)
  699. {
  700. // Default blend func
  701. _bits &= ~RS_BLEND_FUNC;
  702. }
  703. else
  704. {
  705. _bits |= RS_BLEND_FUNC;
  706. }
  707. }
  708. void RenderState::StateBlock::setCullFace(bool enabled)
  709. {
  710. _cullFaceEnabled = enabled;
  711. if (!enabled)
  712. {
  713. _bits &= ~RS_CULL_FACE;
  714. }
  715. else
  716. {
  717. _bits |= RS_CULL_FACE;
  718. }
  719. }
  720. void RenderState::StateBlock::setCullFaceSide(CullFaceSide side)
  721. {
  722. _cullFaceSide = side;
  723. if (_cullFaceSide == CULL_FACE_SIDE_BACK)
  724. {
  725. // Default cull side
  726. _bits &= ~RS_CULL_FACE_SIDE;
  727. }
  728. else
  729. {
  730. _bits |= RS_CULL_FACE_SIDE;
  731. }
  732. }
  733. void RenderState::StateBlock::setFrontFace(FrontFace winding)
  734. {
  735. _frontFace = winding;
  736. if (_frontFace == FRONT_FACE_CCW)
  737. {
  738. // Default front face
  739. _bits &= ~RS_FRONT_FACE;
  740. }
  741. else
  742. {
  743. _bits |= RS_FRONT_FACE;
  744. }
  745. }
  746. void RenderState::StateBlock::setDepthTest(bool enabled)
  747. {
  748. _depthTestEnabled = enabled;
  749. if (enabled)
  750. {
  751. _bits &= ~RS_DEPTH_TEST;
  752. }
  753. else
  754. {
  755. _bits |= RS_DEPTH_TEST;
  756. }
  757. }
  758. void RenderState::StateBlock::setDepthWrite(bool enabled)
  759. {
  760. _depthWriteEnabled = enabled;
  761. if (!enabled)
  762. {
  763. _bits &= ~RS_DEPTH_WRITE;
  764. }
  765. else
  766. {
  767. _bits |= RS_DEPTH_WRITE;
  768. }
  769. }
  770. void RenderState::StateBlock::setDepthFunction(DepthFunction func)
  771. {
  772. _depthFunction = func;
  773. if (_depthFunction == DEPTH_LESS)
  774. {
  775. // Default depth function
  776. _bits &= ~RS_DEPTH_FUNC;
  777. }
  778. else
  779. {
  780. _bits |= RS_DEPTH_FUNC;
  781. }
  782. }
  783. //void RenderState::StateBlock::setStencilTest(bool enabled)
  784. //{
  785. // _stencilTestEnabled = enabled;
  786. // if (!enabled)
  787. // {
  788. // _bits &= ~RS_STENCIL_TEST;
  789. // }
  790. // else
  791. // {
  792. // _bits |= RS_STENCIL_TEST;
  793. // }
  794. //}
  795. //
  796. //void RenderState::StateBlock::setStencilWrite(unsigned int mask)
  797. //{
  798. // _stencilWrite = mask;
  799. // if (mask == RS_ALL_ONES)
  800. // {
  801. // // Default stencil write
  802. // _bits &= ~RS_STENCIL_WRITE;
  803. // }
  804. // else
  805. // {
  806. // _bits |= RS_STENCIL_WRITE;
  807. // }
  808. //}
  809. //
  810. //void RenderState::StateBlock::setStencilFunction(StencilFunction func, int ref, unsigned int mask)
  811. //{
  812. // _stencilFunction = func;
  813. // _stencilFunctionRef = ref;
  814. // _stencilFunctionMask = mask;
  815. // if (func == STENCIL_ALWAYS && ref == 0 && mask == RS_ALL_ONES)
  816. // {
  817. // // Default stencil function
  818. // _bits &= ~RS_STENCIL_FUNC;
  819. // }
  820. // else
  821. // {
  822. // _bits |= RS_STENCIL_FUNC;
  823. // }
  824. //}
  825. //
  826. //void RenderState::StateBlock::setStencilOperation(StencilOperation sfail, StencilOperation dpfail, StencilOperation dppass)
  827. //{
  828. // _stencilOpSfail = sfail;
  829. // _stencilOpDpfail = dpfail;
  830. // _stencilOpDppass = dppass;
  831. // if (sfail == STENCIL_OP_KEEP && dpfail == STENCIL_OP_KEEP && dppass == STENCIL_OP_KEEP)
  832. // {
  833. // // Default stencil operation
  834. // _bits &= ~RS_STENCIL_OP;
  835. // }
  836. // else
  837. // {
  838. // _bits |= RS_STENCIL_OP;
  839. // }
  840. //}
  841. NS_CC_END