Vir*_*rne 19
如果绝对需要使用多边形,例如,如果需要对具有舍入的对象进行缩放或缩放,或者需要控制舍入量,则可以将矩形拆分为多个子对象.

至少有三个矩形部分和四个角.计算角坐标很容易.只需从圆圈中找到一个点并构建三角形,如上图所示.
 float anglerad = PI * angle / 180.0f;
 float x = sinf(anglerad) * radius; 
 float y = cosf(anglerad) * radius;
它仍然会有锋利的边缘,但更多的点使角落更圆.小物体比大物体需要更少的点.
简单的路线是使用GL_TRIANGLE_FAN作为角落.但是对于OpenGL ES,最好尽量减少OpenGL调用量并使用更多顶点,因为可以将整个对象构建为GL_TRIANGLE_STRIP.
这个接近可以用于任何形状.对于矩形,角的角度始终为90度,但是对于其他形状,需要从边缘计算角度.
另一种方法称为9切片缩放.矩形和纹理分为9个切片.实际的舍入位于纹理的角落.想法是角落没有缩放,但保持其原始大小.这种方法在UI设计中被广泛使用,允许可变大小的UI元素,如按钮.它的优点是一个矩形只需要这9个四边形来渲染.但如果角落需要缩放,特别是如果纹理分辨率低,那么它看起来会很糟糕.
有点磕磕碰碰但是今天我遇到了同样的问题,这就是我输出的,它是用Desktop GL创建的,但应该很容易转换为GLES,一切都是条带.它可能没有应有的优化,但如果有人想要刺它,请成为我的客人;)
typedef struct
{
    float x;
    float y;
} Vector2f;
void RoundRect( int x,
            int y,
            int width,
            int height,
            int radius,
            int resolution )
{
float step = ( 2.0f * M_PI ) / resolution,
      angle = 0.0f,
      x_offset,
      y_offset;
int i = 0;
unsigned int index = 0,
             segment_count = ( int )( resolution / 4 );
Vector2f *top_left             = ( Vector2f * ) malloc( segment_count * sizeof( Vector2f ) ), 
         *bottom_left         = ( Vector2f * ) malloc( segment_count * sizeof( Vector2f ) ),
         *top_right             = ( Vector2f * ) malloc( segment_count * sizeof( Vector2f ) ),
         *bottom_right         = ( Vector2f * ) malloc( segment_count * sizeof( 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 = roundf( top_left[ index ].x );
    top_left[ index ].y = roundf( top_left[ index ].y );
    top_right[ index ].x = roundf( top_right[ index ].x );
    top_right[ index ].y = roundf( top_right[ index ].y );
    bottom_right[ index ].x = roundf( bottom_right[ index ].x );
    bottom_right[ index ].y = roundf( bottom_right[ index ].y );
    bottom_left[ index ].x = roundf( bottom_left[ index ].x );
    bottom_left[ index ].y = roundf( bottom_left[ index ].y );
    angle -= step;
    ++index;
    ++i;
}
glBegin( GL_TRIANGLE_STRIP );
{
    // Top
    {
        i = 0;
        while( i != segment_count )
        {
            //glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
            glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
            glVertex2i( top_left[ i ].x,
                        top_left[ i ].y );
            //glColor4f( 0.0f, 1.0f, 0.0f, 1.0f );
            glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
            glVertex2i( top_right[ i ].x,
                        top_right[ i ].y );
            ++i;
        }
    }
    // In order to stop and restart the strip.
    glColor4f( 0.0f, 1.0f, 0.0f,  1.5f );
    glVertex2i( top_right[ 0 ].x,
                top_right[ 0 ].y );
    glColor4f( 0.0f, 1.0f, 0.0f,  1.5f );
    glVertex2i( top_right[ 0 ].x,
                top_right[ 0 ].y );
    // Center
    {
        //glColor4f( 0.0f, 1.0f, 0.0f,  1.0f );
        glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
        glVertex2i( top_right[ 0 ].x,
                    top_right[ 0 ].y );
        //glColor4f( 1.0f, 0.0f, 0.0f,  1.0f );
        glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
        glVertex2i( top_left[ 0 ].x,
                    top_left[ 0 ].y );
        //glColor4f( 0.0f, 0.0f, 1.0f,  1.0f );
        glColor4f( 0.5f, 0.5f, 0.5f,  1.0f );
        glVertex2i( bottom_right[ 0 ].x,
                    bottom_right[ 0 ].y );
        //glColor4f( 1.0f, 1.0f, 0.0f,  1.0f );
        glColor4f( 0.5f, 0.5f, 0.5f,  1.0f );
        glVertex2i( bottom_left[ 0 ].x,
                    bottom_left[ 0 ].y );
    }
    // Bottom
    i = 0;
    while( i != segment_count )
    {
        //glColor4f( 0.0f, 0.0f, 1.0f,  1.0f );
        glColor4f( 0.5f, 0.5f, 0.5f,  1.0f );
        glVertex2i( bottom_right[ i ].x,
                    bottom_right[ i ].y );    
        //glColor4f( 1.0f, 1.0f, 0.0f,  1.0f );
        glColor4f( 0.5f, 0.5f, 0.5f,  1.0f );
        glVertex2i( bottom_left[ i ].x,
                    bottom_left[ i ].y );                                    
        ++i;
    }    
}
glEnd();
glBegin( GL_LINE_STRIP );
//glColor4f( 0.0f, 1.0f, 1.0f, 1.0f );
glColor4f( 1.0f, 0.5f, 0.0f, 1.0f );
// Border
{
    i = ( segment_count - 1 );
    while( i > -1 )
    {    
        glVertex2i( top_left[ i ].x,
                    top_left[ i ].y );
        --i;
    }
    i = 0;
    while( i != segment_count )
    {    
        glVertex2i( bottom_left[ i ].x,
                    bottom_left[ i ].y );
        ++i;
    }
    i = ( segment_count - 1 );
    while( i > -1 )
    {    
        glVertex2i( bottom_right[ i ].x,
                    bottom_right[ i ].y );
        --i;
    }
    i = 0;
    while( i != segment_count )
    {    
        glVertex2i( top_right[ i ].x,
                    top_right[ i ].y );
        ++i;
    }
    // Close the border.
    glVertex2i( top_left[ ( segment_count - 1 ) ].x,
                top_left[ ( segment_count - 1 ) ].y );
}
glEnd();
glBegin( GL_LINES );
//glColor4f( 0.0f, 1.0f, 1.0f, 1.0f );
glColor4f( 0.0f, 0.5f, 1.0f, 1.0f );
// Separator
{
    // Top bar
    glVertex2i( top_right[ 0 ].x,
                top_right[ 0 ].y );
    glVertex2i( top_left[ 0 ].x,
                top_left[ 0 ].y );    
    // Bottom bar
    glVertex2i( bottom_left[ 0 ].x,
                bottom_left[ 0 ].y );    
    glVertex2i( bottom_right[ 0 ].x,
                bottom_right[ 0 ].y );    
}
glEnd();
free( top_left );
free( bottom_left );
free( top_right );
free( bottom_right );
}
要绘制圆角矩形,只需调用类似于正交视图的内容:
RoundRect( 200, /* x */
           400, /* y */
           400, /* width */
           300, /* height */
           25,  /* Corner radius, at least less than 140? */
           64  /* need to be "dividable" by 4 */ );
| 归档时间: | 
 | 
| 查看次数: | 16519 次 | 
| 最近记录: |