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 "Image/BsColor.h"
7#include "CoreThread/BsCoreObject.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI
12 * @{
13 */
14
15 /** Semantics that are used for identifying the meaning of vertex buffer elements. */
16 enum VertexElementSemantic
17 {
18 VES_POSITION = 1, /**< Position */
19 VES_BLEND_WEIGHTS = 2, /**< Blend weights */
20 VES_BLEND_INDICES = 3, /**< Blend indices */
21 VES_NORMAL = 4, /**< Normal */
22 VES_COLOR = 5, /**< Color */
23 VES_TEXCOORD = 6, /**< UV coordinate */
24 VES_BITANGENT = 7, /**< Bitangent */
25 VES_TANGENT = 8, /**< Tangent */
26 VES_POSITIONT = 9, /**< Transformed position */
27 VES_PSIZE = 10 /**< Point size */
28 };
29
30 /** Types used to identify base types of vertex element contents. */
31 enum VertexElementType
32 {
33 VET_FLOAT1 = 0, /**< 1D floating point value */
34 VET_FLOAT2 = 1, /**< 2D floating point value */
35 VET_FLOAT3 = 2, /**< 3D floating point value */
36 VET_FLOAT4 = 3, /**< 4D floating point value */
37 VET_COLOR = 4, /**< Color encoded in 32-bits (8-bits per channel). */
38 VET_SHORT1 = 5, /**< 1D 16-bit signed integer value */
39 VET_SHORT2 = 6, /**< 2D 16-bit signed integer value */
40 VET_SHORT4 = 8, /**< 4D 16-bit signed integer value */
41 VET_UBYTE4 = 9, /**< 4D 8-bit unsigned integer value */
42 VET_COLOR_ARGB = 10, /**< Color encoded in 32-bits (8-bits per channel) in ARGB order) */
43 VET_COLOR_ABGR = 11, /**< Color encoded in 32-bits (8-bits per channel) in ABGR order) */
44 VET_UINT4 = 12, /**< 4D 32-bit unsigned integer value */
45 VET_INT4 = 13, /**< 4D 32-bit signed integer value */
46 VET_USHORT1 = 14, /**< 1D 16-bit unsigned integer value */
47 VET_USHORT2 = 15, /**< 2D 16-bit unsigned integer value */
48 VET_USHORT4 = 17, /**< 4D 16-bit unsigned integer value */
49 VET_INT1 = 18, /**< 1D 32-bit signed integer value */
50 VET_INT2 = 19, /**< 2D 32-bit signed integer value */
51 VET_INT3 = 20, /**< 3D 32-bit signed integer value */
52 VET_UINT1 = 21, /**< 1D 32-bit signed integer value */
53 VET_UINT2 = 22, /**< 2D 32-bit signed integer value */
54 VET_UINT3 = 23, /**< 3D 32-bit signed integer value */
55 VET_UBYTE4_NORM = 24, /**< 4D 8-bit unsigned integer interpreted as a normalized value in [0, 1] range. */
56 VET_COUNT, // Keep at end before VET_UNKNOWN
57 VET_UNKNOWN = 0xffff
58 };
59
60 /** Describes a single vertex element in a vertex declaration. */
61 class BS_CORE_EXPORT VertexElement
62 {
63 public:
64 VertexElement() = default;
65 VertexElement(UINT16 source, UINT32 offset, VertexElementType theType,
66 VertexElementSemantic semantic, UINT16 index = 0, UINT32 instanceStepRate = 0);
67
68 bool operator== (const VertexElement& rhs) const;
69 bool operator!= (const VertexElement& rhs) const;
70
71 /** Returns index of the vertex buffer from which this element is stored. */
72 UINT16 getStreamIdx() const { return mSource; }
73
74 /**
75 * Returns an offset into the buffer where this vertex is stored. This value might be in bytes but doesn't have to
76 * be, it's likely to be render API specific.
77 */
78 UINT32 getOffset() const { return mOffset; }
79
80 /** Gets the base data type of this element. */
81 VertexElementType getType() const { return mType; }
82
83 /** Gets a semantic that describes what this element contains. */
84 VertexElementSemantic getSemantic() const { return mSemantic; }
85
86 /**
87 * Gets an index of this element. Only relevant when you have multiple elements with the same semantic,
88 * for example uv0, uv1.
89 */
90 UINT16 getSemanticIdx() const { return mIndex; }
91
92 /** Returns the size of this element in bytes. */
93 UINT32 getSize() const;
94
95 /**
96 * Returns at what rate do the vertex elements advance during instanced rendering. Provide zero for default
97 * behaviour where each vertex receives the next value from the vertex buffer. Provide a value larger than zero
98 * to ensure vertex data is advanced with every instance, instead of every vertex (for example a value of 1 means
99 * each instance will retrieve a new value from the vertex buffer, a value of 2 means each second instance will,
100 * etc.).
101 */
102 UINT32 getInstanceStepRate() const { return mInstanceStepRate; }
103
104 /** Returns the size of a base element type. */
105 static UINT32 getTypeSize(VertexElementType etype);
106
107 /** Returns the number of values in the provided base element type. For example float4 has four values. */
108 static UINT16 getTypeCount(VertexElementType etype);
109
110 /** Gets packed color vertex element type used by the active render system. */
111 static VertexElementType getBestColorVertexElementType();
112
113 /** Calculates a hash value for the provided vertex element. */
114 static size_t getHash(const VertexElement& element);
115 protected:
116 UINT16 mSource;
117 UINT32 mOffset;
118 VertexElementType mType;
119 VertexElementSemantic mSemantic;
120 UINT16 mIndex;
121 UINT32 mInstanceStepRate;
122 };
123
124 /** @cond SPECIALIZATIONS */
125 BS_ALLOW_MEMCPY_SERIALIZATION(VertexElement);
126 /** @endcond */
127
128 /** Contains information about a vertex declaration. */
129 class BS_CORE_EXPORT VertexDeclarationProperties
130 {
131 public:
132 VertexDeclarationProperties(const Vector<VertexElement>& elements);
133
134 bool operator== (const VertexDeclarationProperties& rhs) const;
135 bool operator!= (const VertexDeclarationProperties& rhs) const;
136
137 /** Get the number of elements in the declaration. */
138 UINT32 getElementCount() const { return (UINT32)mElementList.size(); }
139
140 /** Returns a list of vertex elements in the declaration. */
141 const Vector<VertexElement>& getElements() const { return mElementList; }
142
143 /** Returns a single vertex element at the specified index. */
144 const VertexElement* getElement(UINT16 index) const;
145
146 /**
147 * Attempts to find an element by the given semantic and semantic index. If no element can be found null is returned.
148 */
149 const VertexElement* findElementBySemantic(VertexElementSemantic sem, UINT16 index = 0) const;
150
151 /** Returns a list of all elements that use the provided source index. */
152 Vector<VertexElement> findElementsBySource(UINT16 source) const;
153
154 /** Returns the total size of all vertex elements using the provided source index. */
155 UINT32 getVertexSize(UINT16 source) const;
156
157 protected:
158 friend class VertexDeclaration;
159 friend class VertexDeclarationRTTI;
160
161 Vector<VertexElement> mElementList;
162 };
163
164 /**
165 * Describes a set of vertex elements, used for describing contents of a vertex buffer or inputs to a vertex GPU program.
166 *
167 * @note Sim thread.
168 */
169 class BS_CORE_EXPORT VertexDeclaration : public IReflectable, public CoreObject
170 {
171 public:
172 virtual ~VertexDeclaration() { }
173
174 /** Returns properties describing the vertex declaration. */
175 const VertexDeclarationProperties& getProperties() const { return mProperties; }
176
177 /** Retrieves a core implementation of a vertex declaration usable only from the core thread. */
178 SPtr<ct::VertexDeclaration> getCore() const;
179
180 /** @copydoc HardwareBufferManager::createVertexDeclaration */
181 static SPtr<VertexDeclaration> create(const SPtr<VertexDataDesc>& desc);
182
183 protected:
184 friend class HardwareBufferManager;
185
186 VertexDeclaration(const Vector<VertexElement>& elements);
187
188 /** @copydoc CoreObject::createCore */
189 SPtr<ct::CoreObject> createCore() const override;
190
191 protected:
192 VertexDeclarationProperties mProperties;
193
194 /************************************************************************/
195 /* SERIALIZATION */
196 /************************************************************************/
197 public:
198 friend class VertexDeclarationRTTI;
199 static RTTITypeBase* getRTTIStatic();
200 RTTITypeBase* getRTTI() const override;
201 };
202
203 /** Converts a vertex semantic enum to a readable name. */
204 BS_CORE_EXPORT String toString(const VertexElementSemantic& val);
205
206 /** @} */
207
208 namespace ct
209 {
210 /** @addtogroup RenderAPI-Internal
211 * @{
212 */
213
214 /**
215 * Core thread portion of a bs::VertexDeclaration.
216 *
217 * @note Core thread.
218 */
219 class BS_CORE_EXPORT VertexDeclaration : public CoreObject
220 {
221 public:
222 virtual ~VertexDeclaration() = default;
223
224 /** @copydoc CoreObject::initialize */
225 void initialize() override;
226
227 /** Returns properties describing the vertex declaration. */
228 const VertexDeclarationProperties& getProperties() const { return mProperties; }
229
230 /** Returns an ID unique to this declaration. */
231 UINT32 getId() const { return mId; }
232
233 /**
234 * Checks can a vertex buffer declared with this declaration be bound to a shader defined with the provided
235 * declaration.
236 */
237 bool isCompatible(const SPtr<VertexDeclaration>& shaderDecl);
238
239 /**
240 * Returns a list of vertex elements that the provided shader's vertex declaration expects but aren't present in
241 * this vertex declaration.
242 */
243 Vector<VertexElement> getMissingElements(const SPtr<VertexDeclaration>& shaderDecl);
244
245 /** @copydoc HardwareBufferManager::createVertexDeclaration */
246 static SPtr<VertexDeclaration> create(const SPtr<VertexDataDesc>& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
247
248 protected:
249 friend class HardwareBufferManager;
250
251 VertexDeclaration(const Vector<VertexElement>& elements, GpuDeviceFlags deviceMask);
252
253 VertexDeclarationProperties mProperties;
254 UINT32 mId;
255
256 static UINT32 NextFreeId;
257 };
258
259 /** @} */
260 }
261}