在QML中绘制一个虚线和点状贝塞尔曲线 [英] Draw a dashed and dotted bezier curve in QML

查看:4733
本文介绍了在QML中绘制一个虚线和点状贝塞尔曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到有一个示例实现 Bezier曲线在QML ,但我正在寻找一个提示如何实现虚线或点线贝塞尔曲线。就我所知,Bezier曲线的作者使用 QSGGeometryNode 来存储 QSGGeometry QSGFlatColorMaterial 材质。



可以写一个着色器并应用它到 QSGFlatColorMaterial (显示行虚线 ,等等)?



最终,可以在中存储多个 QSGGeometry QSGGeometryNode



UPDATE



我想在pure QtQuick - 不在旧接口(如 QPainter etc ) - 因为我不想使用某些东西, (openGL和CPU)。我喜欢带有自定义着色器的解决方案(如果它是可行的) - 因为我将有更多的可能性实现自定义的外观和感觉(虚线,肮脏,彩色,可能动画等)。



如果不可能,我将使用 QPainter

解决方案

我认为这个任务不是一个很好的候选实现使用 QSGGeometryNode ,它将更容易实现它使用 QPainter 基于绘图和 QQuickPaintedItem 。你仍然会得到OpenGL的好处,因为 QPainter 支持GL绘图以及它仍然比软件更快。您可以使用股票 QPen 与股票虚线或虚线模式或使用一个简单的 QVector 。 >

或者,你可以去一个自定义的GL绘图方法,而不是使用Qt提供的类,当涉及到代表高级复合几何相当有限。您甚至可以使用实例(如果可用)来进一步提高性能,并且只需沿着路径曲线定位破折号或点几何。

最后但并非最不重要的是,您可以使用一个QML Canvas元素,它支持与 QPainter 几乎相同的操作,并且可能提供相同的性能。



:正如你的更新建议,你错过了我说 QPainter 可以绘制软件和GL的部分,GL绘图通常明显更快。此外,通过绘制到GL上下文,您不必将帧缓冲区从CPU移动到GPU内存,它保存在GPU内存中。所以没有开销。对于动画和其他东西,确实,不可能用 QPainter 你限制于任何 QPen 提供 - 不同的连接,帽子等可以用于在一定程度上修改形状,但没有奇迹...它也不可能使用着色器,它将只能使用自定义几何。如果你为每个dash / dot元素使用一个 QObject 的对象,以便对它们进行独立的动画处理,那么它将会变得非常昂贵, QObject 很重,不应该用这样轻的手。所以自定义GL渲染到FBO几乎是去的方式,如果你想要的那种灵活性,但你必须完全从QtQuick API移动到GL土地。



无论如何,虚线着色器不应该是那么复杂,基本上根据距曲线的距离和沿着它的长度的周期为片段着色。我发现此示例,没有自己尝试过。你可以对阈值进行动画处理,甚至使用正弦函数来获得时髦的样式。



对于一个纯粹的QtQuick实现,API并没有真正设计来处理这种类型的绘图任务,这就是为什么Canvas元素被提供来填补空白,并从QML / JS获得高级的染色功能。 Canvas实际上是一个 QPainter 包装到FBO上的包装。



最后不会煮沸到什么是可能/不可能,但哪种方法是最有意义的,是最有效的完成工作。首先尝试 QQuickPaintedItem 方法,因为它是最简单的,如果你不满意性能,你可以实现另一个更复杂的解决方案和配置文件第一。毕竟,这就是为什么 QQuickPaintedItem 被首先介绍 - 处理与 QQuickItem 不太方便的传统绘画$ c> class。


I've seen there is an example implementation of a Bezier curve in QML, but I'm looking for a hint how to implement dashed or dotted bezier curve line. As far as I see, tha authors of Bezier curve example are using QSGGeometryNode to store inside QSGGeometry with a QSGFlatColorMaterial material applied on it. Then they simply create list of points and draw segments between them.

Is it possible to write a shader and apply it to QSGFlatColorMaterial (to display line as dashed, dotted, etc)?

Eventually, is it possible to store more than one QSGGeometry inside QSGGeometryNode?

UPDATE

I would like to implement this in "pure QtQuick" - not in "old" interfaces (like QPainter etc) - because I do not want to use something, which switches context (openGL and CPU). I prefer the solution with custom shader (if is it doable) - because I'll have more possibilities in implementing custom look and feel (dashed, doted, colored, maybe animated etc).

If it is not possible, I'll use QPainter.

解决方案

I don't think this task is a good candidate for implementing using QSGGeometryNode, it would be much easier to implement it using QPainter based drawing and a QQuickPaintedItem. You will still get the benefits of OpenGL, since QPainter supports GL drawing as well and it is still faster than software. You can use the stock QPen with stock dotted or dashed patterns or make your own with a simple QVector.

Alternatively, you can go for a custom GL drawing approach instead of using the classes provided by Qt, which are pretty limited when it comes to representing advanced compound geometry. You can even use instancing (if available) to improve performance even further, and just position dashes or dot geometry along the path curve.

Last but not least, you can use a QML Canvas element, which supports pretty much the same operations as QPainter and probably offers the same performance.

EDIT: As your update suggests, you missed the part where I said QPainter can draw in both software and GL, with GL drawing being often significantly faster. Also, by drawing to a GL context, you don't have to move the framebuffer from CPU to GPU memory, it is kept in GPU memory. So no overhead. As for animations and the other stuff, sure, it is not possible with QPainter you are limited to whatever QPen provides - different joins, caps and so on can be used to modify the shape to some extent, but no miracles... It won't be possible with shaders too, it will only be possible with custom geometry. And if you use a QObject based object for each dash/dot element in order to independently animate them, it will end up quite expenssive, QObject is very heavy and should not be used with such light hand. So custom GL rendering to a FBO is pretty much the way to go if you want that kind of flexibility, but you will have to move completely out of the QtQuick API and into GL land.

At any rate, a dashed line shader should not be all that complex, basically you color the fragment based on the distance from the curve and the "period" along its length. I found this example, haven't tried it myself. You could animate the thresholds, even use a sine function to get funky looking styling.

As for a "pure" QtQuick implementation, the API has not really been designed to handle such type of drawing tasks, that is why the Canvas element was provided to fill the gap and get advanced paining functionality from QML/JS. The Canvas is effectively a wrapper around QPainter that draws onto a FBO.

In the end it doesn't boil down to what is possible/impossible but which approach makes the most sense and is most efficient at getting the job done. Try the QQuickPaintedItem approach first, since it is the easiest, if you are not happy with performance, you can implement another more complex solution and profile against the first. After all, that is why QQuickPaintedItem was introduced in the first place - to handle legacy painting that is not convenient to do with the QQuickItem class.

这篇关于在QML中绘制一个虚线和点状贝塞尔曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆