X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fvertexformat.cpp;h=e56397e2b088cb93a1204d80027ef875b1c91a73;hb=b617c5d7b5283ad260a77f01e42e6170cabbc03d;hp=25c2b02313e43c3d5b14d64c4ed9136608551d6e;hpb=85facfb688035b5bbc9a3a87d080582fbf34930b;p=libs%2Fgl.git diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 25c2b023..e56397e2 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -1,65 +1,176 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2010 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include +#include +#include "except.h" #include "vertexformat.h" +using namespace std; + namespace Msp { namespace GL { -uint get_stride(VertexFormat f) +VertexFormat::VertexFormat(): + data(0) +{ } + +VertexFormat::VertexFormat(VertexComponent c): + data(new unsigned char[8]) +{ + data[0] = 1; + data[1] = c; +} + +VertexFormat::VertexFormat(const VertexFormat &f): + data(0) +{ + if(f.data) + { + data = new unsigned char[f.data[0]/8+8]; + memcpy(data, f.data, f.data[0]+1); + } +} + +VertexFormat &VertexFormat::operator=(const VertexFormat &f) +{ + delete[] data; + if(f.data) + { + data = new unsigned char[f.data[0]/8+8]; + memcpy(data, f.data, f.data[0]+1); + } + else + data = 0; + + return *this; +} + +VertexFormat::~VertexFormat() +{ + delete[] data; +} + +unsigned VertexFormat::stride() const { - uint stride=0; - for(uint fmt=f; fmt; fmt>>=4) - stride+=(fmt&3)+1; - return stride*sizeof(float); + unsigned s = 0; + for(const unsigned char *i=begin(); i!=end(); ++i) + s += (*i&3)+1; + return s; } -std::istream &operator>>(std::istream &in, VertexFormat &f) +VertexFormat operator,(const VertexFormat &f, VertexComponent c) { - std::string str; + VertexFormat r = f; + if(r.data) + { + const unsigned char n = ++r.data[0]; + if((n&7)==7) + { + unsigned char *newdt = new unsigned char[n+9]; + memcpy(newdt, r.data, n); + delete r.data; + r.data = newdt; + } + r.data[n] = c; + } + else + { + r.data = new unsigned char[8]; + r.data[0] = 1; + r.data[1] = c; + } + + return r; +} + +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; + + return r; +} + +istream &operator>>(istream &in, VertexFormat &f) +{ + string str; in>>str; - unsigned start=0; - unsigned comma; - f=NODATA; + unsigned start = 0; while(1) { - comma=str.find(',', start); - if(str.compare(start, comma-start, "VERTEX2")) - f=f,VERTEX2; - else if(str.compare(start, comma-start, "VERTEX3")) - f=f,VERTEX3; - else if(str.compare(start, comma-start, "VERTEX4")) - f=f,VERTEX4; - else if(str.compare(start, comma-start, "NORMAL3")) - f=f,NORMAL3; - else if(str.compare(start, comma-start, "TEXCOORD1")) - f=f,TEXCOORD1; - else if(str.compare(start, comma-start, "TEXCOORD2")) - f=f,TEXCOORD2; - else if(str.compare(start, comma-start, "TEXCOORD3")) - f=f,TEXCOORD3; - else if(str.compare(start, comma-start, "TEXCOORD4")) - f=f,TEXCOORD4; - else if(str.compare(start, comma-start, "COLOR4_UBYTE")) - f=f,COLOR4_UBYTE; - else if(str.compare(start, comma-start, "COLOR3_FLOAT")) - f=f,COLOR3_FLOAT; - else if(str.compare(start, comma-start, "COLOR4_FLOAT")) - f=f,COLOR4_FLOAT; + string::size_type 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")) + { + 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; + } + } else + fail = true; + + if(fail) { - in.setstate(std::ios_base::failbit); + in.setstate(ios_base::failbit); break; } - start=comma+1; - if(comma==std::string::npos) + + if(underscore==string::npos) break; + start = underscore+1; } return in;