CmMeshData.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 CamelotFramework
  10. {
  11. template<class T>
  12. class VertexElemIter
  13. {
  14. public:
  15. VertexElemIter()
  16. :mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
  17. {
  18. }
  19. VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
  20. :mData(data), mByteStride(byteStride), mNumElements(numElements)
  21. {
  22. mEnd = mData + byteStride * numElements;
  23. }
  24. void addValue(T& value)
  25. {
  26. setValue(value);
  27. moveNext();
  28. }
  29. void setValue(T& value)
  30. {
  31. memcpy(mData, &value, sizeof(T));
  32. }
  33. T& getValue()
  34. {
  35. return *((T*)mData);
  36. }
  37. void moveNext()
  38. {
  39. #ifdef CM_DEBUG_MODE
  40. if(mData >= mEnd)
  41. {
  42. CM_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
  43. }
  44. #endif
  45. mData += mByteStride;
  46. }
  47. UINT32 getNumElements() const { return mNumElements; }
  48. private:
  49. UINT8* mData;
  50. UINT8* mEnd;
  51. UINT32 mByteStride;
  52. UINT32 mNumElements;
  53. };
  54. class CM_EXPORT MeshData : public GpuResourceData
  55. {
  56. public:
  57. MeshData(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
  58. ~MeshData();
  59. /**
  60. * @brief Determines at which position in the mesh will the vertex data be written into or read from.
  61. *
  62. * @param bytes Offset in number of vertices.
  63. */
  64. void setResourceVertexOffset(UINT32 vertices) { mResourceVertexOffset = vertices; }
  65. /**
  66. * @brief Determines at which position in the mesh will the index data be written into or read from.
  67. *
  68. * @param bytes Offset in number of indices.
  69. */
  70. void setResourceIndexOffset(UINT32 indices) { mResourceIndexOffset = indices; }
  71. /**
  72. * @brief Determines at which position in the mesh will the vertex data be written into or read
  73. * from.
  74. *
  75. * @return Offset in number of vertices.
  76. */
  77. UINT32 getResourceVertexOffset() const { return mResourceVertexOffset; }
  78. /**
  79. * @brief Determines at which position in the mesh will the index data be written into or read from.
  80. *
  81. * @return Offset in number of indices.
  82. */
  83. UINT32 getResourceIndexOffset() const { return mResourceIndexOffset; }
  84. /**
  85. * @brief Copies data from "data" parameter into the internal buffer for the specified semantic.
  86. *
  87. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  88. * @param data Vertex data, containing at least "size" bytes.
  89. * @param size The size of the data. Must be the size of the vertex element type * number of vertices.
  90. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  91. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  92. */
  93. void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  94. /**
  95. * @brief Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
  96. * method of assigning or reading vertex data.
  97. *
  98. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  99. */
  100. VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  101. /**
  102. * @brief Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
  103. * method of assigning or reading vertex data.
  104. *
  105. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  106. */
  107. VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  108. /**
  109. * @brief Returns an iterator you can use for easily retrieving or setting Vector4 vertex elements. This is the preferred
  110. * method of assigning or reading vertex data.
  111. *
  112. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  113. */
  114. VertexElemIter<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  115. /**
  116. * @brief Returns an iterator you can use for easily retrieving or setting DWORD vertex elements. This is the preferred
  117. * method of assigning or reading vertex data.
  118. *
  119. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  120. */
  121. VertexElemIter<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  122. UINT32 getNumVertices() const { return mNumVertices; }
  123. UINT32 getNumIndices() const;
  124. UINT16* getIndices16() const;
  125. UINT32* getIndices32() const;
  126. UINT32 getIndexElementSize() const;
  127. IndexBuffer::IndexType getIndexType() const { return mIndexType; }
  128. /**
  129. * @brief Returns the pointer to the first element of the specified type. If you want to
  130. * iterate over all elements you need to call getVertexStride() to get the number
  131. * of bytes you need to advance between each element.
  132. *
  133. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  134. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  135. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  136. *
  137. * @return null if it fails, else the element data.
  138. */
  139. UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  140. UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  141. const VertexDataDescPtr& getVertexDesc() const { return mVertexData; }
  142. static MeshDataPtr combine(const Vector<MeshDataPtr>::type& elements, const Vector<Vector<SubMesh>::type>::type& allSubMeshes,
  143. Vector<SubMesh>::type& subMeshes);
  144. protected:
  145. UINT32 getInternalBufferSize();
  146. private:
  147. friend class Mesh; // To avoid polluting the public interface with a bunch of nearly useless methods for outside world
  148. friend class MeshHeap;
  149. UINT32 mDescBuilding;
  150. UINT8* mData;
  151. UINT32 mResourceVertexOffset;
  152. UINT32 mResourceIndexOffset;
  153. UINT32 mNumVertices;
  154. UINT32 mNumIndices;
  155. IndexBuffer::IndexType mIndexType;
  156. VertexDataDescPtr mVertexData;
  157. UINT8* getIndexData() const { return getData(); }
  158. UINT8* getStreamData(UINT32 streamIdx) const;
  159. UINT32 getIndexBufferOffset() const;
  160. UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
  161. UINT32 getIndexBufferSize() const;
  162. UINT32 getStreamSize(UINT32 streamIdx) const;
  163. UINT32 getStreamSize() const;
  164. void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
  165. /************************************************************************/
  166. /* SERIALIZATION */
  167. /************************************************************************/
  168. private:
  169. MeshData(); // Serialization only
  170. public:
  171. friend class MeshDataRTTI;
  172. static RTTITypeBase* getRTTIStatic();
  173. virtual RTTITypeBase* getRTTI() const;
  174. };
  175. }