X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fvertexformat.h;h=d5835013b53a925584bbfa8055a663f1f1382ed4;hb=df9119a9bf2d348a513c515ed92953353da97b54;hp=3561292245fc640deb2859629cbf8f39c1776e5b;hpb=7aaec9a70b8d7733429bec043f8e33e02956f266;p=libs%2Fgl.git diff --git a/source/core/vertexformat.h b/source/core/vertexformat.h index 35612922..d5835013 100644 --- a/source/core/vertexformat.h +++ b/source/core/vertexformat.h @@ -1,77 +1,139 @@ #ifndef MSP_GL_VERTEXFORMAT_H_ #define MSP_GL_VERTEXFORMAT_H_ +#include #include +#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 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 }; +/** +Describes the attributes of a vertex. Up to 15 attributes are allowed. +*/ class VertexFormat { private: - enum { MAX_COMPONENTS = 15 }; + enum { MAX_ATTRIBUTES = 15 }; - unsigned char count; - unsigned char components[MAX_COMPONENTS]; + std::uint8_t count = 0; + VertexAttribute attributes[MAX_ATTRIBUTES]; public: - VertexFormat(); - VertexFormat(VertexComponent); + VertexFormat() = default; + 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 VertexAttribute *begin() const { return attributes; } + const VertexAttribute *end() const { return attributes+count; } + + /** Returns the displacement from one vertex to the next. */ unsigned stride() const; - int offset(VertexComponent) 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,(VertexComponent c1, VertexComponent c2) -{ return (VertexFormat(c1), c2); } +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 VertexFormat operator,(VertexComponent c, unsigned i) -{ return (VertexFormat(c), i); } +inline unsigned get_attribute_semantic(VertexAttribute a) +{ return a>>10; } -VertexComponent make_indexed_component(VertexComponent, unsigned); +inline DataType get_attribute_source_type(VertexAttribute a) +{ return static_cast((a&0x70)>>4 | (a&0x180)<<1); } -inline unsigned get_component_type(unsigned char c) -{ return c>>2; } +inline unsigned get_attribute_component_count(VertexAttribute a) +{ return a&7; } -inline unsigned get_component_size(unsigned char c) -{ return (c&3)+1; } +inline unsigned get_attribute_size(VertexAttribute a) +{ return get_attribute_component_count(a)*get_type_size(get_attribute_source_type(a)); } -inline unsigned get_stride(const VertexFormat &f) -{ return f.stride(); } +inline bool is_integer_attribute(VertexAttribute a) +{ return a&8; } -void operator>>(const LexicalConverter &, VertexComponent &); +void operator>>(const LexicalConverter &, VertexAttribute &); } // namespace GL } // namespace Msp