From d2f59c3ea1e7a3a262a41888f25f1ef664c2ac1f Mon Sep 17 00:00:00 2001 From: omigamedev Date: Thu, 2 Feb 2017 21:54:48 +0000 Subject: [PATCH] testing bitmap font generation and draw using stb_truetype --- data/layout.xml | 17 +++++++----- engine/app.cpp | 71 +++++++++++++++++++++++++++++++++++++++++------ engine/app.h | 4 +++ engine/pch.h | 5 +++- engine/shader.cpp | 11 ++++++++ engine/shader.h | 5 ++++ 6 files changed, 97 insertions(+), 16 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 5870f49..3e55d57 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -3,21 +3,24 @@ + + + - - - - + + + + - - - + + + diff --git a/engine/app.cpp b/engine/app.cpp index edd0ffa..e0bd349 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -52,6 +52,26 @@ void App::init() "void main(){" " frag = col;" "}"; + static const char* shader_font_v = + "#version 150\n" + "uniform mat4 mvp;" + "uniform vec2 texoff;" + "uniform vec2 texsz;" + "in vec4 pos;" + "in vec2 uvs;" + "out vec2 uv;" + "void main(){" + " uv = texoff + uvs * texsz;" + " gl_Position = mvp * vec4(pos.xyz, 1.f);" + "}"; + static const char* shader_font_f = + "#version 150\n" + "uniform sampler2D tex;" + "in vec2 uv;" + "out vec4 frag;" + "void main(){" + " frag = texture(tex, uv.xy);" + "}"; #ifdef _WIN32 static CONSOLE_SCREEN_BUFFER_INFO info; @@ -77,14 +97,33 @@ void App::init() layout.load("data/layout.xml"); //layout["main"].update(width, height); - sampler.create(); + sampler.create(GL_NEAREST); ShaderManager::create(kShader::Texture, shader_v, shader_f); ShaderManager::create(kShader::Color, shader_color_v, shader_color_f); ShaderManager::create(kShader::UVs, shader_v, shader_uv_f); + ShaderManager::create(kShader::Font, shader_font_v, shader_font_f); WidgetBorder::m_plane.create<1>(1, 1); if (!tex.load("data/uvs.jpg")) printf("error loading image\n"); + + FILE* font_file = fopen("C:\\Windows\\Fonts\\arial.ttf", "rb"); + if (font_file) + { + fseek(font_file, 0, SEEK_END); + long sz = ftell(font_file); + auto data = std::make_unique(sz); + fseek(font_file, 0, SEEK_SET); + int bytes = fread(data.get(), 1, sz, font_file); + int w = 512; + int h = 512; + int num_chars = 96; + auto bitmap = std::make_unique(w*h); + chars.resize(num_chars); + int ret = stbtt_BakeFontBitmap(data.get(), 0, 50, bitmap.get(), w, h, 32, num_chars, chars.data()); + font_tex.create(w, h, GL_RED, bitmap.get()); + } + plane.create<1>(400, 400); glEnable(GL_TEXTURE_2D); glDisable(GL_DEPTH_TEST); @@ -120,12 +159,6 @@ void App::update(float dt) layout[main_id].update(width, height); } - glActiveTexture(GL_TEXTURE0); - tex.bind(); - sampler.bind(0); - ShaderManager::use(kShader::Texture); - ShaderManager::u_int(kShaderUniform::Tex, 0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_SCISSOR_TEST); for (auto& n : layout[main_id]) @@ -138,7 +171,29 @@ void App::update(float dt) } } glDisable(GL_SCISSOR_TEST); - tex.unbind(); + + glm::mat4 proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f); + glm::mat4 tran = glm::translate(glm::vec3(200, 200, 0)); + + static int i = 0; + i = (i + 1) % 32; + auto c = chars["hgfrr56789opk0876ryuewighfcuisdbn"[i] - 32]; + glm::vec2 a(c.x0, c.y0); + glm::vec2 b(c.x1, c.y1); + glm::vec2 s(512, 512); + glm::vec2 tof = a / s; + glm::vec2 tsz = (b - a) / s; + + glActiveTexture(GL_TEXTURE0); + font_tex.bind(); + sampler.bind(0); + ShaderManager::use(kShader::Font); + ShaderManager::u_int(kShaderUniform::Tex, 0); + ShaderManager::u_mat4(kShaderUniform::MVP, proj * tran); + ShaderManager::u_vec2(kShaderUniform::Tof, tof); + ShaderManager::u_vec2(kShaderUniform::Tsz, tsz); + plane.draw_fill(); + font_tex.unbind(); sampler.unbind(); } diff --git a/engine/app.h b/engine/app.h index d4974db..580df95 100644 --- a/engine/app.h +++ b/engine/app.h @@ -10,6 +10,10 @@ class App Sampler sampler; Texture2D tex; LayoutManager layout; + stbtt_fontinfo font; + Texture2D font_tex; + std::vector chars; + Plane plane; public: static App I; float width; diff --git a/engine/pch.h b/engine/pch.h index 3f02b1e..fa437cb 100644 --- a/engine/pch.h +++ b/engine/pch.h @@ -32,5 +32,8 @@ #include #include -#include #endif + +#include +#include +#include diff --git a/engine/shader.cpp b/engine/shader.cpp index 5d500ae..44632aa 100644 --- a/engine/shader.cpp +++ b/engine/shader.cpp @@ -104,6 +104,12 @@ void Shader::u_vec4(kShaderUniform id, const glm::vec4& v) { glUniform4fv(m_umap[id], 1, glm::value_ptr(v)); } + +void Shader::u_vec2(kShaderUniform id, const glm::vec2& v) +{ + glUniform2fv(m_umap[id], 1, glm::value_ptr(v)); +} + void Shader::u_mat4(kShaderUniform id, const glm::mat4& m) { glUniformMatrix4fv(m_umap[id], 1, GL_FALSE, glm::value_ptr(m)); @@ -135,6 +141,11 @@ void ShaderManager::u_vec4(kShaderUniform id, const glm::vec4& v) m_current->u_vec4(id, v); } +void ShaderManager::u_vec2(kShaderUniform id, const glm::vec2& v) +{ + m_current->u_vec2(id, v); +} + void ShaderManager::u_mat4(kShaderUniform id, const glm::mat4& m) { m_current->u_mat4(id, m); diff --git a/engine/shader.h b/engine/shader.h index 4e21454..5bcb5ec 100644 --- a/engine/shader.h +++ b/engine/shader.h @@ -6,6 +6,8 @@ enum class kShaderUniform : uint16_t MVP = const_hash("mvp"), Tex = const_hash("tex"), Col = const_hash("col"), + Tof = const_hash("texoff"), + Tsz = const_hash("texsz"), }; class Shader @@ -16,6 +18,7 @@ public: bool create(const char* vertex, const char* fragment); void use(); void u_vec4(kShaderUniform id, const glm::vec4& v); + void u_vec2(kShaderUniform id, const glm::vec2& v); void u_mat4(kShaderUniform id, const glm::mat4& m); void u_int(kShaderUniform id, int i); }; @@ -25,6 +28,7 @@ enum class kShader : uint16_t Color = const_hash("color"), Texture = const_hash("texture"), UVs = const_hash("uvs"), + Font = const_hash("font"), }; class ShaderManager @@ -36,6 +40,7 @@ public: static void use(kShader id); static void use(const char* name); static void u_vec4(kShaderUniform id, const glm::vec4& v); + static void u_vec2(kShaderUniform id, const glm::vec2& v); static void u_mat4(kShaderUniform id, const glm::mat4& m); static void u_int(kShaderUniform id, int i); };