Qt场景图渲染特定的子节点

时间:2018-09-17 09:51:21

标签: qt opengl qt-quick scenegraph

我正在尝试使用Qt场景图来实现渲染图。在图形渲染中,更新总是发生在特定的像素列(单个垂直列中的像素)上,因此我已经创建了到根节点的n个子节点(QSGNode)(这里n是渲染区域的宽度) ,并为每个子节点创建了6个子节点(在绘图模式GL_LINES中为QSGGeometryNode),每个子节点对应一个屏幕上的图形。基本上,如果渲染区域宽度为100,则根节点将总共具有100 * 6个子节点。更新仅在少数子节点上进行,更新几何之后,我将节点标记为DirtyGeometry。

直到现在为止对我来说还不错,但是我看到它占用了很多CPU,所以我尝试使用QSG_RENDERER_DEBUG = render进行调试,我看到所有子节点都通过updatePaintNode调用再次呈现而不是我标记为肮脏的特定对象。

日志如下

Renderer::render() QSGAbstractRenderer(0xf9a5a0) "rebuild: none"
Rendering:
-> Opaque: 6145 nodes in 2 batches...
-> Alpha: 0 nodes in 0 batches...
- 0xf9a910 [  upload] [noclip] [opaque] [  merged]  Nodes: 6144  
Vertices: 12288  Indices: 12288  root: 0x0
- 0xf9a960 [retained] [noclip] [opaque] [  merged]  Nodes:    1  
Vertices:     4  Indices:     6  root: 0x0
-> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, 
upload(opaque/alpha): 0/0, render: 0

渲染区域为1024 * 624(即1024 * 6 = 6144个子QSGGeometry节点)。

QSGNode *QSGPlot::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
    QSGGeometry *geometry = nullptr;
    QSGNode* parentNode = nullptr;
    if (!oldNode)
    {
        Q_ASSERT (_wfGenerator == nullptr);
        float pixelWidth, pixelHeight;
        DisplayInfo::getPixelSize(pixelWidth,pixelHeight);
        const QRectF bounds = boundingRect();
        float speed = 50.0f;
        float gain = 10.0f;
        _wfGenerator = new WFGenerator(pixelWidth,pixelHeight, speed,gain,bounds.width(),bounds.height());
        parentNode = new QSGNode;
        for (size_t columnI = 0; columnI < bounds.width(); columnI++)
        {
            QSGNode *columnNode = new QSGNode;
            parentNode->appendChildNode(columnNode);
            createGeometryChildNodes(columnNode, Qt::green, 6);
        }
    }
    else
    {
        parentNode = static_cast<QSGGeometryNode*>(oldNode);
        Q_ASSERT (parentNode->childCount() == boundingRect().width());
    }

    size_t dirtyColumnCount = 0;
    _wfGenerator->generateWF(_columnBuffer, dirtyColumnCount);
    for (size_t dirtyColI = 0; dirtyColI < dirtyColumnCount; dirtyColI++)
    {
        size_t updateCol = _columnBuffer[dirtyColI].columnI;
        QSGNode *columnNode = static_cast<QSGNode*>(parentNode->childAtIndex(updateCol));

        if (_columnBuffer[dirtyColI].validDirtyYCoordinates != 0)
        {
            Q_ASSERT (columnNode->childCount() >= _columnBuffer[dirtyColI].validDirtyYCoordinates);
            for (auto rowI = 0; rowI < _columnBuffer[dirtyColI].validDirtyYCoordinates; rowI++)
            {
                QSGGeometryNode *rowNode = static_cast<QSGGeometryNode*>(columnNode->childAtIndex(rowI));
                geometry = rowNode->geometry();
                geometry->vertexDataAsPoint2D()[0].set(updateCol, _columnBuffer[dirtyColI].dirtyYCoordinates[rowI].y);
                geometry->vertexDataAsPoint2D()[1].set(updateCol, _columnBuffer[dirtyColI].dirtyYCoordinates[rowI].y1);
                rowNode->markDirty(QSGNode::DirtyGeometry);
            }
        }
        else
        {
            for (auto rowI = 0; rowI < columnNode->childCount(); rowI++)
            {
                QSGGeometryNode *rowNode = static_cast<QSGGeometryNode*>(columnNode->childAtIndex(rowI));
                geometry = rowNode->geometry();
                geometry->vertexDataAsPoint2D()[0].set(updateCol, 0);
                geometry->vertexDataAsPoint2D()[1].set(updateCol, 0);
                rowNode->markDirty(QSGNode::DirtyGeometry);
            }
        }
    }
    return parentNode;
}

void QSGPlot::createGeometryChildNodes(QSGNode *parent, const QColor &color, const size_t &childCount)
{
    for (size_t childI = 0; childI < childCount; childI++)
    {
        QSGGeometryNode *childNode = new QSGGeometryNode;
        QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
        geometry->setLineWidth(1);
        geometry->setDrawingMode(GL_LINES);
        childNode->setGeometry(geometry);
        childNode->setFlag(QSGNode::OwnsGeometry);
        QSGFlatColorMaterial* material = new QSGFlatColorMaterial();
        material->setColor(color);
        childNode->setMaterial(material);
        childNode->setFlag(QSGNode::OwnsMaterial);
        parent->appendChildNode(childNode);
    }
}

谁能指出我在此实现中做错了什么。 Find the screen recording of application here.

0 个答案:

没有答案