BsVertexDeclaration.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVertexDeclaration.h"
  4. #include "BsVertexDeclarationRTTI.h"
  5. #include "BsHardwareBufferManager.h"
  6. #include "BsRenderAPI.h"
  7. namespace BansheeEngine
  8. {
  9. VertexElement::VertexElement(UINT16 source, UINT32 offset,
  10. VertexElementType theType, VertexElementSemantic semantic, UINT16 index)
  11. : mSource(source), mOffset(offset), mType(theType), mSemantic(semantic), mIndex(index)
  12. {
  13. }
  14. UINT32 VertexElement::getSize(void) const
  15. {
  16. return getTypeSize(mType);
  17. }
  18. UINT32 VertexElement::getTypeSize(VertexElementType etype)
  19. {
  20. switch(etype)
  21. {
  22. case VET_COLOR:
  23. case VET_COLOR_ABGR:
  24. case VET_COLOR_ARGB:
  25. return sizeof(RGBA);
  26. case VET_FLOAT1:
  27. return sizeof(float);
  28. case VET_FLOAT2:
  29. return sizeof(float)*2;
  30. case VET_FLOAT3:
  31. return sizeof(float)*3;
  32. case VET_FLOAT4:
  33. return sizeof(float)*4;
  34. case VET_SHORT1:
  35. return sizeof(short);
  36. case VET_SHORT2:
  37. return sizeof(short)*2;
  38. case VET_SHORT3:
  39. return sizeof(short)*3;
  40. case VET_SHORT4:
  41. return sizeof(short)*4;
  42. case VET_UBYTE4:
  43. return sizeof(unsigned char)*4;
  44. }
  45. return 0;
  46. }
  47. unsigned short VertexElement::getTypeCount(VertexElementType etype)
  48. {
  49. switch (etype)
  50. {
  51. case VET_COLOR:
  52. case VET_COLOR_ABGR:
  53. case VET_COLOR_ARGB:
  54. return 4;
  55. case VET_FLOAT1:
  56. return 1;
  57. case VET_FLOAT2:
  58. return 2;
  59. case VET_FLOAT3:
  60. return 3;
  61. case VET_FLOAT4:
  62. return 4;
  63. case VET_SHORT1:
  64. return 1;
  65. case VET_SHORT2:
  66. return 2;
  67. case VET_SHORT3:
  68. return 3;
  69. case VET_SHORT4:
  70. return 4;
  71. case VET_UBYTE4:
  72. return 4;
  73. }
  74. BS_EXCEPT(InvalidParametersException, "Invalid type");
  75. }
  76. VertexElementType VertexElement::getBestColorVertexElementType()
  77. {
  78. // Use the current render system to determine if possible
  79. if (BansheeEngine::RenderAPICore::instancePtr())
  80. {
  81. return BansheeEngine::RenderAPICore::instancePtr()->getColorVertexElementType();
  82. }
  83. else
  84. {
  85. // We can't know the specific type right now, so pick a type
  86. // based on platform
  87. #if BS_PLATFORM == BS_PLATFORM_WIN32
  88. return VET_COLOR_ARGB; // prefer D3D format on windows
  89. #else
  90. return VET_COLOR_ABGR; // prefer GL format on everything else
  91. #endif
  92. }
  93. }
  94. bool VertexElement::operator== (const VertexElement& rhs) const
  95. {
  96. if (mType != rhs.mType || mIndex != rhs.mIndex || mOffset != rhs.mOffset ||
  97. mSemantic != rhs.mSemantic || mSource != rhs.mSource)
  98. {
  99. return false;
  100. }
  101. else
  102. return true;
  103. }
  104. bool VertexElement::operator!= (const VertexElement& rhs) const
  105. {
  106. return !(*this == rhs);
  107. }
  108. VertexDeclarationProperties::VertexDeclarationProperties(const List<VertexElement>& elements)
  109. {
  110. for (auto& elem : elements)
  111. {
  112. VertexElementType type = elem.getType();
  113. if (elem.getType() == VET_COLOR)
  114. type = VertexElement::getBestColorVertexElementType();
  115. mElementList.push_back(VertexElement(elem.getStreamIdx(), elem.getOffset(), type, elem.getSemantic(), elem.getSemanticIdx()));
  116. }
  117. }
  118. bool VertexDeclarationProperties::operator== (const VertexDeclarationProperties& rhs) const
  119. {
  120. if (mElementList.size() != rhs.mElementList.size())
  121. return false;
  122. auto myIter = mElementList.begin();
  123. auto theirIter = rhs.mElementList.begin();
  124. for (; myIter != mElementList.end() && theirIter != rhs.mElementList.end(); ++myIter, ++theirIter)
  125. {
  126. if (!(*myIter == *theirIter))
  127. return false;
  128. }
  129. return true;
  130. }
  131. bool VertexDeclarationProperties::operator!= (const VertexDeclarationProperties& rhs) const
  132. {
  133. return !(*this == rhs);
  134. }
  135. const VertexElement* VertexDeclarationProperties::getElement(UINT16 index) const
  136. {
  137. assert(index < mElementList.size() && "Index out of bounds");
  138. auto iter = mElementList.begin();
  139. for (UINT16 i = 0; i < index; ++i)
  140. ++iter;
  141. return &(*iter);
  142. }
  143. const VertexElement* VertexDeclarationProperties::findElementBySemantic(VertexElementSemantic sem, UINT16 index) const
  144. {
  145. for (auto& elem : mElementList)
  146. {
  147. if (elem.getSemantic() == sem && elem.getSemanticIdx() == index)
  148. {
  149. return &elem;
  150. }
  151. }
  152. return nullptr;
  153. }
  154. List<VertexElement> VertexDeclarationProperties::findElementsBySource(UINT16 source) const
  155. {
  156. List<VertexElement> retList;
  157. for (auto& elem : mElementList)
  158. {
  159. if (elem.getStreamIdx() == source)
  160. {
  161. retList.push_back(elem);
  162. }
  163. }
  164. return retList;
  165. }
  166. UINT32 VertexDeclarationProperties::getVertexSize(UINT16 source) const
  167. {
  168. UINT32 size = 0;
  169. for (auto& elem : mElementList)
  170. {
  171. if (elem.getStreamIdx() == source)
  172. {
  173. size += elem.getSize();
  174. }
  175. }
  176. return size;
  177. }
  178. UINT32 VertexDeclarationCore::NextFreeId = 0;
  179. VertexDeclarationCore::VertexDeclarationCore(const List<VertexElement>& elements)
  180. :mProperties(elements)
  181. {
  182. }
  183. void VertexDeclarationCore::initialize()
  184. {
  185. mId = NextFreeId++;
  186. CoreObjectCore::initialize();
  187. }
  188. bool VertexDeclarationCore::isCompatible(const SPtr<VertexDeclarationCore>& shaderDecl)
  189. {
  190. const List<VertexElement>& shaderElems = shaderDecl->getProperties().getElements();
  191. const List<VertexElement>& bufferElems = getProperties().getElements();
  192. for (auto shaderIter = shaderElems.begin(); shaderIter != shaderElems.end(); ++shaderIter)
  193. {
  194. const VertexElement* foundElement = nullptr;
  195. for (auto bufferIter = bufferElems.begin(); bufferIter != bufferElems.end(); ++bufferIter)
  196. {
  197. if (shaderIter->getSemantic() == bufferIter->getSemantic() && shaderIter->getSemanticIdx() == bufferIter->getSemanticIdx())
  198. {
  199. foundElement = &(*bufferIter);
  200. break;
  201. }
  202. }
  203. if (foundElement == nullptr)
  204. return false;
  205. }
  206. return true;
  207. }
  208. Vector<VertexElement> VertexDeclarationCore::getMissingElements(const SPtr<VertexDeclarationCore>& shaderDecl)
  209. {
  210. Vector<VertexElement> missingElements;
  211. const List<VertexElement>& shaderElems = shaderDecl->getProperties().getElements();
  212. const List<VertexElement>& bufferElems = getProperties().getElements();
  213. for (auto shaderIter = shaderElems.begin(); shaderIter != shaderElems.end(); ++shaderIter)
  214. {
  215. const VertexElement* foundElement = nullptr;
  216. for (auto bufferIter = bufferElems.begin(); bufferIter != bufferElems.end(); ++bufferIter)
  217. {
  218. if (shaderIter->getSemantic() == bufferIter->getSemantic() && shaderIter->getSemanticIdx() == bufferIter->getSemanticIdx())
  219. {
  220. foundElement = &(*bufferIter);
  221. break;
  222. }
  223. }
  224. if (foundElement == nullptr)
  225. missingElements.push_back(*shaderIter);
  226. }
  227. return missingElements;
  228. }
  229. VertexDeclaration::VertexDeclaration(const List<VertexElement>& elements)
  230. :mProperties(elements)
  231. {
  232. }
  233. SPtr<VertexDeclarationCore> VertexDeclaration::getCore() const
  234. {
  235. return std::static_pointer_cast<VertexDeclarationCore>(mCoreSpecific);
  236. }
  237. SPtr<CoreObjectCore> VertexDeclaration::createCore() const
  238. {
  239. return HardwareBufferCoreManager::instance().createVertexDeclarationInternal(mProperties.mElementList);
  240. }
  241. VertexDeclarationPtr VertexDeclaration::createVertexDeclaration(const List<VertexElement>& elements)
  242. {
  243. return HardwareBufferManager::instance().createVertexDeclaration(elements);
  244. }
  245. /************************************************************************/
  246. /* SERIALIZATION */
  247. /************************************************************************/
  248. RTTITypeBase* VertexDeclaration::getRTTIStatic()
  249. {
  250. return VertexDeclarationRTTI::instance();
  251. }
  252. RTTITypeBase* VertexDeclaration::getRTTI() const
  253. {
  254. return getRTTIStatic();
  255. }
  256. String toString(const VertexElementSemantic& val)
  257. {
  258. switch (val)
  259. {
  260. case VES_POSITION:
  261. return "POSITION";
  262. case VES_BLEND_WEIGHTS:
  263. return "BLEND_WEIGHTS";
  264. case VES_BLEND_INDICES:
  265. return "BLEND_INDICES";
  266. case VES_NORMAL:
  267. return "NORMAL";
  268. case VES_COLOR:
  269. return "COLOR";
  270. case VES_TEXCOORD:
  271. return "TEXCOORD";
  272. case VES_BITANGENT:
  273. return "BITANGENT";
  274. case VES_TANGENT:
  275. return "TANGENT";
  276. case VES_POSITIONT:
  277. return "POSITIONT";
  278. case VES_PSIZE:
  279. return "PSIZE";
  280. }
  281. return "";
  282. }
  283. WString toWString(const VertexElementSemantic& val)
  284. {
  285. return toWString(toString(val));
  286. }
  287. }