#include <msp/strings/lexicalcast.h>
#include <msp/strings/utils.h>
#include "error.h"
+#include "misc.h"
#include "vertexformat.h"
+#include <msp/gl/extensions/arb_vertex_shader.h>
using namespace std;
VertexAttribute make_indexed_attribute(VertexAttribute attr, unsigned index)
{
+ unsigned base = attr;
if(attr>=TEXCOORD1 && attr<=TEXCOORD4)
{
if(index>=4)
throw out_of_range("make_indexed_attribute");
}
- else if(attr>=ATTRIB1 && attr<=ATTRIB4)
- {
- if(index>=24)
- throw out_of_range("make_indexed_attribute");
- }
- else
+ else if(attr>=RAW_ATTRIB1 && attr<=RAW_ATTRIB4)
+ base &= 7;
+ else if(attr<GENERIC1 || attr>GENERIC4)
throw invalid_argument("make_indexed_attribute");
- return static_cast<VertexAttribute>(attr+index*4);
+
+ static int max_attribs = -1;
+ if(max_attribs<0)
+ max_attribs = get_i(GL_MAX_VERTEX_ATTRIBS);
+
+ if(static_cast<int>((base>>3)+index)>=max_attribs)
+ throw out_of_range("make_indexed_attribute");
+
+ return static_cast<VertexAttribute>(base+index*8);
}
void operator>>(const LexicalConverter &conv, VertexAttribute &a)
{
if(str.size()==9)
a = static_cast<VertexAttribute>(TEXCOORD1+(str[8]-'1'));
- else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='7')
- a = static_cast<VertexAttribute>(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4);
+ else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='3')
+ a = make_indexed_attribute(static_cast<VertexAttribute>(TEXCOORD1+(str[8]-'1')), str[10]-'0');
else
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]=='_')
+ else if(str.size()>=10 && !str.compare(0, 6, "GENERIC") && str[7]>='1' && str[7]<='4' && str[8]=='_')
{
unsigned n;
try
{
- n = lexical_cast<unsigned>(str.substr(8));
+ n = lexical_cast<unsigned>(str.substr(9));
}
catch(const lexical_error &)
{
throw lexical_error(format("conversion of '%s' to VertexAttribute", str));
}
- a = static_cast<VertexAttribute>(ATTRIB1+(str[6]-'1')+n*4);
+ a = make_indexed_attribute(static_cast<VertexAttribute>(GENERIC1+(str[7]-'1')), n);
}
else
throw lexical_error(format("conversion of '%s' to VertexAttribute", str));