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

时间:2014-11-27 01:36:04

标签: c++ opengl qml qquickitem

我想在自定义QQuickItem中渲染包含大量点(> 1.000.000)和不同颜色的绘图。

稍后我想为这些点设置动画(在坐标和颜色之间淡入淡出),所以我认为QQuickPaintedItem不够快,我必须使用updatePaintNode的{​​{1}}界面。

问题是为每个点设置颜色。我必须为每个点QQuickItem创建并添加几何和ColorMaterial吗?或者是否有更快的解决方案?

最好的问候

2 个答案:

答案 0 :(得分:2)

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

创意#1

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

创意#2

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

创意#3

在单个图表上显示200万点似乎太多了。一次呈现如此多的数据会损害UX,因为不同颜色的点将重叠,用户可能会错过有价值的信息。

您可以通过将相同颜色的点合并在一起并可视化这些聚类而不是单独的点来降低细节级别。但是,这种方法需要付出相当大的努力,因此我建议在不太复杂的解决方案无法帮助时进行尝试。

答案 1 :(得分:0)

我使用openGL进行了一些工作,找到了一个适合我的解决方案

正常的OpenGL示例使用QSGGeometry::Point2D来设置verticies。但是也有一个带颜色支持的版本(QSGGeometry::defaultAttributes_ColoredPoint2D())。所以我可以用

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

//编辑: 接下来的问题是,如果QSGeometry-Object有许多顶点,gui会不时冻结。我不知道为什么。 在为verticies分配内存后,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 - 对象后( geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), data.size());)gui很慢。

问候