graphics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mcommon/texturefont.cc | 118++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mcommon/texturefont.h | 36+++++++++++++++++++++++++++---------
Mtest/object.cc | 14+++++++++-----
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);