X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fvertexformat.cpp;h=f5e175714187a9eb5a853abc9ba84aa3728864a9;hp=91084bcc273e0bff6524746b22372a10d7b88eee;hb=f14435e58bfa0fa697a06ba9a454bb30cd37d9d8;hpb=bc3c82a86eeadde54be9fe32a8a8a76872ca99c3 diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 91084bcc..f5e17571 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -1,15 +1,11 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - #include #include +#include #include "except.h" #include "vertexformat.h" +using namespace std; + namespace Msp { namespace GL { @@ -20,8 +16,8 @@ VertexFormat::VertexFormat(): VertexFormat::VertexFormat(VertexComponent c): data(new unsigned char[8]) { - data[0]=1; - data[1]=c; + data[0] = 1; + data[1] = c; } VertexFormat::VertexFormat(const VertexFormat &f): @@ -29,7 +25,7 @@ VertexFormat::VertexFormat(const VertexFormat &f): { if(f.data) { - data=new unsigned char[f.data[0]/8+8]; + data = new unsigned char[(f.data[0]&~7)+8]; memcpy(data, f.data, f.data[0]+1); } } @@ -39,11 +35,11 @@ VertexFormat &VertexFormat::operator=(const VertexFormat &f) delete[] data; if(f.data) { - data=new unsigned char[f.data[0]/8+8]; + data = new unsigned char[(f.data[0]&~7)+8]; memcpy(data, f.data, f.data[0]+1); } else - data=0; + data = 0; return *this; } @@ -53,26 +49,58 @@ VertexFormat::~VertexFormat() delete[] data; } +unsigned VertexFormat::stride() const +{ + unsigned s = 0; + for(const unsigned char *i=begin(); i!=end(); ++i) + s += (*i&3)+1; + return s; +} + +int VertexFormat::offset(VertexComponent comp, unsigned index) const +{ + if((comp0) || (comp=8) || index>=53) + throw InvalidParameterValue("Vertex component index out of range"); + + unsigned type = (comp>>2)+index; + unsigned size = comp&3; + unsigned offs = 0; + for(const unsigned char *i=begin(); i!=end(); ++i) + { + if(static_cast(*i>>2)==type) + { + if((*i&3)>=size) + return offs; + else + return -1; + } + else + offs += (*i&3)+1; + } + + return -1; +} + VertexFormat operator,(const VertexFormat &f, VertexComponent c) { - VertexFormat r=f; + VertexFormat r = f; if(r.data) { - const unsigned char n=++r.data[0]; + const unsigned char n = ++r.data[0]; if((n&7)==7) { - unsigned char *newdt=new unsigned char[n+9]; + unsigned char *newdt = new unsigned char[n+9]; memcpy(newdt, r.data, n); delete r.data; - r.data=newdt; + r.data = newdt; } - r.data[n]=c; + r.data[n] = c; } else { - r.data=new unsigned char[8]; - r.data[0]=1; - r.data[1]=c; + r.data = new unsigned char[8]; + r.data[0] = 1; + r.data[1] = c; } return r; @@ -82,96 +110,70 @@ VertexFormat operator,(const VertexFormat &f, unsigned i) { if(!f.data) throw InvalidState("VertexFormat has no components"); - VertexFormat r=f; - unsigned char *c=r.data+r.data[0]; - if(*c=28) - throw InvalidParameterValue("Generic attribute index out of range"); - *c+=i*4; + VertexFormat r = f; + unsigned char *c = r.data+r.data[0]; + if((*c0) || (*c=8) || i>=53) + throw InvalidParameterValue("Vertex component index out of range"); + *c += i*4; return r; } -uint get_stride(const VertexFormat &f) +void operator>>(const LexicalConverter &conv, VertexComponent &c) { - uint stride=0; - for(const unsigned char *i=f.begin(); i!=f.end(); ++i) - stride+=(*i&3)+1; - return stride; -} - -std::istream &operator>>(std::istream &in, VertexFormat &f) -{ - std::string str; - in>>str; - - unsigned start=0; - - while(1) + const string &str = conv.get(); + if(str.size()==7 && !str.compare(0, 6, "VERTEX") && str[6]>='2' && str[6]<='4') + c = static_cast(VERTEX2+(str[6]-'2')); + else if(str=="NORMAL3") + c = 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(COLOR3_FLOAT+(str[5]-'3')); + else if(str=="COLOR4_UBYTE") + c = COLOR4_UBYTE; + else if(str.size()>=9 && !str.compare(0, 8, "TEXCOORD") && str[8]>='1' && str[8]<='4') + { + if(str.size()==9) + c = static_cast(TEXCOORD1+(str[8]-'1')); + else if(str.size()==11 && str[9]=='_' && str[10]>='0' && str[10]<='7') + c = static_cast(TEXCOORD1+(str[8]-'1')+(str[10]-'0')*4); + else + throw LexicalError("Invalid texture unit in VertexComponent conversion"); + } + else if(str.size()>=9 && !str.compare(0, 6, "ATTRIB") && str[6]>='1' && str[6]<='4' && str[7]=='_') { - unsigned underscore=str.find('_', start); - bool fail=false; - if(!str.compare(start, underscore-start, "VERTEX2")) - f=(f,VERTEX2); - else if(!str.compare(start, underscore-start, "VERTEX3")) - f=(f,VERTEX3); - else if(!str.compare(start, underscore-start, "VERTEX4")) - f=(f,VERTEX4); - else if(!str.compare(start, underscore-start, "NORMAL3")) - f=(f,NORMAL3); - else if(!str.compare(start, underscore-start, "TEXCOORD1")) - f=(f,TEXCOORD1); - else if(!str.compare(start, underscore-start, "TEXCOORD2")) - f=(f,TEXCOORD2); - else if(!str.compare(start, underscore-start, "TEXCOORD3")) - f=(f,TEXCOORD3); - else if(!str.compare(start, underscore-start, "TEXCOORD4")) - f=(f,TEXCOORD4); - else if(!str.compare(start, underscore-start, "COLOR4UB")) - f=(f,COLOR4_UBYTE); - else if(!str.compare(start, underscore-start, "COLOR3F")) - f=(f,COLOR3_FLOAT); - else if(!str.compare(start, underscore-start, "COLOR4F")) - f=(f,COLOR4_FLOAT); - else if(underscore>=start+8 && !str.compare(start, 6, "ATTRIB")) + unsigned n; + try { - try - { - char n=str[start+6]; - unsigned i=lexical_cast(str.substr(start+7, underscore-start-7)); - if(n=='1') - f=(f,ATTRIB1,i); - else if(n=='2') - f=(f,ATTRIB2,i); - else if(n=='3') - f=(f,ATTRIB3,i); - else if(n=='4') - f=(f,ATTRIB4,i); - else - fail=true; - } - catch(const LexicalError &) - { - fail=true; - } + n = lexical_cast(str.substr(8)); } - else - fail=true; - - if(fail) + catch(const LexicalError &) { - in.setstate(std::ios_base::failbit); - break; + throw LexicalError("Invalid attribute in VertexComponent conversion"); } + c = static_cast(ATTRIB1+(str[6]-'1')+n*4); + } + else + throw LexicalError("Invalid input in VertexComponent conversion"); +} - if(underscore==std::string::npos) - break; - start=underscore+1; +// XXX This will go away eventually +void operator>>(const LexicalConverter &conv, VertexFormat &f) +{ + vector parts = split(conv.get(), '_'); + for(vector::iterator i=parts.begin(); i!=parts.end(); ++i) + { + if(*i=="COLOR4UB") + *i = "COLOR4_UBYTE"; + else if(i->size()==7 && !i->compare(0, 5, "COLOR") && (*i)[6]=='F') + *i = i->substr(0, 6)+"_FLOAT"; + else if(i->size()>=10 && !i->compare(0, 8, "TEXCOORD")) + *i = i->substr(0, 9)+"_"+i->substr(9); + else if(i->size()>=8 && !i->compare(0, 6, "ATTRIB")) + *i = i->substr(0, 7)+"_"+i->substr(7); } - return in; + for(vector::iterator i=parts.begin(); i!=parts.end(); ++i) + f = (f, lexical_cast(*i)); } } // namespace GL