]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/vertexformat.h
Add support for integer vertex attributes
[libs/gl.git] / source / core / vertexformat.h
index 3561292245fc640deb2859629cbf8f39c1776e5b..132d0b95a88a0b36411b70a55ade9a48c5c19c15 100644 (file)
 #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 {
 
-/** 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 VertexComponent
+/** 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 programs to rely on it.
+*/
+enum VertexAttribute
 {
-       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 = 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,
+       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
 };
 
 class VertexFormat
 {
 private:
-       enum { MAX_COMPONENTS = 15 };
+       enum { MAX_ATTRIBUTES = 15 };
 
-       unsigned char count;
-       unsigned char components[MAX_COMPONENTS];
+       UInt8 count;
+       UInt16 attributes[MAX_ATTRIBUTES];
 
 public:
        VertexFormat();
-       VertexFormat(VertexComponent);
+       VertexFormat(VertexAttribute);
 
-       VertexFormat operator,(VertexComponent c) const;
-       VertexFormat operator,(unsigned i) const;
+       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 components; }
-       const unsigned char *end() const { return components+count; }
+       const UInt16 *begin() const { return attributes; }
+       const UInt16 *end() const { return attributes+count; }
        unsigned stride() const;
-       int offset(VertexComponent) const;
+       int offset(VertexAttribute) const;
 };
 
-inline VertexFormat operator,(VertexComponent c1, VertexComponent c2)
-{ return (VertexFormat(c1), c2); }
+inline VertexFormat operator,(VertexAttribute a1, VertexAttribute a2)
+{ return (VertexFormat(a1), a2); }
 
-inline VertexFormat operator,(VertexComponent c, unsigned i)
-{ return (VertexFormat(c), i); }
+VertexAttribute make_typed_attribute(VertexAttribute, DataType);
 
-VertexComponent make_indexed_component(VertexComponent, unsigned);
+inline VertexAttribute operator,(VertexAttribute a, DataType t)
+{ return make_typed_attribute(a, t); }
 
-inline unsigned get_component_type(unsigned char c)
-{ return c>>2; }
+VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
 
-inline unsigned get_component_size(unsigned char c)
-{ return (c&3)+1; }
+inline VertexAttribute operator,(VertexAttribute a, unsigned i)
+{ return make_indexed_attribute(a, i); }
 
-inline unsigned get_stride(const VertexFormat &f)
-{ return f.stride(); }
+inline unsigned get_attribute_semantic(UInt16 a)
+{ return a>>10; }
 
-void operator>>(const LexicalConverter &, VertexComponent &);
+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(UInt16 a)
+{ return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); }
+
+inline bool is_integer_attribute(UInt16 a)
+{ return a&8; }
+
+void operator>>(const LexicalConverter &, VertexAttribute &);
 
 } // namespace GL
 } // namespace Msp