]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/vertexformat.h
Make VertexFormat capable of storing type information
[libs/gl.git] / source / core / vertexformat.h
index 4c485b0423b9568a89b07b5ba164586b94dfa1fc..a503aff83f84f19bcbbb1d9e3009c77fd526d4bb 100644 (file)
@@ -1,7 +1,9 @@
 #ifndef MSP_GL_VERTEXFORMAT_H_
 #define MSP_GL_VERTEXFORMAT_H_
 
+#include <msp/core/inttypes.h>
 #include <msp/strings/lexicalcast.h>
+#include "datatype.h"
 
 namespace Msp {
 namespace GL {
@@ -14,37 +16,49 @@ 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. */
+are doing.
+
+The values are bitfields laid as follows:
+
+nnnn nn_f gsss _ccc
+      │ │ │  │    └╴Number of components
+      │ │ │  └─────╴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 programs to rely on it.
+*/
 enum VertexAttribute
 {
-       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 = 0x11C1,
+       GROUP2 = 0x11C2,
+       GROUP3 = 0x11C3,
+       GROUP4 = 0x11C4,
+       WEIGHT1 = 0x15C1,
+       WEIGHT2 = 0x15C2,
+       WEIGHT3 = 0x15C3,
+       WEIGHT4 = 0x15C4,
+       TEXCOORD1 = 0x19C1,
+       TEXCOORD2 = 0x19C2,
+       TEXCOORD3 = 0x19C3,
+       TEXCOORD4 = 0x19C4,
+       GENERIC1 = 0x29C1,
+       GENERIC2 = 0x29C2,
+       GENERIC3 = 0x29C3,
+       GENERIC4 = 0x29C4,
+       RAW_ATTRIB1 = 0xFDC1,
+       RAW_ATTRIB2 = 0xFDC2,
+       RAW_ATTRIB3 = 0xFDC3,
+       RAW_ATTRIB4 = 0xFDC4
 };
 
 class VertexFormat
@@ -52,21 +66,22 @@ class VertexFormat
 private:
        enum { MAX_ATTRIBUTES = 15 };
 
-       unsigned char count;
-       unsigned char attributes[MAX_ATTRIBUTES];
+       UInt8 count;
+       UInt16 attributes[MAX_ATTRIBUTES];
 
 public:
        VertexFormat();
        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 UInt16 *begin() const { return attributes; }
+       const UInt16 *end() const { return attributes+count; }
        unsigned stride() const;
        int offset(VertexAttribute) const;
 };
@@ -74,16 +89,27 @@ public:
 inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
 { return (VertexFormat(a1), a2); }
 
+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);
 
 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(UInt16 a)
+{ return a>>10; }
+
+inline DataType get_attribute_source_type(UInt16 a)
+{ return static_cast<DataType>((a&0x70)>>4 | (a&0x180)<<1); }
+
+inline unsigned get_attribute_component_count(UInt16 a)
+{ return a&7; }
 
-inline unsigned get_attribute_size(unsigned char a)
-{ return (a&3)+1; }
+inline unsigned get_attribute_size(UInt16 a)
+{ return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
 
 void operator>>(const LexicalConverter &, VertexAttribute &);