VertexBuffer.cpp 9.3 KB

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