BsVertexDeclaration.cpp 8.9 KB

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