【发布时间】:2013-12-11 00:30:06
【问题描述】:
这是我正在执行的操作的屏幕截图。目前,我无法在这个矩形中绘制曲线边框。
我的第一个解决方案是:在矩形后面画一个四等分圆,但如果我调整形状的不透明度,如您所见,四等分圆会显示出来。
我知道这对你们来说很基础,但我不是很擅长数学。
我确实尝试重用弧的计算边缘并添加边框的大小,但结果是这样。
我也认为 bezier 曲线 可以替代,但我认为重用计算的顶点并添加所有缺失的顶点会更有效。另外,我不知道如何计算 bezier 曲线 的曲线点,并且找到正确数量的 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),并在此基础上附加下一个弧。
我要渲染很多这样的东西,所以我需要尽可能高效(不要过多地使用三角函数)。
更新:
这是我使用stencil buffer 得到的结果,正如Andon M. Coleman 所建议的那样:
顺便说一句,如您所见,我正在尝试使用 OpenGL 模拟我自己的 UI:D
【问题讨论】:
-
您是否考虑过使用模板缓冲区从字面上切出灰色形状覆盖的区域?您将不得不稍微改变绘制的顺序,但您不必使用讨厌的线图元。
-
@AndonM.Coleman 我可能会在应用该矩形的纹理时使用它,但这样做不是很贵吗?
-
@AndonM.Coleman 你能给个链接吗?我该怎么做?我认为这很有趣,并且当我开始在其上应用纹理时会满足我未来的需求。
-
实际上并不比深度测试贵多少。这两件事非常相关。到目前为止,这还不是一个完美的解决方案,但您不必担心圆角正方形外部的顶点与轮廓形状的内部顶点是否匹配。我不知道任何可以描述如何做到这一点的链接,我必须编写一些伪代码来演示......如果你有兴趣,我明天可以做到。
-
@AndonM.Coleman 出于某种原因,我想像 html 的矩形一样绘制它,例如带有锐边和圆边的边框,而内部矩形与外部矩形不同(边框)