How to make rounded rectangle in OpenGL, or any polygon with rounded corners?
I came across this fixing a crash in some open-source software - the non-GL version worked fine but basically the intention was to implement a rounded rectangle but the developer was too lazy for that and decided to force a crash instead :-(
Although I think @vime's answer is succinct and complete, I have seen lots of similar examples, none of which gave me any confidence and that I thought were non-obvious, so here's mine for the record... the calling function implements the 4-corners ( code snippet )...
glBegin(GL_POLYGON);
// top-left corner
DrawGLRoundedCorner(x, y + radius, 3 * PI / 2, PI / 2, radius);
// top-right
DrawGLRoundedCorner(x + size_x - radius, y, 0.0, PI / 2, radius);
// bottom-right
DrawGLRoundedCorner(x + size_x, y + size_y - radius, PI / 2, PI / 2, radius);
// bottom-left
DrawGLRoundedCorner(x + radius, y + size_y, PI, PI / 2, radius);
glEnd();
... and the arc-section function DrawGLRoundedCorner(). Note that this assumes that glBegin() has already been called and plots both the start and the end of the arc - which is why you don't need to explicitly add the vertices at the end of the sides.
void DrawGLRoundedCorner(int x, int y, double sa, double arc, float r) {
// centre of the arc, for clockwise sense
float cent_x = x + r * cos(sa + PI / 2);
float cent_y = y + r * sin(sa + PI / 2);
// build up piecemeal including end of the arc
int n = ceil(N_ROUNDING_PIECES * arc / PI * 2);
for (int i = 0; i <= n; i++) {
double ang = sa + arc * (double)i / (double)n;
// compute the next point
float next_x = cent_x + r * sin(ang);
float next_y = cent_y - r * cos(ang);
glVertex2f(next_x, next_y);
}
}
By using a different glBegin such as with GL_LINE_LOOP I think you would end up with a non-filled rounded rectangle. For larger corner radii there might be a need to use various anti-aliasing hints or the like to make it look prettier, but there are other posts regarding that.
Hope that helps someone.