2
0

CmVertexDeclaration.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. #include "CmVertexDeclaration.h"
  2. #include "CmVertexDeclarationRTTI.h"
  3. #include "CmHardwareBufferManager.h"
  4. #include "CmRenderSystem.h"
  5. namespace CamelotEngine
  6. {
  7. VertexElement::VertexElement(unsigned short source, UINT32 offset,
  8. VertexElementType theType, VertexElementSemantic semantic, unsigned short index)
  9. : mSource(source), mOffset(offset), mType(theType),
  10. mSemantic(semantic), mIndex(index)
  11. {
  12. }
  13. //-----------------------------------------------------------------------------
  14. UINT32 VertexElement::getSize(void) const
  15. {
  16. return getTypeSize(mType);
  17. }
  18. //-----------------------------------------------------------------------------
  19. UINT32 VertexElement::getTypeSize(VertexElementType etype)
  20. {
  21. switch(etype)
  22. {
  23. case VET_COLOR:
  24. case VET_COLOR_ABGR:
  25. case VET_COLOR_ARGB:
  26. return sizeof(RGBA);
  27. case VET_FLOAT1:
  28. return sizeof(float);
  29. case VET_FLOAT2:
  30. return sizeof(float)*2;
  31. case VET_FLOAT3:
  32. return sizeof(float)*3;
  33. case VET_FLOAT4:
  34. return sizeof(float)*4;
  35. case VET_SHORT1:
  36. return sizeof(short);
  37. case VET_SHORT2:
  38. return sizeof(short)*2;
  39. case VET_SHORT3:
  40. return sizeof(short)*3;
  41. case VET_SHORT4:
  42. return sizeof(short)*4;
  43. case VET_UBYTE4:
  44. return sizeof(unsigned char)*4;
  45. }
  46. return 0;
  47. }
  48. //-----------------------------------------------------------------------------
  49. unsigned short VertexElement::getTypeCount(VertexElementType etype)
  50. {
  51. switch (etype)
  52. {
  53. case VET_COLOR:
  54. case VET_COLOR_ABGR:
  55. case VET_COLOR_ARGB:
  56. return 1;
  57. case VET_FLOAT1:
  58. return 1;
  59. case VET_FLOAT2:
  60. return 2;
  61. case VET_FLOAT3:
  62. return 3;
  63. case VET_FLOAT4:
  64. return 4;
  65. case VET_SHORT1:
  66. return 1;
  67. case VET_SHORT2:
  68. return 2;
  69. case VET_SHORT3:
  70. return 3;
  71. case VET_SHORT4:
  72. return 4;
  73. case VET_UBYTE4:
  74. return 4;
  75. }
  76. CM_EXCEPT(InvalidParametersException, "Invalid type");
  77. }
  78. //-----------------------------------------------------------------------------
  79. VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType,
  80. unsigned short count)
  81. {
  82. switch (baseType)
  83. {
  84. case VET_FLOAT1:
  85. switch(count)
  86. {
  87. case 1:
  88. return VET_FLOAT1;
  89. case 2:
  90. return VET_FLOAT2;
  91. case 3:
  92. return VET_FLOAT3;
  93. case 4:
  94. return VET_FLOAT4;
  95. default:
  96. break;
  97. }
  98. break;
  99. case VET_SHORT1:
  100. switch(count)
  101. {
  102. case 1:
  103. return VET_SHORT1;
  104. case 2:
  105. return VET_SHORT2;
  106. case 3:
  107. return VET_SHORT3;
  108. case 4:
  109. return VET_SHORT4;
  110. default:
  111. break;
  112. }
  113. break;
  114. default:
  115. break;
  116. }
  117. CM_EXCEPT(InvalidParametersException, "Invalid base type");
  118. }
  119. //--------------------------------------------------------------------------
  120. VertexElementType VertexElement::getBestColourVertexElementType(void)
  121. {
  122. // Use the current render system to determine if possible
  123. if (CamelotEngine::RenderSystem::instancePtr())
  124. {
  125. return CamelotEngine::RenderSystem::instancePtr()->getColorVertexElementType();
  126. }
  127. else
  128. {
  129. // We can't know the specific type right now, so pick a type
  130. // based on platform
  131. #if CM_PLATFORM == CM_PLATFORM_WIN32
  132. return VET_COLOR_ARGB; // prefer D3D format on windows
  133. #else
  134. return VET_COLOR_ABGR; // prefer GL format on everything else
  135. #endif
  136. }
  137. }
  138. //--------------------------------------------------------------------------
  139. void VertexElement::convertColourValue(VertexElementType srcType,
  140. VertexElementType dstType, UINT32* ptr)
  141. {
  142. if (srcType == dstType)
  143. return;
  144. // Conversion between ARGB and ABGR is always a case of flipping R/B
  145. *ptr =
  146. ((*ptr&0x00FF0000)>>16)|((*ptr&0x000000FF)<<16)|(*ptr&0xFF00FF00);
  147. }
  148. //--------------------------------------------------------------------------
  149. UINT32 VertexElement::convertColourValue(const Color& src,
  150. VertexElementType dst)
  151. {
  152. switch(dst)
  153. {
  154. #if CM_PLATFORM == CM_PLATFORM_WIN32
  155. default:
  156. #endif
  157. case VET_COLOR_ARGB:
  158. return src.getAsARGB();
  159. #if CM_PLATFORM != CM_PLATFORM_WIN32
  160. default:
  161. #endif
  162. case VET_COLOR_ABGR:
  163. return src.getAsABGR();
  164. };
  165. }
  166. //-----------------------------------------------------------------------------
  167. VertexElementType VertexElement::getBaseType(VertexElementType multiType)
  168. {
  169. switch (multiType)
  170. {
  171. case VET_FLOAT1:
  172. case VET_FLOAT2:
  173. case VET_FLOAT3:
  174. case VET_FLOAT4:
  175. return VET_FLOAT1;
  176. case VET_COLOR:
  177. return VET_COLOR;
  178. case VET_COLOR_ABGR:
  179. return VET_COLOR_ABGR;
  180. case VET_COLOR_ARGB:
  181. return VET_COLOR_ARGB;
  182. case VET_SHORT1:
  183. case VET_SHORT2:
  184. case VET_SHORT3:
  185. case VET_SHORT4:
  186. return VET_SHORT1;
  187. case VET_UBYTE4:
  188. return VET_UBYTE4;
  189. };
  190. // To keep compiler happy
  191. return VET_FLOAT1;
  192. }
  193. //-----------------------------------------------------------------------------
  194. VertexDeclaration::VertexDeclaration()
  195. {
  196. }
  197. //-----------------------------------------------------------------------------
  198. VertexDeclaration::~VertexDeclaration()
  199. {
  200. }
  201. //-----------------------------------------------------------------------------
  202. const VertexDeclaration::VertexElementList& VertexDeclaration::getElements(void) const
  203. {
  204. return mElementList;
  205. }
  206. //-----------------------------------------------------------------------------
  207. const VertexElement& VertexDeclaration::addElement(unsigned short source,
  208. UINT32 offset, VertexElementType theType,
  209. VertexElementSemantic semantic, unsigned short index)
  210. {
  211. // Refine colour type to a specific type
  212. if (theType == VET_COLOR)
  213. {
  214. theType = VertexElement::getBestColourVertexElementType();
  215. }
  216. mElementList.push_back(
  217. VertexElement(source, offset, theType, semantic, index)
  218. );
  219. return mElementList.back();
  220. }
  221. //-----------------------------------------------------------------------------
  222. const VertexElement& VertexDeclaration::insertElement(unsigned short atPosition,
  223. unsigned short source, UINT32 offset, VertexElementType theType,
  224. VertexElementSemantic semantic, unsigned short index)
  225. {
  226. if (atPosition >= mElementList.size())
  227. {
  228. return addElement(source, offset, theType, semantic, index);
  229. }
  230. VertexElementList::iterator i = mElementList.begin();
  231. for (unsigned short n = 0; n < atPosition; ++n)
  232. ++i;
  233. i = mElementList.insert(i,
  234. VertexElement(source, offset, theType, semantic, index));
  235. return *i;
  236. }
  237. //-----------------------------------------------------------------------------
  238. const VertexElement* VertexDeclaration::getElement(unsigned short index)
  239. {
  240. assert(index < mElementList.size() && "Index out of bounds");
  241. VertexElementList::iterator i = mElementList.begin();
  242. for (unsigned short n = 0; n < index; ++n)
  243. ++i;
  244. return &(*i);
  245. }
  246. //-----------------------------------------------------------------------------
  247. void VertexDeclaration::removeElement(unsigned short elem_index)
  248. {
  249. assert(elem_index < mElementList.size() && "Index out of bounds");
  250. VertexElementList::iterator i = mElementList.begin();
  251. for (unsigned short n = 0; n < elem_index; ++n)
  252. ++i;
  253. mElementList.erase(i);
  254. }
  255. //-----------------------------------------------------------------------------
  256. void VertexDeclaration::removeElement(VertexElementSemantic semantic, unsigned short index)
  257. {
  258. VertexElementList::iterator ei, eiend;
  259. eiend = mElementList.end();
  260. for (ei = mElementList.begin(); ei != eiend; ++ei)
  261. {
  262. if (ei->getSemantic() == semantic && ei->getIndex() == index)
  263. {
  264. mElementList.erase(ei);
  265. break;
  266. }
  267. }
  268. }
  269. //-----------------------------------------------------------------------------
  270. void VertexDeclaration::removeAllElements(void)
  271. {
  272. mElementList.clear();
  273. }
  274. //-----------------------------------------------------------------------------
  275. void VertexDeclaration::modifyElement(unsigned short elem_index,
  276. unsigned short source, UINT32 offset, VertexElementType theType,
  277. VertexElementSemantic semantic, unsigned short index)
  278. {
  279. assert(elem_index < mElementList.size() && "Index out of bounds");
  280. VertexElementList::iterator i = mElementList.begin();
  281. std::advance(i, elem_index);
  282. (*i) = VertexElement(source, offset, theType, semantic, index);
  283. }
  284. //-----------------------------------------------------------------------------
  285. const VertexElement* VertexDeclaration::findElementBySemantic(
  286. VertexElementSemantic sem, unsigned short index)
  287. {
  288. VertexElementList::const_iterator ei, eiend;
  289. eiend = mElementList.end();
  290. for (ei = mElementList.begin(); ei != eiend; ++ei)
  291. {
  292. if (ei->getSemantic() == sem && ei->getIndex() == index)
  293. {
  294. return &(*ei);
  295. }
  296. }
  297. return NULL;
  298. }
  299. //-----------------------------------------------------------------------------
  300. VertexDeclaration::VertexElementList VertexDeclaration::findElementsBySource(
  301. unsigned short source)
  302. {
  303. VertexElementList retList;
  304. VertexElementList::const_iterator ei, eiend;
  305. eiend = mElementList.end();
  306. for (ei = mElementList.begin(); ei != eiend; ++ei)
  307. {
  308. if (ei->getSource() == source)
  309. {
  310. retList.push_back(*ei);
  311. }
  312. }
  313. return retList;
  314. }
  315. //-----------------------------------------------------------------------------
  316. UINT32 VertexDeclaration::getVertexSize(unsigned short source)
  317. {
  318. VertexElementList::const_iterator i, iend;
  319. iend = mElementList.end();
  320. UINT32 sz = 0;
  321. for (i = mElementList.begin(); i != iend; ++i)
  322. {
  323. if (i->getSource() == source)
  324. {
  325. sz += i->getSize();
  326. }
  327. }
  328. return sz;
  329. }
  330. //-----------------------------------------------------------------------------
  331. VertexDeclarationPtr VertexDeclaration::clone(HardwareBufferManagerBase* mgr)
  332. {
  333. HardwareBufferManagerBase* pManager = mgr ? mgr : HardwareBufferManager::instancePtr();
  334. VertexDeclarationPtr ret = pManager->createVertexDeclaration();
  335. VertexElementList::const_iterator i, iend;
  336. iend = mElementList.end();
  337. for (i = mElementList.begin(); i != iend; ++i)
  338. {
  339. ret->addElement(i->getSource(), i->getOffset(), i->getType(), i->getSemantic(), i->getIndex());
  340. }
  341. return ret;
  342. }
  343. //-----------------------------------------------------------------------------
  344. // Sort routine for VertexElement
  345. bool VertexDeclaration::vertexElementLess(const VertexElement& e1, const VertexElement& e2)
  346. {
  347. // Sort by source first
  348. if (e1.getSource() < e2.getSource())
  349. {
  350. return true;
  351. }
  352. else if (e1.getSource() == e2.getSource())
  353. {
  354. // Use ordering of semantics to sort
  355. if (e1.getSemantic() < e2.getSemantic())
  356. {
  357. return true;
  358. }
  359. else if (e1.getSemantic() == e2.getSemantic())
  360. {
  361. // Use index to sort
  362. if (e1.getIndex() < e2.getIndex())
  363. {
  364. return true;
  365. }
  366. }
  367. }
  368. return false;
  369. }
  370. void VertexDeclaration::sort(void)
  371. {
  372. mElementList.sort(VertexDeclaration::vertexElementLess);
  373. }
  374. //-----------------------------------------------------------------------------
  375. void VertexDeclaration::closeGapsInSource(void)
  376. {
  377. if (mElementList.empty())
  378. return;
  379. // Sort first
  380. sort();
  381. VertexElementList::iterator i, iend;
  382. iend = mElementList.end();
  383. unsigned short targetIdx = 0;
  384. unsigned short lastIdx = getElement(0)->getSource();
  385. unsigned short c = 0;
  386. for (i = mElementList.begin(); i != iend; ++i, ++c)
  387. {
  388. VertexElement& elem = *i;
  389. if (lastIdx != elem.getSource())
  390. {
  391. targetIdx++;
  392. lastIdx = elem.getSource();
  393. }
  394. if (targetIdx != elem.getSource())
  395. {
  396. modifyElement(c, targetIdx, elem.getOffset(), elem.getType(),
  397. elem.getSemantic(), elem.getIndex());
  398. }
  399. }
  400. }
  401. //-----------------------------------------------------------------------------
  402. unsigned short VertexDeclaration::getMaxSource(void) const
  403. {
  404. VertexElementList::const_iterator i, iend;
  405. iend = mElementList.end();
  406. unsigned short ret = 0;
  407. for (i = mElementList.begin(); i != iend; ++i)
  408. {
  409. if (i->getSource() > ret)
  410. {
  411. ret = i->getSource();
  412. }
  413. }
  414. return ret;
  415. }
  416. /************************************************************************/
  417. /* SERIALIZATION */
  418. /************************************************************************/
  419. RTTITypeBase* VertexDeclaration::getRTTIStatic()
  420. {
  421. return VertexDeclarationRTTI::instance();
  422. }
  423. RTTITypeBase* VertexDeclaration::getRTTI() const
  424. {
  425. return getRTTIStatic();
  426. }
  427. }