VertexBuffer.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright (c) 2008-2023 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 byte[(size_t)vertexCount_ * vertexSize_];
  33. else
  34. shadowData_.Reset();
  35. shadowed_ = enable;
  36. }
  37. }
  38. bool VertexBuffer::SetSize(i32 vertexCount, VertexElements 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 byte[(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_ = VertexElements::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_ |= VertexElements{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(VertexElements elementMask)
  119. {
  120. Vector<VertexElement> ret;
  121. for (i32 i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
  122. {
  123. if (!!(elementMask & VertexElements{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(VertexElements elementMask)
  136. {
  137. i32 size = 0;
  138. for (i32 i = 0; i < MAX_LEGACY_VERTEX_ELEMENTS; ++i)
  139. {
  140. if (!!(elementMask & VertexElements{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_D3D11
  162. if (gapi == GAPI_D3D11)
  163. return OnDeviceLost_D3D11();
  164. #endif
  165. }
  166. void VertexBuffer::OnDeviceReset()
  167. {
  168. GAPI gapi = Graphics::GetGAPI();
  169. #ifdef URHO3D_OPENGL
  170. if (gapi == GAPI_OPENGL)
  171. return OnDeviceReset_OGL();
  172. #endif
  173. #ifdef URHO3D_D3D11
  174. if (gapi == GAPI_D3D11)
  175. return OnDeviceReset_D3D11();
  176. #endif
  177. }
  178. void VertexBuffer::Release()
  179. {
  180. GAPI gapi = Graphics::GetGAPI();
  181. #ifdef URHO3D_OPENGL
  182. if (gapi == GAPI_OPENGL)
  183. return Release_OGL();
  184. #endif
  185. #ifdef URHO3D_D3D11
  186. if (gapi == GAPI_D3D11)
  187. return Release_D3D11();
  188. #endif
  189. }
  190. bool VertexBuffer::SetData(const void* data)
  191. {
  192. GAPI gapi = Graphics::GetGAPI();
  193. #ifdef URHO3D_OPENGL
  194. if (gapi == GAPI_OPENGL)
  195. return SetData_OGL(data);
  196. #endif
  197. #ifdef URHO3D_D3D11
  198. if (gapi == GAPI_D3D11)
  199. return SetData_D3D11(data);
  200. #endif
  201. return {}; // Prevent warning
  202. }
  203. bool VertexBuffer::SetDataRange(const void* data, i32 start, i32 count, bool discard)
  204. {
  205. assert(start >= 0 && count >= 0);
  206. GAPI gapi = Graphics::GetGAPI();
  207. #ifdef URHO3D_OPENGL
  208. if (gapi == GAPI_OPENGL)
  209. return SetDataRange_OGL(data, start, count, discard);
  210. #endif
  211. #ifdef URHO3D_D3D11
  212. if (gapi == GAPI_D3D11)
  213. return SetDataRange_D3D11(data, start, count, discard);
  214. #endif
  215. return {}; // Prevent warning
  216. }
  217. void* VertexBuffer::Lock(i32 start, i32 count, bool discard)
  218. {
  219. assert(start >= 0 && count >= 0);
  220. GAPI gapi = Graphics::GetGAPI();
  221. #ifdef URHO3D_OPENGL
  222. if (gapi == GAPI_OPENGL)
  223. return Lock_OGL(start, count, discard);
  224. #endif
  225. #ifdef URHO3D_D3D11
  226. if (gapi == GAPI_D3D11)
  227. return Lock_D3D11(start, count, discard);
  228. #endif
  229. return {}; // Prevent warning
  230. }
  231. void VertexBuffer::Unlock()
  232. {
  233. GAPI gapi = Graphics::GetGAPI();
  234. #ifdef URHO3D_OPENGL
  235. if (gapi == GAPI_OPENGL)
  236. return Unlock_OGL();
  237. #endif
  238. #ifdef URHO3D_D3D11
  239. if (gapi == GAPI_D3D11)
  240. return Unlock_D3D11();
  241. #endif
  242. }
  243. bool VertexBuffer::Create()
  244. {
  245. GAPI gapi = Graphics::GetGAPI();
  246. #ifdef URHO3D_OPENGL
  247. if (gapi == GAPI_OPENGL)
  248. return Create_OGL();
  249. #endif
  250. #ifdef URHO3D_D3D11
  251. if (gapi == GAPI_D3D11)
  252. return Create_D3D11();
  253. #endif
  254. return {}; // Prevent warning
  255. }
  256. bool VertexBuffer::UpdateToGPU()
  257. {
  258. GAPI gapi = Graphics::GetGAPI();
  259. #ifdef URHO3D_OPENGL
  260. if (gapi == GAPI_OPENGL)
  261. return UpdateToGPU_OGL();
  262. #endif
  263. #ifdef URHO3D_D3D11
  264. if (gapi == GAPI_D3D11)
  265. return UpdateToGPU_D3D11();
  266. #endif
  267. return {}; // Prevent warning
  268. }
  269. void* VertexBuffer::MapBuffer(i32 start, i32 count, bool discard)
  270. {
  271. assert(start >= 0 && count >= 0);
  272. GAPI gapi = Graphics::GetGAPI();
  273. #ifdef URHO3D_OPENGL
  274. if (gapi == GAPI_OPENGL)
  275. return MapBuffer_OGL(start, count, discard);
  276. #endif
  277. #ifdef URHO3D_D3D11
  278. if (gapi == GAPI_D3D11)
  279. return MapBuffer_D3D11(start, count, discard);
  280. #endif
  281. return {}; // Prevent warning
  282. }
  283. void VertexBuffer::UnmapBuffer()
  284. {
  285. GAPI gapi = Graphics::GetGAPI();
  286. #ifdef URHO3D_OPENGL
  287. if (gapi == GAPI_OPENGL)
  288. return UnmapBuffer_OGL();
  289. #endif
  290. #ifdef URHO3D_D3D11
  291. if (gapi == GAPI_D3D11)
  292. return UnmapBuffer_D3D11();
  293. #endif
  294. }
  295. }