X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fvertexformat.cpp;h=037305f8d74251c9e6cd882540df733e292afc30;hp=25c2b02313e43c3d5b14d64c4ed9136608551d6e;hb=c5f011ef508d580f332e4bd6065a013b24de8840;hpb=85facfb688035b5bbc9a3a87d080582fbf34930b diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 25c2b023..037305f8 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -1,68 +1,133 @@ -/* $Id$ - -This file is part of libmspgl -Copyright © 2007 Mikko Rasa, Mikkosoft Productions -Distributed under the LGPL -*/ - +#include +#include +#include +#include +#include "error.h" #include "vertexformat.h" +using namespace std; + namespace Msp { namespace GL { -uint get_stride(VertexFormat f) +VertexFormat::VertexFormat(): + count(0) +{ } + +VertexFormat::VertexFormat(VertexComponent c): + count(1) { - uint stride=0; - for(uint fmt=f; fmt; fmt>>=4) - stride+=(fmt&3)+1; - return stride*sizeof(float); + components[0] = c; +} + +VertexFormat VertexFormat::operator,(VertexComponent c) const +{ + if(count>=MAX_COMPONENTS) + throw invalid_operation("VertexFormat::operator,"); + + VertexFormat r = *this; + r.components[r.count++] = c; + + return r; } -std::istream &operator>>(std::istream &in, VertexFormat &f) +VertexFormat VertexFormat::operator,(unsigned i) const { - std::string str; - in>>str; + if(!count) + throw invalid_operation("VertexFormat::operator,"); - unsigned start=0; - unsigned comma; - f=NODATA; + VertexFormat r = *this; + unsigned char *c = &r.components[r.count-1]; + *c = make_indexed_component(static_cast(*c), i); - while(1) + return r; +} + +unsigned VertexFormat::stride() const +{ + unsigned s = 0; + for(const unsigned char *i=begin(); i!=end(); ++i) + s += get_component_size(*i); + return s; +} + +int VertexFormat::offset(VertexComponent comp) const +{ + unsigned type = get_component_type(comp); + unsigned size = get_component_size(comp); + unsigned offs = 0; + for(const unsigned char *i=begin(); i!=end(); ++i) { - 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; - else + if(get_component_type(*i)==type) { - in.setstate(std::ios_base::failbit); - break; + if(get_component_size(*i)>=size) + return offs; + else + return -1; } - start=comma+1; - if(comma==std::string::npos) - break; + else + offs += get_component_size(*i); + } + + return -1; +} + +VertexComponent make_indexed_component(VertexComponent comp, unsigned index) +{ + if(comp>=TEXCOORD1 && comp<=TEXCOORD4) + { + if(index>=4) + throw out_of_range("make_indexed_component"); } + else if(comp>=ATTRIB1 && comp<=ATTRIB4) + { + if(index>=24) + throw out_of_range("make_indexed_component"); + } + else + throw invalid_argument("make_indexed_component"); + return static_cast(comp+index*4); +} - return in; +void operator>>(const LexicalConverter &conv, VertexComponent &c) +{ + 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=="TANGENT3") + c = TANGENT3; + else if(str=="BINORMAL3") + c = BINORMAL3; + 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 lexical_error(format("conversion of '%s' to VertexComponent", str)); + } + else if(str.size()>=9 && !str.compare(0, 6, "ATTRIB") && str[6]>='1' && str[6]<='4' && str[7]=='_') + { + unsigned n; + try + { + n = lexical_cast(str.substr(8)); + } + catch(const lexical_error &) + { + throw lexical_error(format("conversion of '%s' to VertexComponent", str)); + } + c = static_cast(ATTRIB1+(str[6]-'1')+n*4); + } + else + throw lexical_error(format("conversion of '%s' to VertexComponent", str)); } } // namespace GL