diff options
author | dec05eba <dec05eba@protonmail.com> | 2021-11-05 21:38:20 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2021-11-05 21:38:20 +0100 |
commit | e2e7c0bf0747d55967c4be6374f3611cd96babb6 (patch) | |
tree | 7267f2086526ac780f57998ff93bae72266e8ddb | |
parent | ccb3e58071b3e807109918184727b305df8b96a0 (diff) |
Add bounds calculation to text
-rw-r--r-- | include/mgl/gl.h | 3 | ||||
-rw-r--r-- | include/mgl/graphics/image.h | 3 | ||||
-rw-r--r-- | include/mgl/graphics/shader.h | 1 | ||||
-rw-r--r-- | include/mgl/graphics/text.h | 2 | ||||
-rw-r--r-- | src/gl.c | 3 | ||||
-rw-r--r-- | src/graphics/image.c | 6 | ||||
-rw-r--r-- | src/graphics/shader.c | 17 | ||||
-rw-r--r-- | src/graphics/text.c | 55 |
8 files changed, 81 insertions, 9 deletions
diff --git a/include/mgl/gl.h b/include/mgl/gl.h index 1d19339..fc3ad3c 100644 --- a/include/mgl/gl.h +++ b/include/mgl/gl.h @@ -65,7 +65,8 @@ typedef struct { void (*glUseProgram)(unsigned int program); void (*glAttachShader)(unsigned int program, unsigned int shader); int (*glGetUniformLocation)(unsigned int program, const char *name); - void (*glUniform2fv)(int location, int count, const float *value); + void (*glUniform1f)(int location, float v0); + void (*glUniform2f)(int location, float v0, float v1); unsigned int (*glGetError)(void); const unsigned char* (*glGetString)(unsigned int name); diff --git a/include/mgl/graphics/image.h b/include/mgl/graphics/image.h index 40625bb..d27a755 100644 --- a/include/mgl/graphics/image.h +++ b/include/mgl/graphics/image.h @@ -24,6 +24,7 @@ int mgl_image_load_from_file(mgl_image *self, const char *filepath); int mgl_image_load_from_memory(mgl_image *self, const unsigned char *data, size_t size); void mgl_image_unload(mgl_image *self); -size_t mgl_image_get_size(mgl_image *self); +size_t mgl_image_get_size(const mgl_image *self); +int mgl_image_get_num_channels(const mgl_image *self); #endif /* MGL_IMAGE_H */ diff --git a/include/mgl/graphics/shader.h b/include/mgl/graphics/shader.h index ec89df7..daf8ac3 100644 --- a/include/mgl/graphics/shader.h +++ b/include/mgl/graphics/shader.h @@ -22,6 +22,7 @@ int mgl_shader_program_add_shader_from_file(mgl_shader_program *self, const char int mgl_shader_program_add_shader_from_memory(mgl_shader_program *self, const unsigned char *shader_data, int shader_size, mgl_shader_type shader_type); int mgl_shader_program_finalize(mgl_shader_program *self); +int mgl_shader_program_set_uniform_float(mgl_shader_program *self, const char *uniform_name, float value); int mgl_shader_program_set_uniform_vec2f(mgl_shader_program *self, const char *uniform_name, mgl_vec2f value); /* If |shader_program| is NULL then no shader is used */ diff --git a/include/mgl/graphics/text.h b/include/mgl/graphics/text.h index 9169ab0..f832605 100644 --- a/include/mgl/graphics/text.h +++ b/include/mgl/graphics/text.h @@ -29,6 +29,7 @@ typedef struct { size_t text_size; mgl_color color; mgl_vec2f position; + mgl_vec2f bounds; mgl_text_options options; } mgl_text; @@ -46,6 +47,7 @@ void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size); void mgl_text_set_font(mgl_text *self, mgl_font *font); void mgl_text_set_position(mgl_text *self, mgl_vec2f position); void mgl_text_set_color(mgl_text *self, mgl_color color); +mgl_vec2f mgl_text_get_bounds(const mgl_text *self); void mgl_text_draw(mgl_context *context, mgl_text *text); #endif /* MGL_TEXT_H */ @@ -80,7 +80,8 @@ int mgl_gl_load(mgl_gl *self) { { &self->glUseProgram, "glUseProgram" }, { &self->glAttachShader, "glAttachShader" }, { &self->glGetUniformLocation, "glGetUniformLocation" }, - { &self->glUniform2fv, "glUniform2fv" }, + { &self->glUniform1f, "glUniform1f" }, + { &self->glUniform2f, "glUniform2f" }, { &self->glGetError, "glGetError" }, { &self->glGetString, "glGetString" }, diff --git a/src/graphics/image.c b/src/graphics/image.c index 9934b42..0a6a88a 100644 --- a/src/graphics/image.c +++ b/src/graphics/image.c @@ -88,6 +88,10 @@ void mgl_image_unload(mgl_image *self) { self->format = 0; } -size_t mgl_image_get_size(mgl_image *self) { +size_t mgl_image_get_size(const mgl_image *self) { return (size_t)self->width * (size_t)self->height * mgl_image_format_num_channels(self->format); } + +int mgl_image_get_num_channels(const mgl_image *self) { + return mgl_image_format_num_channels(self->format); +} diff --git a/src/graphics/shader.c b/src/graphics/shader.c index 9afde0e..8f44f0f 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -173,6 +173,21 @@ int mgl_shader_program_finalize(mgl_shader_program *self) { /* TODO: Optimize glUseProgram */ /* TODO: Optimize glGetUniformLocation */ +/* TODO: Check if the uniform type matches the type of the value we want to set it to */ + +int mgl_shader_program_set_uniform_float(mgl_shader_program *self, const char *uniform_name, float value) { + mgl_context *context = mgl_get_context(); + int uniform_location = context->gl.glGetUniformLocation(self->id, uniform_name); + if(uniform_location == -1) { + fprintf(stderr, "Error: no uniform by the name %s was found in the shader\n", uniform_name); + return -1; + } + + context->gl.glUseProgram(self->id); + context->gl.glUniform1f(uniform_location, value); + context->gl.glUseProgram(0); + return 0; +} int mgl_shader_program_set_uniform_vec2f(mgl_shader_program *self, const char *uniform_name, mgl_vec2f value) { mgl_context *context = mgl_get_context(); @@ -183,7 +198,7 @@ int mgl_shader_program_set_uniform_vec2f(mgl_shader_program *self, const char *u } context->gl.glUseProgram(self->id); - context->gl.glUniform2fv(uniform_location, 1, &value.x); + context->gl.glUniform2f(uniform_location, value.x, value.y); context->gl.glUseProgram(0); return 0; } diff --git a/src/graphics/text.c b/src/graphics/text.c index 723b37a..31ae794 100644 --- a/src/graphics/text.c +++ b/src/graphics/text.c @@ -11,6 +11,8 @@ takes a while. */ +#define TAB_WIDTH 4 + static bool default_syntax_highlight(void *userdata, const char *str, size_t size, mgl_color *color) { (void)userdata; (void)str; @@ -19,10 +21,42 @@ static bool default_syntax_highlight(void *userdata, const char *str, size_t siz return false; } +static float fmax(float a, float b) { + return a >= b ? a : b; +} + +static mgl_vec2f mgl_text_calculate_bounds(mgl_text *self) { + mgl_vec2f bounds; + bounds.x = 0.0f; + bounds.y = self->font->character_size; + + /* TODO: Combine this with the loop in mgl_text_draw */ + mgl_font_glyph glyph; + float width = 0.0f; + for(size_t i = 0; i < self->text_size; ++i) { + unsigned char c = *(unsigned char*)&self->text[i]; + if((c >= 32 && c < 128)) { + if(mgl_font_get_glyph(self->font, c, &glyph) == 0) { + width += glyph.advance; + bounds.x = fmax(bounds.x, width); + } + } else if(c == '\t') { + if(mgl_font_get_glyph(self->font, ' ', &glyph) == 0) { + width += (glyph.advance * TAB_WIDTH); + bounds.x = fmax(bounds.x, width); + } + } else if(c == '\n') { + width = 0.0f; + bounds.y += self->font->character_size; + } + } + + return bounds; +} + int mgl_text_init(mgl_text *self, mgl_font *font, const char *str, size_t str_size, mgl_text_options *options) { self->font = font; - self->text = str; - self->text_size = str_size; + mgl_text_set_string(self, str, str_size); self->color = (mgl_color){ 255, 255, 255, 255 }; self->position = (mgl_vec2f){ 0.0f, 0.0f }; @@ -46,10 +80,20 @@ void mgl_text_deinit(mgl_text *self) { void mgl_text_set_string(mgl_text *self, const char *str, size_t str_size) { self->text = str; self->text_size = str_size; + if(self->text && self->text_size > 0 && self->font) + self->bounds = mgl_text_calculate_bounds(self); + else + self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; } void mgl_text_set_font(mgl_text *self, mgl_font *font) { self->font = font; + if(self->font) { + if(self->bounds.x < 0.001f && self->bounds.y < 0.001f) + self->bounds = mgl_text_calculate_bounds(self); + } else { + self->bounds = (mgl_vec2f){ 0.0f, 0.0f }; + } } void mgl_text_set_position(mgl_text *self, mgl_vec2f position) { @@ -60,6 +104,10 @@ void mgl_text_set_color(mgl_text *self, mgl_color color) { self->color = color; } +mgl_vec2f mgl_text_get_bounds(const mgl_text *self) { + return self->bounds; +} + static void mgl_text_draw_glyph(mgl_context *context, mgl_font_glyph *glyph, mgl_vec2f position) { context->gl.glTexCoord2f(glyph->texture_position.x, glyph->texture_position.y); context->gl.glVertex3f(position.x + glyph->position.x, position.y + glyph->position.y, 0.0f); @@ -116,8 +164,7 @@ void mgl_text_draw(mgl_context *context, mgl_text *text) { } } else if(c == '\t') { if(mgl_font_get_glyph(text->font, ' ', &glyph) == 0) { - const int tab_width = 4; - for(int i = 0; i < tab_width; ++i) { + for(int i = 0; i < TAB_WIDTH; ++i) { mgl_text_draw_glyph(context, &glyph, position); position.x += glyph.advance; } |