]> git.tdb.fi Git - libs/gl.git/blob - source/core/vertexformat.h
Initial implementation of Vulkan backend
[libs/gl.git] / source / core / vertexformat.h
1 #ifndef MSP_GL_VERTEXFORMAT_H_
2 #define MSP_GL_VERTEXFORMAT_H_
3
4 #include <cstdint>
5 #include <msp/strings/lexicalcast.h>
6 #include "datatype.h"
7
8 namespace Msp {
9 namespace GL {
10
11 /**
12 A single vertex attribute.  Commonly used attributes are named by their
13 semantical meaning in the standard shaders.  Texture coordinates and generic
14 attributes can additionally be given an index.  There are four texture
15 coordinate attributes available.  The number of available generic attributes
16 depends on implementation limits, but is at least five.
17
18 RAW_ATTRIB is handled in a special way; creating an indexed attribute based on
19 it uses the index as raw attribute number.  Only use it if you know what you
20 are doing.
21
22 The values are bitfields laid as follows:
23
24 nnnn nn_f gsss iccc
25       │ │ │  │ │  └╴Number of components
26       │ │ │  │ └───╴Integer attribute flag
27       │ │ │  └─────╴Size of one component
28       │ │ └────────╴Signed flag
29       │ └──────────╴Floating-point flag
30       └────────────╴Attribute index (semantic)
31
32 This information is presented for internal documentation purposes only; it is
33 inadvisable for applications to rely on it.
34 */
35 enum VertexAttribute: std::uint16_t
36 {
37         VERTEX2 = 0x01C2,
38         VERTEX3 = 0x01C3,
39         VERTEX4 = 0x01C4,
40         COLOR3 = 0x05C3,
41         COLOR4 = 0x05C4,
42         NORMAL3 = 0x09C3,
43         TANGENT3 = 0x0DC3,
44         GROUP1 = 0x10C9,
45         GROUP2 = 0x10CA,
46         GROUP3 = 0x10CB,
47         GROUP4 = 0x10CC,
48         WEIGHT1 = 0x15C1,
49         WEIGHT2 = 0x15C2,
50         WEIGHT3 = 0x15C3,
51         WEIGHT4 = 0x15C4,
52         TEXCOORD1 = 0x19C1,
53         TEXCOORD2 = 0x19C2,
54         TEXCOORD3 = 0x19C3,
55         TEXCOORD4 = 0x19C4,
56         GENERIC1 = 0x29C1,
57         GENERIC2 = 0x29C2,
58         GENERIC3 = 0x29C3,
59         GENERIC4 = 0x29C4,
60         GENERIC_I1 = 0x28C9,
61         GENERIC_I2 = 0x28CA,
62         GENERIC_I3 = 0x28CB,
63         GENERIC_I4 = 0x28CC,
64         PADDING1 = 0xF811,
65         PADDING2 = 0xF812,
66         PADDING3 = 0xF813,
67         PADDING4 = 0xF814,
68         RAW_ATTRIB1 = 0xFDC1,
69         RAW_ATTRIB2 = 0xFDC2,
70         RAW_ATTRIB3 = 0xFDC3,
71         RAW_ATTRIB4 = 0xFDC4,
72         RAW_ATTRIB_I1 = 0xFCC9,
73         RAW_ATTRIB_I2 = 0xFCCA,
74         RAW_ATTRIB_I3 = 0xFCCB,
75         RAW_ATTRIB_I4 = 0xFCCC
76 };
77
78 /**
79 Describes the attributes of a vertex.  Up to 15 attributes are allowed.
80 */
81 class VertexFormat
82 {
83 public:
84         static constexpr unsigned MAX_ATTRIBUTES = 15;
85
86 private:
87         std::uint8_t count = 0;
88         VertexAttribute attributes[MAX_ATTRIBUTES];
89
90 public:
91         VertexFormat() = default;
92         VertexFormat(VertexAttribute);
93
94         VertexFormat operator,(VertexAttribute) const;
95         VertexFormat operator,(DataType) const;
96         VertexFormat operator,(unsigned) const;
97         bool operator==(const VertexFormat &) const;
98         bool operator!=(const VertexFormat &other) const { return !(*this==other); }
99
100         unsigned size() const { return count; }
101         bool empty() const { return !count; }
102         const VertexAttribute *begin() const { return attributes; }
103         const VertexAttribute *end() const { return attributes+count; }
104
105         /** Returns the displacement from one vertex to the next. */
106         unsigned stride() const;
107
108         /** Returns the offset of an attribute within a vertex.  A stored attribute
109         must have the same semantic and type and at least as many components as
110         requested to be considered a match. */
111         int offset(VertexAttribute) const;
112 };
113
114 inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
115 { return (VertexFormat(a1), a2); }
116
117 VertexAttribute make_typed_attribute(VertexAttribute, DataType);
118
119 inline VertexAttribute operator,(VertexAttribute a, DataType t)
120 { return make_typed_attribute(a, t); }
121
122 VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
123
124 inline VertexAttribute operator,(VertexAttribute a, unsigned i)
125 { return make_indexed_attribute(a, i); }
126
127 inline unsigned get_attribute_semantic(VertexAttribute a)
128 { return a>>10; }
129
130 inline DataType get_attribute_source_type(VertexAttribute a)
131 { return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
132
133 inline unsigned get_attribute_component_count(VertexAttribute a)
134 { return a&7; }
135
136 inline unsigned get_attribute_size(VertexAttribute a)
137 { return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
138
139 inline bool is_integer_attribute(VertexAttribute a)
140 { return a&8; }
141
142 inline bool is_padding(VertexAttribute a)
143 { return get_attribute_semantic(a)==get_attribute_semantic(PADDING1); }
144
145 void operator>>(const LexicalConverter &, VertexAttribute &);
146
147 } // namespace GL
148 } // namespace Msp
149
150 #include "vertexformat_backend.h"
151
152 #endif