Include only tangent in mesh data and calculate binormal on the fly
[libs/gl.git] / source / builders / vertexbuilder.h
1 #ifndef MSP_GL_VERTEXBUILDER_H_
2 #define MSP_GL_VERTEXBUILDER_H_
3
4 #include <map>
5 #include "color.h"
6 #include "matrix.h"
7 #include "vector.h"
8 #include "vertexformat.h"
9
10 namespace Msp {
11 namespace GL {
12
13 /**
14 Base class for classes that build vertices from a series of function calls.
15 The operating model closely follows that of OpenGL immediate mode: vertex
16 attributes can be specified at any time, and when a vertex() function is
17 called, a vertex is created with the active attribute values.
18
19 A derived class must overload the 4-argument vertex_() function to process the
20 data.  Attributes can be read from protected member variables.
21 */
22 class VertexBuilder
23 {
24 public:
25         class PushMatrix
26         {
27         private:
28                 VertexBuilder &bld;
29                 Matrix mtx;
30
31         public:
32                 PushMatrix(VertexBuilder &b): bld(b), mtx(bld.mtx) { }
33                 ~PushMatrix() { bld.mtx = mtx; }
34         };
35
36 protected:
37         Matrix mtx;
38         std::vector<Vector4> attr;
39
40 public:
41         VertexBuilder() { normal(0, 0, 1); }
42
43         virtual ~VertexBuilder() { }
44
45         void set_matrix(const Matrix &m)
46         { mtx = m; }
47
48         void transform(const Matrix &m)
49         { mtx *= m; }
50
51         const Matrix &get_matrix() const
52         { return mtx; }
53
54         void vertex(float x, float y)
55         { vertex(x, y, 0, 1); }
56
57         void vertex(float x, float y, float z)
58         { vertex(x, y, z, 1); }
59
60         void vertex(float x, float y, float z, float w)
61         { vertex(Vector4(x, y, z, w)); }
62
63         void vertex(const Vector3 &v)
64         { vertex(Vector4(v.x, v.y, v.z, 1)); }
65
66         void vertex(const Vector4 &v)
67         { vertex_(mtx*v); }
68
69 protected:
70         virtual void vertex_(const Vector4 &) = 0;
71
72 public:
73         void attrib(unsigned i, const Vector4 &v)
74         {
75                 if(i>=attr.size())
76                         attr.resize(i+1);
77                 attr[i] = v;
78         }
79
80         void normal(float x, float y, float z)
81         { normal(Vector3(x, y, z)); }
82
83         void normal(const Vector3 &n)
84         { attrib(get_attribute_semantic(NORMAL3), mtx*Vector4(n.x, n.y, n.z, 0)); }
85
86         void tangent(float x, float y, float z)
87         { tangent(Vector3(x, y, z)); }
88
89         void tangent(const Vector3 &t)
90         { attrib(get_attribute_semantic(TANGENT3), mtx*Vector4(t.x, t.y, t.z, 0)); }
91
92         DEPRECATED void binormal(float, float, float)
93         { }
94
95         DEPRECATED void binormal(const Vector3 &)
96         { }
97
98         void texcoord(float s)
99         { texcoord(s, 0, 0, 1); }
100
101         void texcoord(float s, float t)
102         { texcoord(s, t, 0, 1); }
103
104         void texcoord(float s, float t, float r)
105         { texcoord(s, t, r, 1); }
106
107         void texcoord(float s, float t, float r, float q)
108         { texcoord(Vector4(s, t, r, q)); }
109
110         void texcoord(const Vector4 &t)
111         { multitexcoord(0, t); }
112
113         void multitexcoord(unsigned i, float s)
114         { multitexcoord(i, s, 0, 0, 1); }
115
116         void multitexcoord(unsigned i, float s, float t)
117         { multitexcoord(i, s, t, 0, 1); }
118
119         void multitexcoord(unsigned i, float s, float t, float r)
120         { multitexcoord(i, s, t, r, 1); }
121
122         void multitexcoord(unsigned i, float s, float t, float r, float q)
123         { multitexcoord(i, Vector4(s, t, r, q)); }
124
125         void multitexcoord(unsigned i, const Vector4 &t)
126         { attrib(get_attribute_semantic(TEXCOORD4)+i, t); }
127
128         void color(unsigned char r, unsigned char g, unsigned char b)
129         { color(r, g, b, 255); }
130
131         void color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
132         { color(r/255.f, g/255.f, b/255.f, a/255.f); }
133
134         void color(float r, float g, float b)
135         { color(r, g, b, 1); }
136
137         void color(float r, float g, float b, float a)
138         { color(Color(r, g, b, a)); }
139
140         void color(const Color &c)
141         { attrib(get_attribute_semantic(COLOR4_FLOAT), Vector4(c.r, c.g, c.b, c.a)); }
142
143         void group(int g0)
144         { group(g0, 0, 0, 0); }
145
146         void group(int g0, int g1)
147         { group(g0, g1, 0, 0); }
148
149         void group(int g0, int g1, int g2)
150         { group(g0, g1, g2, 0); }
151
152         void group(int g0, int g1, int g2, int g3)
153         { attrib(get_attribute_semantic(GROUP4), Vector4(g0, g1, g2, g3)); }
154
155         void weight(float w0)
156         { weight(w0, 0, 0, 0); }
157
158         void weight(float w0, float w1)
159         { weight(w0, w1, 0, 0); }
160
161         void weight(float w0, float w1, float w2)
162         { weight(w0, w1, w2, 0); }
163
164         void weight(float w0, float w1, float w2, float w3)
165         { attrib(get_attribute_semantic(WEIGHT4), Vector4(w0, w1, w2, w3)); }
166
167         void generic(unsigned i, float x)
168         { generic(i, x, 0, 0, 1); }
169
170         void generic(unsigned i, float x, float y)
171         { generic(i, x, y, 0, 1); }
172
173         void generic(unsigned i, float x, float y, float z)
174         { generic(i, x, y, z, 1); }
175
176         void generic(unsigned i, float x, float y, float z, float w)
177         { generic(i, Vector4(x, y, z, w)); }
178
179         void generic(unsigned i, const Vector4 &a)
180         { attrib(get_attribute_semantic(GENERIC4)+i, a); }
181 };
182
183 } // namespace GL
184 } // namespace Msp
185
186 #endif