]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/vertexformat.h
Add support for padding in vertex formats
[libs/gl.git] / source / core / vertexformat.h
index c7a2fcf166ef28d468289891db3ca9a82ab31e9b..fba206e4386e978674a2d5e6bbc7cc33c9d2119e 100644 (file)
@@ -1,13 +1,15 @@
 #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 attribute.  Commonly used attributes are named by their
+/**
+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
@@ -15,90 +17,129 @@ 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. */
-enum VertexAttribute
+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,
-       COLOR4_UBYTE = 8,
-       COLOR3_FLOAT = 10,
-       COLOR4_FLOAT,
-       NORMAL3 = 18,
-       TANGENT3 = 26,
-       GROUP1 = 32,
-       GROUP2,
-       GROUP3,
-       GROUP4,
-       WEIGHT1 = 40,
-       WEIGHT2,
-       WEIGHT3,
-       WEIGHT4,
-       TEXCOORD1 = 48,
-       TEXCOORD2,
-       TEXCOORD3,
-       TEXCOORD4,
-       GENERIC1 = 80,
-       GENERIC2,
-       GENERIC3,
-       GENERIC4,
-       RAW_ATTRIB1 = 248,
-       RAW_ATTRIB2,
-       RAW_ATTRIB3,
-       RAW_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,
+       PADDING1 = 0xF811,
+       PADDING2 = 0xF812,
+       PADDING3 = 0xF813,
+       PADDING4 = 0xF814,
+       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 };
+public:
+       static constexpr unsigned MAX_ATTRIBUTES = 15;
 
-       unsigned char count;
-       unsigned char attributes[MAX_ATTRIBUTES];
+private:
+       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>>3; }
+inline unsigned get_attribute_semantic(VertexAttribute a)
+{ return a>>10; }
+
+inline DataType get_attribute_source_type(VertexAttribute a)
+{ return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
 
-inline unsigned get_attribute_size(unsigned char a)
-{ return (a&3)+1; }
+inline unsigned get_attribute_component_count(VertexAttribute a)
+{ return a&7; }
 
-DEPRECATED inline unsigned get_component_type(unsigned char c)
-{ return get_attribute_semantic(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_component_size(unsigned char c)
-{ return get_attribute_size(c); }
+inline bool is_integer_attribute(VertexAttribute a)
+{ return a&8; }
 
-DEPRECATED inline unsigned get_stride(const VertexFormat &f)
-{ return f.stride(); }
+inline bool is_padding(VertexAttribute a)
+{ return get_attribute_semantic(a)==get_attribute_semantic(PADDING1); }
 
 void operator>>(const LexicalConverter &, VertexAttribute &);