|
|
@@ -10,7 +10,7 @@
|
|
|
#include "vec2.h"
|
|
|
#include "vec4.h"
|
|
|
#include "glyph_attr.h"
|
|
|
-
|
|
|
+#include "simple_render.h"
|
|
|
|
|
|
struct glyph_info {
|
|
|
struct vec2i64 a;
|
|
|
@@ -24,189 +24,53 @@ struct glyph_info {
|
|
|
float tx;
|
|
|
};
|
|
|
|
|
|
-struct free_glyph {
|
|
|
- struct vec2f pos;
|
|
|
- struct vec2f size;
|
|
|
- struct vec2f uv_pos;
|
|
|
- struct vec2f uv_size;
|
|
|
- struct vec4f fg_color;
|
|
|
- struct vec4f bg_color;
|
|
|
-};
|
|
|
-
|
|
|
-DA_DEF_STRUCT(struct free_glyph, free_glyph_da);
|
|
|
-
|
|
|
-struct free_glyph_render {
|
|
|
+struct free_glyph_atlas {
|
|
|
uint32_t font_tex;
|
|
|
struct vec2ui atlas_dim;
|
|
|
- struct free_glyph_da glyphs;
|
|
|
- struct {
|
|
|
- uint32_t vert;
|
|
|
- uint32_t frag;
|
|
|
- } shaders;
|
|
|
- uint32_t prog;
|
|
|
- struct {
|
|
|
- int32_t resolution;
|
|
|
- int32_t time;
|
|
|
- int32_t camera;
|
|
|
- } uniforms;
|
|
|
- uint32_t vao;
|
|
|
- uint32_t vbo;
|
|
|
|
|
|
struct glyph_info g_infos[128];
|
|
|
};
|
|
|
|
|
|
+struct free_glyph_atlas fga_create(FT_Face font_face);
|
|
|
|
|
|
-enum free_glyph_attr_enum {
|
|
|
- FREE_GLYPH_ATTR_POS = 0,
|
|
|
- FREE_GLYPH_ATTR_SIZE,
|
|
|
- FREE_GLYPH_ATTR_UV_POS,
|
|
|
- FREE_GLYPH_ATTR_UV_SIZE,
|
|
|
- FREE_GLYPH_ATTR_FG_COLOR,
|
|
|
- FREE_GLYPH_ATTR_BG_COLOR,
|
|
|
- FREE_GLYPH_ATTR_TOTAL
|
|
|
-};
|
|
|
-
|
|
|
-struct free_glyph_render free_glyph_render_create(FT_Face font_face,
|
|
|
- const char *vert_path,
|
|
|
- const char *frag_path);
|
|
|
+float fga_calc_col(const struct free_glyph_atlas *fga, const struct app *app,
|
|
|
+ const char *cstr, size_t cstr_size,
|
|
|
+ struct vec2f pos, size_t index);
|
|
|
|
|
|
-struct free_glyph_da free_glyph_da_create(void);
|
|
|
-const struct glyph_attr* free_glyph_get_attrs(void);
|
|
|
+float fga_calc_col_buffer(const struct free_glyph_atlas *fga,
|
|
|
+ const struct app *app);
|
|
|
|
|
|
-void free_glyph_render_use(struct free_glyph_render fgr);
|
|
|
+void fga_calc(struct free_glyph_atlas *fga, struct simple_render *sr,
|
|
|
+ const struct app *app, const char *cstr, size_t cstr_size,
|
|
|
+ struct vec2f pos, struct vec4f fg_color, struct vec4f bg_color);
|
|
|
+void fga_calc_buffer(struct free_glyph_atlas *fga, struct simple_render *sr,
|
|
|
+ const struct app *app, struct vec2f pos);
|
|
|
|
|
|
-float free_glyph_render_calc_col(struct free_glyph_render fgr, struct app app,
|
|
|
- const char *cstr, size_t cstr_size,
|
|
|
- struct vec2f pos, size_t index);
|
|
|
+void fga_load_texture_atlas_or_exit(struct free_glyph_atlas *fga,
|
|
|
+ FT_Face font_face);
|
|
|
|
|
|
-float free_glyph_render_calc_col_buffer(struct free_glyph_render fgr,
|
|
|
- struct app app);
|
|
|
-
|
|
|
-struct free_glyph_render free_glyph_render_calc(
|
|
|
- struct free_glyph_render fgr, struct app app,
|
|
|
- const char *cstr, size_t cstr_size, struct vec2f pos,
|
|
|
- struct vec4f fg_color, struct vec4f bg_color);
|
|
|
-struct free_glyph_render free_glyph_render_calc_buffer(
|
|
|
- struct free_glyph_render fgr, struct app app,
|
|
|
- struct vec2f pos);
|
|
|
-
|
|
|
-void free_glyph_render_sync(struct free_glyph_render fgr);
|
|
|
-struct free_glyph_render free_glyph_render_gen_buffer(
|
|
|
- struct free_glyph_render fgr);
|
|
|
-
|
|
|
-struct free_glyph_render free_glyph_render_load_texture_atlas_or_exit(
|
|
|
- struct free_glyph_render fgr,
|
|
|
- FT_Face font_face);
|
|
|
-
|
|
|
-struct vec2ui free_glyph_render_calc_atlas_dimensions(FT_Face font_face);
|
|
|
+struct vec2ui fga_calc_atlas_dimensions(FT_Face font_face);
|
|
|
|
|
|
#if defined(FREE_GLYPH_IMP) || defined(IMP)
|
|
|
|
|
|
#include "shader.h"
|
|
|
#include "gl_util.h"
|
|
|
|
|
|
-struct free_glyph_render
|
|
|
-free_glyph_render_create(FT_Face font_face, const char *vert_path,
|
|
|
- const char *frag_path)
|
|
|
+struct free_glyph_atlas
|
|
|
+fga_create(FT_Face font_face)
|
|
|
{
|
|
|
- struct free_glyph_render fgr = {0};
|
|
|
- fgr = free_glyph_render_load_texture_atlas_or_exit(fgr, font_face);
|
|
|
- fgr.glyphs = free_glyph_da_create();
|
|
|
-
|
|
|
- fgr.shaders.vert = shader_compile_file_or_exit(
|
|
|
- vert_path, GL_VERTEX_SHADER);
|
|
|
- fgr.shaders.frag = shader_compile_file_or_exit(
|
|
|
- frag_path, GL_FRAGMENT_SHADER);
|
|
|
- fgr.prog = program_link_or_exit(fgr.shaders.vert, fgr.shaders.frag);
|
|
|
-
|
|
|
- glUseProgram(fgr.prog);
|
|
|
-
|
|
|
- fgr.uniforms.resolution = get_uniform_or_exit(fgr.prog, "resolution");
|
|
|
- fgr.uniforms.time = get_uniform_or_exit(fgr.prog, "time");
|
|
|
- fgr.uniforms.camera = get_uniform_or_exit(fgr.prog, "camera");
|
|
|
-
|
|
|
- fgr = free_glyph_render_gen_buffer(fgr);
|
|
|
-
|
|
|
- return fgr;
|
|
|
-}
|
|
|
-
|
|
|
-struct free_glyph_da
|
|
|
-free_glyph_da_create(void)
|
|
|
-{
|
|
|
- struct free_glyph_da glys;
|
|
|
- glys.cap = 1024 * 1024;
|
|
|
- glys.size = 0;
|
|
|
- glys.items = calloc(glys.cap, sizeof(struct free_glyph));
|
|
|
- return glys;
|
|
|
-}
|
|
|
-
|
|
|
-const struct glyph_attr *
|
|
|
-free_glyph_get_attrs(void)
|
|
|
-{
|
|
|
- static const struct glyph_attr
|
|
|
- free_glyph_attr[FREE_GLYPH_ATTR_TOTAL] = {
|
|
|
- [FREE_GLYPH_ATTR_POS] = {
|
|
|
- .size = 2,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, pos)
|
|
|
- },
|
|
|
- [FREE_GLYPH_ATTR_SIZE] = {
|
|
|
- .size = 2,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, size)
|
|
|
- },
|
|
|
- [FREE_GLYPH_ATTR_UV_POS] = {
|
|
|
- .size = 2,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, uv_pos)
|
|
|
- },
|
|
|
- [FREE_GLYPH_ATTR_UV_SIZE] = {
|
|
|
- .size = 2,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, uv_size)
|
|
|
- },
|
|
|
- [FREE_GLYPH_ATTR_FG_COLOR] = {
|
|
|
- .size = 4,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, fg_color)
|
|
|
- },
|
|
|
- [FREE_GLYPH_ATTR_BG_COLOR] = {
|
|
|
- .size = 4,
|
|
|
- .type = GL_FLOAT,
|
|
|
- .norm = GL_FALSE,
|
|
|
- .stride = sizeof(struct free_glyph),
|
|
|
- .offset = offsetof(struct free_glyph, bg_color)
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- return free_glyph_attr;
|
|
|
-}
|
|
|
-
|
|
|
-void
|
|
|
-free_glyph_render_use(struct free_glyph_render fgr)
|
|
|
-{
|
|
|
- glBindVertexArray(fgr.vao);
|
|
|
- glBindBuffer(GL_ARRAY_BUFFER, fgr.vbo);
|
|
|
- glUseProgram(fgr.prog);
|
|
|
+ struct free_glyph_atlas fga = {0};
|
|
|
+ fga_load_texture_atlas_or_exit(&fga, font_face);
|
|
|
+ return fga;
|
|
|
}
|
|
|
|
|
|
float
|
|
|
-free_glyph_render_calc_col(struct free_glyph_render fgr, struct app app,
|
|
|
- const char *cstr, size_t cstr_size, struct vec2f pos,
|
|
|
- size_t index)
|
|
|
+fga_calc_col(const struct free_glyph_atlas *fga, const struct app *app,
|
|
|
+ const char *cstr, size_t cstr_size, struct vec2f pos,
|
|
|
+ size_t index)
|
|
|
{
|
|
|
struct vec2f pen = pos;
|
|
|
- struct vec2f dim = vec2f_from_ui(fgr.atlas_dim);
|
|
|
+ struct vec2f dim = vec2f_from_ui(fga->atlas_dim);
|
|
|
if ( index > cstr_size ) {
|
|
|
index = cstr_size - 1;
|
|
|
}
|
|
|
@@ -217,11 +81,11 @@ free_glyph_render_calc_col(struct free_glyph_render fgr, struct app app,
|
|
|
pen.y -= dim.y;
|
|
|
continue;
|
|
|
}
|
|
|
- struct glyph_info gi = fgr.g_infos[(int64_t)c];
|
|
|
+ struct glyph_info gi = fga->g_infos[(int64_t)c];
|
|
|
if ( c == '\t' ) {
|
|
|
c = ' ';
|
|
|
- gi = fgr.g_infos[(int64_t)c];
|
|
|
- gi.a.x *= app.cfg.tab_size;
|
|
|
+ gi = fga->g_infos[(int64_t)c];
|
|
|
+ gi.a.x *= app->cfg.tab_size;
|
|
|
}
|
|
|
|
|
|
pen.x += (float) gi.a.x;
|
|
|
@@ -231,102 +95,78 @@ free_glyph_render_calc_col(struct free_glyph_render fgr, struct app app,
|
|
|
}
|
|
|
|
|
|
float
|
|
|
-free_glyph_render_calc_col_buffer(struct free_glyph_render fgr,
|
|
|
- struct app app)
|
|
|
-{
|
|
|
- return free_glyph_render_calc_col(fgr, app, app.buf.data.items,
|
|
|
- app.buf.data.size, vec2fs(0),
|
|
|
- app.buf.cur);
|
|
|
-}
|
|
|
-
|
|
|
-struct free_glyph_render
|
|
|
-free_glyph_render_calc(struct free_glyph_render fgr, struct app app,
|
|
|
- const char *cstr, size_t cstr_size, struct vec2f pos,
|
|
|
- struct vec4f fg_color, struct vec4f bg_color)
|
|
|
+fga_calc_col_buffer(const struct free_glyph_atlas *fga,
|
|
|
+ const struct app *app)
|
|
|
{
|
|
|
- struct vec2f pen = pos;
|
|
|
- struct vec2f dim = vec2f_from_ui(fgr.atlas_dim);
|
|
|
- for ( size_t i = 0; i < cstr_size; ++i ) {
|
|
|
- char c = cstr[i];
|
|
|
- if ( c == '\n' ) {
|
|
|
- pen.x = 0;
|
|
|
- pen.y -= dim.y;
|
|
|
- continue;
|
|
|
- }
|
|
|
- struct glyph_info gi = fgr.g_infos[(int64_t)c];
|
|
|
- if ( c == '\t' ) {
|
|
|
- c = ' ';
|
|
|
- gi = fgr.g_infos[(int64_t)c];
|
|
|
- gi.a.x *= app.cfg.tab_size;
|
|
|
- }
|
|
|
-
|
|
|
- float w = (float)gi.b.w;
|
|
|
- float h = (float)gi.b.h;
|
|
|
-
|
|
|
- struct free_glyph gly = {
|
|
|
- .pos = {
|
|
|
- pen.x + (float) gi.b.l,
|
|
|
- pen.y + (float) gi.b.t
|
|
|
- },
|
|
|
- .size = {w, -h},
|
|
|
- .uv_pos = { gi.tx, 0.0f },
|
|
|
- .uv_size = { w / dim.x, h / dim.y },
|
|
|
- .fg_color = fg_color,
|
|
|
- .bg_color = bg_color,
|
|
|
- };
|
|
|
-
|
|
|
- pen.x += (float) gi.a.x;
|
|
|
- pen.y += (float) gi.a.y;
|
|
|
-
|
|
|
- DA_APPEND(fgr.glyphs, gly);
|
|
|
- }
|
|
|
- return fgr;
|
|
|
+ return fga_calc_col(fga, app, app->buf.data.items,
|
|
|
+ app->buf.data.size, vec2fs(0),
|
|
|
+ app->buf.cur);
|
|
|
}
|
|
|
|
|
|
-struct free_glyph_render
|
|
|
-free_glyph_render_calc_buffer(struct free_glyph_render fgr,
|
|
|
- struct app app,
|
|
|
- struct vec2f size)
|
|
|
-{
|
|
|
- return free_glyph_render_calc(fgr, app,
|
|
|
- app.buf.data.items, app.buf.data.size,
|
|
|
- size, vec4fs(1), vec4fs(0));
|
|
|
-}
|
|
|
+/* struct free_glyph_atlas */
|
|
|
+/* fga_calc(struct free_glyph_atlas fga, struct app app, */
|
|
|
+/* const char *cstr, size_t cstr_size, struct vec2f pos, */
|
|
|
+/* struct vec4f fg_color, struct vec4f bg_color) */
|
|
|
+/* { */
|
|
|
+/* struct vec2f pen = pos; */
|
|
|
+/* struct vec2f dim = vec2f_from_ui(fga->atlas_dim); */
|
|
|
+/* for ( size_t i = 0; i < cstr_size; ++i ) { */
|
|
|
+/* char c = cstr[i]; */
|
|
|
+/* if ( c == '\n' ) { */
|
|
|
+/* pen.x = 0; */
|
|
|
+/* pen.y -= dim.y; */
|
|
|
+/* continue; */
|
|
|
+/* } */
|
|
|
+/* struct glyph_info gi = fga->g_infos[(int64_t)c]; */
|
|
|
+/* if ( c == '\t' ) { */
|
|
|
+/* c = ' '; */
|
|
|
+/* gi = fga->g_infos[(int64_t)c]; */
|
|
|
+/* gi.a.x *= app.cfg.tab_size; */
|
|
|
+/* } */
|
|
|
+
|
|
|
+/* float w = (float)gi.b.w; */
|
|
|
+/* float h = (float)gi.b.h; */
|
|
|
+
|
|
|
+/* struct free_glyph gly = { */
|
|
|
+/* .pos = { */
|
|
|
+/* pen.x + (float) gi.b.l, */
|
|
|
+/* pen.y + (float) gi.b.t */
|
|
|
+/* }, */
|
|
|
+/* .size = {w, -h}, */
|
|
|
+/* .uv_pos = { gi.tx, 0.0f }, */
|
|
|
+/* .uv_size = { w / dim.x, h / dim.y }, */
|
|
|
+/* .fg_color = fg_color, */
|
|
|
+/* .bg_color = bg_color, */
|
|
|
+/* }; */
|
|
|
+
|
|
|
+/* pen.x += (float) gi.a.x; */
|
|
|
+/* pen.y += (float) gi.a.y; */
|
|
|
+
|
|
|
+/* DA_APPEND(fga->glyphs, gly); */
|
|
|
+/* } */
|
|
|
+/* return fga; */
|
|
|
+/* } */
|
|
|
+
|
|
|
+/* struct free_glyph_atlas */
|
|
|
+/* fga_calc_buffer(struct free_glyph_atlas fga, */
|
|
|
+/* struct app app, */
|
|
|
+/* struct vec2f size) */
|
|
|
+/* { */
|
|
|
+/* return fga_calc(fga, app, */
|
|
|
+/* app.buf.data.items, app.buf.data.size, */
|
|
|
+/* size, vec4fs(1), vec4fs(0)); */
|
|
|
+/* } */
|
|
|
|
|
|
void
|
|
|
-free_glyph_render_sync(struct free_glyph_render fgr)
|
|
|
+fga_load_texture_atlas_or_exit(struct free_glyph_atlas *fga,
|
|
|
+ FT_Face font_face)
|
|
|
{
|
|
|
- glBufferSubData(GL_ARRAY_BUFFER, 0,
|
|
|
- (ssize_t) (fgr.glyphs.size * sizeof(struct free_glyph)),
|
|
|
- fgr.glyphs.items);
|
|
|
-}
|
|
|
-
|
|
|
-struct free_glyph_render
|
|
|
-free_glyph_render_gen_buffer(struct free_glyph_render fgr)
|
|
|
-{
|
|
|
- glGenVertexArrays(1, &fgr.vao);
|
|
|
- glBindVertexArray(fgr.vao);
|
|
|
-
|
|
|
- glGenBuffers(1, &fgr.vbo);
|
|
|
- glBindBuffer(GL_ARRAY_BUFFER, fgr.vbo);
|
|
|
- glBufferData(GL_ARRAY_BUFFER,
|
|
|
- (ssize_t)(fgr.glyphs.cap * sizeof(struct free_glyph)),
|
|
|
- fgr.glyphs.items,
|
|
|
- GL_DYNAMIC_DRAW);
|
|
|
- glyph_attr_declare(free_glyph_get_attrs(), FREE_GLYPH_ATTR_TOTAL);
|
|
|
- return fgr;
|
|
|
-}
|
|
|
-
|
|
|
-struct free_glyph_render
|
|
|
-free_glyph_render_load_texture_atlas_or_exit(struct free_glyph_render fgr,
|
|
|
- FT_Face font_face)
|
|
|
-{
|
|
|
- struct vec2ui dim = free_glyph_render_calc_atlas_dimensions(font_face);
|
|
|
- fgr.atlas_dim = dim;
|
|
|
+ struct vec2ui dim = fga_calc_atlas_dimensions(font_face);
|
|
|
+ fga->atlas_dim = dim;
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
- glGenTextures(1, &fgr.font_tex);
|
|
|
- glBindTexture(GL_TEXTURE_2D, fgr.font_tex);
|
|
|
+ glGenTextures(1, &fga->font_tex);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, fga->font_tex);
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
@@ -358,7 +198,7 @@ free_glyph_render_load_texture_atlas_or_exit(struct free_glyph_render fgr,
|
|
|
GL_RED, GL_UNSIGNED_BYTE,
|
|
|
g->bitmap.buffer);
|
|
|
|
|
|
- fgr.g_infos[i] = (struct glyph_info) {
|
|
|
+ fga->g_infos[i] = (struct glyph_info) {
|
|
|
.a = {
|
|
|
.x = g->advance.x >> 6,
|
|
|
.y = g->advance.y >> 6,
|
|
|
@@ -374,12 +214,10 @@ free_glyph_render_load_texture_atlas_or_exit(struct free_glyph_render fgr,
|
|
|
|
|
|
x += g->bitmap.width;
|
|
|
}
|
|
|
-
|
|
|
- return fgr;
|
|
|
}
|
|
|
|
|
|
struct vec2ui
|
|
|
-free_glyph_render_calc_atlas_dimensions(FT_Face font_face)
|
|
|
+fga_calc_atlas_dimensions(FT_Face font_face)
|
|
|
{
|
|
|
struct vec2ui dim = {0};
|
|
|
|