OpenGL—ES 1.0 2d rounded rectangle

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

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

7条回答
  •  执笔经年
    2020-12-28 10:36

    I needed to draw similar rectangle, but transparent - and code above draws some of triangles overlap. Fixed that, also removed malloc, just to simplify solution. Here is my version:

    typedef struct
    {
        float x;
        float y;
    } Vector2f;
    
    //
    //  Draws rounded rectangle.
    //
    //  Slightly tuned version of http://stackoverflow.com/questions/5369507/opengles-1-0-2d-rounded-rectangle
    //
    #define ROUNDING_POINT_COUNT 8      // Larger values makes circle smoother.
    void DrawRoundRect( float x, float y, float width, float height, float* color = 0, float radius = 0.0 )
    {
        Vector2f top_left[ROUNDING_POINT_COUNT];
        Vector2f bottom_left[ROUNDING_POINT_COUNT];
        Vector2f top_right[ROUNDING_POINT_COUNT];
        Vector2f bottom_right[ROUNDING_POINT_COUNT];
    
        if( radius == 0.0 )
        {
            radius = min(width, height);
            radius *= 0.10; // 10%
        }
    
        int i = 0;
        float x_offset, y_offset;
        float step = ( 2.0f * pi ) / (ROUNDING_POINT_COUNT * 4),
              angle = 0.0f;
    
        unsigned int index = 0, segment_count = ROUNDING_POINT_COUNT;
        Vector2f bottom_left_corner = { x + radius, y - height + radius }; 
    
    
        while( i != segment_count )
        {
            x_offset = cosf( angle );
            y_offset = sinf( angle );
    
    
            top_left[ index ].x = bottom_left_corner.x - 
                                  ( x_offset * radius );
            top_left[ index ].y = ( height - ( radius * 2.0f ) ) + 
                                    bottom_left_corner.y - 
                                  ( y_offset * radius );
    
    
            top_right[ index ].x = ( width - ( radius * 2.0f ) ) + 
                                     bottom_left_corner.x + 
                                   ( x_offset * radius );
            top_right[ index ].y = ( height - ( radius * 2.0f ) ) + 
                                     bottom_left_corner.y -
                                   ( y_offset * radius );
    
    
            bottom_right[ index ].x = ( width - ( radius * 2.0f ) ) +
                                        bottom_left_corner.x + 
                                      ( x_offset * radius );
            bottom_right[ index ].y = bottom_left_corner.y + 
                                      ( y_offset * radius );
    
    
            bottom_left[ index ].x = bottom_left_corner.x - 
                                     ( x_offset * radius );
            bottom_left[ index ].y = bottom_left_corner.y +
                                     ( y_offset * radius );
    
    
            top_left[ index ].x = top_left[ index ].x;
            top_left[ index ].y = top_left[ index ].y;
    
    
            top_right[ index ].x = top_right[ index ].x;
            top_right[ index ].y = top_right[ index ].y;
    
    
            bottom_right[ index ].x = bottom_right[ index ].x ;
            bottom_right[ index ].y = bottom_right[ index ].y;
    
    
            bottom_left[ index ].x =  bottom_left[ index ].x ;
            bottom_left[ index ].y =  bottom_left[ index ].y ;
    
            angle -= step;
    
            ++index;
    
            ++i;
        }
    
        static GLubyte clr[] = { 156, 207, 255, 128 };   // Light blue, 50% transparent.
    
        if( color )
            glColor4fv(color);
        else
            glColor4ubv(clr);
    
        glBegin( GL_TRIANGLE_STRIP );
        {
            // Top
            for( i = segment_count - 1 ; i >= 0 ; i--)
            {
                glVertex2f( top_left[ i ].x, top_left[ i ].y );
                glVertex2f( top_right[ i ].x, top_right[ i ].y );
            }
    
            // In order to stop and restart the strip.
            glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y );
            glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y );
    
            // Center
            glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y );
            glVertex2f( top_left[ 0 ].x, top_left[ 0 ].y );
            glVertex2f( bottom_right[ 0 ].x, bottom_right[ 0 ].y );
            glVertex2f( bottom_left[ 0 ].x, bottom_left[ 0 ].y );
    
            // Bottom
            for( i = 0; i != segment_count ; i++ )
            {
                glVertex2f( bottom_right[ i ].x, bottom_right[ i ].y );    
                glVertex2f( bottom_left[ i ].x, bottom_left[ i ].y );                                    
            }    
        }
        glEnd();
    } //DrawRoundRect
    

提交回复
热议问题