diff options
author | chai <chaifix@163.com> | 2018-09-17 20:59:39 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-09-17 20:59:39 +0800 |
commit | 7d857455fe2355543a70fddfcdcf438b80591972 (patch) | |
tree | 3c3920e1edbe680618dba6450074c7f0944159a9 | |
parent | 67aeffc5fd6573074a450826fe0c000ca2177451 (diff) |
*update
-rw-r--r-- | libjin/Graphics/Color.h | 4 | ||||
-rw-r--r-- | libjin/Graphics/Font.cpp | 68 | ||||
-rw-r--r-- | libjin/Graphics/Font.h | 12 | ||||
-rw-r--r-- | libjin/Graphics/FontData.cpp | 37 | ||||
-rw-r--r-- | libjin/Graphics/FontData.h | 21 | ||||
-rw-r--r-- | libjin/Graphics/font.shader.h | 10 |
6 files changed, 107 insertions, 45 deletions
diff --git a/libjin/Graphics/Color.h b/libjin/Graphics/Color.h index 3a9c54a..6f9e887 100644 --- a/libjin/Graphics/Color.h +++ b/libjin/Graphics/Color.h @@ -13,6 +13,8 @@ namespace jin namespace graphics { + typedef unsigned char Channel; + class Color { public: @@ -72,7 +74,7 @@ namespace graphics return !(r == c.r && g == c.g && b == c.b && a == c.a); } - unsigned char r, g, b, a; + Channel r, g, b, a; //#if LIBJIN_BYTEORDER == LIBJIN_BIG_ENDIAN // unsigned char r, g, b, a; diff --git a/libjin/Graphics/Font.cpp b/libjin/Graphics/Font.cpp index e5caeac..f0cbeb2 100644 --- a/libjin/Graphics/Font.cpp +++ b/libjin/Graphics/Font.cpp @@ -4,6 +4,7 @@ #include "font.h" #include <stdio.h> #include "color.h" +#include "Shader.h" #include "../Common/Array.hpp" namespace jin @@ -11,6 +12,8 @@ namespace jin namespace graphics { + #include "font.shader.h" + using namespace std; using namespace jin::math; @@ -42,7 +45,7 @@ namespace graphics return p + 1; } - /*static*/ Font* Font::createFont(const FontData* fontData, unsigned int fontSzie) + /*static*/ Font* Font::createFont(FontData* fontData, unsigned int fontSzie) { Font* font; try @@ -56,13 +59,15 @@ namespace graphics return font; } - Font::Font(const FontData* f, unsigned int fontSize) + Font::Font(FontData* f, unsigned int fontSize) : xoffset(0) , yoffset(0) , font(f) , fontsize(fontSize) { - baseline = f->getBaseline(fontsize); + font->pushFontsize(fontsize); + baseline = font->getBaseline(); + font->popFontsize(); createTexture(); } @@ -84,7 +89,7 @@ namespace graphics glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RED, GL_UNSIGNED_BYTE, NULL); if (glGetError() != GL_NO_ERROR) { glDeleteTextures(1, &t); @@ -95,7 +100,7 @@ namespace graphics glBindTexture(GL_TEXTURE_2D, 0); return true; } - + void Font::print(const char* text, int x, int y) { const char* p = text; @@ -138,6 +143,8 @@ namespace graphics } while (*p != NULL); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); + static JSLProgram* shader = JSLProgram::createJSLProgram(font_shader); + shader->use(); for (int i = 0; i < glyphinfolist.size(); ++i) { GlyphArrayDrawInfo& info = glyphinfolist[i]; @@ -145,12 +152,29 @@ namespace graphics int s = sizeof(GlyphVertex); glVertexPointer(2, GL_FLOAT, s, &glyphvertices[info.startvertex].x); glTexCoordPointer(2, GL_FLOAT, s, &glyphvertices[info.startvertex].u); - glDrawArrays(GL_QUADS, 0, info.vertexcount); + //glDrawArrays(GL_QUADS, 0, info.vertexcount); glBindTexture(GL_TEXTURE_2D, 0); - } + glBindTexture(GL_TEXTURE_2D, 1); + float xy[] = { + 0,0, + 0,500, + 500, 500, + 500, 0 + }; + float uv[] = { + 0, 0, + 0, 1, + 1, 1, + 1, 0 + }; + glVertexPointer(2, GL_FLOAT, 0, xy); + glTexCoordPointer(2, GL_FLOAT, 0, uv); + glDrawArrays(GL_QUADS, 0, 4); + glBindTexture(GL_TEXTURE_2D, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); + shader->unuse(); } //float Font::getCharWidth(int c, int last) { @@ -180,25 +204,29 @@ namespace graphics //} /** - * 根据unicode渲染字体文件到texture上,并更新glyphs + * 烘焙glyph到贴图上的特定位置,确保不会重叠 */ - Glyph* Font::addGlyph(unsigned int character) + Glyph* Font::bakeGlyph(unsigned int character) { Glyph* glyph = (Glyph*)malloc(sizeof(Glyph)); int w, h; - const Color* bitmap = font->getCodepointBitmap(character, fontsize, &w, &h); + font->pushFontsize(fontsize); + const Channel* bitmap = font->getCodepointBitmapAlpha(character, &w, &h); + //const Color* bitmap32 = font->getCodepointBitmap(character, &w, &h); + font->popFontsize(); GLuint texture = textures.back(); glBindTexture(GL_TEXTURE_2D, texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RGBA, GL_UNSIGNED_BYTE, bitmap); + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RED, GL_UNSIGNED_BYTE, bitmap); glBindTexture(GL_TEXTURE_2D, 0); - for (int y = 0; y < h; ++y) - { - for (int x = 0; x < w; ++x) - { - putchar(" .:ioVM@"[bitmap[y*w + x].a >> 5]); - } - putchar('\n'); - } + //for (int y = 0; y < h; ++y) + //{ + // for (int x = 0; x < w; ++x) + // { + // putchar(" .:ioVM@"[bitmap[y*w + x] >> 5]); + // } + // putchar('\n'); + //} + free((void*)bitmap); float s = TEXTURE_SIZE; glyph->texture = texture; glyph->box.set(xoffset / s, yoffset / s, w / s, h / s); @@ -216,7 +244,7 @@ namespace graphics } else { - Glyph* glyph = addGlyph(character); + Glyph* glyph = bakeGlyph(character); return glyph; } } diff --git a/libjin/Graphics/Font.h b/libjin/Graphics/Font.h index b71c2cc..4b0a850 100644 --- a/libjin/Graphics/Font.h +++ b/libjin/Graphics/Font.h @@ -63,10 +63,14 @@ namespace graphics static const int DEFAULT_FONT_SIZE = 12; public: - static Font* createFont(const FontData* fontData, unsigned int fontSzie = DEFAULT_FONT_SIZE); + static Font* createFont(FontData* fontData, unsigned int fontSzie = DEFAULT_FONT_SIZE); void print(const char* text, int x, int y); +#if defined(font_debug) + void drawAtlas(); +#endif + private: /* font atlas levels */ @@ -77,11 +81,11 @@ namespace graphics //static const int SPACES_PER_TAB = 4; static const int TEXTURE_SIZE = 512; - Font(const FontData* font, unsigned int fontSize); + Font(FontData* font, unsigned int fontSize); ~Font(); bool createTexture(); - Glyph* addGlyph(unsigned int character); + Glyph* bakeGlyph(unsigned int character); Glyph* findGlyph(unsigned int character); //float getCharWidth(int c, int last); @@ -89,7 +93,7 @@ namespace graphics std::vector<GLuint> textures; std::map<unsigned int, Glyph*> glyphs; // map glyph codepoint to Glyph - const FontData* font; + FontData* font; const unsigned int fontsize; unsigned int baseline; diff --git a/libjin/Graphics/FontData.cpp b/libjin/Graphics/FontData.cpp index 68aa417..33d1875 100644 --- a/libjin/Graphics/FontData.cpp +++ b/libjin/Graphics/FontData.cpp @@ -32,6 +32,8 @@ namespace graphics delete raw.data; throw 0; } + /* push default fontsize */ + pushFontsize(FONT_SIZE); } FontData::~FontData() @@ -39,36 +41,49 @@ namespace graphics free(raw.data); } - int FontData::getBaseline(unsigned int px) const + int FontData::getBaseline() const { - float scale = stbtt_ScaleForPixelHeight(&info, px); + float scale = scales.back(); int ascent; stbtt_GetFontVMetrics(&info, &ascent, 0, 0); int baseline = (int)(ascent*scale); return baseline; } - unsigned char* FontData::getCodepointBitmapAlpha(unsigned int codepoint, int px, int* width, int* height) const + unsigned char* FontData::getCodepointBox(unsigned int codepoint, int*x, int* y, int* x1, int*y1) { - float scale = stbtt_ScaleForPixelHeight(&info, px); - unsigned char* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, NULL, NULL); - return bitmap; + return 0; } - unsigned char* FontData::getCodepointBox(unsigned int codepoint, int px, int*x, int* y, int* x1, int*y1) + unsigned char* FontData::getCodepointBitmapBox(unsigned int codepoint, int*x, int* y, int* x1, int*y1) { + return 0; + } + void FontData::pushFontsize(unsigned int fs) + { + float sc = stbtt_ScaleForPixelHeight(&info, fs); + scales.push_back(sc); } - unsigned char* FontData::getCodepointBitmapBox(unsigned int codepoint, int px, int*x, int* y, int* x1, int*y1) + void FontData::popFontsize() { + /* always keep default font size on the bottom of stack */ + if(scales.size() > 1) + scales.pop_back(); + } + Channel* FontData::getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height) const + { + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, NULL, NULL); + return bitmap; } - Color* FontData::getCodepointBitmap(unsigned int codepoint, int px, int* width, int* height) const + Color* FontData::getCodepointBitmap(unsigned int codepoint, int* width, int* height) const { - float scale = stbtt_ScaleForPixelHeight(&info, px); - unsigned char* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, NULL, NULL); + float scale = scales.back(); + Channel* bitmap = stbtt_GetCodepointBitmap(&info, scale, scale, codepoint, width, height, NULL, NULL); int w = *width, h = *height; Color* bitmap32 = new Color[w*h]; for (int y = 0; y < h; ++y) diff --git a/libjin/Graphics/FontData.h b/libjin/Graphics/FontData.h index 1bfaceb..7d48adb 100644 --- a/libjin/Graphics/FontData.h +++ b/libjin/Graphics/FontData.h @@ -2,6 +2,7 @@ #define __LIBJIN_FONTDATA_H #include "../3rdparty/stb/stb_truetype.h" #include "Color.h" +#include <vector> namespace jin { @@ -15,17 +16,19 @@ namespace graphics ~FontData(); - void pushFontsize(int f) { fontsize = f; scale = 0; }; - void popFontsize() { fontsize = 0; scale = 0; }; + void pushFontsize(unsigned int fontsize); + void popFontsize(); - unsigned char* getCodepointBitmapAlpha(unsigned int codepoint, int px, int* width, int* height) const; - Color* getCodepointBitmap(unsigned int codepoint, int px, int* width, int* height) const; - int getBaseline(unsigned int px) const; + Channel* getCodepointBitmapAlpha(unsigned int codepoint, int* width, int* height) const; + Color* getCodepointBitmap(unsigned int codepoint, int* width, int* height) const; + int getBaseline() const; - unsigned char* getCodepointBox(unsigned int codepoint, int px, int*x, int* y, int* x1, int*y1); - unsigned char* getCodepointBitmapBox(unsigned int codepoint, int px, int*x, int* y, int* x1, int*y1); + unsigned char* getCodepointBox(unsigned int codepoint, int*x, int* y, int* x1, int*y1); + unsigned char* getCodepointBitmapBox(unsigned int codepoint, int*x, int* y, int* x1, int*y1); private: + static const unsigned int FONT_SIZE = 12; + FontData(const unsigned char* data, unsigned int size); stbtt_fontinfo info; @@ -34,8 +37,8 @@ namespace graphics unsigned char* data; unsigned int size; } raw; - int fontsize; - float scale; + std::vector<float> scales; + }; } diff --git a/libjin/Graphics/font.shader.h b/libjin/Graphics/font.shader.h new file mode 100644 index 0000000..04db2f0 --- /dev/null +++ b/libjin/Graphics/font.shader.h @@ -0,0 +1,10 @@ +// shader +static const char* font_shader = R"font_shader( +Color effect(Color col, Texture tex, vec2 uv, vec2 xy) +{ +// r + Color c = Texel(tex, uv); + float alpha = c.r; + return Vec4(col.rgb, alpha); +} +)font_shader";
\ No newline at end of file |