]> git.tdb.fi Git - libs/gl.git/blob - source/core/vertexformat.h
Add support for padding in vertex formats
[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         bool empty() const { return !count; }
101         const VertexAttribute *begin() const { return attributes; }
102         const VertexAttribute *end() const { return attributes+count; }
103
104         /** Returns the displacement from one vertex to the next. */
105         unsigned stride() const;
106
107         /** Returns the offset of an attribute within a vertex.  A stored attribute
108         must have the same semantic and type and at least as many components as
109         requested to be considered a match. */
110         int offset(VertexAttribute) const;
111 };
112
113 inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
114 { return (VertexFormat(a1), a2); }
115
116 VertexAttribute make_typed_attribute(VertexAttribute, DataType);
117
118 inline VertexAttribute operator,(VertexAttribute a, DataType t)
119 { return make_typed_attribute(a, t); }
120
121 VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
122
123 inline VertexAttribute operator,(VertexAttribute a, unsigned i)
124 { return make_indexed_attribute(a, i); }
125
126 inline unsigned get_attribute_semantic(VertexAttribute a)
127 { return a>>10; }
128
129 inline DataType get_attribute_source_type(VertexAttribute a)
130 { return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
131
132 inline unsigned get_attribute_component_count(VertexAttribute a)
133 { return a&7; }
134
135 inline unsigned get_attribute_size(VertexAttribute a)
136 { return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
137
138 inline bool is_integer_attribute(VertexAttribute a)
139 { return a&8; }
140
141 inline bool is_padding(VertexAttribute a)
142 { return get_attribute_semantic(a)==get_attribute_semantic(PADDING1); }
143
144 void operator>>(const LexicalConverter &, VertexAttribute &);
145
146 } // namespace GL
147 } // namespace Msp
148
149 #endif