1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "RenderAPI/BsVertexDeclaration.h"
7
8namespace bs
9{
10 /** @addtogroup Resources
11 * @{
12 */
13
14 /**
15 * Contains information about layout of vertices in a buffer. This is very similar to VertexDeclaration but unlike
16 * VertexDeclaration it has no render API object to back it up and is very lightweight.
17 */
18 class BS_CORE_EXPORT VertexDataDesc : public IReflectable
19 {
20 public:
21 VertexDataDesc() = default;
22
23 /**
24 * Informs the internal buffer that it needs to make room for the specified vertex element. If a vertex with same
25 * stream and semantics already exists it will just be updated.
26 *
27 * @param[in] type Type of the vertex element. Determines size.
28 * @param[in] semantic Semantic that allows the engine to connect the data to a shader input slot.
29 * @param[in] semanticIdx (optional) If there are multiple semantics with the same name, use different
30 * index to differentiate between them.
31 * @param[in] streamIdx (optional) Zero-based index of the stream. Each stream will internally be
32 * represented as a single vertex buffer.
33 * @param[in] instanceStepRate Determines at what rate does vertex element data advance. Zero means each vertex
34 * will advance the data pointer and receive new data (standard behaviour). Values
35 * larger than one are relevant for instanced rendering and determine how often do
36 * instances advance the vertex element (for example a value of 1 means each
37 * instance will retrieve a new value for this vertex element, a value of 2 means
38 * each second instance will, etc.).
39 */
40 void addVertElem(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx = 0,
41 UINT32 streamIdx = 0, UINT32 instanceStepRate = 0);
42
43 /** Query if we have vertex data for the specified semantic. */
44 bool hasElement(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
45
46 /** Returns the size in bytes of the vertex element with the specified semantic. */
47 UINT32 getElementSize(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
48
49 /** Returns offset of the vertex from start of the stream in bytes. */
50 UINT32 getElementOffsetFromStream(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
51
52 /** Gets vertex stride in bytes (offset from one vertex to another) in the specified stream. */
53 UINT32 getVertexStride(UINT32 streamIdx) const;
54
55 /** Gets vertex stride in bytes (offset from one vertex to another) in all the streams. */
56 UINT32 getVertexStride() const;
57
58 /** Gets offset in bytes from the start of the internal buffer to the start of the specified stream. */
59 UINT32 getStreamOffset(UINT32 streamIdx) const;
60
61 /** Returns the number of vertex elements. */
62 UINT32 getNumElements() const { return (UINT32)mVertexElements.size(); }
63
64 /** Returns the vertex element at the specified index. */
65 const VertexElement& getElement(UINT32 idx) const { return mVertexElements[idx]; }
66
67 /** Returns the vertex element with the specified semantic. */
68 const VertexElement* getElement(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
69
70 /** Creates a list of vertex elements from internal data. */
71 Vector<VertexElement> createElements() const;
72
73 /** Creates a new empty vertex data descriptor. */
74 static SPtr<VertexDataDesc> create();
75
76 private:
77 friend class Mesh;
78 friend class ct::Mesh;
79 friend class MeshHeap;
80 friend class ct::MeshHeap;
81
82 /** Returns the largest stream index of all the stored vertex elements. */
83 UINT32 getMaxStreamIdx() const;
84
85 /** Checks if any of the vertex elements use the specified stream index. */
86 bool hasStream(UINT32 streamIdx) const;
87
88 /** Removes a vertex element of the specified type and semantics if it exists. */
89 void clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx);
90
91 private:
92 Vector<VertexElement> mVertexElements;
93
94 /************************************************************************/
95 /* SERIALIZATION */
96 /************************************************************************/
97 public:
98 friend class VertexDataDescRTTI;
99 static RTTITypeBase* getRTTIStatic();
100 RTTITypeBase* getRTTI() const override;
101 };
102
103 /** @} */
104}