void PrimitiveBuilder::vertex_(const Vector4 &v)
{
const VertexFormat &format = array.get_format();
- for(const unsigned char *c=format.begin(); c!=format.end(); ++c)
+ for(const unsigned char *a=format.begin(); a!=format.end(); ++a)
{
- unsigned t = get_component_type(*c);
- if(t<attr.size())
- vab.attrib(t, attr[t]);
+ unsigned sem = get_attribute_semantic(*a);
+ if(sem<attr.size())
+ vab.attrib(sem, attr[sem]);
}
vab.vertex(v);
{
float *ptr = array.append();
const VertexFormat &format = array.get_format();
- for(const unsigned char *c=format.begin(); c!=format.end(); ++c)
+ for(const unsigned char *a=format.begin(); a!=format.end(); ++a)
{
- unsigned sz = get_component_size(*c);
- unsigned t = get_component_type(*c);
- if(t>=attr.size())
+ unsigned sem = get_attribute_semantic(*a);
+ unsigned sz = get_attribute_size(*a);
+ if(sem>=attr.size())
ptr += sz;
- else if(*c==COLOR4_UBYTE)
+ else if(*a==COLOR4_UBYTE)
{
union { unsigned char c[4]; float f; } u;
- u.c[0] = static_cast<unsigned char>(attr[t].x*255);
- u.c[1] = static_cast<unsigned char>(attr[t].y*255);
- u.c[2] = static_cast<unsigned char>(attr[t].z*255);
- u.c[3] = static_cast<unsigned char>(attr[t].w*255);
+ u.c[0] = static_cast<unsigned char>(attr[sem].x*255);
+ u.c[1] = static_cast<unsigned char>(attr[sem].y*255);
+ u.c[2] = static_cast<unsigned char>(attr[sem].z*255);
+ u.c[3] = static_cast<unsigned char>(attr[sem].w*255);
*ptr++ = u.f;
}
else
{
- const Vector4 &v = (t==0 ? vtx : attr[t]);
+ const Vector4 &v = (sem==0 ? vtx : attr[sem]);
*ptr++ = v.x;
if(sz>=2) *ptr++ = v.y;
if(sz>=3) *ptr++ = v.z;
{ normal(Vector3(x, y, z)); }
void normal(const Vector3 &n)
- { attrib(get_component_type(NORMAL3), mtx*Vector4(n.x, n.y, n.z, 0)); }
+ { attrib(get_attribute_semantic(NORMAL3), mtx*Vector4(n.x, n.y, n.z, 0)); }
void tangent(float x, float y, float z)
{ tangent(Vector3(x, y, z)); }
void tangent(const Vector3 &t)
- { attrib(get_component_type(TANGENT3), mtx*Vector4(t.x, t.y, t.z, 0)); }
+ { attrib(get_attribute_semantic(TANGENT3), mtx*Vector4(t.x, t.y, t.z, 0)); }
void binormal(float x, float y, float z)
{ binormal(Vector3(x, y, z)); }
void binormal(const Vector3 &b)
- { attrib(get_component_type(BINORMAL3), mtx*Vector4(b.x, b.y, b.z, 0)); }
+ { attrib(get_attribute_semantic(BINORMAL3), mtx*Vector4(b.x, b.y, b.z, 0)); }
void texcoord(float s)
{ texcoord(s, 0, 0, 1); }
{ multitexcoord(i, Vector4(s, t, r, q)); }
void multitexcoord(unsigned i, const Vector4 &t)
- { attrib(get_component_type(TEXCOORD4)+i, t); }
+ { attrib(get_attribute_semantic(TEXCOORD4)+i, t); }
void color(unsigned char r, unsigned char g, unsigned char b)
{ color(r, g, b, 255); }
{ color(Color(r, g, b, a)); }
void color(const Color &c)
- { attrib(get_component_type(COLOR4_FLOAT), Vector4(c.r, c.g, c.b, c.a)); }
+ { attrib(get_attribute_semantic(COLOR4_FLOAT), Vector4(c.r, c.g, c.b, c.a)); }
void attrib(unsigned i, float x)
{ attrib(i, x, 0, 0, 1); }
add("winding", &Loader::winding);
}
-void Mesh::Loader::vertices(const vector<VertexComponent> &c)
+void Mesh::Loader::vertices(const vector<VertexAttribute> &a)
{
- if(c.empty())
- throw invalid_argument("No vertex components");
+ if(a.empty())
+ throw invalid_argument("No vertex attributes");
VertexFormat fmt;
- for(vector<VertexComponent>::const_iterator i=c.begin(); i!=c.end(); ++i)
+ for(vector<VertexAttribute>::const_iterator i=a.begin(); i!=a.end(); ++i)
fmt = (fmt, *i);
obj.vertices.reset(fmt);
load_sub(obj.vertices);
public:
Loader(Mesh &, bool = true);
private:
- void vertices(const std::vector<VertexComponent> &);
+ void vertices(const std::vector<VertexAttribute> &);
void batch(PrimitiveType);
void winding(FaceWinding);
};
glBindAttribLocation(id, index, name.c_str());
}
-void Program::bind_attribute(VertexComponent comp, const string &name)
+void Program::bind_attribute(VertexAttribute attr, const string &name)
{
- bind_attribute(get_component_type(comp), name);
+ bind_attribute(get_attribute_semantic(attr), name);
}
void Program::bind_fragment_data(unsigned index, const string &name)
DEPRECATED const std::vector<Shader *> &get_attached_shaders() const;
DEPRECATED void bind_attribute(unsigned, const std::string &);
- DEPRECATED void bind_attribute(VertexComponent, const std::string &);
+ DEPRECATED void bind_attribute(VertexAttribute, const std::string &);
DEPRECATED void bind_fragment_data(unsigned, const std::string &);
void link();
{
clear();
format = f;
- stride = get_stride(format);
+ stride = format.stride();
}
void VertexArray::clear()
count(0)
{ }
-VertexFormat::VertexFormat(VertexComponent c):
+VertexFormat::VertexFormat(VertexAttribute a):
count(1)
{
- components[0] = c;
+ attributes[0] = a;
}
-VertexFormat VertexFormat::operator,(VertexComponent c) const
+VertexFormat VertexFormat::operator,(VertexAttribute a) const
{
- if(count>=MAX_COMPONENTS)
+ if(count>=MAX_ATTRIBUTES)
throw invalid_operation("VertexFormat::operator,");
VertexFormat r = *this;
- r.components[r.count++] = c;
+ r.attributes[r.count++] = a;
return r;
}
throw invalid_operation("VertexFormat::operator,");
VertexFormat r = *this;
- unsigned char *c = &r.components[r.count-1];
- *c = make_indexed_component(static_cast<VertexComponent>(*c), i);
+ unsigned char &a = r.attributes[r.count-1];
+ a = make_indexed_attribute(static_cast<VertexAttribute>(a), i);
return r;
}
{
if(count!=other.count)
return false;
- return equal(components, components+count, other.components);
+ return equal(attributes, attributes+count, other.attributes);
}
unsigned VertexFormat::stride() const
{
unsigned s = 0;
for(const unsigned char *i=begin(); i!=end(); ++i)
- s += get_component_size(*i);
+ s += get_attribute_size(*i);
return s;
}
-int VertexFormat::offset(VertexComponent comp) const
+int VertexFormat::offset(VertexAttribute attr) const
{
- unsigned type = get_component_type(comp);
- unsigned size = get_component_size(comp);
+ unsigned sem = get_attribute_semantic(attr);
+ unsigned sz = get_attribute_size(attr);
unsigned offs = 0;
for(const unsigned char *i=begin(); i!=end(); ++i)
{
- if(get_component_type(*i)==type)
+ if(get_attribute_semantic(*i)==sem)
{
- if(get_component_size(*i)>=size)
+ if(get_attribute_size(*i)>=sz)
return offs;
else
return -1;
}
else
- offs += get_component_size(*i);
+ offs += get_attribute_size(*i);
}
return -1;
}
-VertexComponent make_indexed_component(VertexComponent comp, unsigned index)
+
+VertexAttribute make_indexed_attribute(VertexAttribute attr, unsigned index)
{
- if(comp>=TEXCOORD1 && comp<=TEXCOORD4)
+ if(attr>=TEXCOORD1 && attr<=TEXCOORD4)
{
if(index>=4)
- throw out_of_range("make_indexed_component");
+ throw out_of_range("make_indexed_attribute");
}
- else if(comp>=ATTRIB1 && comp<=ATTRIB4)
+ else if(attr>=ATTRIB1 && attr<=ATTRIB4)
{
if(index>=24)
- throw out_of_range("make_indexed_component");
+ throw out_of_range("make_indexed_attribute");
}
else
- throw invalid_argument("make_indexed_component");
- return static_cast<VertexComponent>(comp+index*4);
+ throw invalid_argument("make_indexed_attribute");
+ return static_cast<VertexAttribute>(attr+index*4);
}
-void operator>>(const LexicalConverter &conv, VertexComponent &c)
+void operator>>(const LexicalConverter &conv, VertexAttribute &a)
{
const string &str = conv.get();
if(str.size()==7 && !str.compare(0, 6, "VERTEX") && str[6]>='2' && str[6]<='4')
- c = static_cast<VertexComponent>(VERTEX2+(str[6]-'2'));
+ a = static_cast<VertexAttribute>(VERTEX2+(str[6]-'2'));
else if(str=="NORMAL3")
- c = NORMAL3;
+ a = NORMAL3;
else if(str.size()==12 && !str.compare(0, 5, "COLOR") && str[5]>='3' && str[5]<='4' && !str.compare(6, 6, "_FLOAT"))
- c = static_cast<VertexComponent>(COLOR3_FLOAT+(str[5]-'3'));
+ a = static_cast<VertexAttribute>(COLOR3_FLOAT+(str[5]-'3'));
else if(str=="COLOR4_UBYTE")
- c = COLOR4_UBYTE;
+ a = COLOR4_UBYTE;
else if(str=="TANGENT3")
- c = TANGENT3;
+ a = TANGENT3;
else if(str=="BINORMAL3")
- c = BINORMAL3;
+ a = BINORMAL3;
else if(str.size()>=9 && !str.compare(0, 8, "TEXCOORD") && str[8]>='1' && str[8]<='4')
{
if(str.size()==9)
- c = static_cast<VertexComponent>(TEXCOORD1+(str[8]-'1'));
+ a = static_cast<VertexAttribute>(TEXCOORD1+(str[8]-'1'));
else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='7')
- c = static_cast<VertexComponent>(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4);
+ a = static_cast<VertexAttribute>(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4);
else
- throw lexical_error(format("conversion of '%s' to VertexComponent", str));
+ throw lexical_error(format("conversion of '%s' to VertexAttribute", str));
}
else if(str.size()>=9 && !str.compare(0, 6, "ATTRIB") && str[6]>='1' && str[6]<='4' && str[7]=='_')
{
}
catch(const lexical_error &)
{
- throw lexical_error(format("conversion of '%s' to VertexComponent", str));
+ throw lexical_error(format("conversion of '%s' to VertexAttribute", str));
}
- c = static_cast<VertexComponent>(ATTRIB1+(str[6]-'1')+n*4);
+ a = static_cast<VertexAttribute>(ATTRIB1+(str[6]-'1')+n*4);
}
else
- throw lexical_error(format("conversion of '%s' to VertexComponent", str));
+ throw lexical_error(format("conversion of '%s' to VertexAttribute", str));
}
} // namespace GL
#ifndef MSP_GL_VERTEXFORMAT_H_
#define MSP_GL_VERTEXFORMAT_H_
+#include <msp/core/attributes.h>
#include <msp/strings/lexicalcast.h>
namespace Msp {
/** 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
+enum VertexAttribute
{
VERTEX2 = 1,
VERTEX3,
ATTRIB4
};
+DEPRECATED typedef VertexAttribute VertexComponent;
+
class VertexFormat
{
private:
- enum { MAX_COMPONENTS = 15 };
+ enum { MAX_ATTRIBUTES = 15 };
unsigned char count;
- unsigned char components[MAX_COMPONENTS];
+ unsigned char 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,(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 unsigned char *begin() const { return attributes; }
+ const unsigned char *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,(VertexAttribute a, unsigned i)
+{ return (VertexFormat(a), i); }
+
+VertexAttribute make_indexed_attribute(VertexAttribute, unsigned);
+
+DEPRECATED inline VertexAttribute make_indexed_component(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(unsigned char a)
+{ return a>>2; }
-VertexComponent make_indexed_component(VertexComponent, unsigned);
+inline unsigned get_attribute_size(unsigned char a)
+{ return (a&3)+1; }
-inline unsigned get_component_type(unsigned char c)
-{ return c>>2; }
+DEPRECATED inline unsigned get_component_type(unsigned char c)
+{ return get_attribute_semantic(c); }
-inline unsigned get_component_size(unsigned char c)
-{ return (c&3)+1; }
+DEPRECATED inline unsigned get_component_size(unsigned char c)
+{ return get_attribute_size(c); }
-inline unsigned get_stride(const VertexFormat &f)
+DEPRECATED inline unsigned get_stride(const VertexFormat &f)
{ return f.stride(); }
-void operator>>(const LexicalConverter &, VertexComponent &);
+void operator>>(const LexicalConverter &, VertexAttribute &);
} // namespace GL
} // namespace Msp
unsigned VertexSetup::get_attribs(const VertexFormat &fmt)
{
unsigned mask = 0;
- for(const unsigned char *c=fmt.begin(); c!=fmt.end(); ++c)
+ for(const unsigned char *a=fmt.begin(); a!=fmt.end(); ++a)
{
- unsigned t = get_component_type(*c);
- if(t>=get_component_type(ATTRIB1))
- t -= get_component_type(ATTRIB1);
- mask |= 1<<t;
+ unsigned sem = get_attribute_semantic(*a);
+ if(sem>=get_attribute_semantic(ATTRIB1))
+ sem -= get_attribute_semantic(ATTRIB1);
+ mask |= 1<<sem;
}
return mask;
}
Conditional<Bind> bind_vbuf(!direct, array.get_buffer(), ARRAY_BUFFER);
const VertexFormat &fmt = array.get_format();
- unsigned stride = get_stride(fmt)*sizeof(float);
+ unsigned stride = fmt.stride()*sizeof(float);
if(direct)
{
glVertexArrayVertexBuffer(id, binding, array.get_buffer()->get_id(), 0, stride);
}
unsigned offset = 0;
- for(const unsigned char *c=fmt.begin(); c!=fmt.end(); ++c)
+ for(const unsigned char *a=fmt.begin(); a!=fmt.end(); ++a)
{
- unsigned t = get_component_type(*c);
- if(t>=get_component_type(ATTRIB1))
- t -= get_component_type(ATTRIB1);
- unsigned sz = get_component_size(*c);
+ unsigned sem = get_attribute_semantic(*a);
+ if(sem>=get_attribute_semantic(ATTRIB1))
+ sem -= get_attribute_semantic(ATTRIB1);
+ unsigned sz = get_attribute_size(*a);
if(direct)
{
- if(*c==COLOR4_UBYTE)
- glVertexArrayAttribFormat(id, t, 4, GL_UNSIGNED_BYTE, true, offset);
+ if(*a==COLOR4_UBYTE)
+ glVertexArrayAttribFormat(id, sem, 4, GL_UNSIGNED_BYTE, true, offset);
else
- glVertexArrayAttribFormat(id, t, sz, GL_FLOAT, false, offset);
- glVertexArrayAttribBinding(id, t, binding);
- glEnableVertexArrayAttrib(id, t);
+ glVertexArrayAttribFormat(id, sem, sz, GL_FLOAT, false, offset);
+ glVertexArrayAttribBinding(id, sem, binding);
+ glEnableVertexArrayAttrib(id, sem);
}
else
{
- if(*c==COLOR4_UBYTE)
- glVertexAttribPointer(t, 4, GL_UNSIGNED_BYTE, true, stride, reinterpret_cast<unsigned char *>(offset));
+ if(*a==COLOR4_UBYTE)
+ glVertexAttribPointer(sem, 4, GL_UNSIGNED_BYTE, true, stride, reinterpret_cast<unsigned char *>(offset));
else
- glVertexAttribPointer(t, sz, GL_FLOAT, false, stride, reinterpret_cast<float *>(offset));
+ glVertexAttribPointer(sem, sz, GL_FLOAT, false, stride, reinterpret_cast<float *>(offset));
if(ARB_instanced_arrays)
- glVertexAttribDivisor(t, divisor);
- glEnableVertexAttribArray(t);
+ glVertexAttribDivisor(sem, divisor);
+ glEnableVertexAttribArray(sem);
}
offset += sz*sizeof(float);
}
{
instance_data = new VertexArray((ATTRIB4,matrix_location, ATTRIB4,matrix_location+1, ATTRIB4,matrix_location+2));
const VertexFormat &fmt = instance_data->get_format();
- matrix_offset = fmt.offset(make_indexed_component(ATTRIB4, matrix_location));
+ matrix_offset = fmt.offset(make_indexed_attribute(ATTRIB4, matrix_location));
instance_buffer = new Buffer(ARRAY_BUFFER);
instance_data->use_buffer(instance_buffer);