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 | |
9 | namespace 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 | } |