commit c1b14a92e65828d44aa996027a4153101aa01e84
parent b33667baf1857c2b982b78c1a72f2b47fd209a2a
Author: Brian Swetland <swetland@frotz.net>
Date: Mon, 16 Sep 2013 13:28:44 -0700
texturefont: split font resouce (TextureFont) and renderer (Text)
Diffstat:
3 files changed, 99 insertions(+), 69 deletions(-)
diff --git a/common/texturefont.cc b/common/texturefont.cc
@@ -29,24 +29,21 @@
* - explore different vtx formats (int vs float vs short, etc)
*/
-// idx, src, dst, count, offset, stride, divisor
-static VertexAttrDesc layout[] = {
- { 0, SRC_INT32, DST_INTEGER, 4, 0, 16, 6 },
-};
+TextureFont* TextureFont::load(const char *fontname) {
+ TextureFont *f = new TextureFont();
+ if (f->init(fontname)) {
+ delete f;
+ return nullptr;
+ }
+ return f;
+}
int TextureFont::init(const char *fontname) {
- VertexBuffer *vdata[] = { &vtx };
char tmp[256];
float *cdata, *cp;
float dim, adj;
unsigned sz;
header = NULL;
- max = 128;
- count = 0;
- data = (CharData *) malloc(sizeof(CharData) * max);
- if (!data)
- goto fail;
- next = data;
sprintf(tmp, "%s.font.png", fontname);
if (glyphs.load(tmp, OPT_TEX2D_GRAY))
@@ -112,23 +109,13 @@ int TextureFont::init(const char *fontname) {
*cp++ = float(info[n].y) / dim + adj;
}
cbuf.load(cdata, sizeof(float) * 4 * 6 * header->count);
- vtx.load(data, sizeof(CharData) * max);
-
- attr.init(layout, vdata, sizeof(layout) / sizeof(layout[0]));
- dirty = 0;
glGenTextures(1, &tbid);
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_BUFFER, tbid);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, cbuf.id);
-
- color = RGBA(255,255,255,0);
return 0;
fail:
- if (data) {
- free(data);
- data = NULL;
- }
if (header) {
free(header);
header = NULL;
@@ -137,16 +124,58 @@ fail:
return 0;
}
-void TextureFont::clear(void) {
+void TextureFont::measure(const char *s, unsigned *width, unsigned *height) {
+ unsigned w = 0;
+ unsigned h = 0;
+ while (*s) {
+ unsigned n = *s++;
+ if (n == 0)
+ break;
+ if ((n < first) || (n > last))
+ continue;
+ n -= first;
+ unsigned ch = info[n].h;
+ if (ch > h)
+ h = ch;
+ w += info[n].advance;
+ }
+ *width = w;
+ *height = h;
+}
+
+// idx, src, dst, count, offset, stride, divisor
+static VertexAttrDesc layout[] = {
+ { 0, SRC_INT32, DST_INTEGER, 4, 0, 16, 6 },
+};
+
+Text* Text::create(TextureFont *font) {
+ Text *t = new Text();
+ VertexBuffer *vdata[] = { &t->vtx };
+ t->font = font;
+ t->max = 128;
+ t->count = 0;
+ t->data = (CharData*) malloc(sizeof(CharData) * t->max);
+ t->next = t->data;
+ t->color = RGBA(255,255,255,255);
+ t->dirty = 0;
+
+ t->vtx.load(t->data, sizeof(CharData) * t->max);
+ t->attr.init(layout, vdata, sizeof(layout) / sizeof(layout[0]));
+
+ return t;
+};
+
+void Text::clear(void) {
next = data;
count = 0;
+ dirty = 1;
}
-void TextureFont::setColor(unsigned rgba) {
+void Text::setColor(unsigned rgba) {
color = rgba;
}
-void TextureFont::render(void) {
+void Text::render(void) {
if (count == 0)
return;
@@ -155,57 +184,36 @@ void TextureFont::render(void) {
dirty = 0;
}
- effect->apply();
+ font->effect->apply();
+ font->glyphs.use(1);
attr.use();
- glyphs.use(1);
glActiveTexture(GL_TEXTURE0 + 0);
- glBindTexture(GL_TEXTURE_BUFFER, tbid);
- glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, cbuf.id);
+ glBindTexture(GL_TEXTURE_BUFFER, font->tbid);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArraysInstanced(GL_TRIANGLES, 0, 6, count * 6);
glDisable(GL_BLEND);
}
-void TextureFont::measure(const char *s, unsigned *width, unsigned *height) {
- unsigned w = 0;
- unsigned h = 0;
- while (*s) {
- unsigned n = *s++;
- if (n == 0)
- break;
- if ((n < first) || (n > last))
- continue;
- n -= first;
- unsigned ch = info[n].h;
- unsigned cw = info[n].w;
- if (ch > h)
- h = ch;
- w += info[n].advance;
- }
- *width = w;
- *height = h;
-}
-
-void TextureFont::puts(int x, int y, const char *s) {
+void Text::puts(int x, int y, const char *s) {
while (count < max) {
unsigned n = *s++;
if (n == 0)
break;
- if ((n < first) || (n > last))
+ if ((n < font->first) || (n > font->last))
continue;
- n -= first;
- data[count].x = x + info[n].dx;
- data[count].y = y - info[n].dy;
+ n -= font->first;
+ data[count].x = x + font->info[n].dx;
+ data[count].y = y - font->info[n].dy;
data[count].id = n * 6;
data[count].rgba = color & 0xFFFFFF; // strip alpha
count++;
- x += info[n].advance;
+ x += font->info[n].advance;
}
dirty = 1;
}
-void TextureFont::printf(int x, int y, const char *fmt, ...) {
+void Text::printf(int x, int y, const char *fmt, ...) {
char buf[128];
int len;
va_list ap;
diff --git a/common/texturefont.h b/common/texturefont.h
@@ -20,6 +20,7 @@
#include "matrix.h"
#include "Effect.h"
+#include "Renderable.h"
struct CharInfo {
// location in texture
@@ -57,29 +58,46 @@ struct CharData {
};
class TextureFont {
+ friend class Text;
public:
- int init(const char *fontname);
- void render(void);
- void clear(void);
- void printf(int x, int y, const char *fmt, ...);
- void puts(int x, int y, const char *s);
- void setColor(unsigned rgba);
void measure(const char *s, unsigned *width, unsigned *height);
int getMaxHeight(void) { return header->height_max; }
int getMaxAscent(void) { return header->ascent_max; }
+ static TextureFont *load(const char *fontname);
+
private:
+ TextureFont(void) {}
+ DISALLOW_COPY_AND_ASSIGN(TextureFont);
+ int init(const char *fontname);
+
FontInfo *header;
CharInfo *info;
unsigned first;
unsigned last;
Effect *effect;
- VertexBuffer vtx;
VertexBuffer cbuf;
- VertexAttributes attr;
Texture2D glyphs;
-
unsigned tbid;
+};
+
+class Text : public Renderable {
+public:
+ void printf(int x, int y, const char *fmt, ...);
+ void puts(int x, int y, const char *s);
+ void setColor(unsigned rgba);
+ void render(void);
+ void clear(void);
+ static Text* create(TextureFont *_font);
+protected:
+ Text(void) : Renderable() {};
+private:
+ DISALLOW_COPY_AND_ASSIGN(Text);
+
+ TextureFont *font;
+
+ VertexBuffer vtx;
+ VertexAttributes attr;
CharData *data;
CharData *next;
diff --git a/test/object.cc b/test/object.cc
@@ -42,7 +42,8 @@ private:
UniformBuffer obj, mat, scn;
mat4 proj;
- TextureFont font;
+ TextureFont *font;
+ Text *text;
Renderable *fullscreen;
Effect *copy;
@@ -67,7 +68,10 @@ int TestApp::init(void) {
proj.setPerspective(D2R(90.0), width / (float) height, 0.1f, 250.0f);
- font.init("orbitron-bold-72");
+ if (!(font = TextureFont::load("orbitron-bold-72")))
+ return error("cannot load font");
+
+ text = Text::create(font);
/* resources for post-processing */
hblur = Effect::load("rectangle+HBLUR");
@@ -154,9 +158,9 @@ void TestApp::render(void) {
e->apply();
m->render();
- font.clear();
- font.puts(100, 100, "Hello World!");
- font.render();
+ text->clear();
+ text->puts(100, 100, "Hello World!");
+ text->render();
if (postproc) {
glDisable(GL_DEPTH_TEST);