aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-09-17 20:59:39 +0800
committerchai <chaifix@163.com>2018-09-17 20:59:39 +0800
commit7d857455fe2355543a70fddfcdcf438b80591972 (patch)
tree3c3920e1edbe680618dba6450074c7f0944159a9
parent67aeffc5fd6573074a450826fe0c000ca2177451 (diff)
*update
-rw-r--r--libjin/Graphics/Color.h4
-rw-r--r--libjin/Graphics/Font.cpp68
-rw-r--r--libjin/Graphics/Font.h12
-rw-r--r--libjin/Graphics/FontData.cpp37
-rw-r--r--libjin/Graphics/FontData.h21
-rw-r--r--libjin/Graphics/font.shader.h10
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