这是我在做什么的屏幕截图.目前,我无法在该矩形中绘制弯曲的边框.
我的第一个解决方案是:在矩形后面绘制一个四等分的圆,但是,如您所见,如果我调整形状的不透明度,则会显示该四等分的圆.
我知道这对你们来说是非常基本的,但是我并不擅长数学.
我确实尝试过重用圆弧的计算边缘并添加边框的大小,但结果是这样.
我也认为贝塞尔曲线可以替代,但我认为重用计算的顶点并添加所有缺失的顶点会更有效.另外,我不知道如何计算贝塞尔曲线的弯曲点,而找到正确的t量将在计算上非常昂贵,因此我不实现它.
这是我绘制内部四分之一圆的代码,我想我可以重用它.
void drawArc(int x, int y,
int startAngle, int endAngle,
uint32_t radiusX, uint32_t radiusY,
int border_x, int border_y,
const rgb color,
const rgb bcX, const rgb bcY,
uint8_t opacity)
{
if (radiusX <= 0 || radiusY <= 0) return;
static constexpr float DTR = 3.14159 / 180;
float cx, cy;
int step;
static std::vector<float> verts;
static std::vector<uint8_t> colors;
if (startAngle < endAngle)
{
step = +1;
++ endAngle;
} else
{
step = -1;
-- endAngle;
}
verts.clear();
colors.clear();
verts.push_back(x);
verts.push_back(y);
colors.push_back(color[R]);
colors.push_back(color[G]);
colors.push_back(color[B]);
colors.push_back(opacity);
while (startAngle != endAngle)
{
cx = cos(DTR * startAngle) * radiusX;
cy = sin(DTR * startAngle) * radiusY;
verts.push_back(x + cx);
verts.push_back(y - cy);
colors.push_back(color[R]);
colors.push_back(color[G]);
colors.push_back(color[B]);
colors.push_back(opacity);
startAngle += step;
}
drawElements(GL_POLYGON, sizeof(arcIndices) / sizeof(arcIndices[0]), GL_FLOAT,
&verts[0], &colors[0], &arcIndices[0]);
if (border_x != 0 || border_y != 0)
{
//remove (x, y)
verts.erase(verts.begin(), verts.begin() + 2);
// float px, py;
//
// px = *(verts.begin() + 0);
// py = *(verts.begin() + 1);
//
// glPointSize(5);
//
// glBegin(GL_POINTS);
//
// glColor3ub(0,0,255);
// glVertex2i(px, py);
//
// px = *(verts.end() - 2);
// py = *(verts.end() - 1);
//
// glColor3ub(255,0,0);
// glVertex2i(px , py);
// glEnd();
//attempting to reuse the edges
//I think the last vertices are opposed
//that's why I got a crossed out lines??
for (int i = 0;i <= 90; ++i)
{
verts.push_back(verts[i + 0] + border_x);
verts.push_back(verts[i + 1] + border_y);
colors.push_back(bcX[R]);
colors.push_back(bcX[G]);
colors.push_back(bcX[B]);
colors.push_back(opacity);
}
//91 = steps from 0-90 degree revolution
//182 = 91 * 2
unsigned int index[182 + 91 * 2];
for (int i = 0;i < 182 + 91 * 2; ++i)
index[i] = i;
drawElements(GL_LINE_LOOP, verts.size() / 2, GL_FLOAT,
&verts[0], &colors[0], &index[0]);
}
}
编辑:
我不能只重复使用预先计算的(x,y)吗?
对不起,图片使用过多
红点是我正在指的预先计算的(x,y),仅在此基础上附加下一个弧.
我将渲染许多此类内容,因此我需要尽可能高效(不需过多使用trigo函数).
更新:
这是我从使用模板缓冲区作为Andon M. Coleman建议得到的结果:
顺便说一句,如您所见,我正在尝试使用OpenGL:D来模仿自己的UI
解决方法:
您表示有兴趣了解昨天如何使用模板缓冲区解决此问题,因此我将跟进一些基本的伪代码.
glClearStencil (0x0);
glClear (GL_STENCIL_BUFFER_BIT);
glEnable (GL_STENCIL_TEST);
glStencilFunc (GL_ALWAYS, 0x0, 0x0);
// Add 1 to stencil buffer at every location the object to be bordered is visible
glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);
// Draw your grey object
// Only draw the red border where the grey object was never drawn (stencil = 0x0)
glStencilFunc (GL_EQUAL, 0x0, 0xff);
// Draw your red quarter circles
glDisable (GL_STENCIL_TEST);
每次绘制轮廓对象时清除模板缓冲区可能是过大的.如果您选择每帧一次清除模板缓冲区,则可以做一些非常有趣的事情.例如,如果在绘制所有非轮廓线形状之后以单独的方式绘制轮廓线,则可以使用此模具缓冲区设置来轮廓线任何重叠对象的并集(而不是将对象的交集作为绘制轮廓线的一部分) ..这将允许您从简单的圆角矩形构造更复杂的形状.
当然,要使它起作用,您的像素格式必须具有模板缓冲区.我将不得不把这部分交给您,因为设置过程是特定于实现的.