#ifndef MSP_GL_VERTEXFORMAT_H_
#define MSP_GL_VERTEXFORMAT_H_
-#include <msp/core/attributes.h>
+#include <cstdint>
#include <msp/strings/lexicalcast.h>
+#include "datatype.h"
namespace Msp {
namespace GL {
-/** A single vertex component. Symbolic names are provided for commonly used
-attributes. These are aliased with with generic attributes, so be careful when
-picking your attribute indices. */
-enum VertexAttribute
+/**
+A single vertex attribute. Commonly used attributes are named by their
+semantical meaning in the standard shaders. Texture coordinates and generic
+attributes can additionally be given an index. There are four texture
+coordinate attributes available. The number of available generic attributes
+depends on implementation limits, but is at least five.
+
+RAW_ATTRIB is handled in a special way; creating an indexed attribute based on
+it uses the index as raw attribute number. Only use it if you know what you
+are doing.
+
+The values are bitfields laid as follows:
+
+nnnn nn_f gsss iccc
+ │ │ │ │ │ └╴Number of components
+ │ │ │ │ └───╴Integer attribute flag
+ │ │ │ └─────╴Size of one component
+ │ │ └────────╴Signed flag
+ │ └──────────╴Floating-point flag
+ └────────────╴Attribute index (semantic)
+
+This information is presented for internal documentation purposes only; it is
+inadvisable for applications to rely on it.
+*/
+enum VertexAttribute: std::uint16_t
{
- VERTEX2 = 1,
- VERTEX3,
- VERTEX4,
- NORMAL3 = 10,
- COLOR4_UBYTE = 12,
- COLOR3_FLOAT = 14,
- COLOR4_FLOAT,
- TANGENT3 = 18,
- BINORMAL3 = 22,
- TEXCOORD1 = 32,
- TEXCOORD2,
- TEXCOORD3,
- TEXCOORD4,
- ATTRIB1 = 64,
- ATTRIB2,
- ATTRIB3,
- ATTRIB4
+ VERTEX2 = 0x01C2,
+ VERTEX3 = 0x01C3,
+ VERTEX4 = 0x01C4,
+ COLOR3 = 0x05C3,
+ COLOR4 = 0x05C4,
+ NORMAL3 = 0x09C3,
+ TANGENT3 = 0x0DC3,
+ GROUP1 = 0x10C9,
+ GROUP2 = 0x10CA,
+ GROUP3 = 0x10CB,
+ GROUP4 = 0x10CC,
+ WEIGHT1 = 0x15C1,
+ WEIGHT2 = 0x15C2,
+ WEIGHT3 = 0x15C3,
+ WEIGHT4 = 0x15C4,
+ TEXCOORD1 = 0x19C1,
+ TEXCOORD2 = 0x19C2,
+ TEXCOORD3 = 0x19C3,
+ TEXCOORD4 = 0x19C4,
+ GENERIC1 = 0x29C1,
+ GENERIC2 = 0x29C2,
+ GENERIC3 = 0x29C3,
+ GENERIC4 = 0x29C4,
+ GENERIC_I1 = 0x28C9,
+ GENERIC_I2 = 0x28CA,
+ GENERIC_I3 = 0x28CB,
+ GENERIC_I4 = 0x28CC,
+ RAW_ATTRIB1 = 0xFDC1,
+ RAW_ATTRIB2 = 0xFDC2,
+ RAW_ATTRIB3 = 0xFDC3,
+ RAW_ATTRIB4 = 0xFDC4,
+ RAW_ATTRIB_I1 = 0xFCC9,
+ RAW_ATTRIB_I2 = 0xFCCA,
+ RAW_ATTRIB_I3 = 0xFCCB,
+ RAW_ATTRIB_I4 = 0xFCCC
};
-DEPRECATED typedef VertexAttribute VertexComponent;
-
+/**
+Describes the attributes of a vertex. Up to 15 attributes are allowed.
+*/
class VertexFormat
{
private:
enum { MAX_ATTRIBUTES = 15 };
- unsigned char count;
- unsigned char attributes[MAX_ATTRIBUTES];
+ std::uint8_t count = 0;
+ VertexAttribute attributes[MAX_ATTRIBUTES];
public:
- VertexFormat();
+ VertexFormat() = default;
VertexFormat(VertexAttribute);
VertexFormat operator,(VertexAttribute) const;
+ VertexFormat operator,(DataType) const;
VertexFormat operator,(unsigned) const;
bool operator==(const VertexFormat &) const;
bool operator!=(const VertexFormat &other) const { return !(*this==other); }
bool empty() const { return !count; }
- const unsigned char *begin() const { return attributes; }
- const unsigned char *end() const { return attributes+count; }
+ const VertexAttribute *begin() const { return attributes; }
+ const VertexAttribute *end() const { return attributes+count; }
+
+ /** Returns the displacement from one vertex to the next. */
unsigned stride() const;
+
+ /** Returns the offset of an attribute within a vertex. A stored attribute
+ must have the same semantic and type and at least as many components as
+ requested to be considered a match. */
int offset(VertexAttribute) const;
};
inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
{ return (VertexFormat(a1), a2); }
-inline VertexFormat operator,(VertexAttribute a, unsigned i)
-{ return (VertexFormat(a), i); }
+VertexAttribute make_typed_attribute(VertexAttribute, DataType);
+
+inline VertexAttribute operator,(VertexAttribute a, DataType t)
+{ return make_typed_attribute(a, t); }
VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
-DEPRECATED inline VertexAttribute make_indexed_component(VertexAttribute a, unsigned i)
+inline VertexAttribute operator,(VertexAttribute a, unsigned i)
{ return make_indexed_attribute(a, i); }
-inline unsigned get_attribute_semantic(unsigned char a)
-{ return a>>2; }
+inline unsigned get_attribute_semantic(VertexAttribute a)
+{ return a>>10; }
-inline unsigned get_attribute_size(unsigned char a)
-{ return (a&3)+1; }
+inline DataType get_attribute_source_type(VertexAttribute a)
+{ return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
-DEPRECATED inline unsigned get_component_type(unsigned char c)
-{ return get_attribute_semantic(c); }
+inline unsigned get_attribute_component_count(VertexAttribute a)
+{ return a&7; }
-DEPRECATED inline unsigned get_component_size(unsigned char c)
-{ return get_attribute_size(c); }
+inline unsigned get_attribute_size(VertexAttribute a)
+{ return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
-DEPRECATED inline unsigned get_stride(const VertexFormat &f)
-{ return f.stride(); }
+inline bool is_integer_attribute(VertexAttribute a)
+{ return a&8; }
void operator>>(const LexicalConverter &, VertexAttribute &);