Filled rounded rectangle as a TRIANGLE_LIST mesh.
Composed of a center rect, four edge rects, and four corner fans. corner_radius is clamped to half the shorter axis to prevent overlap. Minimum corner_segments is 1.
126{
127 corner_segments = std::max<uint32_t>(corner_segments, 1U);
128 const float max_r = std::min(region.
width(), region.
height()) * 0.5F;
129 const float r = std::min(corner_radius, max_r);
130
131 const glm::vec2 bl { region.
min.x + r, region.
min.y + r };
132 const glm::vec2 br { region.
max.x - r, region.
min.y + r };
133 const glm::vec2 tl { region.
min.x + r, region.
max.y - r };
134 const glm::vec2 tr { region.
max.x - r, region.
max.y - r };
135
136 std::vector<Kakshya::Vertex> out;
137
138 out.reserve(18 + 4 * (size_t)corner_segments * 3);
139
140
141 auto push_quad = [&](glm::vec2
a, glm::vec2
b, glm::vec2 c, glm::vec2 d) {
142 out.push_back(vert2(
a, color));
143 out.push_back(vert2(
b, color));
144 out.push_back(vert2(c, color));
145 out.push_back(vert2(
b, color));
146 out.push_back(vert2(d, color));
147 out.push_back(vert2(c, color));
148 };
149
150 push_quad({ bl.x, region.
min.y }, { tl.x, region.
max.y }, { tr.x, region.
min.y }, { tr.x, region.
max.y });
151 push_quad({ region.
min.x, bl.y }, { region.
min.x, tl.y }, { bl.x, bl.y }, { bl.x, tl.y });
152 push_quad({ tr.x, br.y }, { tr.x, tr.y }, { region.
max.x, br.y }, { region.
max.x, tr.y });
153
154
155 struct Corner {
156 glm::vec2 c;
157 float a0;
158 };
159 const auto half_pi = glm::half_pi<float>();
160 const Corner corners[4] = {
161 { .c = bl, .a0 = glm::pi<float>() },
162 { .c = br, .a0 = -half_pi },
163 { .c = tl, .a0 = half_pi },
164 { .c = tr, .a0 = 0.F },
165 };
166
167 const float step = half_pi / static_cast<float>(corner_segments);
168 for (const auto& [c, a0] : corners) {
169 for (uint32_t i = 0; i < corner_segments; ++i) {
170 const float a1 = a0 + static_cast<float>(i) * step;
171 const float a2 = a0 + static_cast<float>(i + 1) * step;
172 out.push_back(vert2(c, color));
173 out.push_back(vert2(ring_point(c, r, a1), color));
174 out.push_back(vert2(ring_point(c, r, a2), color));
175 }
176 }
177
178 return out;
179}
float height() const noexcept
float width() const noexcept