CmHardwareVertexBuffer.cpp 19 KB

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