--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#define GL_GLEXT_PROTOTYPES
+#include "batch.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Batch::Batch(PrimitiveType t):
+ type(t),
+ min_index(0),
+ max_index(0)
+{ }
+
+void Batch::append(uint i)
+{
+ if(indices.empty())
+ min_index=max_index=i;
+ else
+ {
+ min_index=min(min_index, i);
+ max_index=max(max_index, i);
+ }
+ indices.push_back(i);
+}
+
+void Batch::append(const vector<uint> &ind)
+{
+ indices.reserve(indices.size()+ind.size());
+ for(vector<uint>::const_iterator i=ind.begin(); i!=ind.end(); ++i)
+ append(*i);
+}
+
+void Batch::draw() const
+{
+ glDrawRangeElements(type, min_index, max_index, indices.size(), GL_UNSIGNED_INT, &indices[0]);
+}
+
+
+Batch::Loader::Loader(Batch &b):
+ batch(b)
+{
+ add("indices", &Loader::indices);
+}
+
+void Batch::Loader::indices(const vector<uint> &ind)
+{
+ batch.append(ind);
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_BATCH_H_
+#define MSP_GL_BATCH_H_
+
+#include <vector>
+#include <GL/gl.h>
+#include <msp/datafile/loader.h>
+#include "primitivetype.h"
+#include "types.h"
+
+namespace Msp {
+namespace GL {
+
+class Batch
+{
+public:
+ class Loader: public DataFile::Loader
+ {
+ public:
+ Loader(Batch &);
+ private:
+ Batch &batch;
+
+ void indices(const std::vector<uint> &);
+ };
+
+ Batch(PrimitiveType t);
+ void append(uint);
+ void append(const std::vector<uint> &);
+ void draw() const;
+private:
+ PrimitiveType type;
+ std::vector<uint> indices;
+ uint min_index;
+ uint max_index;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "mesh.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Mesh::Mesh():
+ vertices(NODATA)
+{ }
+
+void Mesh::draw() const
+{
+ vertices.apply();
+ for(list<Batch>::const_iterator i=batches.begin(); i!=batches.end(); ++i)
+ i->draw();
+}
+
+
+Mesh::Loader::Loader(Mesh &m):
+ mesh(m)
+{
+ add("vertices", &Loader::vertices);
+ add("batch", &Loader::batch);
+}
+
+void Mesh::Loader::vertices(VertexFormat f)
+{
+ mesh.vertices.reset(f);
+ load_sub(mesh.vertices);
+}
+
+void Mesh::Loader::batch(PrimitiveType p)
+{
+ mesh.batches.push_back(Batch(p));
+ load_sub(mesh.batches.back());
+}
+
+} // namespace GL
+} // namespace Msp
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#ifndef MSP_GL_MESH_H_
+#define MSP_GL_MESH_H_
+
+#include <msp/datafile/loader.h>
+#include "batch.h"
+#include "vertexarray.h"
+
+namespace Msp {
+namespace GL {
+
+class Mesh
+{
+public:
+ class Loader: public DataFile::Loader
+ {
+ public:
+ Loader(Mesh &);
+ private:
+ Mesh &mesh;
+
+ void vertices(VertexFormat);
+ void batch(PrimitiveType);
+ };
+
+ Mesh();
+ void draw() const;
+private:
+ VertexArray vertices;
+ std::list<Batch> batches;
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of libmspgl
+Copyright © 2007 Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include "primitivetype.h"
+
+namespace Msp {
+namespace GL {
+
+std::istream &operator>>(std::istream &in, PrimitiveType &pt)
+{
+ std::string str;
+ in>>str;
+
+ if(str=="POINTS")
+ pt=POINTS;
+ else if(str=="LINES")
+ pt=LINES;
+ else if(str=="LINE_LOOP")
+ pt=LINE_LOOP;
+ else if(str=="LINE_STRIP")
+ pt=LINE_STRIP;
+ else if(str=="TRIANGLES")
+ pt=TRIANGLES;
+ else if(str=="TRIANGLE_STRIP")
+ pt=TRIANGLE_STRIP;
+ else if(str=="TRIANGLE_FAN")
+ pt=TRIANGLE_FAN;
+ else if(str=="QUADS")
+ pt=QUADS;
+ else if(str=="QUAD_STRIP")
+ pt=QUAD_STRIP;
+ else if(str=="POLYGON")
+ pt=POLYGON;
+ else
+ in.setstate(std::ios_base::failbit);
+
+ return in;
+}
+
+} // namespace GL
+} // namespace Msp
#ifndef MSP_GL_PRIMITIVETYPE_H_
#define MSP_GL_PRIMITIVETYPE_H_
+#include <istream>
#include <GL/gl.h>
namespace Msp {
TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
TRIANGLE_FAN = GL_TRIANGLE_FAN,
QUADS = GL_QUADS,
- QUAD = GL_QUAD_STRIP,
+ QUAD_STRIP = GL_QUAD_STRIP,
POLYGON = GL_POLYGON
};
+std::istream &operator>>(std::istream &in, PrimitiveType &pt);
+
} // namespace GL
} // namespace Msp
void VertexArray::apply() const
{
- if(vbuf) vbuf->bind();
+ if(format==NODATA)
+ throw InvalidState("Trying to apply a vertex apply of format NODATA");
+
+ if(vbuf)
+ vbuf->bind();
const float *base=vbuf?0:&data[0];
uint offset=0;
glDeleteBuffers(1, &id);
}
+void VertexBuffer::unbind()
+{
+ if(bound)
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ bound=0;
+ }
+}
+
const VertexBuffer *VertexBuffer::bound=0;
} // namespace GL
void data(sizei, void *);
~VertexBuffer();
- static void unbind() { bound=0; }
+ static void unbind();
private:
uint id;
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;
+ unsigned underscore=str.find('_', start);
+ if(!str.compare(start, underscore-start, "VERTEX2"))
+ f=(f,VERTEX2);
+ else if(!str.compare(start, underscore-start, "VERTEX3"))
+ f=(f,VERTEX3);
+ else if(!str.compare(start, underscore-start, "VERTEX4"))
+ f=(f,VERTEX4);
+ else if(!str.compare(start, underscore-start, "NORMAL3"))
+ f=(f,NORMAL3);
+ else if(!str.compare(start, underscore-start, "TEXCOORD1"))
+ f=(f,TEXCOORD1);
+ else if(!str.compare(start, underscore-start, "TEXCOORD2"))
+ f=(f,TEXCOORD2);
+ else if(!str.compare(start, underscore-start, "TEXCOORD3"))
+ f=(f,TEXCOORD3);
+ else if(!str.compare(start, underscore-start, "TEXCOORD4"))
+ f=(f,TEXCOORD4);
+ else if(!str.compare(start, underscore-start, "COLOR4UB"))
+ f=(f,COLOR4_UBYTE);
+ else if(!str.compare(start, underscore-start, "COLOR3F"))
+ f=(f,COLOR3_FLOAT);
+ else if(!str.compare(start, underscore-start, "COLOR4F"))
+ f=(f,COLOR4_FLOAT);
else
{
in.setstate(std::ios_base::failbit);
break;
}
- start=comma+1;
- if(comma==std::string::npos)
+
+ if(underscore==std::string::npos)
break;
+ start=underscore+1;
}
return in;