]> git.tdb.fi Git - libs/gl.git/blobdiff - source/builders/vertexbuilder.h
Rearrange soucre files into subdirectories
[libs/gl.git] / source / builders / vertexbuilder.h
diff --git a/source/builders/vertexbuilder.h b/source/builders/vertexbuilder.h
new file mode 100644 (file)
index 0000000..55f914a
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef MSP_GL_VERTEXBUILDER_H_
+#define MSP_GL_VERTEXBUILDER_H_
+
+#include <map>
+#include "color.h"
+#include "matrix.h"
+#include "vector.h"
+#include "vertexformat.h"
+
+namespace Msp {
+namespace GL {
+
+/**
+Base class for classes that build vertices from a series of function calls.
+The operating model closely follows that of OpenGL immediate mode: vertex
+attributes can be specified at any time, and when a vertex() function is
+called, a vertex is created with the active attribute values.
+
+A derived class must overload the 4-argument vertex_() function to process the
+data.  Attributes can be read from protected member variables.
+*/
+class VertexBuilder
+{
+public:
+       class PushMatrix
+       {
+       private:
+               VertexBuilder &bld;
+               Matrix mtx;
+
+       public:
+               PushMatrix(VertexBuilder &b): bld(b), mtx(bld.mtx) { }
+               ~PushMatrix() { bld.mtx = mtx; }
+       };
+
+protected:
+       Matrix mtx;
+       Vector3 nor;
+       Color col;
+       std::map<unsigned, Vector4> texc;
+       std::map<unsigned, Vector4> attr;
+
+public:
+       VertexBuilder(): nor(0, 0, 1) { }
+
+       virtual ~VertexBuilder() { }
+
+       void set_matrix(const Matrix &m)
+       { mtx = m; }
+
+       void transform(const Matrix &m)
+       { mtx *= m; }
+
+       const Matrix &get_matrix() const
+       { return mtx; }
+
+       void vertex(float x, float y)
+       { vertex(x, y, 0, 1); }
+
+       void vertex(float x, float y, float z)
+       { vertex(x, y, z, 1); }
+
+       void vertex(float x, float y, float z, float w)
+       { vertex(Vector4(x, y, z, w)); }
+
+       void vertex(const Vector3 &v)
+       { vertex(Vector4(v.x, v.y, v.z, 1)); }
+
+       void vertex(const Vector4 &v)
+       { vertex_(mtx*v); }
+
+protected:
+       virtual void vertex_(const Vector4 &) = 0;
+
+public:
+       void normal(float x, float y, float z)
+       { normal(Vector3(x, y, z)); }
+
+       void normal(const Vector3 &n)
+       {
+               Vector4 tn = mtx*Vector4(n.x, n.y, n.z, 0);
+               nor = Vector3(tn.x, tn.y, tn.z);
+       }
+
+       void tangent(float x, float y, float z)
+       { tangent(Vector3(x, y, z)); }
+
+       void tangent(const Vector3 &t)
+       {
+               Vector4 tt = mtx*Vector4(t.x, t.y, t.z, 0);
+               attrib(get_component_type(TANGENT3), tt);
+       }
+
+       void binormal(float x, float y, float z)
+       { binormal(Vector3(x, y, z)); }
+
+       void binormal(const Vector3 &b)
+       {
+               Vector4 tb = mtx*Vector4(b.x, b.y, b.z, 0);
+               attrib(get_component_type(BINORMAL3), tb);
+       }
+
+       void texcoord(float s)
+       { texcoord(s, 0, 0, 1); }
+
+       void texcoord(float s, float t)
+       { texcoord(s, t, 0, 1); }
+
+       void texcoord(float s, float t, float r)
+       { texcoord(s, t, r, 1); }
+
+       void texcoord(float s, float t, float r, float q)
+       { texcoord(Vector4(s, t, r, q)); }
+
+       void texcoord(const Vector4 &t)
+       { multitexcoord(0, t); }
+
+       void multitexcoord(unsigned i, float s)
+       { multitexcoord(i, s, 0, 0, 1); }
+
+       void multitexcoord(unsigned i, float s, float t)
+       { multitexcoord(i, s, t, 0, 1); }
+
+       void multitexcoord(unsigned i, float s, float t, float r)
+       { multitexcoord(i, s, t, r, 1); }
+
+       void multitexcoord(unsigned i, float s, float t, float r, float q)
+       { multitexcoord(i, Vector4(s, t, r, q)); }
+
+       void multitexcoord(unsigned i, const Vector4 &t)
+       { texc[i] = t; }
+
+       void color(unsigned char r, unsigned char g, unsigned char b)
+       { color(r, g, b, 255); }
+
+       void color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
+       { color(r/255.f, g/255.f, b/255.f, a/255.f); }
+
+       void color(float r, float g, float b)
+       { color(r, g, b, 1); }
+
+       void color(float r, float g, float b, float a)
+       { color(Color(r, g, b, a)); }
+
+       void color(const Color &c)
+       { col = c; }
+
+       void attrib(unsigned i, float x)
+       { attrib(i, x, 0, 0, 1); }
+
+       void attrib(unsigned i, float x, float y)
+       { attrib(i, x, y, 0, 1); }
+
+       void attrib(unsigned i, float x, float y, float z)
+       { attrib(i, x, y, z, 1); }
+
+       void attrib(unsigned i, float x, float y, float z, float w)
+       { attrib(i, Vector4(x, y, z, w)); }
+
+       void attrib(unsigned i, const Vector4 &a)
+       { attr[i] = a; }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif