diff --git a/src/rendering/twn_circles.c b/src/rendering/twn_circles.c index 8cab9b2..5b99d84 100644 --- a/src/rendering/twn_circles.c +++ b/src/rendering/twn_circles.c @@ -27,8 +27,10 @@ void create_circle_geometry(Vec2 position, size_t num_vertices, Vec2 vertices[]) { + SDL_assert(num_vertices <= CIRCLE_VERTICES_MAX); + /* the angle (in radians) to rotate by on each iteration */ - float seg_rotation_angle = (360.0f / (float)num_vertices) * ((float)M_PI / 180); + float seg_rotation_angle = (360.0f / (float)(num_vertices - 2)) * ((float)M_PI / 180); vertices[0].x = (float)position.x; vertices[0].y = (float)position.y; @@ -37,7 +39,7 @@ void create_circle_geometry(Vec2 position, float start_x = 0.0f - radius; float start_y = 0.0f; - for (size_t i = 1; i < num_vertices + 1; ++i) { + for (size_t i = 1; i < num_vertices - 1; ++i) { float final_seg_rotation_angle = (float)i * seg_rotation_angle; float c, s; @@ -49,4 +51,18 @@ void create_circle_geometry(Vec2 position, vertices[i].x += position.x; vertices[i].y += position.y; } + + // place a redundant vertex to make proper circling over shared element buffer + { + float final_seg_rotation_angle = (float)1 * seg_rotation_angle; + + float c, s; + sincosf(final_seg_rotation_angle, &s, &c); + + vertices[num_vertices - 1].x = c * start_x - s * start_y; + vertices[num_vertices - 1].y = c * start_y + s * start_x; + + vertices[num_vertices - 1].x += position.x; + vertices[num_vertices - 1].y += position.y; + } } diff --git a/src/rendering/twn_draw_c.h b/src/rendering/twn_draw_c.h index 18db197..3bc3add 100644 --- a/src/rendering/twn_draw_c.h +++ b/src/rendering/twn_draw_c.h @@ -23,7 +23,6 @@ extern Matrix4 camera_look_at_matrix; #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) #define CIRCLE_VERTICES_MAX 2048 -#define CIRCLE_ELEMENT_BUFFER_LENGTH (CIRCLE_VERTICES_MAX * 3) typedef GLuint VertexBuffer; diff --git a/src/rendering/twn_gl_15_rendering.c b/src/rendering/twn_gl_15_rendering.c index e83a586..b548772 100644 --- a/src/rendering/twn_gl_15_rendering.c +++ b/src/rendering/twn_gl_15_rendering.c @@ -867,7 +867,7 @@ static void load_cubemap_side(const char *path, GLenum target) { void render_circle(const CirclePrimitive *circle) { static Vec2 vertices[CIRCLE_VERTICES_MAX]; - int num_vertices = CIRCLE_VERTICES_MAX - 1; + int num_vertices = MIN((int)circle->radius, CIRCLE_VERTICES_MAX); create_circle_geometry(circle->position, circle->radius, @@ -891,8 +891,8 @@ void render_circle(const CirclePrimitive *circle) { command.color = circle->color; command.element_buffer = get_circle_element_buffer(); - command.element_count = num_vertices * 3; - command.range_end = num_vertices * 3; + command.element_count = (num_vertices - 2) * 3; + command.range_end = (num_vertices - 2) * 3; use_texture_mode(circle->color.a == 255 ? TEXTURE_MODE_OPAQUE : TEXTURE_MODE_GHOSTLY); diff --git a/src/rendering/twn_gl_any_rendering.c b/src/rendering/twn_gl_any_rendering.c index 9c30571..982e04c 100644 --- a/src/rendering/twn_gl_any_rendering.c +++ b/src/rendering/twn_gl_any_rendering.c @@ -65,9 +65,9 @@ VertexBuffer get_circle_element_buffer(void) { if (buffer == 0) { buffer = create_vertex_buffer(); - VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * (CIRCLE_VERTICES_MAX - 1) * 3); + VertexBufferBuilder builder = build_vertex_buffer(buffer, sizeof (GLshort) * (CIRCLE_VERTICES_MAX - 2) * 3); - for (size_t i = 1; i < CIRCLE_VERTICES_MAX; ++i) { + for (size_t i = 1; i < CIRCLE_VERTICES_MAX - 1; ++i) { /* first one is center point index, always zero */ GLshort indices[3]; @@ -76,10 +76,7 @@ VertexBuffer get_circle_element_buffer(void) { /* generated point index */ indices[1] = (GLshort)i; - size_t index = (i + 1) % (CIRCLE_VERTICES_MAX - 1); - if (index == 0) /* don't use center for outer ring */ - index = (CIRCLE_VERTICES_MAX - 1); - indices[2] = (GLshort)index; + indices[2] = (GLshort)i + 1; push_to_vertex_buffer_builder(&builder, indices, sizeof indices); }