我想在自定义中渲染一个有很多点(> 1.000.000)和不同颜色的图QQuickItem
。
后来我想对这些点进行动画处理(在坐标和颜色之间渐变),所以我认为这QQuickPaintedItem
还不够快,我必须使用.updatePaintNode
QQuickItem
问题是为每个点设置颜色。我必须为每个点 a 创建QSGGeometryNode
并添加 Geometry 和 ColorMaterial 吗?还是有更快的解决方案?
此致
我想在自定义中渲染一个有很多点(> 1.000.000)和不同颜色的图QQuickItem
。
后来我想对这些点进行动画处理(在坐标和颜色之间渐变),所以我认为这QQuickPaintedItem
还不够快,我必须使用.updatePaintNode
QQuickItem
问题是为每个点设置颜色。我必须为每个点 a 创建QSGGeometryNode
并添加 Geometry 和 ColorMaterial 吗?还是有更快的解决方案?
此致
200 万个元素相当多,我相信 GUI 会因为内部的循环而冻结updatePaintNode
(GUI 线程在updatePaintNode
执行期间被阻塞,如文档所述)。
想法#1
如果您不经常更改整个点数组,则可以updatePaintNode
仅更新自上次绘制以来已更改的那些顶点,而不是每次都运行巨大的 2kk 循环。但是在调整直方图大小的情况下,您仍然需要更新所有顶点。
想法#2
另一个潜在的优化可能是在之前准备顶点数据数组updatePaintNode
,然后使用memcpy
或std::copy
在内部复制整个数组updatePaintNode
。将连续内存数组作为一个整体进行复制往往比按元素复制要快得多,并且由于您使用访问器函数填充数组,因此我不确定它是否已被编译器优化。
想法#3
200 万个点似乎太多,无法在一张图表上呈现。一次呈现这么多数据会损害用户体验,因为不同颜色的点会重叠,用户可能会错过有价值的信息。
您可以通过将相同颜色的点合并在一起并可视化这些集群而不是单独的点来降低细节级别。但是,这种方法需要相当大的努力,所以我建议在不太复杂的解决方案没有帮助时尝试它。
我用openGL做了一点工作,找到了一个适合我的解决方案
QSGGeometry::Point2D
用于设置顶点的普通 OpenGL 示例。但是也有一个支持颜色的版本(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 非常慢。
问候