BsMesh.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsMesh.h"
  4. #include "BsMeshRTTI.h"
  5. #include "BsMeshData.h"
  6. #include "BsDebug.h"
  7. #include "BsHardwareBufferManager.h"
  8. #include "BsMeshManager.h"
  9. #include "BsCoreThread.h"
  10. #include "BsAsyncOp.h"
  11. #include "BsVertexDataDesc.h"
  12. #include "BsResources.h"
  13. #include "BsRenderAPI.h"
  14. namespace BansheeEngine
  15. {
  16. MeshCore::MeshCore(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  17. const Vector<SubMesh>& subMeshes, int usage, IndexType indexType, SPtr<MeshData> initialMeshData)
  18. :MeshCoreBase(numVertices, numIndices, subMeshes), mVertexData(nullptr), mIndexBuffer(nullptr),
  19. mVertexDesc(vertexDesc), mUsage(usage), mIndexType(indexType), mTempInitialMeshData(initialMeshData)
  20. { }
  21. MeshCore::~MeshCore()
  22. {
  23. THROW_IF_NOT_CORE_THREAD;
  24. mVertexData = nullptr;
  25. mIndexBuffer = nullptr;
  26. mVertexDesc = nullptr;
  27. mTempInitialMeshData = nullptr;
  28. }
  29. void MeshCore::initialize()
  30. {
  31. THROW_IF_NOT_CORE_THREAD;
  32. bool isDynamic = (mUsage & MU_DYNAMIC) != 0;
  33. mIndexBuffer = HardwareBufferCoreManager::instance().createIndexBuffer(mIndexType,
  34. mProperties.mNumIndices, isDynamic ? GBU_DYNAMIC : GBU_STATIC);
  35. mVertexData = SPtr<VertexData>(bs_new<VertexData>());
  36. mVertexData->vertexCount = mProperties.mNumVertices;
  37. mVertexData->vertexDeclaration = HardwareBufferCoreManager::instance().createVertexDeclaration(mVertexDesc);
  38. for (UINT32 i = 0; i <= mVertexDesc->getMaxStreamIdx(); i++)
  39. {
  40. if (!mVertexDesc->hasStream(i))
  41. continue;
  42. SPtr<VertexBufferCore> vertexBuffer = HardwareBufferCoreManager::instance().createVertexBuffer(
  43. mVertexData->vertexDeclaration->getProperties().getVertexSize(i),
  44. mVertexData->vertexCount,
  45. isDynamic ? GBU_DYNAMIC : GBU_STATIC);
  46. mVertexData->setBuffer(i, vertexBuffer);
  47. }
  48. // TODO Low priority - DX11 (and maybe OpenGL)? allow an optimization that allows you to set
  49. // buffer data upon buffer construction, instead of setting it in a second step like I do here
  50. if (mTempInitialMeshData != nullptr)
  51. {
  52. writeSubresource(0, *mTempInitialMeshData, isDynamic);
  53. mTempInitialMeshData = nullptr;
  54. }
  55. MeshCoreBase::initialize();
  56. }
  57. SPtr<VertexData> MeshCore::getVertexData() const
  58. {
  59. THROW_IF_NOT_CORE_THREAD;
  60. return mVertexData;
  61. }
  62. SPtr<IndexBufferCore> MeshCore::getIndexBuffer() const
  63. {
  64. THROW_IF_NOT_CORE_THREAD;
  65. return mIndexBuffer;
  66. }
  67. SPtr<VertexDataDesc> MeshCore::getVertexDesc() const
  68. {
  69. THROW_IF_NOT_CORE_THREAD;
  70. return mVertexDesc;
  71. }
  72. void MeshCore::writeSubresource(UINT32 subresourceIdx, const MeshData& meshData, bool discardEntireBuffer, bool performUpdateBounds)
  73. {
  74. THROW_IF_NOT_CORE_THREAD;
  75. if (discardEntireBuffer)
  76. {
  77. if ((mUsage & MU_STATIC) != 0)
  78. {
  79. LOGWRN("Buffer discard is enabled but buffer was not created as dynamic. Disabling discard.");
  80. discardEntireBuffer = false;
  81. }
  82. }
  83. else
  84. {
  85. if ((mUsage & MU_DYNAMIC) != 0)
  86. {
  87. LOGWRN("Buffer discard is not enabled but buffer was created as dynamic. Enabling discard.");
  88. discardEntireBuffer = true;
  89. }
  90. }
  91. // Indices
  92. const IndexBufferProperties& ibProps = mIndexBuffer->getProperties();
  93. UINT32 indicesSize = meshData.getIndexBufferSize();
  94. UINT8* srcIdxData = meshData.getIndexData();
  95. if (meshData.getIndexElementSize() != ibProps.getIndexSize())
  96. {
  97. BS_EXCEPT(InvalidParametersException, "Provided index size doesn't match meshes index size. Needed: " +
  98. toString(ibProps.getIndexSize()) + ". Got: " + toString(meshData.getIndexElementSize()));
  99. }
  100. if (indicesSize > mIndexBuffer->getSizeInBytes())
  101. BS_EXCEPT(InvalidParametersException, "Index buffer values are being written out of valid range.");
  102. mIndexBuffer->writeData(0, indicesSize, srcIdxData, discardEntireBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
  103. // Vertices
  104. for (UINT32 i = 0; i <= mVertexDesc->getMaxStreamIdx(); i++)
  105. {
  106. if (!mVertexDesc->hasStream(i))
  107. continue;
  108. if (!meshData.getVertexDesc()->hasStream(i))
  109. continue;
  110. // Ensure both have the same sized vertices
  111. UINT32 myVertSize = mVertexDesc->getVertexStride(i);
  112. UINT32 otherVertSize = meshData.getVertexDesc()->getVertexStride(i);
  113. if (myVertSize != otherVertSize)
  114. {
  115. BS_EXCEPT(InvalidParametersException, "Provided vertex size for stream " + toString(i) + " doesn't match meshes vertex size. Needed: " +
  116. toString(myVertSize) + ". Got: " + toString(otherVertSize));
  117. }
  118. SPtr<VertexBufferCore> vertexBuffer = mVertexData->getBuffer(i);
  119. const VertexBufferProperties& vbProps = vertexBuffer->getProperties();
  120. UINT32 bufferSize = meshData.getStreamSize(i);
  121. UINT8* srcVertBufferData = meshData.getStreamData(i);
  122. if (bufferSize > vertexBuffer->getSizeInBytes())
  123. BS_EXCEPT(InvalidParametersException, "Vertex buffer values for stream \"" + toString(i) + "\" are being written out of valid range.");
  124. if (RenderAPICore::instance().getAPIInfo().getVertexColorFlipRequired())
  125. {
  126. UINT8* bufferCopy = (UINT8*)bs_alloc(bufferSize);
  127. memcpy(bufferCopy, srcVertBufferData, bufferSize); // TODO Low priority - Attempt to avoid this copy
  128. UINT32 vertexStride = meshData.getVertexDesc()->getVertexStride(i);
  129. for (INT32 semanticIdx = 0; semanticIdx < VertexBuffer::MAX_SEMANTIC_IDX; semanticIdx++)
  130. {
  131. if (!meshData.getVertexDesc()->hasElement(VES_COLOR, semanticIdx, i))
  132. continue;
  133. UINT8* colorData = bufferCopy + mVertexDesc->getElementOffsetFromStream(VES_COLOR, semanticIdx, i);
  134. for (UINT32 j = 0; j < mVertexData->vertexCount; j++)
  135. {
  136. UINT32* curColor = (UINT32*)colorData;
  137. (*curColor) = ((*curColor) & 0xFF00FF00) | ((*curColor >> 16) & 0x000000FF) | ((*curColor << 16) & 0x00FF0000);
  138. colorData += vertexStride;
  139. }
  140. }
  141. vertexBuffer->writeData(0, bufferSize, bufferCopy, discardEntireBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
  142. bs_free(bufferCopy);
  143. }
  144. else
  145. {
  146. vertexBuffer->writeData(0, bufferSize, srcVertBufferData, discardEntireBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
  147. }
  148. }
  149. if (performUpdateBounds)
  150. updateBounds(meshData);
  151. }
  152. void MeshCore::readSubresource(UINT32 subresourceIdx, MeshData& meshData)
  153. {
  154. THROW_IF_NOT_CORE_THREAD;
  155. IndexType indexType = IT_32BIT;
  156. if (mIndexBuffer)
  157. indexType = mIndexBuffer->getProperties().getType();
  158. if (mIndexBuffer)
  159. {
  160. const IndexBufferProperties& ibProps = mIndexBuffer->getProperties();
  161. if (meshData.getIndexElementSize() != ibProps.getIndexSize())
  162. {
  163. BS_EXCEPT(InvalidParametersException, "Provided index size doesn't match meshes index size. Needed: " +
  164. toString(ibProps.getIndexSize()) + ". Got: " + toString(meshData.getIndexElementSize()));
  165. }
  166. UINT8* idxData = static_cast<UINT8*>(mIndexBuffer->lock(GBL_READ_ONLY));
  167. UINT32 idxElemSize = ibProps.getIndexSize();
  168. UINT8* indices = nullptr;
  169. if (indexType == IT_16BIT)
  170. indices = (UINT8*)meshData.getIndices16();
  171. else
  172. indices = (UINT8*)meshData.getIndices32();
  173. UINT32 numIndicesToCopy = std::min(mProperties.mNumIndices, meshData.getNumIndices());
  174. UINT32 indicesSize = numIndicesToCopy * idxElemSize;
  175. if (indicesSize > meshData.getIndexBufferSize())
  176. BS_EXCEPT(InvalidParametersException, "Provided buffer doesn't have enough space to store mesh indices.");
  177. memcpy(indices, idxData, numIndicesToCopy * idxElemSize);
  178. mIndexBuffer->unlock();
  179. }
  180. if (mVertexData)
  181. {
  182. auto vertexBuffers = mVertexData->getBuffers();
  183. UINT32 streamIdx = 0;
  184. for (auto iter = vertexBuffers.begin(); iter != vertexBuffers.end(); ++iter)
  185. {
  186. if (!meshData.getVertexDesc()->hasStream(streamIdx))
  187. continue;
  188. SPtr<VertexBufferCore> vertexBuffer = iter->second;
  189. const VertexBufferProperties& vbProps = vertexBuffer->getProperties();
  190. // Ensure both have the same sized vertices
  191. UINT32 myVertSize = mVertexDesc->getVertexStride(streamIdx);
  192. UINT32 otherVertSize = meshData.getVertexDesc()->getVertexStride(streamIdx);
  193. if (myVertSize != otherVertSize)
  194. {
  195. BS_EXCEPT(InvalidParametersException, "Provided vertex size for stream " + toString(streamIdx) + " doesn't match meshes vertex size. Needed: " +
  196. toString(myVertSize) + ". Got: " + toString(otherVertSize));
  197. }
  198. UINT32 numVerticesToCopy = meshData.getNumVertices();
  199. UINT32 bufferSize = vbProps.getVertexSize() * numVerticesToCopy;
  200. if (bufferSize > vertexBuffer->getSizeInBytes())
  201. BS_EXCEPT(InvalidParametersException, "Vertex buffer values for stream \"" + toString(streamIdx) + "\" are being read out of valid range.");
  202. UINT8* vertDataPtr = static_cast<UINT8*>(vertexBuffer->lock(GBL_READ_ONLY));
  203. UINT8* dest = meshData.getStreamData(streamIdx);
  204. memcpy(dest, vertDataPtr, bufferSize);
  205. vertexBuffer->unlock();
  206. streamIdx++;
  207. }
  208. }
  209. }
  210. void MeshCore::updateBounds(const MeshData& meshData)
  211. {
  212. mProperties.mBounds = meshData.calculateBounds();
  213. // TODO - Sync this to sim-thread possibly?
  214. }
  215. SPtr<MeshCore> MeshCore::create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  216. int usage, DrawOperationType drawOp, IndexType indexType)
  217. {
  218. SubMesh subMesh(0, numIndices, drawOp);
  219. SPtr<MeshCore> mesh = bs_shared_ptr<MeshCore>(new (bs_alloc<MeshCore>()) MeshCore(numVertices, numIndices,
  220. vertexDesc, { subMesh }, usage, indexType, nullptr));
  221. mesh->_setThisPtr(mesh);
  222. mesh->initialize();
  223. return mesh;
  224. }
  225. SPtr<MeshCore> MeshCore::create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  226. const Vector<SubMesh>& subMeshes, int usage, IndexType indexType)
  227. {
  228. SPtr<MeshCore> mesh = bs_shared_ptr<MeshCore>(new (bs_alloc<MeshCore>()) MeshCore(numVertices, numIndices,
  229. vertexDesc, subMeshes, usage, indexType, nullptr));
  230. mesh->_setThisPtr(mesh);
  231. mesh->initialize();
  232. return mesh;
  233. }
  234. SPtr<MeshCore> MeshCore::create(const SPtr<MeshData>& initialMeshData, int usage, DrawOperationType drawOp)
  235. {
  236. UINT32 numVertices = initialMeshData->getNumVertices();
  237. UINT32 numIndices = initialMeshData->getNumIndices();
  238. SPtr<VertexDataDesc> vertexDesc = initialMeshData->getVertexDesc();
  239. SubMesh subMesh(0, numIndices, drawOp);
  240. IndexType indexType = initialMeshData->getIndexType();
  241. SPtr<MeshCore> mesh = bs_shared_ptr<MeshCore>(new (bs_alloc<MeshCore>()) MeshCore(numVertices, numIndices,
  242. vertexDesc, { subMesh }, usage, indexType, initialMeshData));
  243. mesh->_setThisPtr(mesh);
  244. mesh->initialize();
  245. return mesh;
  246. }
  247. SPtr<MeshCore> MeshCore::create(const SPtr<MeshData>& initialMeshData, const Vector<SubMesh>& subMeshes, int usage)
  248. {
  249. UINT32 numVertices = initialMeshData->getNumVertices();
  250. UINT32 numIndices = initialMeshData->getNumIndices();
  251. SPtr<VertexDataDesc> vertexDesc = initialMeshData->getVertexDesc();
  252. IndexType indexType = initialMeshData->getIndexType();
  253. SPtr<MeshCore> mesh = bs_shared_ptr<MeshCore>(new (bs_alloc<MeshCore>()) MeshCore(numVertices, numIndices,
  254. vertexDesc, subMeshes, usage, indexType, initialMeshData));
  255. mesh->_setThisPtr(mesh);
  256. mesh->initialize();
  257. return mesh;
  258. }
  259. Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  260. int usage, DrawOperationType drawOp, IndexType indexType)
  261. :MeshBase(numVertices, numIndices, drawOp), mVertexDesc(vertexDesc), mUsage(usage),
  262. mIndexType(indexType)
  263. {
  264. }
  265. Mesh::Mesh(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  266. const Vector<SubMesh>& subMeshes, int usage, IndexType indexType)
  267. :MeshBase(numVertices, numIndices, subMeshes), mVertexDesc(vertexDesc), mUsage(usage),
  268. mIndexType(indexType)
  269. {
  270. }
  271. Mesh::Mesh(const SPtr<MeshData>& initialMeshData, int usage, DrawOperationType drawOp)
  272. :MeshBase(initialMeshData->getNumVertices(), initialMeshData->getNumIndices(), drawOp),
  273. mIndexType(initialMeshData->getIndexType()), mVertexDesc(initialMeshData->getVertexDesc()),
  274. mCPUData(initialMeshData), mUsage(usage)
  275. {
  276. }
  277. Mesh::Mesh(const SPtr<MeshData>& initialMeshData, const Vector<SubMesh>& subMeshes, int usage)
  278. :MeshBase(initialMeshData->getNumVertices(), initialMeshData->getNumIndices(), subMeshes),
  279. mIndexType(initialMeshData->getIndexType()), mVertexDesc(initialMeshData->getVertexDesc()),
  280. mCPUData(initialMeshData), mUsage(usage)
  281. {
  282. }
  283. Mesh::Mesh()
  284. :MeshBase(0, 0, DOT_TRIANGLE_LIST), mUsage(MU_STATIC), mIndexType(IT_32BIT)
  285. {
  286. }
  287. Mesh::~Mesh()
  288. {
  289. }
  290. AsyncOp Mesh::writeSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const SPtr<MeshData>& data, bool discardEntireBuffer)
  291. {
  292. updateBounds(*data);
  293. updateCPUBuffer(subresourceIdx, *data);
  294. data->_lock();
  295. std::function<void(const SPtr<MeshCore>&, UINT32, const SPtr<MeshData>&, bool, AsyncOp&)> func =
  296. [&](const SPtr<MeshCore>& mesh, UINT32 _subresourceIdx, const SPtr<MeshData>& _meshData, bool _discardEntireBuffer, AsyncOp& asyncOp)
  297. {
  298. mesh->writeSubresource(_subresourceIdx, *_meshData, _discardEntireBuffer, false);
  299. _meshData->_unlock();
  300. asyncOp._completeOperation();
  301. };
  302. return accessor.queueReturnCommand(std::bind(func, getCore(), subresourceIdx,
  303. data, discardEntireBuffer, std::placeholders::_1));
  304. }
  305. AsyncOp Mesh::readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const SPtr<MeshData>& data)
  306. {
  307. data->_lock();
  308. std::function<void(const SPtr<MeshCore>&, UINT32, const SPtr<MeshData>&, AsyncOp&)> func =
  309. [&](const SPtr<MeshCore>& mesh, UINT32 _subresourceIdx, const SPtr<MeshData>& _meshData, AsyncOp& asyncOp)
  310. {
  311. mesh->readSubresource(_subresourceIdx, *_meshData);
  312. _meshData->_unlock();
  313. asyncOp._completeOperation();
  314. };
  315. return accessor.queueReturnCommand(std::bind(func, getCore(), subresourceIdx,
  316. data, std::placeholders::_1));
  317. }
  318. SPtr<MeshData> Mesh::allocateSubresourceBuffer(UINT32 subresourceIdx) const
  319. {
  320. SPtr<MeshData> meshData = bs_shared_ptr_new<MeshData>(mProperties.mNumVertices, mProperties.mNumIndices, mVertexDesc, mIndexType);
  321. return meshData;
  322. }
  323. void Mesh::initialize()
  324. {
  325. if (mCPUData != nullptr)
  326. updateBounds(*mCPUData);
  327. MeshBase::initialize();
  328. if ((mUsage & MU_CPUCACHED) != 0 && mCPUData == nullptr)
  329. createCPUBuffer();
  330. }
  331. void Mesh::updateBounds(const MeshData& meshData)
  332. {
  333. mProperties.mBounds = meshData.calculateBounds();
  334. markCoreDirty();
  335. }
  336. SPtr<MeshCore> Mesh::getCore() const
  337. {
  338. return std::static_pointer_cast<MeshCore>(mCoreSpecific);
  339. }
  340. SPtr<CoreObjectCore> Mesh::createCore() const
  341. {
  342. MeshCore* obj = new (bs_alloc<MeshCore>()) MeshCore(mProperties.mNumVertices, mProperties.mNumIndices,
  343. mVertexDesc, mProperties.mSubMeshes, mUsage, mIndexType, mCPUData);
  344. SPtr<CoreObjectCore> meshCore = bs_shared_ptr<MeshCore>(obj);
  345. meshCore->_setThisPtr(meshCore);
  346. if ((mUsage & MU_CPUCACHED) == 0)
  347. mCPUData = nullptr;
  348. return meshCore;
  349. }
  350. void Mesh::updateCPUBuffer(UINT32 subresourceIdx, const MeshData& pixelData)
  351. {
  352. if ((mUsage & MU_CPUCACHED) == 0)
  353. return;
  354. if (subresourceIdx > 0)
  355. {
  356. LOGERR("Invalid subresource index: " + toString(subresourceIdx) + ". Supported range: 0 .. 1.");
  357. return;
  358. }
  359. if (pixelData.getNumIndices() != mProperties.getNumIndices() ||
  360. pixelData.getNumVertices() != mProperties.getNumVertices() ||
  361. pixelData.getIndexType() != mIndexType ||
  362. pixelData.getVertexDesc()->getVertexStride() != mVertexDesc->getVertexStride())
  363. {
  364. LOGERR("Provided buffer is not of valid dimensions or format in order to update this mesh.");
  365. return;
  366. }
  367. if (mCPUData->getSize() != pixelData.getSize())
  368. BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
  369. UINT8* dest = mCPUData->getData();
  370. UINT8* src = pixelData.getData();
  371. memcpy(dest, src, pixelData.getSize());
  372. }
  373. void Mesh::readData(MeshData& dest)
  374. {
  375. if ((mUsage & MU_CPUCACHED) == 0)
  376. {
  377. LOGERR("Attempting to read CPU data from a mesh that is created without CPU caching.");
  378. return;
  379. }
  380. if (dest.getNumIndices() != mProperties.getNumIndices() ||
  381. dest.getNumVertices() != mProperties.getNumVertices() ||
  382. dest.getIndexType() != mIndexType ||
  383. dest.getVertexDesc()->getVertexStride() != mVertexDesc->getVertexStride())
  384. {
  385. LOGERR("Provided buffer is not of valid dimensions or format in order to read from this mesh.");
  386. return;
  387. }
  388. if (mCPUData->getSize() != dest.getSize())
  389. BS_EXCEPT(InternalErrorException, "Buffer sizes don't match.");
  390. UINT8* srcPtr = mCPUData->getData();
  391. UINT8* destPtr = dest.getData();
  392. memcpy(destPtr, srcPtr, dest.getSize());
  393. }
  394. void Mesh::createCPUBuffer()
  395. {
  396. mCPUData = allocateSubresourceBuffer(0);
  397. }
  398. HMesh Mesh::dummy()
  399. {
  400. return MeshManager::instance().getDummyMesh();
  401. }
  402. /************************************************************************/
  403. /* SERIALIZATION */
  404. /************************************************************************/
  405. RTTITypeBase* Mesh::getRTTIStatic()
  406. {
  407. return MeshRTTI::instance();
  408. }
  409. RTTITypeBase* Mesh::getRTTI() const
  410. {
  411. return Mesh::getRTTIStatic();
  412. }
  413. /************************************************************************/
  414. /* STATICS */
  415. /************************************************************************/
  416. HMesh Mesh::create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  417. int usage, DrawOperationType drawOp, IndexType indexType)
  418. {
  419. SPtr<Mesh> meshPtr = _createPtr(numVertices, numIndices, vertexDesc, usage, drawOp, indexType);
  420. return static_resource_cast<Mesh>(gResources()._createResourceHandle(meshPtr));
  421. }
  422. HMesh Mesh::create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  423. const Vector<SubMesh>& subMeshes, int usage, IndexType indexType)
  424. {
  425. SPtr<Mesh> meshPtr = _createPtr(numVertices, numIndices, vertexDesc, subMeshes, usage, indexType);
  426. return static_resource_cast<Mesh>(gResources()._createResourceHandle(meshPtr));
  427. }
  428. HMesh Mesh::create(const SPtr<MeshData>& initialMeshData, int usage, DrawOperationType drawOp)
  429. {
  430. SPtr<Mesh> meshPtr = _createPtr(initialMeshData, usage, drawOp);
  431. return static_resource_cast<Mesh>(gResources()._createResourceHandle(meshPtr));
  432. }
  433. HMesh Mesh::create(const SPtr<MeshData>& initialMeshData, const Vector<SubMesh>& subMeshes, int usage)
  434. {
  435. SPtr<Mesh> meshPtr = _createPtr(initialMeshData, subMeshes, usage);
  436. return static_resource_cast<Mesh>(gResources()._createResourceHandle(meshPtr));
  437. }
  438. SPtr<Mesh> Mesh::_createPtr(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  439. int usage, DrawOperationType drawOp, IndexType indexType)
  440. {
  441. return MeshManager::instance().create(numVertices, numIndices, vertexDesc, usage, drawOp, indexType);
  442. }
  443. SPtr<Mesh> Mesh::_createPtr(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  444. const Vector<SubMesh>& subMeshes, int usage, IndexType indexType)
  445. {
  446. return MeshManager::instance().create(numVertices, numIndices, vertexDesc, subMeshes, usage, indexType);
  447. }
  448. SPtr<Mesh> Mesh::_createPtr(const SPtr<MeshData>& initialMeshData, int usage, DrawOperationType drawOp)
  449. {
  450. return MeshManager::instance().create(initialMeshData, usage, drawOp);
  451. }
  452. SPtr<Mesh> Mesh::_createPtr(const SPtr<MeshData>& initialMeshData, const Vector<SubMesh>& subMeshes, int usage)
  453. {
  454. return MeshManager::instance().create(initialMeshData, subMeshes, usage);
  455. }
  456. }