X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fvertexformat.cpp;h=91084bcc273e0bff6524746b22372a10d7b88eee;hb=bc3c82a86eeadde54be9fe32a8a8a76872ca99c3;hp=5c02f2ab3aec7180f2a40a4a12b225bbe8ae5c38;hpb=f71aee8c20ff85e4857e4dfad0c20ce606ea3717;p=libs%2Fgl.git diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 5c02f2ab..91084bcc 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -1,21 +1,105 @@ /* $Id$ This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions +Copyright © 2007-2009 Mikko Rasa, Mikkosoft Productions Distributed under the LGPL */ +#include +#include +#include "except.h" #include "vertexformat.h" 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; +} + +VertexFormat operator,(const VertexFormat &f, VertexComponent c) +{ + 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; +} + +uint get_stride(const VertexFormat &f) { uint stride=0; - for(uint fmt=f; fmt; fmt>>=4) - stride+=(fmt&3)+1; - return stride*sizeof(float); + 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) @@ -24,11 +108,11 @@ std::istream &operator>>(std::istream &in, VertexFormat &f) in>>str; unsigned start=0; - f=NODATA; while(1) { 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")) @@ -51,7 +135,32 @@ std::istream &operator>>(std::istream &in, VertexFormat &f) 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); break;