FCT
载入中...
搜索中...
未找到
Vertex.h
浏览该文件的文档.
1#ifndef FCT_VERTEX_H
2#define FCT_VERTEX_H
3#include "./Format.h"
4#include "./DataTypes.h"
5#include "../Base/string.h"
6namespace FCT
7{
25 /*
26 *添加一个需要 添加
27 * GetDefaultModelAttribute
28 * GetDefaultFormat
29 * GetDefaultSemantic
30 */
31
33 Position, // 对应 position
34 Normal, // 对应 normal
35 TexCoord0, // 对应 texCoords[0]
36 TexCoord1, // 对应 texCoords[1]
43 Color0, // 对应 colors[0]
44 Color1, // 对应 colors[1]
51 Tangent, // 对应 tangent
52 Bitangent, // 对应 bitangent
53 None // 不对应任何ModelVertex属性
54 };
93
94 constexpr bool isPositionType(VtxType type) noexcept
95 {
96 return type == VtxType::Position2f || type == VtxType::Position3f || type == VtxType::Position4f;
97 }
98
99 constexpr Format GetDefaultFormat(VtxType type) noexcept {
100 switch (type)
101 {
116 case VtxType::Color3f:
118 case VtxType::Color4f:
123 return Format::R32_UINT;
124 case VtxType::BatchID:
125 return Format::R32_UINT;
126 case VtxType::FaceId:
127 return Format::R32_UINT;
129 return Format::R32_UINT;
130 case VtxType::Custom:
131 default:
132 return Format::UNDEFINED;
133 }
134 }
135
136 constexpr const char* GetDefaultSemantic(VtxType type) noexcept {
137 switch (type)
138 {
142 return "pos";
144 return "normal";
146 return "tangent";
148 return "bitangent";
150 return "texcoord";
151 case VtxType::Color3f:
152 case VtxType::Color4f:
153 return "color";
155 return "vertexcoord";
157 return "cmdoffset";
159 return "cmdSize";
160 case VtxType::FaceId:
161 return "faceId";
162 case VtxType::Custom:
163 default:
164 return "Custom";
165 }
166 }
167
169 public:
172 template<typename... Args>
173 constexpr VertexElement(Args&&... args) noexcept
176 processArgs(std::forward<Args>(args)...);
177 }
178 constexpr ModelVertexAttribute getModelAttribute() const noexcept { return m_modelAttribute; }
179
180 constexpr VtxType getType() const noexcept { return m_type; }
181
182 constexpr Format getFormat() const noexcept { return m_format; }
183
184 constexpr const char* getSemantic() const noexcept { return m_semantic; }
185
186 constexpr size_t getSize() const noexcept {
187 return FormatSize(m_format);
188 }
189
190 private:
191 constexpr void processArgs() noexcept {}
192 constexpr void processArgs(VtxType type) noexcept {
193 m_type = type;
196 }
197 if (StringEquals(m_semantic, "")) {
199 }
202 }
203 }
204
205 constexpr void processArgs(Format format) noexcept {
206 m_format = format;
207 }
208
209 constexpr void processArgs(const char* semantic) noexcept {
210 m_semantic = semantic;
211 }
212
213 constexpr void processArgs(ModelVertexAttribute attr) noexcept {
214 m_modelAttribute = attr;
215 }
216
217 template<typename First, typename... Rest>
218 constexpr void processArgs(First&& first, Rest&&... rest) noexcept {
219 processArgs(std::forward<First>(first));
220 processArgs(std::forward<Rest>(rest)...);
221 }
224 const char* m_semantic;
226 };
227
229 {
230 public:
231 template<typename... Elements>
232 constexpr VertexLayout(const Elements&... elements) noexcept {
233 (addElement(elements), ...);
234 }
235 constexpr void addElement(const VertexElement& element) noexcept {
237 m_elements[m_elementCount++] = element;
238 m_stride += element.getSize();
239 }
240 }
241
242 constexpr size_t getElementCount() const noexcept {
243 return m_elementCount;
244 }
245
246 constexpr const VertexElement& getElement(size_t index) const noexcept {
247 return (index < m_elementCount) ? m_elements[index] : m_elements[0];
248 }
249
250 constexpr size_t getStride() const noexcept {
251 return m_stride;
252 }
253
254 constexpr int getElementIndexBySemantic(const char* semantic) const noexcept {
255 for (size_t i = 0; i < m_elementCount; ++i) {
256 if (StringEquals(m_elements[i].getSemantic(), semantic)) {
257 return static_cast<int>(i);
258 }
259 }
260 return -1;
261 }
262
263 constexpr int getElementIndexByType(VtxType type) const noexcept {
264 for (size_t i = 0; i < m_elementCount; ++i) {
265 if (m_elements[i].getType() == type) {
266 return static_cast<int>(i);
267 }
268 }
269 return -1;
270 }
271
272 constexpr const VertexElement* getElementByType(VtxType type) const noexcept {
273 int index = getElementIndexByType(type);
274 return (index >= 0) ? &m_elements[index] : nullptr;
275 }
276
277 constexpr const VertexElement* getElementBySemantic(const char* semantic) const noexcept {
278 int index = getElementIndexBySemantic(semantic);
279 return (index >= 0) ? &m_elements[index] : nullptr;
280 }
281
282 constexpr size_t getElementOffset(size_t index) const noexcept {
283 size_t offset = 0;
284 for (size_t i = 0; i < index && i < m_elementCount; ++i) {
285 offset += m_elements[i].getSize();
286 }
287 return offset;
288 }
289
290 constexpr size_t getElementOffsetByType(VtxType type) const noexcept {
291 int index = getElementIndexByType(type);
292 return (index >= 0) ? getElementOffset(index) : 0;
293 }
294
295 constexpr size_t getElementOffsetBySemantic(const char* semantic) const noexcept {
296 int index = getElementIndexBySemantic(semantic);
297 return (index >= 0) ? getElementOffset(index) : 0;
298 }
299
300 private:
301 static constexpr size_t MaxElements = 64;
303 size_t m_elementCount = 0;
304 size_t m_stride = 0;
305 };
307 {
308 public:
309 //constexpr PixelLayout() noexcept : m_elementCount(0), m_stride(0) {}
310
311 template<typename... Args>
312 constexpr PixelLayout(Args&&... args) noexcept : m_elementCount(0), m_stride(0) {
313 addElements(std::forward<Args>(args)...);
314 }
315
316 constexpr void addElement(const VertexElement& element) noexcept {
318 m_elements[m_elementCount++] = element;
319 m_stride += element.getSize();
320 }
321 }
322
323 constexpr void addElements(const VertexLayout& layout) noexcept {
324 for (size_t i = 0; i < layout.getElementCount() && m_elementCount < MaxElements; ++i) {
325 addElement(layout.getElement(i));
326 }
327 }
328
329 constexpr void addElements(const PixelLayout& layout) noexcept {
330 for (size_t i = 0; i < layout.getElementCount() && m_elementCount < MaxElements; ++i) {
331 addElement(layout.getElement(i));
332 }
333 }
334
335 constexpr size_t getElementCount() const noexcept {
336 return m_elementCount;
337 }
338
339 constexpr const VertexElement& getElement(size_t index) const noexcept {
340 return (index < m_elementCount) ? m_elements[index] : m_elements[0];
341 }
342
343 constexpr size_t getStride() const noexcept {
344 return m_stride;
345 }
346
347 constexpr int getElementIndexBySemantic(const char* semantic) const noexcept {
348 for (size_t i = 0; i < m_elementCount; ++i) {
349 if (StringEquals(m_elements[i].getSemantic(), semantic)) {
350 return static_cast<int>(i);
351 }
352 }
353 return -1;
354 }
355
356 constexpr int getElementIndexByType(VtxType type) const noexcept {
357 for (size_t i = 0; i < m_elementCount; ++i) {
358 if (m_elements[i].getType() == type) {
359 return static_cast<int>(i);
360 }
361 }
362 return -1;
363 }
364
365 constexpr const VertexElement* getElementByType(VtxType type) const noexcept {
366 int index = getElementIndexByType(type);
367 return (index >= 0) ? &m_elements[index] : nullptr;
368 }
369
370 constexpr const VertexElement* getElementBySemantic(const char* semantic) const noexcept {
371 int index = getElementIndexBySemantic(semantic);
372 return (index >= 0) ? &m_elements[index] : nullptr;
373 }
374
375 constexpr size_t getElementOffset(size_t index) const noexcept {
376 size_t offset = 0;
377 for (size_t i = 0; i < index && i < m_elementCount; ++i) {
378 offset += m_elements[i].getSize();
379 }
380 return offset;
381 }
382
383 constexpr size_t getElementOffsetByType(VtxType type) const noexcept {
384 int index = getElementIndexByType(type);
385 return (index >= 0) ? getElementOffset(index) : 0;
386 }
387
388 constexpr size_t getElementOffsetBySemantic(const char* semantic) const noexcept {
389 int index = getElementIndexBySemantic(semantic);
390 return (index >= 0) ? getElementOffset(index) : 0;
391 }
392
393 constexpr void ensurePositionFirst() noexcept {
395 if (posIndex < 0) {
397 }
398
399 if (posIndex > 0) {
400 VertexElement posElement = m_elements[posIndex];
401
402 for (int i = posIndex; i > 0; --i) {
403 m_elements[i] = m_elements[i - 1];
404 }
405
406 m_elements[0] = posElement;
407
408 }
409 }
410
411 private:
412 constexpr void addElements() noexcept {}
413
414 template<typename... Rest>
415 constexpr void addElements(const VertexElement& element, Rest&&... rest) noexcept {
416 addElement(element);
417 addElements(std::forward<Rest>(rest)...);
418 }
419
420 template<typename... Rest>
421 constexpr void addElements(const VertexLayout& layout, Rest&&... rest) noexcept {
422 addElements(layout);
423 addElements(std::forward<Rest>(rest)...);
424 }
425
426 static constexpr size_t MaxElements = 64;
429 size_t m_stride;
430 };
431 class VertexBuffer;
432
433 class Vertex {
434 friend class VertexBuffer;
435 public:
436 template<typename T>
437 T& getAttribute(VtxType type) noexcept {
438 const auto* element = m_layout.getElementByType(type);
439 if (element) {
440 size_t offset = m_layout.getElementOffsetByType(type);
441 return *reinterpret_cast<T*>(m_data + offset);
442 }
443 static T dummy{};
444 return dummy;
445 }
446
447 template<typename T>
448 T& getAttribute(const char* semantic) noexcept {
449 const auto* element = m_layout.getElementBySemantic(semantic);
450 if (element) {
451 size_t offset = m_layout.getElementOffsetBySemantic(semantic);
452 return *reinterpret_cast<T*>(m_data + offset);
453 }
454 static T dummy{};
455 return dummy;
456 }
457
458 template<typename T>
459 void setAttribute(VtxType type, const T& value) noexcept {
460 const auto* element = m_layout.getElementByType(type);
461 if (element) {
462 size_t offset = m_layout.getElementOffsetByType(type);
463 *reinterpret_cast<T*>(m_data + offset) = value;
464 }
465 }
466 template<typename T>
467 void setAttribute(size_t elementIndex, const T& value) noexcept {
468 if (elementIndex < m_layout.getElementCount()) {
469 size_t offset = m_layout.getElementOffset(elementIndex);
470 *reinterpret_cast<T*>(m_data + offset) = value;
471 }
472 }
473
474 template<typename T>
475 void setAttribute(const char* semantic, const T& value) noexcept {
476 const auto* element = m_layout.getElementBySemantic(semantic);
477 if (element) {
478 size_t offset = m_layout.getElementOffsetBySemantic(semantic);
479 *reinterpret_cast<T*>(m_data + offset) = value;
480 }
481 }
482
483 uint8_t* getData() noexcept {
484 return m_data;
485 }
486
487 const uint8_t* getData() const noexcept {
488 return m_data;
489 }
490
491 const VertexLayout& getLayout() const noexcept {
492 return m_layout;
493 }
494
495 private:
496 Vertex(uint8_t* data, const VertexLayout& layout) noexcept
497 : m_data(data), m_layout(layout) {}
498
499 uint8_t* m_data;
501 };
502
504 public:
505 ConstVertex(const Vertex& vertex) noexcept
506 : m_data(vertex.getData()), m_layout(vertex.getLayout()) {}
507
508 template<typename T>
509 const T& getAttribute(VtxType type) const noexcept {
510 const auto* element = m_layout.getElementByType(type);
511 if (element) {
512 size_t offset = m_layout.getElementOffsetByType(type);
513 return *reinterpret_cast<const T*>(m_data + offset);
514 }
515 static const T dummy{};
516 return dummy;
517 }
518
519 template<typename T>
520 const T& getAttribute(const char* semantic) const noexcept {
521 const auto* element = m_layout.getElementBySemantic(semantic);
522 if (element) {
523 size_t offset = m_layout.getElementOffsetBySemantic(semantic);
524 return *reinterpret_cast<const T*>(m_data + offset);
525 }
526 static const T dummy{};
527 return dummy;
528 }
529
530 const uint8_t* getData() const noexcept {
531 return m_data;
532 }
533
534 const VertexLayout& getLayout() const noexcept {
535 return m_layout;
536 }
537
538 private:
539 const uint8_t* m_data;
541 };
543 public:
544 explicit VertexBuffer(const VertexLayout& layout) noexcept
545 : m_layout(layout), m_stride(layout.getStride()) {}
546
547 const VertexLayout& getLayout() const noexcept {
548 return m_layout;
549 }
550
551 size_t getVertexCount() const noexcept {
552 return m_data.size() / m_stride;
553 }
554
555 size_t getStride() const noexcept {
556 return m_stride;
557 }
558 void* getData()
559 {
560 return m_data.data();
561 }
562
563 const void* getData() const noexcept {
564 return m_data.data();
565 }
566
567 size_t getDataSize() const noexcept {
568 return m_data.size();
569 }
570
571 void reserve(size_t vertexCount) {
572 m_data.reserve(vertexCount * m_stride);
573 }
574
575 void resize(size_t vertexCount) {
576 m_data.resize(vertexCount * m_stride);
577 }
578
579 void clear() noexcept {
580 m_data.clear();
581 }
582
583 size_t addVertex() {
584 size_t index = getVertexCount();
585 m_data.resize((index + 1) * m_stride);
586 return index;
587 }
588
589 Vertex operator[](size_t index) noexcept {
590 assert(index < getVertexCount() && "Vertex index out of range");
591 return Vertex(m_data.data() + (index * m_stride), m_layout);
592 }
593/*
594 ConstVertex operator[](size_t index) const noexcept {
595 assert(index < getVertexCount() && "Vertex index out of range");
596 return ConstVertex(Vertex(const_cast<uint8_t*>(m_data.data()) + (index * m_stride), m_layout));
597 }*/
598
599 Vertex front() noexcept {
600 assert(!m_data.empty() && "Vertex buffer is empty");
601 return Vertex(m_data.data(), m_layout);
602 }
603
604 Vertex back() noexcept {
605 assert(!m_data.empty() && "Vertex buffer is empty");
606 return Vertex(m_data.data() + ((getVertexCount() - 1) * m_stride), m_layout);
607 }
608
609 ConstVertex front() const noexcept {
610 assert(!m_data.empty() && "Vertex buffer is empty");
611 return ConstVertex(Vertex(const_cast<uint8_t*>(m_data.data()), m_layout));
612 }
613
614 ConstVertex back() const noexcept {
615 assert(!m_data.empty() && "Vertex buffer is empty");
616 return ConstVertex(Vertex(const_cast<uint8_t*>(m_data.data() + ((getVertexCount() - 1) * m_stride)), m_layout));
617 }
618
619 template<typename... Args>
620 void emplaceBack(Args&&... args) {
621 static_assert(sizeof...(args) > 0, "At least one attribute must be provided");
622
623 size_t index = addVertex();
624 Vertex vertex = (*this)[index];
625
626 setAttributes(vertex, 0, std::forward<Args>(args)...);
627 }
628
629
630 private:
631 template<typename T>
632 void setAttributes(Vertex& vertex, size_t elementIndex, T&& value) {
633 if (elementIndex < m_layout.getElementCount()) {
634 vertex.setAttribute(elementIndex, std::forward<T>(value));
635 }
636 }
637
638 template<typename T, typename... Rest>
639 void setAttributes(Vertex& vertex, size_t elementIndex, T&& first, Rest&&... rest) {
640 if (elementIndex < m_layout.getElementCount()) {
641 vertex.setAttribute(elementIndex, std::forward<T>(first));
642 setAttributes(vertex, elementIndex + 1, std::forward<Rest>(rest)...);
643 }
644 }
645
646 std::vector<uint8_t> m_data;
648 size_t m_stride;
649 };
650}
651#endif //VERTEX_H
const uint8_t * m_data
const VertexLayout & getLayout() const noexcept
const T & getAttribute(const char *semantic) const noexcept
const VertexLayout & m_layout
const uint8_t * getData() const noexcept
ConstVertex(const Vertex &vertex) noexcept
const T & getAttribute(VtxType type) const noexcept
constexpr const VertexElement * getElementByType(VtxType type) const noexcept
constexpr void addElements(const VertexElement &element, Rest &&... rest) noexcept
constexpr size_t getElementCount() const noexcept
constexpr size_t getElementOffsetBySemantic(const char *semantic) const noexcept
constexpr const VertexElement & getElement(size_t index) const noexcept
constexpr size_t getElementOffset(size_t index) const noexcept
constexpr void addElements(const VertexLayout &layout, Rest &&... rest) noexcept
VertexElement m_elements[MaxElements]
constexpr void ensurePositionFirst() noexcept
constexpr void addElement(const VertexElement &element) noexcept
static constexpr size_t MaxElements
constexpr void addElements() noexcept
constexpr const VertexElement * getElementBySemantic(const char *semantic) const noexcept
constexpr int getElementIndexBySemantic(const char *semantic) const noexcept
constexpr size_t getElementOffsetByType(VtxType type) const noexcept
constexpr PixelLayout(Args &&... args) noexcept
constexpr int getElementIndexByType(VtxType type) const noexcept
constexpr void addElements(const PixelLayout &layout) noexcept
constexpr void addElements(const VertexLayout &layout) noexcept
constexpr size_t getStride() const noexcept
VertexBuffer(const VertexLayout &layout) noexcept
void emplaceBack(Args &&... args)
void reserve(size_t vertexCount)
Vertex back() noexcept
size_t getStride() const noexcept
ConstVertex front() const noexcept
Vertex front() noexcept
const void * getData() const noexcept
void setAttributes(Vertex &vertex, size_t elementIndex, T &&first, Rest &&... rest)
size_t getDataSize() const noexcept
std::vector< uint8_t > m_data
void setAttributes(Vertex &vertex, size_t elementIndex, T &&value)
size_t getVertexCount() const noexcept
ConstVertex back() const noexcept
VertexLayout m_layout
Vertex operator[](size_t index) noexcept
void clear() noexcept
const VertexLayout & getLayout() const noexcept
void resize(size_t vertexCount)
constexpr void processArgs(First &&first, Rest &&... rest) noexcept
constexpr VtxType getType() const noexcept
constexpr void processArgs(VtxType type) noexcept
const char * m_semantic
constexpr Format getFormat() const noexcept
constexpr void processArgs(Format format) noexcept
constexpr void processArgs(ModelVertexAttribute attr) noexcept
constexpr VertexElement() noexcept
constexpr size_t getSize() const noexcept
constexpr const char * getSemantic() const noexcept
constexpr ModelVertexAttribute getModelAttribute() const noexcept
constexpr void processArgs(const char *semantic) noexcept
constexpr VertexElement(Args &&... args) noexcept
ModelVertexAttribute m_modelAttribute
constexpr void processArgs() noexcept
uint8_t * m_data
void setAttribute(const char *semantic, const T &value) noexcept
void setAttribute(size_t elementIndex, const T &value) noexcept
uint8_t * getData() noexcept
void setAttribute(VtxType type, const T &value) noexcept
const VertexLayout & getLayout() const noexcept
Vertex(uint8_t *data, const VertexLayout &layout) noexcept
friend class VertexBuffer
T & getAttribute(const char *semantic) noexcept
T & getAttribute(VtxType type) noexcept
const uint8_t * getData() const noexcept
const VertexLayout & m_layout
constexpr const VertexElement * getElementByType(VtxType type) const noexcept
VertexElement m_elements[MaxElements]
constexpr size_t getElementOffset(size_t index) const noexcept
constexpr size_t getStride() const noexcept
constexpr int getElementIndexByType(VtxType type) const noexcept
constexpr size_t getElementOffsetBySemantic(const char *semantic) const noexcept
constexpr size_t getElementOffsetByType(VtxType type) const noexcept
constexpr int getElementIndexBySemantic(const char *semantic) const noexcept
static constexpr size_t MaxElements
constexpr void addElement(const VertexElement &element) noexcept
constexpr size_t getElementCount() const noexcept
constexpr const VertexElement & getElement(size_t index) const noexcept
constexpr const VertexElement * getElementBySemantic(const char *semantic) const noexcept
constexpr VertexLayout(const Elements &... elements) noexcept
constexpr const char * GetDefaultSemantic(VtxType type) noexcept
constexpr bool StringEquals(const char *a, const char *b) noexcept
定义 string.h:8
constexpr bool isPositionType(VtxType type) noexcept
constexpr ModelVertexAttribute GetDefaultModelAttribute(VtxType type) noexcept
ModelVertexAttribute
constexpr Format GetDefaultFormat(VtxType type) noexcept
constexpr size_t FormatSize(Format format) noexcept