diff --git a/src/draw.cpp b/src/draw.cpp index 7b3e50c..d54512e 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -108,7 +108,40 @@ namespace glez::draw void line(int x, int y, int dx, int dy, rgba color, int thickness) { + detail::render::vertex vertices[4]; + for (auto &vertex : vertices) + { + vertex.mode = static_cast(detail::program::mode::PLAIN); + vertex.color = color; + } + + float nx = dx; + float ny = dy; + + float ex = x + dx; + float ey = y + dy; + + float length = sqrtf(nx * nx + ny * ny); + + if (length == 0) + return; + + nx /= length; + ny /= length; + + nx *= thickness * 0.5f; + ny *= thickness * 0.5f; + + float px = ny; + float py = -nx; + + vertices[0].position = { x - nx + px, y - ny + py }; + vertices[1].position = { x + nx + px, y + ny + py }; + vertices[2].position = { x + dx + nx - px, y + dy + ny - py }; + vertices[3].position = { x + dx - nx - px, y + dy - ny - py }; + + ftgl::vertex_buffer_push_back(detail::program::buffer, vertices, 4, indices::rectangle, 6); } void rect(int x, int y, int w, int h, rgba color) @@ -131,13 +164,28 @@ void rect(int x, int y, int w, int h, rgba color) void rect_outline(int x, int y, int w, int h, rgba color, int thickness) { - + rect(x, y, w, 1, color); + rect(x, y, 1, h, color); + rect(x + w - 1, y, 1, h, color); + rect(x, y + h - 1, w, 1, color); } void circle(int x, int y, int radius, rgba color, int thickness, int steps) { - + float px = 0; + float py = 0; + for (int i = 0; i < steps; i++) + { + float ang = 2 * float(M_PI) * (float(i) / steps); + if (!i) + ang = 2 * float(M_PI) * (float(steps - 1) / float(steps)); + if (i) + line(px, py, x - px + radius * cos(ang), + y - py + radius * sin(ang), color, thickness); + px = x + radius * cos(ang); + py = y + radius * sin(ang); + } } void string(int x, int y, const std::string &string, font& font, diff --git a/src/glez.c b/src/glez.c index 5989dc6..3729927 100644 --- a/src/glez.c +++ b/src/glez.c @@ -16,313 +16,4 @@ #include #include -/* Drawing functions */ - -void glez_line(float x, float y, float dx, float dy, glez_rgba_t color, - float thickness) -{ - /*x += 0.325f; - y += 0.325f; - - dx -= 0.325f; - dy -= 0.325f;*/ - x += 1; - - GLuint indices[6] = { 0, 3, 2, 2, 1, 0 }; - - struct vertex_main vertices[4]; - - float nx = dx; - float ny = dy; - - float ex = x + dx; - float ey = y + dy; - - float length = sqrtf(nx * nx + ny * ny); - - if (length == 0) - return; - - nx /= length; - ny /= length; - - nx *= thickness * 0.5f; - ny *= thickness * 0.5f; - - float px = ny; - float py = -nx; - - vertices[0].position.x = x + -nx + px; - vertices[0].position.y = y + -ny + py; - vertices[0].color = color; - vertices[0].mode = DRAW_MODE_PLAIN; - - vertices[1].position.x = ex + nx + px; - vertices[1].position.y = ey + ny + py; - vertices[1].color = color; - vertices[1].mode = DRAW_MODE_PLAIN; - - vertices[2].position.x = ex + nx + -px; - vertices[2].position.y = ey + ny + -py; - vertices[2].color = color; - vertices[2].mode = DRAW_MODE_PLAIN; - - vertices[3].position.x = x + -nx + -px; - vertices[3].position.y = y + -ny + -py; - vertices[3].color = color; - vertices[3].mode = DRAW_MODE_PLAIN; - - vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); -} - -void glez_rect(float x, float y, float w, float h, glez_rgba_t color) -{ - struct vertex_main vertices[4]; - GLuint indices[6] = { 0, 1, 2, 2, 3, 0 }; - - vertices[0].position.x = x; - vertices[0].position.y = y; - vertices[0].color = color; - vertices[0].mode = DRAW_MODE_PLAIN; - - vertices[1].position.x = x; - vertices[1].position.y = y + h; - vertices[1].color = color; - vertices[1].mode = DRAW_MODE_PLAIN; - - vertices[2].position.x = x + w; - vertices[2].position.y = y + h; - vertices[2].color = color; - vertices[2].mode = DRAW_MODE_PLAIN; - - vertices[3].position.x = x + w; - vertices[3].position.y = y; - vertices[3].color = color; - vertices[3].mode = DRAW_MODE_PLAIN; - - vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); -} - -void glez_rect_outline(float x, float y, float w, float h, glez_rgba_t color, - float thickness) -{ - glez_rect(x, y, w, 1, color); - glez_rect(x, y, 1, h, color); - glez_rect(x + w - 1, y, 1, h, color); - glez_rect(x, y + h - 1, w, 1, color); -} -void glez_rect_textured(float x, float y, float w, float h, glez_rgba_t color, - glez_texture_t texture, float tx, float ty, float tw, - float th, float angle) -{ - internal_texture_t *tex = internal_texture_get(texture); - internal_texture_bind(texture); - - /*x += 0.375f; - y += 0.375f;*/ - - GLuint idx = program_next_index(); - - struct vertex_main vertices[4]; - GLuint indices[6] = { idx, idx + 1, idx + 2, idx + 2, idx + 3, idx }; - - float s0 = tx / tex->width; - float s1 = (tx + tw) / tex->width; - float t0 = ty / tex->height; - float t1 = (ty + th) / tex->height; - - vertices[0].position.x = x; - vertices[0].position.y = y; - vertices[0].tex_coords.x = s0; - vertices[0].tex_coords.y = t1; - vertices[0].color = color; - vertices[0].mode = DRAW_MODE_TEXTURED; - - vertices[1].position.x = x; - vertices[1].position.y = y + h; - vertices[1].tex_coords.x = s0; - vertices[1].tex_coords.y = t0; - vertices[1].color = color; - vertices[1].mode = DRAW_MODE_TEXTURED; - - vertices[2].position.x = x + w; - vertices[2].position.y = y + h; - vertices[2].tex_coords.x = s1; - vertices[2].tex_coords.y = t0; - vertices[2].color = color; - vertices[2].mode = DRAW_MODE_TEXTURED; - - vertices[3].position.x = x + w; - vertices[3].position.y = y; - vertices[3].tex_coords.x = s1; - vertices[3].tex_coords.y = t1; - vertices[3].color = color; - vertices[3].mode = DRAW_MODE_TEXTURED; - - if (angle) { - float v1[2] = {vertices[0].position.x, vertices[0].position.y}; - float v2[2] = {vertices[1].position.x, vertices[1].position.y}; - float v3[2] = {vertices[2].position.x, vertices[2].position.y}; - float v4[2] = {vertices[3].position.x, vertices[3].position.y}; - vertices[0].position.x = -tw; - vertices[1].position.x = -tw; - vertices[2].position.x = tw; - vertices[3].position.x = tw; - - vertices[0].position.y = -th; - vertices[1].position.y = th; - vertices[2].position.y = th; - vertices[3].position.y = -th; - for (int i = 0; i < 4; i++) { - float x = vertices[i].position.x; - float y = vertices[i].position.y; - vertices[i].position.x = x *cos(angle) - y *sin(angle); - vertices[i].position.y = x *sin(angle) + y *cos(angle); - } - vertices[0].position.x += v1[0]; - vertices[0].position.y += v1[1]; - vertices[1].position.x += v2[0]; - vertices[1].position.y += v2[1]; - vertices[2].position.x += v3[0]; - vertices[2].position.y += v3[1]; - vertices[3].position.x += v4[0]; - vertices[3].position.y += v4[1]; - } - - vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); -} - -/* INTERNAL FUNCTION */ -void draw_string_internal(float x, float y, const char *string, - texture_font_t *fnt, glez_vec4_t color, float *out_x, - float *out_y) -{ - float pen_x = x; - float pen_y = y + fnt->height / 1.5f; - float size_y = 0; - - if (fnt->atlas->id == 0) - { - glGenTextures(1, &fnt->atlas->id); - } - ds_bind_texture(fnt->atlas->id); - if (fnt->atlas->dirty) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, fnt->atlas->width, - fnt->atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE, - fnt->atlas->data); - fnt->atlas->dirty = 0; - } - - int len = strlen(string); - if (len == 0) - return; - - for (size_t i = 0; i < len; ++i) - { - texture_glyph_t *glyph = texture_font_find_glyph(fnt, &string[i]); - if (glyph == NULL) - { - texture_font_load_glyph(fnt, &string[i]); - continue; - } - GLuint indices[6]; - struct vertex_main vertices[4]; - if (i > 0) - { - x += texture_glyph_get_kerning(glyph, &string[i - 1]); - } - - float x0 = (int)(pen_x + glyph->offset_x); - float y0 = (int)(pen_y - glyph->offset_y); - float x1 = (int)(x0 + glyph->width); - float y1 = (int)(y0 + glyph->height); - float s0 = glyph->s0; - float t0 = glyph->t0; - float s1 = glyph->s1; - float t1 = glyph->t1; - - indices[0] = 0; - indices[1] = 1; - indices[2] = 2; - indices[3] = 2; - indices[4] = 3; - indices[5] = 0; - - vertices[0] = (struct vertex_main){ (vec2){ x0, y0 }, (vec2){ s0, t0 }, - color, DRAW_MODE_FREETYPE }; - vertices[1] = (struct vertex_main){ (vec2){ x0, y1 }, (vec2){ s0, t1 }, - color, DRAW_MODE_FREETYPE }; - vertices[2] = (struct vertex_main){ (vec2){ x1, y1 }, (vec2){ s1, t1 }, - color, DRAW_MODE_FREETYPE }; - vertices[3] = (struct vertex_main){ (vec2){ x1, y0 }, (vec2){ s1, t0 }, - color, DRAW_MODE_FREETYPE }; - - pen_x += glyph->advance_x; - //pen_x = (int) pen_x + 1; - if (glyph->height > size_y) - size_y = glyph->height; - - vertex_buffer_push_back(program.buffer, vertices, 4, indices, 6); - } - - if (out_x) - *out_x = pen_x - x; - if (out_y) - *out_y = size_y; -} - -void glez_string(float x, float y, const char *string, glez_font_t font, - glez_rgba_t color, float *out_x, float *out_y) -{ - texture_font_t *fnt = internal_font_get(font); - - ds_bind_texture(fnt->atlas->id); - - fnt->rendermode = RENDER_NORMAL; - fnt->outline_thickness = 0.0f; - - draw_string_internal(x, y, string, fnt, color, out_x, out_y); -} - -void glez_string_with_outline(float x, float y, const char *string, - glez_font_t font, glez_rgba_t color, - glez_rgba_t outline_color, float outline_width, - int adjust_outline_alpha, float *out_x, - float *out_y) -{ - if (adjust_outline_alpha) - outline_color.a = color.a; - - texture_font_t *fnt = internal_font_get(font); - - fnt->rendermode = RENDER_OUTLINE_POSITIVE; - fnt->outline_thickness = outline_width; - draw_string_internal(x, y, string, fnt, outline_color, NULL, NULL); - - fnt->rendermode = RENDER_NORMAL; - fnt->outline_thickness = 0.0f; - draw_string_internal(x, y, string, fnt, color, out_x, out_y); -} - -void glez_circle(float x, float y, float radius, glez_rgba_t color, - float thickness, int steps) -{ - float px = 0; - float py = 0; - for (int i = 0; i < steps; i++) - { - float ang = 2 * M_PI * ((float) i / steps); - if (!i) - ang = 2 * M_PI * ((float) (steps - 1) / steps); - if (i) - glez_line(px, py, x - px + radius * cos(ang), - y - py + radius * sin(ang), color, thickness); - px = x + radius * cos(ang); - py = y + radius * sin(ang); - } -} +/* Drawing functions