CCRenderState.cpp 27 KB

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