2017-12-16 4 views
0

Wie kann ich den Bereich zwischen zwei Bezier-Kurven mit dear imgui füllen?Wie füllt man den Bereich zwischen zwei Bezier-Kurven mit Hilfe von Lieber Imgui

zog ich die Kurven, die die ImDrawList API verwenden, wie folgt aus:

 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); 

Edit:

ich die Stateful-API verwendet, um den Pfad zu zeichnen ich wollte, und dann rief ich eine Funktion, diesen Weg zu füllen . Hier ist der Code:

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

     draw_list->PathFillConvex(col); 

Aber es ist etwas falsch, wie man sehen kann:

result

Die richtige Geometrie in weiß gezeichnet.

Antwort

3

Das Problem, das Sie in ist, ist, dass Füllen von Primitiven in OpenGL nur für konvexen Primitiven definiert ist. Ein Satz wird als konvex definiert, wenn Sie für zwei beliebige Punkte innerhalb des Satzes eine Linie zwischen diesen Punkten zeichnen können, ohne die Grenzen des Satzes zu verlassen.

Dear-ImGUI übergibt die übersetzten Zeichnungsbefehle meist so an OpenGL, wie sie sind, ohne dazwischenliegende Tesselation. ... was das Problem verursacht, das Sie sehen und warum die Füllfunktion das …Convex Teil in seinem Namen hat. Die Lösung besteht darin, entweder die nicht konvexe Form in kleinere, konvexe Teilformen aufzuteilen oder eine Füllmethode zu verwenden, die auch für konvexe Formen funktioniert, wie den scanline Algorithmus (dessen Implementierung auf einer GPU am einfachsten ist) Verwenden eines Compute Shaders).

+0

Vielen Dank. Auf der Suche nach dem Scanline-Algorithmus habe ich eine Implementierung mit imgui gefunden: https://github.com/ocornut/imgui/issues/760. – user3762200

1

Sie benötigen einen konkaven Füllalgorithmus, den Lieber Imgui nicht bietet. Im Allgemeinen ist es einfacher/schneller, Ihre Formen in konvexe Formen zu zerlegen. Der generelle Fall, dass "zwischen zwei Bezierern" gefüllt wird, ist schwierig, da sich die Beziers kreuzen können, so dass es mehrere Bereiche geben kann. Wenn Sie wissen, dass sie sich niemals überschneiden und Ihre Tangenten nicht zu verrückt sind, können Sie verschiedene Annäherungen verwenden. Versuchen Sie vielleicht, N Quads zu zeichnen, wo jedes Quads zwei Segmente der Beziers in regelmäßigen Abständen usw. verbindet. Datenwolf Antworten sind ein guter Ausgangspunkt für die allgemeinere Antwort.

Ich muss auch auf Datenwolf Antwort kommentieren. Lieber ImGui "gibt die übersetzten Zeichnungsbefehle nicht an OpenGL weiter, so wie sie sind". Diese Aussage ergibt hier keinen Sinn, da die gesamte Triangulation von imgui durchgeführt wird und es kein Konzept der Füllung oder Formen gibt, das OpenGL seither kennt es wird nur an texturierte Rohdreiecke übergeben.

Theoretisch könnte Lieber Imgui eine "PathFillConcave()" Funktion zur Verfügung stellen, aber es wurde nicht implementiert und es kann teuer und komplex zu tun sein. Der oben genannte Link hat tatsächlich einen.

Verwandte Themen