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 | #include "RenderAPI/BsVertexDataDesc.h" |
4 | #include "Managers/BsHardwareBufferManager.h" |
5 | #include "Private/RTTI/BsVertexDataDescRTTI.h" |
6 | |
7 | namespace bs |
8 | { |
9 | void VertexDataDesc::addVertElem(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, |
10 | UINT32 streamIdx, UINT32 instanceStepRate) |
11 | { |
12 | clearIfItExists(type, semantic, semanticIdx, streamIdx); |
13 | |
14 | VertexElement newElement(streamIdx, 0, type, semantic, semanticIdx, instanceStepRate); |
15 | |
16 | // Insert it so it is sorted by stream |
17 | UINT32 insertToIndex = (UINT32)mVertexElements.size(); |
18 | UINT32 idx = 0; |
19 | for(auto& elem : mVertexElements) |
20 | { |
21 | if(elem.getStreamIdx() > streamIdx) |
22 | { |
23 | insertToIndex = idx; |
24 | break; |
25 | } |
26 | |
27 | idx++; |
28 | } |
29 | |
30 | mVertexElements.insert(mVertexElements.begin() + insertToIndex, newElement); |
31 | } |
32 | |
33 | Vector<VertexElement> VertexDataDesc::createElements() const |
34 | { |
35 | UINT32 maxStreamIdx = getMaxStreamIdx(); |
36 | |
37 | UINT32 numStreams = maxStreamIdx + 1; |
38 | UINT32* streamOffsets = bs_newN<UINT32>(numStreams); |
39 | for (UINT32 i = 0; i < numStreams; i++) |
40 | streamOffsets[i] = 0; |
41 | |
42 | Vector<VertexElement> declarationElements; |
43 | for (auto& vertElem : mVertexElements) |
44 | { |
45 | UINT32 streamIdx = vertElem.getStreamIdx(); |
46 | |
47 | declarationElements.push_back(VertexElement(streamIdx, streamOffsets[streamIdx], vertElem.getType(), |
48 | vertElem.getSemantic(), vertElem.getSemanticIdx(), vertElem.getInstanceStepRate())); |
49 | |
50 | streamOffsets[streamIdx] += vertElem.getSize(); |
51 | } |
52 | |
53 | bs_deleteN(streamOffsets, numStreams); |
54 | |
55 | return declarationElements; |
56 | } |
57 | |
58 | UINT32 VertexDataDesc::getMaxStreamIdx() const |
59 | { |
60 | UINT32 maxStreamIdx = 0; |
61 | UINT32 numElems = (UINT32)mVertexElements.size(); |
62 | for(UINT32 i = 0; i < numElems; i++) |
63 | { |
64 | for(auto& vertElem : mVertexElements) |
65 | { |
66 | maxStreamIdx = std::max((UINT32)maxStreamIdx, (UINT32)vertElem.getStreamIdx()); |
67 | } |
68 | } |
69 | |
70 | return maxStreamIdx; |
71 | } |
72 | |
73 | bool VertexDataDesc::hasStream(UINT32 streamIdx) const |
74 | { |
75 | for(auto& vertElem : mVertexElements) |
76 | { |
77 | if(vertElem.getStreamIdx() == streamIdx) |
78 | return true; |
79 | } |
80 | |
81 | return false; |
82 | } |
83 | |
84 | bool VertexDataDesc::hasElement(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const |
85 | { |
86 | auto findIter = std::find_if(mVertexElements.begin(), mVertexElements.end(), |
87 | [semantic, semanticIdx, streamIdx] (const VertexElement& x) |
88 | { |
89 | return x.getSemantic() == semantic && x.getSemanticIdx() == semanticIdx && x.getStreamIdx() == streamIdx; |
90 | }); |
91 | |
92 | if(findIter != mVertexElements.end()) |
93 | { |
94 | return true; |
95 | } |
96 | |
97 | return false; |
98 | } |
99 | |
100 | UINT32 VertexDataDesc::getElementSize(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const |
101 | { |
102 | for(auto& element : mVertexElements) |
103 | { |
104 | if(element.getSemantic() == semantic && element.getSemanticIdx() == semanticIdx && element.getStreamIdx() == streamIdx) |
105 | return element.getSize(); |
106 | } |
107 | |
108 | return -1; |
109 | } |
110 | |
111 | UINT32 VertexDataDesc::getElementOffsetFromStream(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const |
112 | { |
113 | UINT32 vertexOffset = 0; |
114 | for(auto& element : mVertexElements) |
115 | { |
116 | if(element.getStreamIdx() != streamIdx) |
117 | continue; |
118 | |
119 | if(element.getSemantic() == semantic && element.getSemanticIdx() == semanticIdx) |
120 | break; |
121 | |
122 | vertexOffset += element.getSize(); |
123 | } |
124 | |
125 | return vertexOffset; |
126 | } |
127 | |
128 | UINT32 VertexDataDesc::getVertexStride(UINT32 streamIdx) const |
129 | { |
130 | UINT32 vertexStride = 0; |
131 | for(auto& element : mVertexElements) |
132 | { |
133 | if(element.getStreamIdx() == streamIdx) |
134 | vertexStride += element.getSize(); |
135 | } |
136 | |
137 | return vertexStride; |
138 | } |
139 | |
140 | UINT32 VertexDataDesc::getVertexStride() const |
141 | { |
142 | UINT32 vertexStride = 0; |
143 | for(auto& element : mVertexElements) |
144 | { |
145 | vertexStride += element.getSize(); |
146 | } |
147 | |
148 | return vertexStride; |
149 | } |
150 | |
151 | UINT32 VertexDataDesc::getStreamOffset(UINT32 streamIdx) const |
152 | { |
153 | UINT32 streamOffset = 0; |
154 | for(auto& element : mVertexElements) |
155 | { |
156 | if(element.getStreamIdx() == streamIdx) |
157 | break; |
158 | |
159 | streamOffset += element.getSize(); |
160 | } |
161 | |
162 | return streamOffset; |
163 | } |
164 | |
165 | const VertexElement* VertexDataDesc::getElement(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const |
166 | { |
167 | auto findIter = std::find_if(mVertexElements.begin(), mVertexElements.end(), |
168 | [semantic, semanticIdx, streamIdx](const VertexElement& x) |
169 | { |
170 | return x.getSemantic() == semantic && x.getSemanticIdx() == semanticIdx && x.getStreamIdx() == streamIdx; |
171 | }); |
172 | |
173 | if (findIter != mVertexElements.end()) |
174 | return &(*findIter); |
175 | |
176 | return nullptr; |
177 | } |
178 | |
179 | void VertexDataDesc::clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) |
180 | { |
181 | auto findIter = std::find_if(mVertexElements.begin(), mVertexElements.end(), |
182 | [semantic, semanticIdx, streamIdx] (const VertexElement& x) |
183 | { |
184 | return x.getSemantic() == semantic && x.getSemanticIdx() == semanticIdx && x.getStreamIdx() == streamIdx; |
185 | }); |
186 | |
187 | if(findIter != mVertexElements.end()) |
188 | { |
189 | mVertexElements.erase(findIter); |
190 | } |
191 | } |
192 | |
193 | SPtr<VertexDataDesc> VertexDataDesc::create() |
194 | { |
195 | return bs_shared_ptr_new<VertexDataDesc>(); |
196 | } |
197 | |
198 | /************************************************************************/ |
199 | /* SERIALIZATION */ |
200 | /************************************************************************/ |
201 | |
202 | RTTITypeBase* VertexDataDesc::getRTTIStatic() |
203 | { |
204 | return VertexDataDescRTTI::instance(); |
205 | } |
206 | |
207 | RTTITypeBase* VertexDataDesc::getRTTI() const |
208 | { |
209 | return VertexDataDesc::getRTTIStatic(); |
210 | } |
211 | } |