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

至少有三个矩形部分和四个角.计算角坐标很容易.只需从圆圈中找到一个点并构建三角形,如上图所示.
float anglerad = PI * angle / 180.0f;
float x = sinf(anglerad) * radius;
float y = cosf(anglerad) * radius;
Run Code Online (Sandbox Code Playgroud)
它仍然会有锋利的边缘,但更多的点使角落更圆.小物体比大物体需要更少的点.
简单的路线是使用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 );
}
Run Code Online (Sandbox Code Playgroud)
要绘制圆角矩形,只需调用类似于正交视图的内容:
RoundRect( 200, /* x */
400, /* y */
400, /* width */
300, /* height */
25, /* Corner radius, at least less than 140? */
64 /* need to be "dividable" by 4 */ );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16519 次 |
| 最近记录: |