Cogs.Core
VertexFormat.cpp
1#include "VertexFormat.h"
2
3#include <algorithm>
4#include <unordered_map>
5
6#include "Foundation/HashFunctions.h"
7#include "Base/ResourceMap.h"
8
9namespace
10{
12 uint32_t calculateSize(const Cogs::VertexFormat & vertexFormat)
13 {
14 uint32_t size = 0;
15 for (size_t i = 0; i < vertexFormat.elements.size(); ++i) {
16 auto & element = vertexFormat.elements[i];
17 size = std::max(element.offset + (uint32_t)Cogs::getFormatInfo(element.format)->blockSize, size);
18 }
19 return size;
20 }
21}
22
23namespace Cogs
24{
26 {
28 std::mutex vertexFormatsByHashMutex;
29 std::unordered_map<size_t, VertexFormatHandle> vertexFormatsByHash;
30 };
31
32 VertexFormatStorage& getStorage()
33 {
34 static Cogs::VertexFormatStorage storage;
35 return storage;
36 }
37
38 VertexFormatHandle VertexFormats::createVertexFormat(const VertexElement * elements, size_t count)
39 {
40 VertexFormat vertexFormat;
41 vertexFormat.elements.assign(elements, elements + count);
42
43 size_t formatHash = Cogs::hash(vertexFormat);
44
45 auto& storage = getStorage();
46 std::lock_guard<std::mutex> lock(storage.vertexFormatsByHashMutex);
47
48 auto foundIt = storage.vertexFormatsByHash.find(formatHash);
49
50 if (foundIt != storage.vertexFormatsByHash.end()) {
51 return foundIt->second;
52 } else {
53 vertexFormat.hash = formatHash;
54 vertexFormat.size = calculateSize(vertexFormat);
55 auto handle = storage.vertexFormats.addResource(std::move(vertexFormat));
56 storage.vertexFormatsByHash[formatHash] = handle;
57 return handle;
58 }
59 }
60
61 VertexFormatHandle VertexFormats::createVertexFormat(const PackedVertexElement * packedElements, size_t count)
62 {
63 VertexFormat vertexFormat;
64 uint16_t offset = 0;
65 for (size_t i = 0; i < count; ++i) {
66 auto & packedElement = packedElements[i];
67
68 VertexElement element = {
69 offset,
70 packedElement.format,
71 packedElement.semantic,
72 packedElement.semanticIndex,
73 packedElement.inputType,
74 packedElement.instanceStep
75 };
76
77 offset += getFormatInfo(packedElement.format)->blockSize;
78
79 vertexFormat.elements.emplace_back(element);
80 }
81
82 size_t formatHash = Cogs::hash(vertexFormat);
83
84 auto& storage = getStorage();
85 std::lock_guard<std::mutex> lock(storage.vertexFormatsByHashMutex);
86
87 auto foundIt = storage.vertexFormatsByHash.find(formatHash);
88
89 if (foundIt != storage.vertexFormatsByHash.end()) {
90 return foundIt->second;
91 } else {
92 vertexFormat.hash = formatHash;
93 vertexFormat.size = calculateSize(vertexFormat);
94 auto handle = storage.vertexFormats.addResource(std::move(vertexFormat));
95 storage.vertexFormatsByHash[formatHash] = handle;
96 return handle;
97 }
98 }
99
100 const VertexFormat * VertexFormats::getVertexFormat(VertexFormatHandle handle)
101 {
102 return &getStorage().vertexFormats[handle];
103 }
104}
105
106Cogs::StringView Cogs::getElementSemanticName(ElementSemantic semantic)
107{
108 switch (semantic) {
109 case ElementSemantic::Position:
110 return "Position";
111 case ElementSemantic::Normal:
112 return "Normal";
113 case ElementSemantic::Color:
114 return "Color";
115 case ElementSemantic::TextureCoordinate:
116 return "TextureCoordinate";
117 case ElementSemantic::Tangent:
118 return "Tangent";
119 case ElementSemantic::InstanceVector:
120 return "InstanceVector";
121 case ElementSemantic::InstanceMatrix:
122 return "InstanceMatrix";
123 case ElementSemantic::Semantic_Size:
124 default:
125 return "Illegal";
126 }
127}
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
uint8_t blockSize
Bytesize of one block of data.
Definition: DataFormat.h:257
Vertex format structure used to describe a single vertex for the input assembler.
Definition: VertexFormat.h:60
std::vector< VertexElement > elements
Vector containing all vertex elements of this format.
Definition: VertexFormat.h:62