CmMeshData.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmGpuResourceData.h"
  4. #include "CmVertexBuffer.h"
  5. #include "CmIndexBuffer.h"
  6. #include "CmVertexDeclaration.h"
  7. #include "CmDrawOps.h"
  8. #include "CmSubMesh.h"
  9. namespace BansheeEngine
  10. {
  11. /**
  12. * @brief Iterator that allows you to easily populate or read vertex elements
  13. * in MeshData.
  14. */
  15. template<class T>
  16. class VertexElemIter
  17. {
  18. public:
  19. VertexElemIter()
  20. :mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
  21. {
  22. }
  23. VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
  24. :mData(data), mByteStride(byteStride), mNumElements(numElements)
  25. {
  26. mEnd = mData + byteStride * numElements;
  27. }
  28. /**
  29. * @brief Adds a new value to the iterators current position and
  30. * advances the iterator.
  31. */
  32. void addValue(T& value)
  33. {
  34. setValue(value);
  35. moveNext();
  36. }
  37. /**
  38. * @brief Sets a new value at the iterators current position.
  39. */
  40. void setValue(T& value)
  41. {
  42. memcpy(mData, &value, sizeof(T));
  43. }
  44. /**
  45. * @brief Returns the value at the iterators current position.
  46. */
  47. T& getValue()
  48. {
  49. return *((T*)mData);
  50. }
  51. /**
  52. * @brief Moves the iterator to the next position. Returns true
  53. * if there are more elements.
  54. */
  55. bool moveNext()
  56. {
  57. #ifdef CM_DEBUG_MODE
  58. if(mData >= mEnd)
  59. {
  60. CM_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
  61. }
  62. #endif
  63. mData += mByteStride;
  64. return mData < mEnd;
  65. }
  66. /**
  67. * @brief Returns the number of elements this iterator can iterate over.
  68. */
  69. UINT32 getNumElements() const { return mNumElements; }
  70. private:
  71. UINT8* mData;
  72. UINT8* mEnd;
  73. UINT32 mByteStride;
  74. UINT32 mNumElements;
  75. };
  76. /**
  77. * @brief Used for initializing, updating and reading mesh data from Meshes.
  78. */
  79. class CM_EXPORT MeshData : public GpuResourceData
  80. {
  81. public:
  82. /**
  83. * @brief Constructs a new object that can hold number of vertices described by the provided vertex data description. As well
  84. * as a number of indices of the provided type.
  85. */
  86. MeshData(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
  87. ~MeshData();
  88. /**
  89. * @brief Determines at which position in the mesh will the vertex data be written into or read from.
  90. *
  91. * @param bytes Offset in number of vertices.
  92. */
  93. void setResourceVertexOffset(UINT32 vertices) { mResourceVertexOffset = vertices; }
  94. /**
  95. * @brief Determines at which position in the mesh will the index data be written into or read from.
  96. *
  97. * @param bytes Offset in number of indices.
  98. */
  99. void setResourceIndexOffset(UINT32 indices) { mResourceIndexOffset = indices; }
  100. /**
  101. * @brief Determines at which position in the mesh will the vertex data be written into or read
  102. * from.
  103. *
  104. * @return Offset in number of vertices.
  105. */
  106. UINT32 getResourceVertexOffset() const { return mResourceVertexOffset; }
  107. /**
  108. * @brief Determines at which position in the mesh will the index data be written into or read from.
  109. *
  110. * @return Offset in number of indices.
  111. */
  112. UINT32 getResourceIndexOffset() const { return mResourceIndexOffset; }
  113. /**
  114. * @brief Copies data from "data" parameter into the internal buffer for the specified semantic.
  115. *
  116. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  117. * @param data Vertex data, containing at least "size" bytes.
  118. * @param size The size of the data. Must be the size of the vertex element type * number of vertices.
  119. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  120. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  121. */
  122. void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  123. /**
  124. * @brief Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
  125. * method of assigning or reading vertex data.
  126. *
  127. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  128. */
  129. VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  130. /**
  131. * @brief Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
  132. * method of assigning or reading vertex data.
  133. *
  134. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  135. */
  136. VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  137. /**
  138. * @brief Returns an iterator you can use for easily retrieving or setting Vector4 vertex elements. This is the preferred
  139. * method of assigning or reading vertex data.
  140. *
  141. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  142. */
  143. VertexElemIter<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  144. /**
  145. * @brief Returns an iterator you can use for easily retrieving or setting DWORD vertex elements. This is the preferred
  146. * method of assigning or reading vertex data.
  147. *
  148. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  149. */
  150. VertexElemIter<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  151. /**
  152. * @brief Returns the total number of vertices this object can hold.
  153. */
  154. UINT32 getNumVertices() const { return mNumVertices; }
  155. /**
  156. * @brief Returns the total number of indices this object can hold.
  157. */
  158. UINT32 getNumIndices() const;
  159. /**
  160. * @brief Returns a 16-bit pointer to the start of the internal index buffer.
  161. */
  162. UINT16* getIndices16() const;
  163. /**
  164. * @brief Returns a 32-bit pointer to the start of the internal index buffer.
  165. */
  166. UINT32* getIndices32() const;
  167. /**
  168. * @brief Returns the size of an index element in bytes.
  169. */
  170. UINT32 getIndexElementSize() const;
  171. /**
  172. * @brief Returns the type of an index element.
  173. */
  174. IndexBuffer::IndexType getIndexType() const { return mIndexType; }
  175. /**
  176. * @brief Returns the pointer to the first element of the specified type. If you want to
  177. * iterate over all elements you need to call getVertexStride() to get the number
  178. * of bytes you need to advance between each element.
  179. *
  180. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  181. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  182. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  183. *
  184. * @return null if it fails, else the element data.
  185. */
  186. UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  187. /**
  188. * @brief Returns an offset into the internal buffer where this element with the provided semantic starts.
  189. * Offset is provided in number of bytes.
  190. *
  191. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  192. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  193. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  194. */
  195. UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  196. /**
  197. * @brief Returns an object that describes data contained in a single vertex.
  198. */
  199. const VertexDataDescPtr& getVertexDesc() const { return mVertexData; }
  200. /**
  201. * @brief Combines a number of submeshes and their mesh data into one large mesh data buffer.
  202. *
  203. * @param elements Data containing vertices and indices referenced by the submeshes. Number of elements
  204. * must be the same as number of submeshes.
  205. * @param subMeshes Submeshes representing vertex and index range to take from mesh data and combine. Number of
  206. * submeshes must match the number of provided MeshData elements.
  207. * @param [out] subMeshes Outputs all combined sub-meshes with their new index and vertex offsets referencing
  208. * the newly created MeshData.
  209. *
  210. * @returns Combined mesh data containing all vertices and indexes references by the provided sub-meshes.
  211. */
  212. static MeshDataPtr combine(const Vector<MeshDataPtr>& elements, const Vector<Vector<SubMesh>>& allSubMeshes,
  213. Vector<SubMesh>& subMeshes);
  214. protected:
  215. /**
  216. * @brief Returns the size of the internal buffer in bytes.
  217. */
  218. UINT32 getInternalBufferSize();
  219. private:
  220. /**
  221. * @brief Returns a pointer to the start of the index buffer.
  222. */
  223. UINT8* getIndexData() const { return getData(); }
  224. /**
  225. * @brief Returns a pointer to the start of the specified vertex stream.
  226. */
  227. UINT8* getStreamData(UINT32 streamIdx) const;
  228. /**
  229. * @brief Returns an offset in bytes to the start of the index buffer from the start of the
  230. * internal buffer.
  231. */
  232. UINT32 getIndexBufferOffset() const;
  233. /**
  234. * @brief Returns an offset in bytes to the start of the stream from the start of the
  235. * internal buffer.
  236. */
  237. UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
  238. /**
  239. * @brief Returns the size of the index buffer in bytes.
  240. */
  241. UINT32 getIndexBufferSize() const;
  242. /**
  243. * @brief Returns the size of the specified stream in bytes.
  244. */
  245. UINT32 getStreamSize(UINT32 streamIdx) const;
  246. /**
  247. * @brief Returns the size of all the streams in bytes.
  248. */
  249. UINT32 getStreamSize() const;
  250. /**
  251. * @brief Returns the data needed for iterating over the requested vertex element.
  252. *
  253. * @param semantic Semantic of the element we are looking for.
  254. * @param semanticIdx If there are multiple semantics with the same name, use different index to differentiate between them.
  255. * @param streamIdx Zero-based index of the stream the element resides in.
  256. * @param [out] data Pointer to the start of this elements data.
  257. * @param [out] stride Number of bytes between vertex elements of this type.
  258. */
  259. void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
  260. private:
  261. friend class Mesh;
  262. friend class MeshHeap;
  263. UINT32 mDescBuilding;
  264. UINT8* mData;
  265. UINT32 mResourceVertexOffset;
  266. UINT32 mResourceIndexOffset;
  267. UINT32 mNumVertices;
  268. UINT32 mNumIndices;
  269. IndexBuffer::IndexType mIndexType;
  270. VertexDataDescPtr mVertexData;
  271. /************************************************************************/
  272. /* SERIALIZATION */
  273. /************************************************************************/
  274. private:
  275. MeshData(); // Serialization only
  276. public:
  277. friend class MeshDataRTTI;
  278. static RTTITypeBase* getRTTIStatic();
  279. virtual RTTITypeBase* getRTTI() const;
  280. };
  281. }