]> git.tdb.fi Git - libs/gl.git/commitdiff
Move VertexFormat and VertexArrayBuilder to their own files
authorMikko Rasa <tdb@tdb.fi>
Mon, 3 Sep 2007 11:39:58 +0000 (11:39 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 3 Sep 2007 11:39:58 +0000 (11:39 +0000)
Create a generix VertexBuilder class for building vertices
Add attribute binding to Program
Add primitive types
Add VertexArray loader
Add Immediate

13 files changed:
source/immediate.cpp [new file with mode: 0644]
source/immediate.h [new file with mode: 0644]
source/primitivetype.h [new file with mode: 0644]
source/program.cpp
source/program.h
source/vertexarray.cpp
source/vertexarray.h
source/vertexarraybuilder.cpp [new file with mode: 0644]
source/vertexarraybuilder.h [new file with mode: 0644]
source/vertexbuilder.cpp [new file with mode: 0644]
source/vertexbuilder.h [new file with mode: 0644]
source/vertexformat.cpp [new file with mode: 0644]
source/vertexformat.h [new file with mode: 0644]

diff --git a/source/immediate.cpp b/source/immediate.cpp
new file mode 100644 (file)
index 0000000..f341397
--- /dev/null
@@ -0,0 +1,52 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "immediate.h"
+
+namespace Msp {
+namespace GL {
+
+Immediate::Immediate(VertexFormat f):
+       array(f),
+       in_batch(false),
+       n_vertices(0)
+{ }
+
+void Immediate::begin(PrimitiveType t)
+{
+       type=t;
+       in_batch=true;
+       n_vertices=0;
+       builder=array.modify();
+}
+
+void Immediate::end()
+{
+       builder=0;
+
+       array.apply();
+       glDrawArrays(type, 0, n_vertices);
+
+       array.clear();
+       in_batch=false;
+}
+
+void Immediate::vertex_(float x, float y, float z, float w)
+{
+       if(!in_batch)
+               throw InvalidState("Vertex specification not between begin and end");
+
+       builder->texcoord(ts, tt, tr,tq);
+       builder->color(cr, cg, cb, ca);
+       builder->normal(nx, ny, nz);
+       builder->vertex(x, y, z, w);
+
+       ++n_vertices;
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/immediate.h b/source/immediate.h
new file mode 100644 (file)
index 0000000..b979973
--- /dev/null
@@ -0,0 +1,44 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_IMMEDIATE_H_
+#define MSP_GL_IMMEDIATE_H_
+
+#include "primitivetype.h"
+#include "vertexarray.h"
+#include "vertexbuilder.h"
+
+namespace Msp {
+namespace GL {
+
+/**
+Draws primitives on the screen.  This works similarly to the OpenGL immediate
+mode: call begin() to start a batch of primitives, specify vertices, and call
+end() to terminate the batch.  However, unlike OpenGL immediate mode, vertices
+are not drawn as they are specified.  Instead, they are accumulated in a
+VertexArray and drawn when end() is called.
+*/
+class Immediate: public VertexBuilder
+{
+public:
+       Immediate(VertexFormat);
+       void begin(PrimitiveType);
+       void end();
+private:
+       VertexArray array;
+       RefPtr<VertexArrayBuilder> builder;
+       PrimitiveType type;
+       bool in_batch;
+       unsigned n_vertices;
+
+       virtual void vertex_(float, float, float, float);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/primitivetype.h b/source/primitivetype.h
new file mode 100644 (file)
index 0000000..459c18e
--- /dev/null
@@ -0,0 +1,33 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_PRIMITIVETYPE_H_
+#define MSP_GL_PRIMITIVETYPE_H_
+
+#include <GL/gl.h>
+
+namespace Msp {
+namespace GL {
+
+enum PrimitiveType
+{
+       POINTS         = GL_POINTS,
+       LINES          = GL_LINES,
+       LINE_STRIP     = GL_LINE_STRIP,
+       LINE_LOOP      = GL_LINE_LOOP,
+       TRIANGLES      = GL_TRIANGLES,
+       TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
+       TRIANGLE_FAN   = GL_TRIANGLE_FAN,
+       QUADS          = GL_QUADS,
+       QUAD           = GL_QUAD_STRIP,
+       POLYGON        = GL_POLYGON
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index b7f8577dc698c3190ba8e8b4dfd092c5e241772d..1d08270fd50aca7abd45e18f9660213e09a24227 100644 (file)
@@ -43,6 +43,11 @@ void Program::detach_shader(Shader &shader)
        }
 }
 
+void Program::bind_attribute(int index, const string &name)
+{
+       glBindAttribLocation(id, index, name.c_str());
+}
+
 bool Program::link()
 {
        for(list<Shader *>::iterator i=shaders.begin(); i!=shaders.end(); ++i)
index 5b1ae29f3ed0681b9a4eb930d938a712fecfacdc..a77a70d708102fcf9345e33b80ab273bd97bda9e 100644 (file)
@@ -27,6 +27,7 @@ public:
 
        void attach_shader(Shader &shader);
        void detach_shader(Shader &shader);
+       void bind_attribute(int, const std::string &);
        bool link();
        int get_param(GLenum param) const;
        std::string get_info_log() const;
index 3c94b4cfffc27ec20fc1b0e34a96a821e3ee40a3..e7d7386509d6208b2b5130be5bb780f3bc757521 100644 (file)
@@ -14,85 +14,13 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-uint get_stride(VertexFormat f)
-{
-       uint stride=0;
-       for(uint fmt=f; fmt; fmt>>=4)
-               stride+=(fmt&3)+1;
-       return stride*sizeof(float);
-}
-
-
-VertexArrayBuilder::VertexArrayBuilder(VertexArray &a, vector<float> &d):
-       data(d),
-       array(a),
-       format(array.get_format()),
-       stride(get_stride(format)),
-       cr(1), cg(1), cb(1), ca(1),
-       ts(0), tt(0), tr(0), tq(0),
-       nx(0), ny(0), nz(1)
-{ }
-
-void VertexArrayBuilder::vertex(float x, float y, float z, float w)
-{
-       for(uint fmt=format; fmt; fmt>>=4)
-       {
-               uint size=(fmt&3)+1;
-               switch(fmt&12)
-               {
-               case 0:
-                       data.push_back(x);
-                       data.push_back(y);
-                       if(size>=3) data.push_back(z);
-                       if(size>=4) data.push_back(w);
-                       break;
-               case 4:
-                       data.push_back(nx);
-                       data.push_back(ny);
-                       data.push_back(nz);
-                       break;
-               case 8:
-                       data.push_back(ts);
-                       if(size>=2) data.push_back(tt);
-                       if(size>=3) data.push_back(tr);
-                       if(size>=4) data.push_back(tq);
-                       break;
-               case 12:
-                       if(size==1)
-                       {
-                               union { ubyte c[4]; float f; } u;
-                               u.c[0]=(ubyte)(cr*255);
-                               u.c[1]=(ubyte)(cg*255);
-                               u.c[2]=(ubyte)(cb*255);
-                               u.c[3]=(ubyte)(ca*255);
-                               data.push_back(u.f);
-                       }
-                       else
-                       {
-                               data.push_back(cr);
-                               data.push_back(cg);
-                               data.push_back(cb);
-                               if(size>=4) data.push_back(ca);
-                       }
-                       break;
-               }
-       }
-       //cout<<"Added vertex with "<<data.size()-old_size<<" floats\n";
-}
-
-VertexArrayBuilder::~VertexArrayBuilder()
-{
-       array.update_data();
-}
-
-
 VertexArray::VertexArray(VertexFormat f):
        format(NODATA),
        stride(get_stride(f)),
        vbuf(0),
        own_vbuf(false)
 {
-       // Reverse the format so the first item is in lowest bits
+       // Reverse the format so the first item is in lowest bits.  This makes handling in bind() easier.
        for(uint fmt=f; fmt; fmt>>=4)
                format=(format, static_cast<VertexFormat>(fmt&15));
 }
@@ -125,6 +53,20 @@ void VertexArray::clear()
        data.clear();
 }
 
+void VertexArray::reset(VertexFormat f)
+{
+       clear();
+       format=NODATA;
+       for(uint fmt=f; fmt; fmt>>=4)
+               format=(format, static_cast<VertexFormat>(fmt&15));
+       stride=get_stride(format);
+}
+
+RefPtr<VertexArrayBuilder> VertexArray::modify()
+{
+       return new VertexArrayBuilder(*this, data);
+}
+
 void VertexArray::apply() const
 {
        if(vbuf) vbuf->bind();
@@ -191,5 +133,20 @@ void VertexArray::set_array(unsigned array, unsigned bit, unsigned mask) const
 unsigned VertexArray::enabled_arrays=0;
 
 
+VertexArray::Loader::Loader(VertexArray &a):
+       VertexArrayBuilder(a, a.data)
+{
+       add("vertex2",   static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
+       add("vertex3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
+       add("vertex4",   static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
+       add("normal3",   static_cast<void (Loader::*)(float, float, float)>(&Loader::normal));
+       add("texcoord1", static_cast<void (Loader::*)(float)>(&Loader::texcoord));
+       add("texcoord2", static_cast<void (Loader::*)(float, float)>(&Loader::texcoord));
+       add("texcoord3", static_cast<void (Loader::*)(float, float, float)>(&Loader::texcoord));
+       add("texcoord4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
+       add("color3",    static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
+       add("color4",    static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
+}
+
 } // namespace GL
 } // namespace Msp
index 52b8888227b80cc39bc365d7b484bf0d639f3e85..9610905d218994fcb2e539a6fe06d1a4e3934a41 100644 (file)
@@ -10,65 +10,25 @@ Distributed under the LGPL
 
 #include <vector>
 #include <msp/core/refptr.h>
+#include <msp/datafile/loader.h>
 #include "types.h"
+#include "vertexarraybuilder.h"
+#include "vertexformat.h"
 
 namespace Msp {
 namespace GL {
 
-class VertexArray;
 class VertexBuffer;
 
-enum VertexFormat
-{
-       NODATA=0,
-       VERTEX2=1,
-       VERTEX3,
-       VERTEX4,
-       NORMAL3=6,
-       TEXCOORD1=8,
-       TEXCOORD2,
-       TEXCOORD3,
-       TEXCOORD4,
-       COLOR4_UBYTE=12,
-       COLOR3_FLOAT=14,
-       COLOR4_FLOAT,
-};
-
-inline VertexFormat operator,(VertexFormat a, VertexFormat b) { return VertexFormat((a<<4)|b); }
-uint get_stride(VertexFormat);
-
-class VertexArrayBuilder
-{
-public:
-       std::vector<float> &data;
-
-       VertexArrayBuilder(VertexArray &, std::vector<float> &);
-       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, float, float, float);
-       void normal(float x, float y, float z)            { nx=x; ny=y; nz=z; }
-       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) { ts=s; tt=t; tr=r; tq=q; }
-       void color(ubyte r, ubyte g, ubyte b)             { color(r, g, b, 255); }
-       void color(ubyte r, ubyte g, ubyte b, ubyte 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)    { cr=r; cg=g; cb=b; ca=a; }
-       ~VertexArrayBuilder();
-private:
-       VertexArray  &array;
-       VertexFormat format;
-       uint         stride;
-
-       float cr, cg, cb, ca;  // Color
-       float ts, tt, tr, tq;  // TexCoord
-       float nx, ny, nz;     // Normal
-};
-
 class VertexArray
 {
 public:
+       class Loader: public DataFile::Loader, public VertexArrayBuilder
+       {
+       public:
+               Loader(VertexArray &);
+       };
+
        VertexArray(VertexFormat);
        ~VertexArray();
 
@@ -77,7 +37,8 @@ public:
        void         use_vertex_buffer();
        void         use_vertex_buffer(VertexBuffer *);
        void         clear();
-       RefPtr<VertexArrayBuilder> modify() { return new VertexArrayBuilder(*this, data); }
+       void         reset(VertexFormat);
+       RefPtr<VertexArrayBuilder> modify();
        void         apply() const;
        void         update_data();
 private:
@@ -87,6 +48,8 @@ private:
        VertexBuffer *vbuf;
        bool         own_vbuf;
 
+       VertexArray(const VertexArray &);
+       VertexArray &operator=(const VertexArray &);
        void set_array(unsigned, unsigned, unsigned) const;
 
        static unsigned enabled_arrays;
diff --git a/source/vertexarraybuilder.cpp b/source/vertexarraybuilder.cpp
new file mode 100644 (file)
index 0000000..5f469a9
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "vertexarray.h"
+#include "vertexarraybuilder.h"
+
+namespace Msp {
+namespace GL {
+
+VertexArrayBuilder::VertexArrayBuilder(VertexArray &a, std::vector<float> &d):
+       data(d),
+       array(a)
+{ }
+
+VertexArrayBuilder::~VertexArrayBuilder()
+{
+       array.update_data();
+}
+
+void VertexArrayBuilder::vertex_(float x, float y, float z, float w)
+{
+       for(uint fmt=array.get_format(); fmt; fmt>>=4)
+       {
+               uint size=(fmt&3)+1;
+               switch(fmt&12)
+               {
+               case 0:
+                       data.push_back(x);
+                       data.push_back(y);
+                       if(size>=3) data.push_back(z);
+                       if(size>=4) data.push_back(w);
+                       break;
+               case 4:
+                       data.push_back(nx);
+                       data.push_back(ny);
+                       data.push_back(nz);
+                       break;
+               case 8:
+                       data.push_back(ts);
+                       if(size>=2) data.push_back(tt);
+                       if(size>=3) data.push_back(tr);
+                       if(size>=4) data.push_back(tq);
+                       break;
+               case 12:
+                       if(size==1)
+                       {
+                               union { ubyte c[4]; float f; } u;
+                               u.c[0]=(ubyte)(cr*255);
+                               u.c[1]=(ubyte)(cg*255);
+                               u.c[2]=(ubyte)(cb*255);
+                               u.c[3]=(ubyte)(ca*255);
+                               data.push_back(u.f);
+                       }
+                       else
+                       {
+                               data.push_back(cr);
+                               data.push_back(cg);
+                               data.push_back(cb);
+                               if(size>=4) data.push_back(ca);
+                       }
+                       break;
+               }
+       }
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/vertexarraybuilder.h b/source/vertexarraybuilder.h
new file mode 100644 (file)
index 0000000..5435767
--- /dev/null
@@ -0,0 +1,38 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_VERTEXARRAYBUIDER_H_
+#define MSP_GL_VERTEXARRAYBUIDER_H_
+
+#include <vector>
+#include "vertexbuilder.h"
+#include "vertexformat.h"
+
+namespace Msp {
+namespace GL {
+
+class VertexArray;
+
+class VertexArrayBuilder: public VertexBuilder
+{
+public:
+       std::vector<float> &data;
+
+       VertexArrayBuilder(VertexArray &, std::vector<float> &);
+       ~VertexArrayBuilder();
+
+private:
+       VertexArray  &array;
+
+       VertexArrayBuilder(const VertexArrayBuilder &);
+       virtual void vertex_(float, float, float, float);
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/vertexbuilder.cpp b/source/vertexbuilder.cpp
new file mode 100644 (file)
index 0000000..0b1d3f3
--- /dev/null
@@ -0,0 +1,20 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "vertexbuilder.h"
+
+namespace Msp {
+namespace GL {
+
+VertexBuilder::VertexBuilder():
+       cr(1), cg(1), cb(1), ca(1),
+       ts(0), tt(0), tr(0), tq(0),
+       nx(0), ny(0), nz(1)
+{ }
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/vertexbuilder.h b/source/vertexbuilder.h
new file mode 100644 (file)
index 0000000..1b2d02d
--- /dev/null
@@ -0,0 +1,54 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_VERTEXBUILDER_H_
+#define MSP_GL_VERTEXBUILDER_H_
+
+#include "types.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:
+       VertexBuilder();
+       virtual ~VertexBuilder() { }
+
+       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_(x, y, z, w); }
+       void normal(float x, float y, float z)            { nx=x; ny=y; nz=z; }
+       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) { ts=s; tt=t; tr=r; tq=q; }
+       void color(ubyte r, ubyte g, ubyte b)             { color(r, g, b, 255); }
+       void color(ubyte r, ubyte g, ubyte b, ubyte 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)    { cr=r; cg=g; cb=b; ca=a; }
+protected:
+       float cr, cg, cb, ca;  // Color
+       float ts, tt, tr, tq;  // TexCoord
+       float nx, ny, nz;     // Normal
+
+       virtual void vertex_(float, float, float, float) =0;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp
new file mode 100644 (file)
index 0000000..25c2b02
--- /dev/null
@@ -0,0 +1,69 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "vertexformat.h"
+
+namespace Msp {
+namespace GL {
+
+uint get_stride(VertexFormat f)
+{
+       uint stride=0;
+       for(uint fmt=f; fmt; fmt>>=4)
+               stride+=(fmt&3)+1;
+       return stride*sizeof(float);
+}
+
+std::istream &operator>>(std::istream &in, VertexFormat &f)
+{
+       std::string str;
+       in>>str;
+
+       unsigned start=0;
+       unsigned comma;
+       f=NODATA;
+
+       while(1)
+       {
+               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
+               {
+                       in.setstate(std::ios_base::failbit);
+                       break;
+               }
+               start=comma+1;
+               if(comma==std::string::npos)
+                       break;
+       }
+
+       return in;
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/vertexformat.h b/source/vertexformat.h
new file mode 100644 (file)
index 0000000..3a0eb71
--- /dev/null
@@ -0,0 +1,40 @@
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_VERTEXFORMAT_H_
+#define MSP_GL_VERTEXFORMAT_H_
+
+#include <istream>
+#include "types.h"
+
+namespace Msp {
+namespace GL {
+
+enum VertexFormat
+{
+       NODATA=0,
+       VERTEX2=1,
+       VERTEX3,
+       VERTEX4,
+       NORMAL3=6,
+       TEXCOORD1=8,
+       TEXCOORD2,
+       TEXCOORD3,
+       TEXCOORD4,
+       COLOR4_UBYTE=12,
+       COLOR3_FLOAT=14,
+       COLOR4_FLOAT,
+};
+
+inline VertexFormat operator,(VertexFormat a, VertexFormat b) { return VertexFormat(a<<4 | b); }
+uint get_stride(VertexFormat);
+std::istream &operator>>(std::istream &, VertexFormat &);
+
+} // namespace GL
+} // namespace Msp
+
+#endif