VertexBuffer.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. // This file contains VertexBuffer code common to all graphics APIs.
  4. #include "../Precompiled.h"
  5. #include "../Graphics/Graphics.h"
  6. #include "../Math/MathDefs.h"
  7. #include "VertexBuffer.h"
  8. #include "../DebugNew.h"
  9. namespace Urho3D
  10. {
  11. VertexBuffer::VertexBuffer(Context* context, bool forceHeadless) :
  12. Object(context),
  13. GPUObject(forceHeadless ? nullptr : GetSubsystem<Graphics>())
  14. {
  15. UpdateOffsets();
  16. // Force shadowing mode if graphics subsystem does not exist
  17. if (!graphics_)
  18. shadowed_ = true;
  19. }
  20. VertexBuffer::~VertexBuffer()
  21. {
  22. Release();
  23. }
  24. void VertexBuffer::SetShadowed(bool enable)
  25. {
  26. // If no graphics subsystem, can not disable shadowing
  27. if (!graphics_)
  28. enable = true;
  29. if (enable != shadowed_)
  30. {
  31. if (enable && vertexSize_ && vertexCount_)
  32. shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
  33. else
  34. shadowData_.Reset();
  35. shadowed_ = enable;
  36. }
  37. }
  38. bool VertexBuffer::SetSize(unsigned vertexCount, unsigned elementMask, bool dynamic)
  39. {
  40. return SetSize(vertexCount, GetElements(elementMask), dynamic);
  41. }
  42. bool VertexBuffer::SetSize(unsigned vertexCount, const PODVector<VertexElement>& elements, bool dynamic)
  43. {
  44. Unlock();
  45. vertexCount_ = vertexCount;
  46. elements_ = elements;
  47. dynamic_ = dynamic;
  48. UpdateOffsets();
  49. if (shadowed_ && vertexCount_ && vertexSize_)
  50. shadowData_ = new unsigned char[vertexCount_ * vertexSize_];
  51. else
  52. shadowData_.Reset();
  53. return Create();
  54. }
  55. void VertexBuffer::UpdateOffsets()
  56. {
  57. unsigned elementOffset = 0;
  58. elementHash_ = 0;
  59. elementMask_ = MASK_NONE;
  60. for (PODVector<VertexElement>::Iterator i = elements_.Begin(); i != elements_.End(); ++i)
  61. {
  62. i->offset_ = elementOffset;
  63. elementOffset += ELEMENT_TYPESIZES[i->type_];
  64. elementHash_ <<= 6;
  65. elementHash_ += (((int)i->type_ + 1) * ((int)i->semantic_ + 1) + i->index_);
  66. for (unsigned j = 0; j < MAX_LEGACY_VERTEX_ELEMENTS; ++j)
  67. {
  68. const VertexElement& legacy = LEGACY_VERTEXELEMENTS[j];
  69. if (i->type_ == legacy.type_ && i->semantic_ == legacy.semantic_ && i->index_ == legacy.index_)
  70. elementMask_ |= VertexMaskFlags(1u << j);
  71. }
  72. }
  73. vertexSize_ = elementOffset;
  74. }
  75. const VertexElement* VertexBuffer::GetElement(VertexElementSemantic semantic, unsigned char index) const
  76. {
  77. for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
  78. {
  79. if (i->semantic_ == semantic && i->index_ == index)
  80. return &(*i);
  81. }
  82. return nullptr;
  83. }
  84. const VertexElement* VertexBuffer::GetElement(VertexElementType type, VertexElementSemantic semantic, unsigned char index) const
  85. {
  86. for (PODVector<VertexElement>::ConstIterator i = elements_.Begin(); i != elements_.End(); ++i)
  87. {
  88. if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
  89. return &(*i);
  90. }
  91. return nullptr;
  92. }
  93. const VertexElement* VertexBuffer::GetElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
  94. {
  95. for (PODVector<VertexElement>::ConstIterator i = elements.Begin(); i != elements.End(); ++i)
  96. {
  97. if (i->type_ == type && i->semantic_ == semantic && i->index_ == index)
  98. return &(*i);
  99. }
  100. return nullptr;
  101. }
  102. bool VertexBuffer::HasElement(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
  103. {
  104. return GetElement(elements, type, semantic, index) != nullptr;
  105. }
  106. unsigned VertexBuffer::GetElementOffset(const PODVector<VertexElement>& elements, VertexElementType type, VertexElementSemantic semantic, unsigned char index)
  107. {
  108. const VertexElement* element = GetElement(elements, type, semantic, index);
  109. return element ? element->offset_ : M_MAX_UNSIGNED;
  110. }
  111. PODVector<VertexElement> VertexBuffer::GetElements(unsigned elementMask)
  112. {
  113. PODVector<VertexElement> ret;
  114. for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
  115. {
  116. if (elementMask & (1u << i))
  117. ret.Push(LEGACY_VERTEXELEMENTS[i]);
  118. }
  119. return ret;
  120. }
  121. unsigned VertexBuffer::GetVertexSize(const PODVector<VertexElement>& elements)
  122. {
  123. unsigned size = 0;
  124. for (unsigned i = 0; i < elements.Size(); ++i)
  125. size += ELEMENT_TYPESIZES[elements[i].type_];
  126. return size;
  127. }
  128. unsigned VertexBuffer::GetVertexSize(unsigned elementMask)
  129. {
  130. unsigned size = 0;
  131. for (unsigned i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
  132. {
  133. if (elementMask & (1u << i))
  134. size += ELEMENT_TYPESIZES[LEGACY_VERTEXELEMENTS[i].type_];
  135. }
  136. return size;
  137. }
  138. void VertexBuffer::UpdateOffsets(PODVector<VertexElement>& elements)
  139. {
  140. unsigned elementOffset = 0;
  141. for (PODVector<VertexElement>::Iterator i = elements.Begin(); i != elements.End(); ++i)
  142. {
  143. i->offset_ = elementOffset;
  144. elementOffset += ELEMENT_TYPESIZES[i->type_];
  145. }
  146. }
  147. void VertexBuffer::OnDeviceLost()
  148. {
  149. GAPI gapi = Graphics::GetGAPI();
  150. #ifdef URHO3D_OPENGL
  151. if (gapi == GAPI_OPENGL)
  152. return OnDeviceLost_OGL();
  153. #endif
  154. #ifdef URHO3D_D3D9
  155. if (gapi == GAPI_D3D9)
  156. return OnDeviceLost_D3D9();
  157. #endif
  158. #ifdef URHO3D_D3D11
  159. if (gapi == GAPI_D3D11)
  160. return OnDeviceLost_D3D11();
  161. #endif
  162. }
  163. void VertexBuffer::OnDeviceReset()
  164. {
  165. GAPI gapi = Graphics::GetGAPI();
  166. #ifdef URHO3D_OPENGL
  167. if (gapi == GAPI_OPENGL)
  168. return OnDeviceReset_OGL();
  169. #endif
  170. #ifdef URHO3D_D3D9
  171. if (gapi == GAPI_D3D9)
  172. return OnDeviceReset_D3D9();
  173. #endif
  174. #ifdef URHO3D_D3D11
  175. if (gapi == GAPI_D3D11)
  176. return OnDeviceReset_D3D11();
  177. #endif
  178. }
  179. void VertexBuffer::Release()
  180. {
  181. GAPI gapi = Graphics::GetGAPI();
  182. #ifdef URHO3D_OPENGL
  183. if (gapi == GAPI_OPENGL)
  184. return Release_OGL();
  185. #endif
  186. #ifdef URHO3D_D3D9
  187. if (gapi == GAPI_D3D9)
  188. return Release_D3D9();
  189. #endif
  190. #ifdef URHO3D_D3D11
  191. if (gapi == GAPI_D3D11)
  192. return Release_D3D11();
  193. #endif
  194. }
  195. bool VertexBuffer::SetData(const void* data)
  196. {
  197. GAPI gapi = Graphics::GetGAPI();
  198. #ifdef URHO3D_OPENGL
  199. if (gapi == GAPI_OPENGL)
  200. return SetData_OGL(data);
  201. #endif
  202. #ifdef URHO3D_D3D9
  203. if (gapi == GAPI_D3D9)
  204. return SetData_D3D9(data);
  205. #endif
  206. #ifdef URHO3D_D3D11
  207. if (gapi == GAPI_D3D11)
  208. return SetData_D3D11(data);
  209. #endif
  210. return {}; // Prevent warning
  211. }
  212. bool VertexBuffer::SetDataRange(const void* data, unsigned start, unsigned count, bool discard)
  213. {
  214. GAPI gapi = Graphics::GetGAPI();
  215. #ifdef URHO3D_OPENGL
  216. if (gapi == GAPI_OPENGL)
  217. return SetDataRange_OGL(data, start, count, discard);
  218. #endif
  219. #ifdef URHO3D_D3D9
  220. if (gapi == GAPI_D3D9)
  221. return SetDataRange_D3D9(data, start, count, discard);
  222. #endif
  223. #ifdef URHO3D_D3D11
  224. if (gapi == GAPI_D3D11)
  225. return SetDataRange_D3D11(data, start, count, discard);
  226. #endif
  227. return {}; // Prevent warning
  228. }
  229. void* VertexBuffer::Lock(unsigned start, unsigned count, bool discard)
  230. {
  231. GAPI gapi = Graphics::GetGAPI();
  232. #ifdef URHO3D_OPENGL
  233. if (gapi == GAPI_OPENGL)
  234. return Lock_OGL(start, count, discard);
  235. #endif
  236. #ifdef URHO3D_D3D9
  237. if (gapi == GAPI_D3D9)
  238. return Lock_D3D9(start, count, discard);
  239. #endif
  240. #ifdef URHO3D_D3D11
  241. if (gapi == GAPI_D3D11)
  242. return Lock_D3D11(start, count, discard);
  243. #endif
  244. return {}; // Prevent warning
  245. }
  246. void VertexBuffer::Unlock()
  247. {
  248. GAPI gapi = Graphics::GetGAPI();
  249. #ifdef URHO3D_OPENGL
  250. if (gapi == GAPI_OPENGL)
  251. return Unlock_OGL();
  252. #endif
  253. #ifdef URHO3D_D3D9
  254. if (gapi == GAPI_D3D9)
  255. return Unlock_D3D9();
  256. #endif
  257. #ifdef URHO3D_D3D11
  258. if (gapi == GAPI_D3D11)
  259. return Unlock_D3D11();
  260. #endif
  261. }
  262. bool VertexBuffer::Create()
  263. {
  264. GAPI gapi = Graphics::GetGAPI();
  265. #ifdef URHO3D_OPENGL
  266. if (gapi == GAPI_OPENGL)
  267. return Create_OGL();
  268. #endif
  269. #ifdef URHO3D_D3D9
  270. if (gapi == GAPI_D3D9)
  271. return Create_D3D9();
  272. #endif
  273. #ifdef URHO3D_D3D11
  274. if (gapi == GAPI_D3D11)
  275. return Create_D3D11();
  276. #endif
  277. return {}; // Prevent warning
  278. }
  279. bool VertexBuffer::UpdateToGPU()
  280. {
  281. GAPI gapi = Graphics::GetGAPI();
  282. #ifdef URHO3D_OPENGL
  283. if (gapi == GAPI_OPENGL)
  284. return UpdateToGPU_OGL();
  285. #endif
  286. #ifdef URHO3D_D3D9
  287. if (gapi == GAPI_D3D9)
  288. return UpdateToGPU_D3D9();
  289. #endif
  290. #ifdef URHO3D_D3D11
  291. if (gapi == GAPI_D3D11)
  292. return UpdateToGPU_D3D11();
  293. #endif
  294. return {}; // Prevent warning
  295. }
  296. void* VertexBuffer::MapBuffer(unsigned start, unsigned count, bool discard)
  297. {
  298. GAPI gapi = Graphics::GetGAPI();
  299. #ifdef URHO3D_OPENGL
  300. if (gapi == GAPI_OPENGL)
  301. return MapBuffer_OGL(start, count, discard);
  302. #endif
  303. #ifdef URHO3D_D3D9
  304. if (gapi == GAPI_D3D9)
  305. return MapBuffer_D3D9(start, count, discard);
  306. #endif
  307. #ifdef URHO3D_D3D11
  308. if (gapi == GAPI_D3D11)
  309. return MapBuffer_D3D11(start, count, discard);
  310. #endif
  311. return {}; // Prevent warning
  312. }
  313. void VertexBuffer::UnmapBuffer()
  314. {
  315. GAPI gapi = Graphics::GetGAPI();
  316. #ifdef URHO3D_OPENGL
  317. if (gapi == GAPI_OPENGL)
  318. return UnmapBuffer_OGL();
  319. #endif
  320. #ifdef URHO3D_D3D9
  321. if (gapi == GAPI_D3D9)
  322. return UnmapBuffer_D3D9();
  323. #endif
  324. #ifdef URHO3D_D3D11
  325. if (gapi == GAPI_D3D11)
  326. return UnmapBuffer_D3D11();
  327. #endif
  328. }
  329. }