#include "gl.h"
#include "font.h"
+#include "immediate.h"
#include "primitivetype.h"
#include "texture2d.h"
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;
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<VertexArrayBuilder> 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
namespace Msp {
namespace GL {
+class PrimitiveBuilder;
class Texture2D;
class Font
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; }
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<class C>
float get_string_width(const std::string &str) const
void draw_string(const std::string &str) const
{ draw_string<Codecs::Utf8>(str); }
+ template<class C>
+ 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<Codecs::Utf8>(str, pb); }
+
private:
struct Glyph
{
vertices.use_vertex_buffer();
}
+RefPtr<MeshBuilder> Mesh::modify()
+{
+ return new MeshBuilder(*this);
+}
+
void Mesh::add_batch(const Batch &b)
{
batches.push_back(b);
#include <msp/datafile/loader.h>
#include "batch.h"
+#include "meshbuilder.h"
#include "vertexarray.h"
namespace Msp {
class Mesh
{
+ friend class MeshBuilder;
+
public:
class Loader: public DataFile::Loader
{
void batch(PrimitiveType);
};
+private:
+ VertexArray vertices;
+ std::list<Batch> batches;
+
+public:
Mesh();
Mesh(VertexFormat f);
- RefPtr<VertexArrayBuilder> modify_vertices() { return vertices.modify(); }
- void add_batch(const Batch &b);
+ RefPtr<MeshBuilder> modify();
const VertexArray &get_vertices() const { return vertices; }
+ void add_batch(const Batch &b);
const std::list<Batch> &get_batches() { return batches; }
void draw() const;
-private:
- VertexArray vertices;
- std::list<Batch> batches;
};
} // namespace GL
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");
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");
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());
}
void Texture2D::Loader::raw_data(const string &data)
{
Texture2D &t2d=static_cast<Texture2D &>(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)
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
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);
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
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; }
RefPtr<VertexArrayBuilder> VertexArray::modify()
{
- return new VertexArrayBuilder(*this, data);
+ return new VertexArrayBuilder(*this);
}
void VertexArray::apply() const
VertexArray::Loader::Loader(VertexArray &a):
- VertexArrayBuilder(a, a.data)
+ VertexArrayBuilder(a)
{
add("vertex2", static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
add("vertex3", static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
class VertexArray
{
+ friend class VertexArrayBuilder;
+
public:
class Loader: public DataFile::Loader, public VertexArrayBuilder
{
Loader(VertexArray &);
};
+private:
+ VertexFormat format;
+ std::vector<float> data;
+ uint stride;
+ VertexBuffer *vbuf;
+ bool own_vbuf;
+
+ VertexArray(const VertexArray &);
+ VertexArray &operator=(const VertexArray &);
+public:
VertexArray(VertexFormat);
~VertexArray();
void apply() const;
void update_data();
private:
- VertexFormat format;
- std::vector<float> 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;
namespace Msp {
namespace GL {
-VertexArrayBuilder::VertexArrayBuilder(VertexArray &a, std::vector<float> &d):
- data(d),
+VertexArrayBuilder::VertexArrayBuilder(VertexArray &a):
+ data(a.data),
array(a)
{ }
public:
std::vector<float> &data;
- VertexArrayBuilder(VertexArray &, std::vector<float> &);
+ VertexArrayBuilder(VertexArray &);
~VertexArrayBuilder();
private: