在 QQuickItem 中绘制不同颜色的多个点

Posted

技术标签:

【中文标题】在 QQuickItem 中绘制不同颜色的多个点【英文标题】:draw multiple points with different colors in a QQuickItem 【发布时间】:2014-11-27 01:36:04 【问题描述】:

我想在自定义 QQuickItem 中渲染一个包含很多点 (>1.000.000) 和不同颜色的图。

稍后我想为这些点设置动画(在坐标和颜色之间渐变),所以我认为QQuickPaintedItem 不够快,我必须使用QQuickItemupdatePaintNode 接口。

问题是为每个点设置颜色。我必须为每个点创建一个QSGGeometryNode 并添加几何和颜色材料吗?还是有更快的解决方案?

最好的问候

【问题讨论】:

【参考方案1】:

200 万个元素相当多,我相信 GUI 会因为 updatePaintNode 内的循环而冻结(GUI 线程在 updatePaintNode 执行期间被阻塞,如 documentation states)。

想法 #1

如果您不经常更改整个点数组,您可以在updatePaintNode 中仅更新自上次绘制以来已更改的那些顶点,而不是每次都运行巨大的 2kk 循环。但是在调整直方图大小的情况下,您仍然需要更新所有顶点。

想法 #2

另一个潜在的优化可能是在updatePaintNode 之前准备顶点数据数组,然后在updatePaintNode 内部使用memcpystd::copy 复制整个数组。将连续内存数组作为一个整体复制tends to be much faster 而不是按元素复制,并且由于您使用访问器函数填充数组,我不确定它是否已被编译器优化。

想法 #3

200 万个点似乎太多,无法在一张图表上呈现。一次呈现这么多数据会损害用户体验,因为不同颜色的点会重叠,用户可能会错过有价值的信息。

您可以通过将相同颜色的点合并在一起并可视化这些集群而不是单独的点来降低细节级别。但是,这种方法需要相当大的努力,所以我建议在不太复杂的解决方案没有帮助时尝试它。

【讨论】:

【参考方案2】:

我在 openGL 上做了一些工作,找到了一个适合我的解决方案

普通的 OpenGL 示例使用QSGGeometry::Point2D 来设置顶点。但是也有支持颜色的版本(QSGGeometry::defaultAttributes_ColoredPoint2D())。所以我可以设置顶点

  vertices[i].set(x, y, r,g, b, a);

//编辑: 下一个问题是 gui 不时冻结,如果 QSGeometry-Object 有很多顶点。我不知道为什么。 为顶点分配内存后,GUI 速度变慢,因此这种方法性能不佳。

//编辑2:

我添加了当前updatePaint-方法的简化代码。如果数据对象非常大(> 2.000.000 个点),小部件会渲染这些点,但整个 gui 会挂起并结结巴巴。

QSGNode *HistogramView::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)

QSGGeometryNode *node = 0;
QSGGeometry *geometry = 0;

if (!oldNode) 
    node = new QSGGeometryNode;
    geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), data.size());
    geometry->setDrawingModeelsize(GL_POINTS);
    node->setGeometry(geometry);
    node->setFlag(QSGNode::OwnsGeometry);

    QSGVertexColorMaterial *material = new QSGVertexColorMaterial();
    //material->setColor(QColor(255, 0, 0));
    node->setMaterial(material);
    node->setFlag(QSGNode::OwnsMaterial);

 else 
    node = static_cast<QSGGeometryNode *>(oldNode);
    geometry = node->geometry();
    geometry->allocate(222);

QSGGeometry::ColoredPoint2D *vertices = geometry->vertexDataAsColoredPoint2D();
for (int i = 0; i < data.size(); i++) 
        vertices[id].set(x, y,red, green, blue, 255);
        
    

node->markDirty(QSGNode::DirtyGeometry);
return node;




我可以定位错误。 在调用初始化QSGGeometry-object( geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), data.size());) gui 很慢。

问候

【讨论】:

查看您的商品的一些代码以及您如何使用它可能会很有帮助 我用一些代码和定位的错误更新了我的答案。但我找不到解决办法 我在单独的答案中发布了一些关于如何提高渲染性能的想法。我认为将您的答案作为原始问题的一部分是合适的,因为答案描述了您的问题:) 另外,您能否澄清“坐标和颜色之间的渐变”是什么意思?这对我来说不是很清楚。 谢谢 :) 随着褪色,我想在两种不同颜色之间制作动画。

以上是关于在 QQuickItem 中绘制不同颜色的多个点的主要内容,如果未能解决你的问题,请参考以下文章

在 hyperSpec 对象中绘制具有不同颜色的多个光谱

自定义 QQuickItem 未绘制

要在屏幕上绘制一些小图块,我应该使用 QQuickItem 还是 QQuickPaintedItem?

定期重绘 QQuickItem

绘制多个轴颜色合并

有效地从 QPaintDevice 到 QQuickItem 中的 QSGTexture