CmHardwareVertexBuffer.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "CmHardwareVertexBuffer.h"
  25. #include "CmColor.h"
  26. #include "CmException.h"
  27. #include "CmHardwareBufferManager.h"
  28. #include "CmDefaultHardwareBufferManager.h"
  29. #include "CmRenderSystem.h"
  30. #include "CmRenderSystemManager.h"
  31. #include "CmVertexDeclarationRTTI.h"
  32. namespace CamelotEngine {
  33. //-----------------------------------------------------------------------------
  34. HardwareVertexBuffer::HardwareVertexBuffer(HardwareBufferManagerBase* mgr, size_t vertexSize,
  35. size_t numVertices, HardwareBuffer::Usage usage,
  36. bool useSystemMemory, bool useShadowBuffer)
  37. : HardwareBuffer(usage, useSystemMemory, useShadowBuffer),
  38. mMgr(mgr),
  39. mNumVertices(numVertices),
  40. mVertexSize(vertexSize)
  41. {
  42. // Calculate the size of the vertices
  43. mSizeInBytes = mVertexSize * numVertices;
  44. // Create a shadow buffer if required
  45. if (mUseShadowBuffer)
  46. {
  47. mpShadowBuffer = new DefaultHardwareVertexBuffer(mMgr, mVertexSize,
  48. mNumVertices, HardwareBuffer::HBU_DYNAMIC);
  49. }
  50. }
  51. //-----------------------------------------------------------------------------
  52. HardwareVertexBuffer::~HardwareVertexBuffer()
  53. {
  54. if (mMgr)
  55. {
  56. mMgr->_notifyVertexBufferDestroyed(this);
  57. }
  58. if (mpShadowBuffer)
  59. {
  60. delete mpShadowBuffer;
  61. }
  62. }
  63. //-----------------------------------------------------------------------------
  64. VertexElement::VertexElement(unsigned short source, size_t offset,
  65. VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
  66. : mSource(source), mOffset(offset), mType(theType),
  67. mSemantic(semantic), mIndex(index)
  68. {
  69. }
  70. //-----------------------------------------------------------------------------
  71. size_t VertexElement::getSize(void) const
  72. {
  73. return getTypeSize(mType);
  74. }
  75. //-----------------------------------------------------------------------------
  76. size_t VertexElement::getTypeSize(VertexElementType etype)
  77. {
  78. switch(etype)
  79. {
  80. case VET_COLOUR:
  81. case VET_COLOUR_ABGR:
  82. case VET_COLOUR_ARGB:
  83. return sizeof(RGBA);
  84. case VET_FLOAT1:
  85. return sizeof(float);
  86. case VET_FLOAT2:
  87. return sizeof(float)*2;
  88. case VET_FLOAT3:
  89. return sizeof(float)*3;
  90. case VET_FLOAT4:
  91. return sizeof(float)*4;
  92. case VET_SHORT1:
  93. return sizeof(short);
  94. case VET_SHORT2:
  95. return sizeof(short)*2;
  96. case VET_SHORT3:
  97. return sizeof(short)*3;
  98. case VET_SHORT4:
  99. return sizeof(short)*4;
  100. case VET_UBYTE4:
  101. return sizeof(unsigned char)*4;
  102. }
  103. return 0;
  104. }
  105. //-----------------------------------------------------------------------------
  106. unsigned short VertexElement::getTypeCount(VertexElementType etype)
  107. {
  108. switch (etype)
  109. {
  110. case VET_COLOUR:
  111. case VET_COLOUR_ABGR:
  112. case VET_COLOUR_ARGB:
  113. return 1;
  114. case VET_FLOAT1:
  115. return 1;
  116. case VET_FLOAT2:
  117. return 2;
  118. case VET_FLOAT3:
  119. return 3;
  120. case VET_FLOAT4:
  121. return 4;
  122. case VET_SHORT1:
  123. return 1;
  124. case VET_SHORT2:
  125. return 2;
  126. case VET_SHORT3:
  127. return 3;
  128. case VET_SHORT4:
  129. return 4;
  130. case VET_UBYTE4:
  131. return 4;
  132. }
  133. CM_EXCEPT(InvalidParametersException, "Invalid type");
  134. }
  135. //-----------------------------------------------------------------------------
  136. VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType,
  137. unsigned short count)
  138. {
  139. switch (baseType)
  140. {
  141. case VET_FLOAT1:
  142. switch(count)
  143. {
  144. case 1:
  145. return VET_FLOAT1;
  146. case 2:
  147. return VET_FLOAT2;
  148. case 3:
  149. return VET_FLOAT3;
  150. case 4:
  151. return VET_FLOAT4;
  152. default:
  153. break;
  154. }
  155. break;
  156. case VET_SHORT1:
  157. switch(count)
  158. {
  159. case 1:
  160. return VET_SHORT1;
  161. case 2:
  162. return VET_SHORT2;
  163. case 3:
  164. return VET_SHORT3;
  165. case 4:
  166. return VET_SHORT4;
  167. default:
  168. break;
  169. }
  170. break;
  171. default:
  172. break;
  173. }
  174. CM_EXCEPT(InvalidParametersException, "Invalid base type");
  175. }
  176. //--------------------------------------------------------------------------
  177. VertexElementType VertexElement::getBestColourVertexElementType(void)
  178. {
  179. // Use the current render system to determine if possible
  180. if (CamelotEngine::RenderSystemManager::getActive())
  181. {
  182. return CamelotEngine::RenderSystemManager::getActive()->getColorVertexElementType();
  183. }
  184. else
  185. {
  186. // We can't know the specific type right now, so pick a type
  187. // based on platform
  188. #if CM_PLATFORM == CM_PLATFORM_WIN32
  189. return VET_COLOUR_ARGB; // prefer D3D format on windows
  190. #else
  191. return VET_COLOUR_ABGR; // prefer GL format on everything else
  192. #endif
  193. }
  194. }
  195. //--------------------------------------------------------------------------
  196. void VertexElement::convertColourValue(VertexElementType srcType,
  197. VertexElementType dstType, UINT32* ptr)
  198. {
  199. if (srcType == dstType)
  200. return;
  201. // Conversion between ARGB and ABGR is always a case of flipping R/B
  202. *ptr =
  203. ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00);
  204. }
  205. //--------------------------------------------------------------------------
  206. UINT32 VertexElement::convertColourValue(const Color& src,
  207. VertexElementType dst)
  208. {
  209. switch(dst)
  210. {
  211. #if CM_PLATFORM == CM_PLATFORM_WIN32
  212. default:
  213. #endif
  214. case VET_COLOUR_ARGB:
  215. return src.getAsARGB();
  216. #if CM_PLATFORM != CM_PLATFORM_WIN32
  217. default:
  218. #endif
  219. case VET_COLOUR_ABGR:
  220. return src.getAsABGR();
  221. };
  222. }
  223. //-----------------------------------------------------------------------------
  224. VertexElementType VertexElement::getBaseType(VertexElementType multiType)
  225. {
  226. switch (multiType)
  227. {
  228. case VET_FLOAT1:
  229. case VET_FLOAT2:
  230. case VET_FLOAT3:
  231. case VET_FLOAT4:
  232. return VET_FLOAT1;
  233. case VET_COLOUR:
  234. return VET_COLOUR;
  235. case VET_COLOUR_ABGR:
  236. return VET_COLOUR_ABGR;
  237. case VET_COLOUR_ARGB:
  238. return VET_COLOUR_ARGB;
  239. case VET_SHORT1:
  240. case VET_SHORT2:
  241. case VET_SHORT3:
  242. case VET_SHORT4:
  243. return VET_SHORT1;
  244. case VET_UBYTE4:
  245. return VET_UBYTE4;
  246. };
  247. // To keep compiler happy
  248. return VET_FLOAT1;
  249. }
  250. //-----------------------------------------------------------------------------
  251. VertexDeclaration::VertexDeclaration()
  252. {
  253. }
  254. //-----------------------------------------------------------------------------
  255. VertexDeclaration::~VertexDeclaration()
  256. {
  257. }
  258. //-----------------------------------------------------------------------------
  259. const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
  260. {
  261. return mElementList;
  262. }
  263. //-----------------------------------------------------------------------------
  264. const VertexElement& VertexDeclaration::addElement(unsigned short source,
  265. size_t offset, VertexElementType theType,
  266. VertexElementSemantic semantic, unsigned short index)
  267. {
  268. // Refine colour type to a specific type
  269. if (theType == VET_COLOUR)
  270. {
  271. theType = VertexElement::getBestColourVertexElementType();
  272. }
  273. mElementList.push_back(
  274. VertexElement(source, offset, theType, semantic, index)
  275. );
  276. return mElementList.back();
  277. }
  278. //-----------------------------------------------------------------------------
  279. const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
  280. unsigned short source, size_t offset, VertexElementType theType,
  281. VertexElementSemantic semantic, unsigned short index)
  282. {
  283. if (atPosition >= mElementList.size())
  284. {
  285. return addElement(source, offset, theType, semantic, index);
  286. }
  287. VertexElementList::iterator i = mElementList.begin();
  288. for (unsigned short n = 0; n < atPosition; ++n)
  289. ++i;
  290. i = mElementList.insert(i,
  291. VertexElement(source, offset, theType, semantic, index));
  292. return *i;
  293. }
  294. //-----------------------------------------------------------------------------
  295. const VertexElement* VertexDeclaration::getElement(unsigned short index)
  296. {
  297. assert(index < mElementList.size() && "Index out of bounds");
  298. VertexElementList::iterator i = mElementList.begin();
  299. for (unsigned short n = 0; n < index; ++n)
  300. ++i;
  301. return &(*i);
  302. }
  303. //-----------------------------------------------------------------------------
  304. void VertexDeclaration::removeElement(unsigned short elem_index)
  305. {
  306. assert(elem_index < mElementList.size() && "Index out of bounds");
  307. VertexElementList::iterator i = mElementList.begin();
  308. for (unsigned short n = 0; n < elem_index; ++n)
  309. ++i;
  310. mElementList.erase(i);
  311. }
  312. //-----------------------------------------------------------------------------
  313. void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
  314. {
  315. VertexElementList::iterator ei, eiend;
  316. eiend = mElementList.end();
  317. for (ei = mElementList.begin(); ei != eiend; ++ei)
  318. {
  319. if (ei->getSemantic() == semantic && ei->getIndex() == index)
  320. {
  321. mElementList.erase(ei);
  322. break;
  323. }
  324. }
  325. }
  326. //-----------------------------------------------------------------------------
  327. void VertexDeclaration::removeAllElements(void)
  328. {
  329. mElementList.clear();
  330. }
  331. //-----------------------------------------------------------------------------
  332. void VertexDeclaration::modifyElement(unsigned short elem_index,
  333. unsigned short source, size_t offset, VertexElementType theType,
  334. VertexElementSemantic semantic, unsigned short index)
  335. {
  336. assert(elem_index < mElementList.size() && "Index out of bounds");
  337. VertexElementList::iterator i = mElementList.begin();
  338. std::advance(i, elem_index);
  339. (*i) = VertexElement(source, offset, theType, semantic, index);
  340. }
  341. //-----------------------------------------------------------------------------
  342. const VertexElement* VertexDeclaration::findElementBySemantic(
  343. VertexElementSemantic sem, unsigned short index)
  344. {
  345. VertexElementList::const_iterator ei, eiend;
  346. eiend = mElementList.end();
  347. for (ei = mElementList.begin(); ei != eiend; ++ei)
  348. {
  349. if (ei->getSemantic() == sem && ei->getIndex() == index)
  350. {
  351. return &(*ei);
  352. }
  353. }
  354. return NULL;
  355. }
  356. //-----------------------------------------------------------------------------
  357. VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
  358. unsigned short source)
  359. {
  360. VertexElementList retList;
  361. VertexElementList::const_iterator ei, eiend;
  362. eiend = mElementList.end();
  363. for (ei = mElementList.begin(); ei != eiend; ++ei)
  364. {
  365. if (ei->getSource() == source)
  366. {
  367. retList.push_back(*ei);
  368. }
  369. }
  370. return retList;
  371. }
  372. //-----------------------------------------------------------------------------
  373. size_t VertexDeclaration::getVertexSize(unsigned short source)
  374. {
  375. VertexElementList::const_iterator i, iend;
  376. iend = mElementList.end();
  377. size_t sz = 0;
  378. for (i = mElementList.begin(); i != iend; ++i)
  379. {
  380. if (i->getSource() == source)
  381. {
  382. sz += i->getSize();
  383. }
  384. }
  385. return sz;
  386. }
  387. //-----------------------------------------------------------------------------
  388. VertexDeclarationPtr VertexDeclaration::clone(HardwareBufferManagerBase* mgr)
  389. {
  390. HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::instancePtr();
  391. VertexDeclarationPtr ret = pManager->createVertexDeclaration();
  392. VertexElementList::const_iterator i, iend;
  393. iend = mElementList.end();
  394. for (i = mElementList.begin(); i != iend; ++i)
  395. {
  396. ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
  397. }
  398. return ret;
  399. }
  400. //-----------------------------------------------------------------------------
  401. // Sort routine for VertexElement
  402. bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
  403. {
  404. // Sort by source first
  405. if (e1.getSource() < e2.getSource())
  406. {
  407. return true;
  408. }
  409. else if (e1.getSource() == e2.getSource())
  410. {
  411. // Use ordering of semantics to sort
  412. if (e1.getSemantic() < e2.getSemantic())
  413. {
  414. return true;
  415. }
  416. else if (e1.getSemantic() == e2.getSemantic())
  417. {
  418. // Use index to sort
  419. if (e1.getIndex() < e2.getIndex())
  420. {
  421. return true;
  422. }
  423. }
  424. }
  425. return false;
  426. }
  427. void VertexDeclaration::sort(void)
  428. {
  429. mElementList.sort(VertexDeclaration::vertexElementLess);
  430. }
  431. //-----------------------------------------------------------------------------
  432. void VertexDeclaration::closeGapsInSource(void)
  433. {
  434. if (mElementList.empty())
  435. return;
  436. // Sort first
  437. sort();
  438. VertexElementList::iterator i, iend;
  439. iend = mElementList.end();
  440. unsigned short targetIdx = 0;
  441. unsigned short lastIdx = getElement(0)->getSource();
  442. unsigned short c = 0;
  443. for (i = mElementList.begin(); i != iend; ++i, ++c)
  444. {
  445. VertexElement& elem = *i;
  446. if (lastIdx != elem.getSource())
  447. {
  448. targetIdx++;
  449. lastIdx = elem.getSource();
  450. }
  451. if (targetIdx != elem.getSource())
  452. {
  453. modifyElement(c, targetIdx, elem.getOffset(), elem.getType(),
  454. elem.getSemantic(), elem.getIndex());
  455. }
  456. }
  457. }
  458. //-----------------------------------------------------------------------------
  459. unsigned short VertexDeclaration::getMaxSource(void) const
  460. {
  461. VertexElementList::const_iterator i, iend;
  462. iend = mElementList.end();
  463. unsigned short ret = 0;
  464. for (i = mElementList.begin(); i != iend; ++i)
  465. {
  466. if (i->getSource() > ret)
  467. {
  468. ret = i->getSource();
  469. }
  470. }
  471. return ret;
  472. }
  473. /************************************************************************/
  474. /* SERIALIZATION */
  475. /************************************************************************/
  476. RTTITypeBase* VertexDeclaration::getRTTIStatic()
  477. {
  478. return VertexDeclarationRTTI::instance();
  479. }
  480. RTTITypeBase* VertexDeclaration::getRTTI() const
  481. {
  482. return getRTTIStatic();
  483. }
  484. //-----------------------------------------------------------------------------
  485. VertexBufferBinding::VertexBufferBinding() : mHighIndex(0)
  486. {
  487. }
  488. //-----------------------------------------------------------------------------
  489. VertexBufferBinding::~VertexBufferBinding()
  490. {
  491. unsetAllBindings();
  492. }
  493. //-----------------------------------------------------------------------------
  494. void VertexBufferBinding::setBinding(unsigned short index, const HardwareVertexBufferPtr& buffer)
  495. {
  496. // NB will replace any existing buffer ptr at this index, and will thus cause
  497. // reference count to decrement on that buffer (possibly destroying it)
  498. mBindingMap[index] = buffer;
  499. mHighIndex = std::max(mHighIndex, (unsigned short)(index+1));
  500. }
  501. //-----------------------------------------------------------------------------
  502. void VertexBufferBinding::unsetBinding(unsigned short index)
  503. {
  504. VertexBufferBindingMap::iterator i = mBindingMap.find(index);
  505. if (i == mBindingMap.end())
  506. {
  507. CM_EXCEPT(ItemIdentityException,
  508. "Cannot find buffer binding for index " + toString(index));
  509. }
  510. mBindingMap.erase(i);
  511. }
  512. //-----------------------------------------------------------------------------
  513. void VertexBufferBinding::unsetAllBindings(void)
  514. {
  515. mBindingMap.clear();
  516. mHighIndex = 0;
  517. }
  518. //-----------------------------------------------------------------------------
  519. const VertexBufferBinding::VertexBufferBindingMap&
  520. VertexBufferBinding::getBindings(void) const
  521. {
  522. return mBindingMap;
  523. }
  524. //-----------------------------------------------------------------------------
  525. const HardwareVertexBufferPtr& VertexBufferBinding::getBuffer(unsigned short index) const
  526. {
  527. VertexBufferBindingMap::const_iterator i = mBindingMap.find(index);
  528. if (i == mBindingMap.end())
  529. {
  530. CM_EXCEPT(ItemIdentityException, "No buffer is bound to that index.");
  531. }
  532. return i->second;
  533. }
  534. //-----------------------------------------------------------------------------
  535. bool VertexBufferBinding::isBufferBound(unsigned short index) const
  536. {
  537. return mBindingMap.find(index) != mBindingMap.end();
  538. }
  539. //-----------------------------------------------------------------------------
  540. unsigned short VertexBufferBinding::getLastBoundIndex(void) const
  541. {
  542. return mBindingMap.empty() ? 0 : mBindingMap.rbegin()->first + 1;
  543. }
  544. //-----------------------------------------------------------------------------
  545. bool VertexBufferBinding::hasGaps(void) const
  546. {
  547. if (mBindingMap.empty())
  548. return false;
  549. if (mBindingMap.rbegin()->first + 1 == (int) mBindingMap.size())
  550. return false;
  551. return true;
  552. }
  553. //-----------------------------------------------------------------------------
  554. void VertexBufferBinding::closeGaps(BindingIndexMap& bindingIndexMap)
  555. {
  556. bindingIndexMap.clear();
  557. VertexBufferBindingMap newBindingMap;
  558. VertexBufferBindingMap::const_iterator it;
  559. UINT16 targetIndex = 0;
  560. for (it = mBindingMap.begin(); it != mBindingMap.end(); ++it, ++targetIndex)
  561. {
  562. bindingIndexMap[it->first] = targetIndex;
  563. newBindingMap[targetIndex] = it->second;
  564. }
  565. mBindingMap.swap(newBindingMap);
  566. mHighIndex = targetIndex;
  567. }
  568. }