From f71aee8c20ff85e4857e4dfad0c20ce606ea3717 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 4 Sep 2007 09:59:14 +0000 Subject: [PATCH] Add Mesh and Batch classes Implement VertexBuffer::unbind correctly Fix VertexFormat parsing Add input conversion for PrimitiveType --- source/batch.cpp | 59 ++++++++++++++++++++++++++++++++++++++++ source/batch.h | 47 ++++++++++++++++++++++++++++++++ source/mesh.cpp | 47 ++++++++++++++++++++++++++++++++ source/mesh.h | 42 ++++++++++++++++++++++++++++ source/primitivetype.cpp | 45 ++++++++++++++++++++++++++++++ source/primitivetype.h | 5 +++- source/vertexarray.cpp | 6 +++- source/vertexbuffer.cpp | 9 ++++++ source/vertexbuffer.h | 2 +- source/vertexformat.cpp | 52 +++++++++++++++++------------------ 10 files changed, 285 insertions(+), 29 deletions(-) create mode 100644 source/batch.cpp create mode 100644 source/batch.h create mode 100644 source/mesh.cpp create mode 100644 source/mesh.h create mode 100644 source/primitivetype.cpp diff --git a/source/batch.cpp b/source/batch.cpp new file mode 100644 index 00000000..d650fda8 --- /dev/null +++ b/source/batch.cpp @@ -0,0 +1,59 @@ +/* $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 &ind) +{ + indices.reserve(indices.size()+ind.size()); + for(vector::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 &ind) +{ + batch.append(ind); +} + +} // namespace GL +} // namespace Msp diff --git a/source/batch.h b/source/batch.h new file mode 100644 index 00000000..aace6528 --- /dev/null +++ b/source/batch.h @@ -0,0 +1,47 @@ +/* $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 +#include +#include +#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 &); + }; + + Batch(PrimitiveType t); + void append(uint); + void append(const std::vector &); + void draw() const; +private: + PrimitiveType type; + std::vector indices; + uint min_index; + uint max_index; +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/mesh.cpp b/source/mesh.cpp new file mode 100644 index 00000000..2f2a29b1 --- /dev/null +++ b/source/mesh.cpp @@ -0,0 +1,47 @@ +/* $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::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 diff --git a/source/mesh.h b/source/mesh.h new file mode 100644 index 00000000..648fb72c --- /dev/null +++ b/source/mesh.h @@ -0,0 +1,42 @@ +/* $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 +#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 batches; +}; + +} // namespace GL +} // namespace Msp + +#endif diff --git a/source/primitivetype.cpp b/source/primitivetype.cpp new file mode 100644 index 00000000..c11a59f7 --- /dev/null +++ b/source/primitivetype.cpp @@ -0,0 +1,45 @@ +/* $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 diff --git a/source/primitivetype.h b/source/primitivetype.h index 459c18e7..40018525 100644 --- a/source/primitivetype.h +++ b/source/primitivetype.h @@ -8,6 +8,7 @@ Distributed under the LGPL #ifndef MSP_GL_PRIMITIVETYPE_H_ #define MSP_GL_PRIMITIVETYPE_H_ +#include #include namespace Msp { @@ -23,10 +24,12 @@ enum PrimitiveType 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 diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index e7d73865..a2d3936c 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -69,7 +69,11 @@ RefPtr VertexArray::modify() 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; diff --git a/source/vertexbuffer.cpp b/source/vertexbuffer.cpp index c10dec40..d579a373 100644 --- a/source/vertexbuffer.cpp +++ b/source/vertexbuffer.cpp @@ -37,6 +37,15 @@ VertexBuffer::~VertexBuffer() glDeleteBuffers(1, &id); } +void VertexBuffer::unbind() +{ + if(bound) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + bound=0; + } +} + const VertexBuffer *VertexBuffer::bound=0; } // namespace GL diff --git a/source/vertexbuffer.h b/source/vertexbuffer.h index 3b1344f9..815e2682 100644 --- a/source/vertexbuffer.h +++ b/source/vertexbuffer.h @@ -21,7 +21,7 @@ public: void data(sizei, void *); ~VertexBuffer(); - static void unbind() { bound=0; } + static void unbind(); private: uint id; diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 25c2b023..5c02f2ab 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -24,42 +24,42 @@ std::istream &operator>>(std::istream &in, VertexFormat &f) 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; -- 2.45.2