I want to draw a rectangle with rounded corners. An example is this:
For reasons, I prefer to use intermediate mode, but shaders are fine either.
How can I do so in OpenGL? I want to have a method like:
public static void drawRectWithRoundedCorners(float x, float y, float width, float height, float radius, Color color) {
// code
}
I could not find any instructions on it.
I tried to use a texture, the problem was the corners also got stretched so now I cannot use an image.
You create geometry for the circumference and render it ... so shorten the rectangle lines by radius from all sides and add circular arc using circle parametric equation ... (~36 lines per whole circle is usually enough), another option is use shaders and compute the distance to rounded rectangle in fragment shader and simply discard;
pixels outside...
I do not code in JAVA but C++ is close enough so here C++/old api GL example:
void drawRectWithRoundedCorners(float cx,float cy, float dx, float dy, float r,unsigned __int32 rgba)
{
int i;
float x0,y0,x,y,a=0.0;
const int n=9;
const float da=1.5707963267948966192313216916398/float(n);
dx-=r+r;
dy-=r+r;
glColor4ubv((unsigned __int8*)(&rgba));
glBegin(GL_TRIANGLE_FAN);
glVertex2f(cx,cy);
x0=cx+(0.5*dx);
y0=cy+(0.5*dy);
for (i=0;i<n;i++,a+=da)
{
x=x0+(r*cos(a));
y=y0+(r*sin(a));
glVertex2f(x,y);
}
x0-=dx;
for (i=0;i<n;i++,a+=da)
{
x=x0+(r*cos(a));
y=y0+(r*sin(a));
glVertex2f(x,y);
}
y0-=dy;
for (i=0;i<n;i++,a+=da)
{
x=x0+(r*cos(a));
y=y0+(r*sin(a));
glVertex2f(x,y);
}
x0+=dx;
for (i=0;i<n;i++,a+=da)
{
x=x0+(r*cos(a));
y=y0+(r*sin(a));
glVertex2f(x,y);
}
glVertex2f(x,cy+(0.5*dy));
glEnd();
}
to improve speed you could have the 36 cos
and sin
values hardcoded in a table and as cos
is just shifted sin
you can do this:
void drawRectWithRoundedCorners(float cx,float cy, float dx, float dy, float r,unsigned __int32 rgba)
{
int i;
float x0,y0,x,y;
static const float sina[45]={0,0.1736482,0.3420201,0.5,0.6427876,0.7660444,0.8660254,0.9396926,0.9848077,1,0.9848078,0.9396927,0.8660255,0.7660446,0.6427878,0.5000002,0.3420205,0.1736485,3.894144E-07,-0.1736478,-0.3420197,-0.4999996,-0.6427872,-0.7660443,-0.8660252,-0.9396925,-0.9848077,-1,-0.9848078,-0.9396928,-0.8660257,-0.7660449,-0.6427881,-0.5000006,-0.3420208,-0.1736489,0,0.1736482,0.3420201,0.5,0.6427876,0.7660444,0.8660254,0.9396926,0.9848077};
static const float *cosa=sina+9;
dx-=r+r;
dy-=r+r;
glColor4ubv((unsigned __int8*)(&rgba));
glBegin(GL_TRIANGLE_FAN);
glVertex2f(cx,cy);
x0=cx+(0.5*dx);
y0=cy+(0.5*dy);
for (i=0;i<9;i++)
{
x=x0+(r*cosa[i]);
y=y0+(r*sina[i]);
glVertex2f(x,y);
}
x0-=dx;
for (;i<18;i++)
{
x=x0+(r*cosa[i]);
y=y0+(r*sina[i]);
glVertex2f(x,y);
}
y0-=dy;
for (;i<27;i++)
{
x=x0+(r*cosa[i]);
y=y0+(r*sina[i]);
glVertex2f(x,y);
}
x0+=dx;
for (;i<36;i++)
{
x=x0+(r*cosa[i]);
y=y0+(r*sina[i]);
glVertex2f(x,y);
}
glVertex2f(x,cy+(0.5*dy));
glEnd();
}
This is preview of drawRectWithRoundedCorners(200,200,100,50,10,0x00204080);
: