From e92458a4a0e6191bff549a8b316dbbbd7c56e90f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 26 Feb 2008 10:28:32 +0000 Subject: [PATCH] Add class MeshBuilder Enable drawing text with a custom PrimitiveBuilder (possibly into a mesh) Refactor VertexArray and VertexArrayBuilder so that the latter can be created in stack Use the DataType enum in Texture[23]D --- source/font.cpp | 28 +++++++++++++++++++++------- source/font.h | 14 +++++++++++++- source/mesh.cpp | 5 +++++ source/mesh.h | 15 ++++++++++----- source/texture2d.cpp | 8 ++++---- source/texture2d.h | 4 ++-- source/texture3d.cpp | 6 +++--- source/texture3d.h | 4 ++-- source/vertexarray.cpp | 4 ++-- source/vertexarray.h | 20 ++++++++++++-------- source/vertexarraybuilder.cpp | 4 ++-- source/vertexarraybuilder.h | 2 +- 12 files changed, 77 insertions(+), 37 deletions(-) diff --git a/source/font.cpp b/source/font.cpp index 7d9b306b..766f011a 100644 --- a/source/font.cpp +++ b/source/font.cpp @@ -7,6 +7,7 @@ Distributed under the LGPL #include "gl.h" #include "font.h" +#include "immediate.h" #include "primitivetype.h" #include "texture2d.h" @@ -27,6 +28,13 @@ void Font::set_texture(const Texture2D &t) tex=&t; } +const Texture2D &Font::get_texture() const +{ + if(!tex) + throw InvalidState("No texture"); + return *tex; +} + void Font::add_glyph(unsigned code, float x1, float y1, float x2, float y2, float w, float h, float ox, float oy, float adv) { Glyph glyph; @@ -55,26 +63,32 @@ float Font::get_string_width(const string &str, Codecs::Decoder &dec) const void Font::draw_string(const string &str, Codecs::Decoder &dec) const { + Immediate imm((TEXCOORD2, VERTEX2)); + draw_string(str, dec, imm); +} + +void Font::draw_string(const string &str, Codecs::Decoder &dec, PrimitiveBuilder &pbuilder) const +{ + if(!tex) + throw InvalidState("No texture"); + tex->bind(); - VertexArray va((TEXCOORD2, VERTEX2)); - va.reserve(str.size()*4); - RefPtr vab=va.modify(); float x=0; unsigned count=0; + + pbuilder.begin(QUADS); for(string::const_iterator i=str.begin(); i!=str.end();) { GlyphMap::const_iterator j=glyphs.find(dec.decode_char(str, i)); if(j==glyphs.end()) continue; - create_glyph_vertices(j->second, *vab, x); + create_glyph_vertices(j->second, pbuilder, x); x+=j->second.advance; count+=4; } - vab=0; - va.apply(); - glDrawArrays(QUADS, 0, count); + pbuilder.end(); } void Font::create_glyph_vertices(const Glyph &glyph, VertexBuilder &vbuilder, float x) const diff --git a/source/font.h b/source/font.h index f647dbbd..b48c6445 100644 --- a/source/font.h +++ b/source/font.h @@ -17,6 +17,7 @@ Distributed under the LGPL namespace Msp { namespace GL { +class PrimitiveBuilder; class Texture2D; class Font @@ -44,6 +45,7 @@ public: Font(); void set_texture(const Texture2D &); + const Texture2D &get_texture() const; void add_glyph(unsigned, float, float, float, float, float, float, float, float, float); float get_default_size() const { return default_size; } float get_ascent() const { return ascent; } @@ -51,7 +53,7 @@ public: float get_string_width(const std::string &, Codecs::Decoder &) const; void draw_glyph(unsigned); void draw_string(const std::string &, Codecs::Decoder &) const; - void draw_multiline(const std::string &) const; + void draw_string(const std::string &, Codecs::Decoder &, PrimitiveBuilder &) const; template float get_string_width(const std::string &str) const @@ -73,6 +75,16 @@ public: void draw_string(const std::string &str) const { draw_string(str); } + template + void draw_string(const std::string &str, PrimitiveBuilder &pb) const + { + typename C::Decoder dec; + draw_string(str, dec, pb); + } + + void draw_string(const std::string &str, PrimitiveBuilder &pb) const + { return draw_string(str, pb); } + private: struct Glyph { diff --git a/source/mesh.cpp b/source/mesh.cpp index 8d039977..cba1bf57 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -24,6 +24,11 @@ Mesh::Mesh(VertexFormat f): vertices.use_vertex_buffer(); } +RefPtr Mesh::modify() +{ + return new MeshBuilder(*this); +} + void Mesh::add_batch(const Batch &b) { batches.push_back(b); diff --git a/source/mesh.h b/source/mesh.h index 4af66a39..2a5ce474 100644 --- a/source/mesh.h +++ b/source/mesh.h @@ -10,6 +10,7 @@ Distributed under the LGPL #include #include "batch.h" +#include "meshbuilder.h" #include "vertexarray.h" namespace Msp { @@ -17,6 +18,8 @@ namespace GL { class Mesh { + friend class MeshBuilder; + public: class Loader: public DataFile::Loader { @@ -29,16 +32,18 @@ public: void batch(PrimitiveType); }; +private: + VertexArray vertices; + std::list batches; + +public: Mesh(); Mesh(VertexFormat f); - RefPtr modify_vertices() { return vertices.modify(); } - void add_batch(const Batch &b); + RefPtr modify(); const VertexArray &get_vertices() const { return vertices; } + void add_batch(const Batch &b); const std::list &get_batches() { return batches; } void draw() const; -private: - VertexArray vertices; - std::list batches; }; } // namespace GL diff --git a/source/texture2d.cpp b/source/texture2d.cpp index 8a93d031..baee22ee 100644 --- a/source/texture2d.cpp +++ b/source/texture2d.cpp @@ -35,7 +35,7 @@ void Texture2D::storage(PixelFormat fmt, sizei wd, sizei ht, int brd) border=brd; } -void Texture2D::image(int level, PixelFormat fmt, GLenum type, const void *data) +void Texture2D::image(int level, PixelFormat fmt, DataType type, const void *data) { if(width==0) throw InvalidState("Texture storage has not been specified"); @@ -45,7 +45,7 @@ void Texture2D::image(int level, PixelFormat fmt, GLenum type, const void *data) glTexImage2D(target, level, ifmt, width, height, border, fmt, type, data); } -void Texture2D::sub_image(int level, int x, int y, sizei wd, sizei ht, PixelFormat fmt, GLenum type, const void *data) +void Texture2D::sub_image(int level, int x, int y, sizei wd, sizei ht, PixelFormat fmt, DataType type, const void *data) { if(width==0) throw InvalidState("Texture storage has not been specified"); @@ -73,7 +73,7 @@ void Texture2D::image(const Image &img) else if(w!=width || h!=height) throw IncompatibleData("Image does not match texture storage"); - image(0, fmt, GL_UNSIGNED_BYTE, img.get_data()); + image(0, fmt, UNSIGNED_BYTE, img.get_data()); } @@ -96,7 +96,7 @@ void Texture2D::Loader::image_data(const string &data) void Texture2D::Loader::raw_data(const string &data) { Texture2D &t2d=static_cast(tex);; - t2d.image(0, t2d.ifmt, GL_UNSIGNED_BYTE, data.data()); + t2d.image(0, t2d.ifmt, UNSIGNED_BYTE, data.data()); } void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h, unsigned b) diff --git a/source/texture2d.h b/source/texture2d.h index 30eab26c..13073a2d 100644 --- a/source/texture2d.h +++ b/source/texture2d.h @@ -54,13 +54,13 @@ public: this, and the image must have dimensions conforming to the specified storage. */ - void image(int level, PixelFormat fmt, GLenum type, const void *data); + void image(int level, PixelFormat fmt, DataType type, const void *data); /** Uploads a sub-image into the texture. Unlike full image upload, there are no constraints on the size of the sub-image. */ - void sub_image(int level, int x, int y, sizei wd, sizei ht, PixelFormat fmt, GLenum type, const void *data); + void sub_image(int level, int x, int y, sizei wd, sizei ht, PixelFormat fmt, DataType type, const void *data); /** Loads an image from a file and uploads it to the texture. If storage() has diff --git a/source/texture3d.cpp b/source/texture3d.cpp index c38b4465..fdf61cde 100644 --- a/source/texture3d.cpp +++ b/source/texture3d.cpp @@ -41,10 +41,10 @@ void Texture3D::storage(PixelFormat f, sizei w, sizei h, sizei d, int b) ifmt=f; border=b; - image(0, ifmt, GL_UNSIGNED_BYTE, 0); + image(0, ifmt, UNSIGNED_BYTE, 0); } -void Texture3D::image(int level, PixelFormat fmt, GLenum type, const void *data) +void Texture3D::image(int level, PixelFormat fmt, DataType type, const void *data) { maybe_bind(); glTexImage3D(target, level, ifmt, width, height, depth, border, fmt, type, data); @@ -83,7 +83,7 @@ void Texture3D::load_image(const string &fn, int dp) else if(w!=width || h!=height || d!=depth) throw IncompatibleData("Image does not match texture storage"); - image(0, fmt, GL_UNSIGNED_INT, img.get_data()); + image(0, fmt, UNSIGNED_INT, img.get_data()); } } // namespace GL diff --git a/source/texture3d.h b/source/texture3d.h index b4260e88..ec3b57ba 100644 --- a/source/texture3d.h +++ b/source/texture3d.h @@ -27,8 +27,8 @@ private: public: Texture3D(); void storage(PixelFormat, sizei, sizei, sizei, int); - void image(int, PixelFormat, GLenum, const void *); - void sub_image(int, int, int, sizei, sizei, sizei, PixelFormat, GLenum, const void *); + void image(int, PixelFormat, DataType, const void *); + void sub_image(int, int, int, sizei, sizei, sizei, PixelFormat, DataType, const void *); void load_image(const std::string &fn, int dp=-1); sizei get_width() const { return width; } sizei get_height() const { return height; } diff --git a/source/vertexarray.cpp b/source/vertexarray.cpp index 38d490c0..c0ca8dca 100644 --- a/source/vertexarray.cpp +++ b/source/vertexarray.cpp @@ -69,7 +69,7 @@ void VertexArray::reset(VertexFormat f) RefPtr VertexArray::modify() { - return new VertexArrayBuilder(*this, data); + return new VertexArrayBuilder(*this); } void VertexArray::apply() const @@ -144,7 +144,7 @@ unsigned VertexArray::enabled_arrays=0; VertexArray::Loader::Loader(VertexArray &a): - VertexArrayBuilder(a, a.data) + VertexArrayBuilder(a) { add("vertex2", static_cast(&Loader::vertex)); add("vertex3", static_cast(&Loader::vertex)); diff --git a/source/vertexarray.h b/source/vertexarray.h index b1b5fdee..f0baf2d4 100644 --- a/source/vertexarray.h +++ b/source/vertexarray.h @@ -23,6 +23,8 @@ class VertexBuffer; class VertexArray { + friend class VertexArrayBuilder; + public: class Loader: public DataFile::Loader, public VertexArrayBuilder { @@ -30,6 +32,16 @@ public: Loader(VertexArray &); }; +private: + VertexFormat format; + std::vector data; + uint stride; + VertexBuffer *vbuf; + bool own_vbuf; + + VertexArray(const VertexArray &); + VertexArray &operator=(const VertexArray &); +public: VertexArray(VertexFormat); ~VertexArray(); @@ -45,14 +57,6 @@ public: void apply() const; void update_data(); private: - VertexFormat format; - std::vector data; - uint stride; - 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 index 5f469a98..32fa8392 100644 --- a/source/vertexarraybuilder.cpp +++ b/source/vertexarraybuilder.cpp @@ -11,8 +11,8 @@ Distributed under the LGPL namespace Msp { namespace GL { -VertexArrayBuilder::VertexArrayBuilder(VertexArray &a, std::vector &d): - data(d), +VertexArrayBuilder::VertexArrayBuilder(VertexArray &a): + data(a.data), array(a) { } diff --git a/source/vertexarraybuilder.h b/source/vertexarraybuilder.h index 54357677..0b8eef86 100644 --- a/source/vertexarraybuilder.h +++ b/source/vertexarraybuilder.h @@ -22,7 +22,7 @@ class VertexArrayBuilder: public VertexBuilder public: std::vector &data; - VertexArrayBuilder(VertexArray &, std::vector &); + VertexArrayBuilder(VertexArray &); ~VertexArrayBuilder(); private: -- 2.45.2