]> git.tdb.fi Git - libs/gl.git/blob - source/vertexformat.cpp
Fix compilation on 64-bit platforms
[libs/gl.git] / source / vertexformat.cpp
1 /* $Id$
2
3 This file is part of libmspgl
4 Copyright © 2007-2009  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 VertexFormat operator,(const VertexFormat &f, VertexComponent c)
59 {
60         VertexFormat r=f;
61         if(r.data)
62         {
63                 const unsigned char n=++r.data[0];
64                 if((n&7)==7)
65                 {
66                         unsigned char *newdt=new unsigned char[n+9];
67                         memcpy(newdt, r.data, n);
68                         delete r.data;
69                         r.data=newdt;
70                 }
71                 r.data[n]=c;
72         }
73         else
74         {
75                 r.data=new unsigned char[8];
76                 r.data[0]=1;
77                 r.data[1]=c;
78         }
79
80         return r;
81 }
82
83 VertexFormat operator,(const VertexFormat &f, unsigned i)
84 {
85         if(!f.data)
86                 throw InvalidState("VertexFormat has no components");
87         VertexFormat r=f;
88         unsigned char *c=r.data+r.data[0];
89         if(*c<ATTRIB1)
90                 throw InvalidState("Last component is not a generic attribute");
91         // VertexArray uses an unsigned to store flags for enabled arrays
92         if(i>=28)
93                 throw InvalidParameterValue("Generic attribute index out of range");
94         *c+=i*4;
95
96         return r;
97 }
98
99 uint get_stride(const VertexFormat &f)
100 {
101         uint stride=0;
102         for(const unsigned char *i=f.begin(); i!=f.end(); ++i)
103                 stride+=(*i&3)+1;
104         return stride;
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