CmHardwareVertexBuffer.cpp 19 KB

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