]> git.tdb.fi Git - libs/gl.git/blob - source/core/vertexformat.h
Make VertexFormat capable of storing type information
[libs/gl.git] / source / core / vertexformat.h
1 #ifndef MSP_GL_VERTEXFORMAT_H_
2 #define MSP_GL_VERTEXFORMAT_H_
3
4 #include <msp/core/inttypes.h>
5 #include <msp/strings/lexicalcast.h>
6 #include "datatype.h"
7
8 namespace Msp {
9 namespace GL {
10
11 /** A single vertex attribute.  Commonly used attributes are named by their
12 semantical meaning in the standard shaders.  Texture coordinates and generic
13 attributes can additionally be given an index.  There are four texture
14 coordinate attributes available.  The number of available generic attributes
15 depends on implementation limits, but is at least five.
16
17 RAW_ATTRIB is handled in a special way; creating an indexed attribute based on
18 it uses the index as raw attribute number.  Only use it if you know what you
19 are doing.
20
21 The values are bitfields laid as follows:
22
23 nnnn nn_f gsss _ccc
24       │ │ │  │    └╴Number of components
25       │ │ │  └─────╴Size of one component
26       │ │ └────────╴Signed flag
27       │ └──────────╴Floating-point flag
28       └────────────╴Attribute index (semantic)
29
30 This information is presented for internal documentation purposes only; it is
31 inadvisable for programs to rely on it.
32 */
33 enum VertexAttribute
34 {
35         VERTEX2 = 0x01C2,
36         VERTEX3 = 0x01C3,
37         VERTEX4 = 0x01C4,
38         COLOR3 = 0x05C3,
39         COLOR4 = 0x05C4,
40         NORMAL3 = 0x09C3,
41         TANGENT3 = 0x0DC3,
42         GROUP1 = 0x11C1,
43         GROUP2 = 0x11C2,
44         GROUP3 = 0x11C3,
45         GROUP4 = 0x11C4,
46         WEIGHT1 = 0x15C1,
47         WEIGHT2 = 0x15C2,
48         WEIGHT3 = 0x15C3,
49         WEIGHT4 = 0x15C4,
50         TEXCOORD1 = 0x19C1,
51         TEXCOORD2 = 0x19C2,
52         TEXCOORD3 = 0x19C3,
53         TEXCOORD4 = 0x19C4,
54         GENERIC1 = 0x29C1,
55         GENERIC2 = 0x29C2,
56         GENERIC3 = 0x29C3,
57         GENERIC4 = 0x29C4,
58         RAW_ATTRIB1 = 0xFDC1,
59         RAW_ATTRIB2 = 0xFDC2,
60         RAW_ATTRIB3 = 0xFDC3,
61         RAW_ATTRIB4 = 0xFDC4
62 };
63
64 class VertexFormat
65 {
66 private:
67         enum { MAX_ATTRIBUTES = 15 };
68
69         UInt8 count;
70         UInt16 attributes[MAX_ATTRIBUTES];
71
72 public:
73         VertexFormat();
74         VertexFormat(VertexAttribute);
75
76         VertexFormat operator,(VertexAttribute) const;
77         VertexFormat operator,(DataType) const;
78         VertexFormat operator,(unsigned) const;
79         bool operator==(const VertexFormat &) const;
80         bool operator!=(const VertexFormat &other) const { return !(*this==other); }
81
82         bool empty() const { return !count; }
83         const UInt16 *begin() const { return attributes; }
84         const UInt16 *end() const { return attributes+count; }
85         unsigned stride() const;
86         int offset(VertexAttribute) const;
87 };
88
89 inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
90 { return (VertexFormat(a1), a2); }
91
92 VertexAttribute make_typed_attribute(VertexAttribute, DataType);
93
94 inline VertexAttribute operator,(VertexAttribute a, DataType t)
95 { return make_typed_attribute(a, t); }
96
97 VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
98
99 inline VertexAttribute operator,(VertexAttribute a, unsigned i)
100 { return make_indexed_attribute(a, i); }
101
102 inline unsigned get_attribute_semantic(UInt16 a)
103 { return a>>10; }
104
105 inline DataType get_attribute_source_type(UInt16 a)
106 { return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
107
108 inline unsigned get_attribute_component_count(UInt16 a)
109 { return a&7; }
110
111 inline unsigned get_attribute_size(UInt16 a)
112 { return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
113
114 void operator>>(const LexicalConverter &, VertexAttribute &);
115
116 } // namespace GL
117 } // namespace Msp
118
119 #endif