]> git.tdb.fi Git - libs/gl.git/blob - source/vertexformat.cpp
Style update: add spaces around assignment operators
[libs/gl.git] / source / vertexformat.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007-2010  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <cstring>
9 #include <msp/strings/lexicalcast.h>
10 #include "except.h"
11 #include "vertexformat.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace GL {
17
18 VertexFormat::VertexFormat():
19         data(0)
20 { }
21
22 VertexFormat::VertexFormat(VertexComponent c):
23         data(new unsigned char[8])
24 {
25         data[0] = 1;
26         data[1] = c;
27 }
28
29 VertexFormat::VertexFormat(const VertexFormat &f):
30         data(0)
31 {
32         if(f.data)
33         {
34                 data = new unsigned char[f.data[0]/8+8];
35                 memcpy(data, f.data, f.data[0]+1);
36         }
37 }
38
39 VertexFormat &VertexFormat::operator=(const VertexFormat &f)
40 {
41         delete[] data;
42         if(f.data)
43         {
44                 data = new unsigned char[f.data[0]/8+8];
45                 memcpy(data, f.data, f.data[0]+1);
46         }
47         else
48                 data = 0;
49
50         return *this;
51 }
52
53 VertexFormat::~VertexFormat()
54 {
55         delete[] data;
56 }
57
58 unsigned VertexFormat::stride() const
59 {
60         unsigned s = 0;
61         for(const unsigned char *i=begin(); i!=end(); ++i)
62                 s += (*i&3)+1;
63         return s;
64 }
65
66 VertexFormat operator,(const VertexFormat &f, VertexComponent c)
67 {
68         VertexFormat r = f;
69         if(r.data)
70         {
71                 const unsigned char n = ++r.data[0];
72                 if((n&7)==7)
73                 {
74                         unsigned char *newdt = new unsigned char[n+9];
75                         memcpy(newdt, r.data, n);
76                         delete r.data;
77                         r.data = newdt;
78                 }
79                 r.data[n] = c;
80         }
81         else
82         {
83                 r.data = new unsigned char[8];
84                 r.data[0] = 1;
85                 r.data[1] = c;
86         }
87
88         return r;
89 }
90
91 VertexFormat operator,(const VertexFormat &f, unsigned i)
92 {
93         if(!f.data)
94                 throw InvalidState("VertexFormat has no components");
95         VertexFormat r = f;
96         unsigned char *c = r.data+r.data[0];
97         if(*c<ATTRIB1)
98                 throw InvalidState("Last component is not a generic attribute");
99         // VertexArray uses an unsigned to store flags for enabled arrays
100         if(i>=28)
101                 throw InvalidParameterValue("Generic attribute index out of range");
102         *c += i*4;
103
104         return r;
105 }
106
107 istream &operator>>(istream &in, VertexFormat &f)
108 {
109         string str;
110         in>>str;
111
112         unsigned start = 0;
113
114         while(1)
115         {
116                 string::size_type underscore = str.find('_', start);
117                 bool fail = false;
118                 if(!str.compare(start, underscore-start, "VERTEX2"))
119                         f = (f,VERTEX2);
120                 else if(!str.compare(start, underscore-start, "VERTEX3"))
121                         f = (f,VERTEX3);
122                 else if(!str.compare(start, underscore-start, "VERTEX4"))
123                         f = (f,VERTEX4);
124                 else if(!str.compare(start, underscore-start, "NORMAL3"))
125                         f = (f,NORMAL3);
126                 else if(!str.compare(start, underscore-start, "TEXCOORD1"))
127                         f = (f,TEXCOORD1);
128                 else if(!str.compare(start, underscore-start, "TEXCOORD2"))
129                         f = (f,TEXCOORD2);
130                 else if(!str.compare(start, underscore-start, "TEXCOORD3"))
131                         f = (f,TEXCOORD3);
132                 else if(!str.compare(start, underscore-start, "TEXCOORD4"))
133                         f = (f,TEXCOORD4);
134                 else if(!str.compare(start, underscore-start, "COLOR4UB"))
135                         f = (f,COLOR4_UBYTE);
136                 else if(!str.compare(start, underscore-start, "COLOR3F"))
137                         f = (f,COLOR3_FLOAT);
138                 else if(!str.compare(start, underscore-start, "COLOR4F"))
139                         f = (f,COLOR4_FLOAT);
140                 else if(underscore>=start+8 && !str.compare(start, 6, "ATTRIB"))
141                 {
142                         try
143                         {
144                                 char n = str[start+6];
145                                 unsigned i = lexical_cast<unsigned>(str.substr(start+7, underscore-start-7));
146                                 if(n=='1')
147                                         f = (f,ATTRIB1,i);
148                                 else if(n=='2')
149                                         f = (f,ATTRIB2,i);
150                                 else if(n=='3')
151                                         f = (f,ATTRIB3,i);
152                                 else if(n=='4')
153                                         f = (f,ATTRIB4,i);
154                                 else
155                                         fail = true;
156                         }
157                         catch(const LexicalError &)
158                         {
159                                 fail = true;
160                         }
161                 }
162                 else
163                         fail = true;
164
165                 if(fail)
166                 {
167                         in.setstate(ios_base::failbit);
168                         break;
169                 }
170
171                 if(underscore==string::npos)
172                         break;
173                 start = underscore+1;
174         }
175
176         return in;
177 }
178
179 } // namespace GL
180 } // namespace Msp