From a3c6774f211ee765f910df76837548bdadd4e959 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Mon, 15 Nov 2021 08:20:13 +0100 Subject: Add dynamic font atlas creation (not finished) --- include/mgl/gl.h | 3 +++ include/mgl/gl_macro.h | 3 +++ include/mgl/graphics/font.h | 34 ++++++++++++++---------- include/mgl/graphics/font_char_map.h | 50 ++++++++++++++++++++++++++++++++++++ include/mgl/graphics/font_glyph.h | 14 ++++++++++ include/mgl/graphics/rectangle.h | 2 +- include/mgl/graphics/texture.h | 10 ++++++++ include/mgl/system/fileutils.h | 6 +++-- 8 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 include/mgl/graphics/font_char_map.h create mode 100644 include/mgl/graphics/font_glyph.h (limited to 'include') diff --git a/include/mgl/gl.h b/include/mgl/gl.h index fc3ad3c..75bc764 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -27,6 +27,7 @@ typedef struct { void (*glGenTextures)(int n, unsigned int *textures); void (*glDeleteTextures)(int n, const unsigned int *textures); void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels); + void (*glTexSubImage2D)(unsigned int target, int level, int xoffset, int yoffset, int width, int height, unsigned int format, unsigned int type, const void *pixels); void (*glBindTexture)(unsigned int target, unsigned int texture); void (*glTexParameteri)(unsigned int target, unsigned int pname, int param); void (*glHint)(unsigned int target, unsigned int mode); @@ -40,6 +41,7 @@ typedef struct { void (*glPushMatrix)(void); void (*glPopMatrix)(void); void (*glLoadIdentity)(void); + void (*glLoadMatrixf)(const float *m); void (*glTranslatef)(float x, float y, float z); void (*glGenBuffers)(int n, unsigned int *buffers); void (*glBindBuffer)(unsigned int target, unsigned int buffer); @@ -69,6 +71,7 @@ typedef struct { void (*glUniform2f)(int location, float v0, float v1); unsigned int (*glGetError)(void); const unsigned char* (*glGetString)(unsigned int name); + void (*glGetIntegerv)(unsigned int pname, int *params); /* Optional*/ void (*glXSwapIntervalEXT)(Display * dpy, GLXDrawable drawable, int interval); diff --git a/include/mgl/gl_macro.h b/include/mgl/gl_macro.h index aa264ee..5e634df 100644 --- a/include/mgl/gl_macro.h +++ b/include/mgl/gl_macro.h @@ -29,6 +29,7 @@ #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_UNSIGNED_BYTE 0x1401 +#define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_ALPHA 0x1906 #define GL_LUMINANCE 0x1909 @@ -59,7 +60,9 @@ #define GL_QUAD_STRIP 0x0008 #define GL_POLYGON 0x0009 +#define GL_MODELVIEW 0x1700 #define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 #define GL_STREAM_DRAW 0x88E0 #define GL_STATIC_DRAW 0x88E4 diff --git a/include/mgl/graphics/font.h b/include/mgl/graphics/font.h index c4904ff..adcc8a7 100644 --- a/include/mgl/graphics/font.h +++ b/include/mgl/graphics/font.h @@ -1,37 +1,45 @@ #ifndef MGL_FONT_H #define MGL_FONT_H -#include "../system/vec.h" +#include "../system/fileutils.h" +#include "font_char_map.h" #include "texture.h" #include +typedef struct mgl_memory_mapped_file mgl_memory_mapped_file; typedef struct mgl_font mgl_font; -typedef struct { - mgl_vec2f position; - mgl_vec2f size; - mgl_vec2f texture_position; - mgl_vec2f texture_size; - float advance; -} mgl_font_glyph; +typedef enum { + MGL_ATLAS_SECTION_INITIAL, + MGL_ATLAS_SECTION_RIGHT, + MGL_ATLAS_SECTION_BOTTOM +} mgl_font_atlas_render_section; typedef struct { - unsigned char *atlas; int width; int height; + int prev_width; + int prev_height; + mgl_vec2i pointer_position; + mgl_font_atlas_render_section render_section; } mgl_font_atlas; struct mgl_font { mgl_texture texture; mgl_font_atlas font_atlas; unsigned int character_size; - void *packed_chars; - uint32_t num_packed_chars; + mgl_font_char_map char_map; + int current_line_max_height; + void *font_info; }; -int mgl_font_load_from_file(mgl_font *self, const char *filepath, unsigned int character_size); +int mgl_font_load_from_file(mgl_font *self, const mgl_memory_mapped_file *mapped_file, unsigned int character_size); void mgl_font_unload(mgl_font *self); -int mgl_font_get_glyph(const mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph); +/* Note: loads the glyph if it hasn't been loaded yet */ +int mgl_font_get_glyph(mgl_font *self, uint32_t codepoint, mgl_font_glyph *glyph); + +/* Returns the kerning */ +int mgl_font_get_kerning(const mgl_font *self, uint32_t prev_codepoint, uint32_t codepoint); #endif /* MGL_FONT_H */ diff --git a/include/mgl/graphics/font_char_map.h b/include/mgl/graphics/font_char_map.h new file mode 100644 index 0000000..1daf4a2 --- /dev/null +++ b/include/mgl/graphics/font_char_map.h @@ -0,0 +1,50 @@ +#ifndef MGL_FONT_CHAR_MAP_H +#define MGL_FONT_CHAR_MAP_H + +#include "font_glyph.h" +#include +#include +#include + +typedef struct mgl_font_char_entry mgl_font_char_entry; +typedef struct mgl_font_char_map mgl_font_char_map; + +struct mgl_font_char_entry { + uint32_t key; + mgl_font_glyph value; + mgl_font_char_entry *next; + /* TODO: Remove when fonts copy textures */ + mgl_vec2i render_offset; + /* TODO: Remove when fonts copy textures */ + bool rendered; +}; + +typedef struct { + mgl_font_char_map *char_map; + size_t index; + mgl_font_char_entry *value; +} mgl_font_char_iterator; + +struct mgl_font_char_map { + mgl_font_char_entry **entries; + size_t size; + size_t capacity; +}; + +void mgl_font_char_map_init(mgl_font_char_map *self); +void mgl_font_char_map_deinit(mgl_font_char_map *self); + +/* + |value| is copied. + |inserted_entry| is the newly allocated and inserted entry. the entry wont ever reallocate. may be set to NULL to ignore it. +*/ +int mgl_font_char_map_insert(mgl_font_char_map *self, uint32_t key, const mgl_font_glyph *value, mgl_font_char_entry **inserted_entry); +/* The returned value is only valid until the next insert */ +mgl_font_char_entry* mgl_font_char_map_get(const mgl_font_char_map *self, uint32_t key); +void mgl_font_char_map_clear_rendered(mgl_font_char_map *self); + +/* Iterator value is NULL when the end has been reached */ +mgl_font_char_iterator mgl_font_char_map_begin(mgl_font_char_map *self); +void mgl_font_char_iterator_next(mgl_font_char_iterator *self); + +#endif /* MGL_FONT_CHAR_MAP_H */ diff --git a/include/mgl/graphics/font_glyph.h b/include/mgl/graphics/font_glyph.h new file mode 100644 index 0000000..0d9cb2d --- /dev/null +++ b/include/mgl/graphics/font_glyph.h @@ -0,0 +1,14 @@ +#ifndef MGL_FONT_GLYPH_H +#define MGL_FONT_GLYPH_H + +#include "../system/vec.h" + +typedef struct { + mgl_vec2i position; + mgl_vec2i size; + mgl_vec2i texture_position; /* In pixel space */ + mgl_vec2i texture_size; /* In pixel space */ + int advance; +} mgl_font_glyph; + +#endif /* MGL_FONT_GLYPH_H */ diff --git a/include/mgl/graphics/rectangle.h b/include/mgl/graphics/rectangle.h index 5bcc521..c48d108 100644 --- a/include/mgl/graphics/rectangle.h +++ b/include/mgl/graphics/rectangle.h @@ -7,9 +7,9 @@ typedef struct mgl_context mgl_context; typedef struct { - mgl_color color; mgl_vec2f position; mgl_vec2f size; + mgl_color color; } mgl_rectangle; void mgl_rectangle_draw(mgl_context *context, mgl_rectangle *rect); diff --git a/include/mgl/graphics/texture.h b/include/mgl/graphics/texture.h index 9e7a423..61ac273 100644 --- a/include/mgl/graphics/texture.h +++ b/include/mgl/graphics/texture.h @@ -19,18 +19,28 @@ struct mgl_texture { int width; int height; mgl_texture_format format; + int max_width; + int max_height; + bool pixel_coordinates; }; typedef struct { bool compressed; /* false by default */ + bool pixel_coordinates; /* false by default, texture coordinates are normalized */ } mgl_texture_load_options; +int mgl_texture_init(mgl_texture *self); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_file(mgl_texture *self, const char *filepath, mgl_texture_load_options *load_options); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_image(mgl_texture *self, const mgl_image *image, mgl_texture_load_options *load_options); /* |load_options| can be null, in which case the default options are used */ int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, int width, int height, mgl_image_format format, mgl_texture_load_options *load_options); +int mgl_texture_update(mgl_texture *self, const unsigned char *data, int offset_x, int offset_y, int width, int height, mgl_image_format format); +/* |load_options| can be null, in which case the default options are used */ +int mgl_texture_resize(mgl_texture *self, int new_width, int new_height, mgl_texture_load_options *load_options); +/* If |texture| is NULL then no texture is used */ +void mgl_texture_use(const mgl_texture *texture); void mgl_texture_unload(mgl_texture *self); #endif /* MGL_TEXTURE_H */ diff --git a/include/mgl/system/fileutils.h b/include/mgl/system/fileutils.h index 5e45cb3..5add345 100644 --- a/include/mgl/system/fileutils.h +++ b/include/mgl/system/fileutils.h @@ -4,6 +4,8 @@ #include #include +typedef struct mgl_memory_mapped_file mgl_memory_mapped_file; + typedef struct { unsigned char *data; size_t size; @@ -13,11 +15,11 @@ typedef struct { bool null_terminated; /* false by default */ } mgl_file_load_options; -typedef struct { +struct mgl_memory_mapped_file { void *data; size_t size; int fd; -} mgl_memory_mapped_file; +}; typedef struct { bool readable; /* true by default */ -- cgit v1.2.3