OpenGL—ES 1.0 2d rounded rectangle

后端 未结 7 446
生来不讨喜
生来不讨喜 2020-12-28 09:46

How to make rounded rectangle in OpenGL, or any polygon with rounded corners?

7条回答
  •  一整个雨季
    2020-12-28 10:25

    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.

提交回复
热议问题