aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-11-05 21:38:20 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-05 21:38:20 +0100
commite2e7c0bf0747d55967c4be6374f3611cd96babb6 (patch)
tree7267f2086526ac780f57998ff93bae72266e8ddb
parentccb3e58071b3e807109918184727b305df8b96a0 (diff)
Add bounds calculation to text
-rw-r--r--include/mgl/gl.h3
-rw-r--r--include/mgl/graphics/image.h3
-rw-r--r--include/mgl/graphics/shader.h1
-rw-r--r--include/mgl/graphics/text.h2
-rw-r--r--src/gl.c3
-rw-r--r--src/graphics/image.c6
-rw-r--r--src/graphics/shader.c17
-rw-r--r--src/graphics/text.c55
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 */
diff --git a/src/gl.c b/src/gl.c
index efcfbd4..966023a 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -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;
}