CmMeshData.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmGpuResourceData.h"
  4. #include "CmVertexBuffer.h"
  5. #include "CmIndexBuffer.h"
  6. #include "CmVertexDeclaration.h"
  7. namespace CamelotFramework
  8. {
  9. template<class T>
  10. class VertexElemIter
  11. {
  12. public:
  13. VertexElemIter()
  14. :mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
  15. {
  16. }
  17. VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
  18. :mData(data), mByteStride(byteStride), mNumElements(numElements)
  19. {
  20. mEnd = mData + byteStride * numElements;
  21. }
  22. void addValue(T& value)
  23. {
  24. setValue(value);
  25. moveNext();
  26. }
  27. void setValue(T& value)
  28. {
  29. memcpy(mData, &value, sizeof(T));
  30. }
  31. T& getValue()
  32. {
  33. return *((T*)mData);
  34. }
  35. void moveNext()
  36. {
  37. #ifdef CM_DEBUG_MODE
  38. if(mData >= mEnd)
  39. {
  40. CM_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
  41. }
  42. #endif
  43. mData += mByteStride;
  44. }
  45. UINT32 getNumElements() const { return mNumElements; }
  46. private:
  47. UINT8* mData;
  48. UINT8* mEnd;
  49. UINT32 mByteStride;
  50. UINT32 mNumElements;
  51. };
  52. class CM_EXPORT MeshData : public GpuResourceData
  53. {
  54. public:
  55. struct IndexElementData
  56. {
  57. IndexElementData()
  58. :numIndices(0), subMesh(0), elementSize(0)
  59. { }
  60. UINT32 numIndices;
  61. UINT32 elementSize;
  62. UINT32 subMesh;
  63. };
  64. MeshData(UINT32 numVertices, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
  65. ~MeshData();
  66. /**
  67. * @brief Begins the mesh data definition. After this call you may call various add* methods to inform
  68. * the internal buffer which data it will need to hold. Each beginDesc() call needs to be followed with
  69. * an endDesc().
  70. */
  71. void beginDesc();
  72. /**
  73. * @brief Call after you are done defining data to actually allocate the internal buffer. Any previous buffer will be overwritten.
  74. * Must be called after beginDesc().
  75. */
  76. void endDesc();
  77. /**
  78. * @brief Informs the internal buffer that it needs to make room for the specified vertex element. If a vertex
  79. * with same stream and semantics already exists it will just be updated. This must be called between beginDesc and endDesc.
  80. *
  81. * @param type Type of the vertex element. Determines size.
  82. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  83. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  84. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  85. */
  86. void addVertElem(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  87. /**
  88. * @brief Informs the internal buffer that it needs to make room for an index buffer of the specified size. If specified submesh
  89. * already exists it will just be updated. This must be called between beginDesc and endDesc.
  90. *
  91. * @param numIndices Number of indices.
  92. * @param subMesh (optional) the sub mesh.
  93. */
  94. void addSubMesh(UINT32 numIndices, UINT32 subMesh = 0);
  95. /**
  96. * @brief Query if we have vertex data for the specified semantic.
  97. */
  98. bool hasElement(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  99. /**
  100. * @brief Copies data from "data" parameter into the internal buffer for the specified semantic.
  101. *
  102. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  103. * @param data Vertex data, containing at least "size" bytes.
  104. * @param size The size of the data. Must be the size of the vertex element type * number of vertices.
  105. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  106. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  107. */
  108. void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  109. /**
  110. * @brief Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
  111. * method of assigning or reading vertex data.
  112. *
  113. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  114. */
  115. VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  116. /**
  117. * @brief Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
  118. * method of assigning or reading vertex data.
  119. *
  120. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  121. */
  122. VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  123. /**
  124. * @brief Returns an iterator you can use for easily retrieving or setting Vector4 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<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  130. /**
  131. * @brief Returns an iterator you can use for easily retrieving or setting Color 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<Color> getColorDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  137. /**
  138. * @brief Returns an iterator you can use for easily retrieving or setting DWORD 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<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  144. /**
  145. * @brief Creates a new vertex declaration based on set vertex elements.
  146. */
  147. VertexDeclarationPtr createDeclaration() const;
  148. UINT32 getNumSubmeshes() const { return (UINT32)mSubMeshes.size(); }
  149. UINT32 getNumVertices() const { return mNumVertices; }
  150. UINT32 getNumIndices(UINT32 subMesh) const;
  151. UINT32 getNumIndices() const;
  152. UINT16* getIndices16(UINT32 subMesh = 0) const;
  153. UINT32* getIndices32(UINT32 subMesh = 0) const;
  154. UINT32 getIndexElementSize() const;
  155. IndexBuffer::IndexType getIndexType() const { return mIndexType; }
  156. /**
  157. * @brief Returns the pointer to the first element of the specified type. If you want to
  158. * iterate over all elements you need to call getVertexStride() to get the number
  159. * of bytes you need to advance between each element.
  160. *
  161. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  162. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  163. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  164. *
  165. * @return null if it fails, else the element data.
  166. */
  167. UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  168. UINT32 getElementSize(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  169. UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  170. UINT32 getVertexStride(UINT32 streamIdx = 0) const;
  171. static MeshDataPtr combine(const Vector<MeshDataPtr>::type& elements);
  172. protected:
  173. UINT32 getInternalBufferSize();
  174. private:
  175. friend class Mesh; // To avoid polluting the public interface with a bunch of nearly useless methods for outside world
  176. UINT32 mDescBuilding;
  177. UINT8* mData;
  178. UINT32 mNumVertices;
  179. IndexBuffer::IndexType mIndexType;
  180. Vector<IndexElementData>::type mSubMeshes;
  181. Vector<VertexElement>::type mVertexElements;
  182. UINT32 getMaxStreamIdx() const;
  183. bool hasStream(UINT32 streamIdx) const;
  184. UINT8* getIndexData() const { return getData(); }
  185. UINT8* getStreamData(UINT32 streamIdx) const;
  186. UINT32 getIndexBufferOffset(UINT32 subMesh) const;
  187. UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
  188. UINT32 getIndexBufferSize() const { return getIndexBufferOffset(getNumSubmeshes()); }
  189. UINT32 getStreamSize(UINT32 streamIdx) const;
  190. UINT32 getStreamSize() const;
  191. void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
  192. void clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx);
  193. /************************************************************************/
  194. /* SERIALIZATION */
  195. /************************************************************************/
  196. private:
  197. MeshData() {} // Serialization only
  198. public:
  199. friend class MeshDataRTTI;
  200. static RTTITypeBase* getRTTIStatic();
  201. virtual RTTITypeBase* getRTTI() const;
  202. };
  203. }