如何使用亲爱的imgui填充两条贝塞尔曲线之间的区域

时间:2017-12-16 13:18:52

标签: c++ opengl glfw

如何使用dear imgui填充两条贝塞尔曲线之间的区域?

我使用ImDrawList API绘制曲线,如下所示:

        ImVec2 p0(10, 100); ImVec2 c1(110, 50); ImVec2 p1(210, 100);
        ImVec2 q0(10, 200); ImVec2 c2(110, 100); ImVec2 q1(210, 200);

        auto col = IM_COL32(0,255,255, 255);

        ImDrawList* draw_list = ImGui::GetWindowDrawList();

        draw_list->AddBezierCurve(p0, c1, c1, p1, col, 1.0f);
        draw_list->AddBezierCurve(q0, c2, c2, q1, col, 1.0f);

        // I can close the curves, visually, with these lines
        draw_list->AddLine(p0, q0, col, 1.0f);
        draw_list->AddLine(p1, q1, col, 1.0f);

编辑:

我使用有状态API绘制我想要的路径,然后调用一个函数来填充此路径。这是代码:

        draw_list->PathLineTo(p0);
        draw_list->PathBezierCurveTo(c1, c1, p1);
        draw_list->PathLineTo(q1);
        draw_list->PathBezierCurveTo(c2, c2, q0);

        draw_list->PathFillConvex(col);

但是你可以看到有什么问题:

result

正确的几何体以白色绘制。

2 个答案:

答案 0 :(得分:3)

您遇到的问题是,OpenGL中的填充基元仅为基元定义。如果对于集合中的任何两个点,您可以在这些点之间绘制一条线而不离开所述集合的边界,则将集合定义为

亲爱的ImGUI大多只是将已翻译的绘图命令原样传递给OpenGL,没有任何中间的细分。 ...导致您看到的问题以及填充函数为何具有…Convex部分名称。

解决方案是将非凸形状分解为更小的凸形状,或使用也适用于凸形的填充方法,如scanline算法(在GPU上实现)最容易使用计算着色器完成。)

答案 1 :(得分:1)

你需要一个凹面填充算法,亲爱的imgui没有提供。通常,将形状分解为凸形更容易/更快。填充“两个beziers之间”的一般情况是棘手的,因为beziers可以相交,因此可以有多个区域。如果你知道它们永远不会相交并且你的切线不是太疯狂,你可以使用各种近似值。也许尝试绘制N个四边形,其中每个四边形以规则间隔的间隔链接贝塞尔的两个部分等。对于更通用的答案,Datenwolf答案是一个很好的起点。

我还需要对Datenwolf的回答发表评论。亲爱的ImGui并没有“将翻译的绘图命令传递给OpenGL,因为它们是”这个声明在这里没有意义,因为所有的三角测量都是由imgui执行的,并且没有OpenGL意识到的填充或形状的概念,因为它仅通过原始纹理三角形。

理论上,亲爱的imgui可以提供“PathFillConcave()”函数,但它尚未实现,并且可能成本高昂且复杂。上面发布的链接确实有一个。