Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Can this updatePaintNode implementation be faster/neater/more elegant?



  • Hello, I'm trying to draw a bunch of polygons of various colors on top of video. Each polygon will NOT be filled, but the perimeter (outline) will consist of 2 colors. The 2 colors could be anything defined by the user input. This is to make sure that the polygons are visible no matter what video is on in the background.

    I had tried Canvas QML at first, but it used too much CPU. Then I tried QQuickPaintedItem - paint(), and that used less CPU. And now I'm trying QQuickItem - updatePaintNode().

    I have implemented an QSGNode updatePaintNode() method, and it uses less CPU than a QQuickPaintedItem. I'm just not very happy with how this code looks. I feel like it could be much shorter and elegant. And I wonder if maybe I'm not taking full advantage of this batch processing ability of the scene graph?

    I would appreciate any feedback.

    QSGNode *Zones::updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData *)
    {
     qDebug("hello");
     //QSGGeometryNode *root = static_cast<QSGGeometryNode *>(oldNode);
     QSGNode *root = static_cast<QSGNode *>(oldNode);
     if(!root) {
         root = new QSGNode;
     }
    
     root->removeAllChildNodes();
     int sz = m_zoneList.size();    //m_zonelist holds the 4 QPointF coords of the zone, the foreground color and the background color
     QColor fgnd;
     QColor bgnd;
    
     if(sz > 0)
     {
         int i = 0;
         while(i < sz)	// paint the contrast zone (bgnd color) then the normal zone (fgnd color)
         {
            //i = 0;
            QVariantList zList = m_zoneList.at(i).toList();
    	QPointF xy1 = zList.at(0).toPointF();
    	QPointF xy2 = zList.at(1).toPointF();
    	QPointF xy3 = zList.at(2).toPointF();
    	QPointF xy4 = zList.at(3).toPointF();
            fgnd.setNamedColor(zList.at(4).toString());
            bgnd.setNamedColor(zList.at(5).toString());
    
            QSGFlatColorMaterial *cm = new QSGFlatColorMaterial;    // get contrast color
     	cm->setColor(bgnd);
    
            QSGGeometry *geoCZone = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);   //create contrast zone geometry
    	geoCZone->setLineWidth(6);
    	geoCZone->setDrawingMode(QSGGeometry::DrawLineLoop);
    	geoCZone->vertexDataAsPoint2D()[0].set(xy1.x(),xy1.y());
    	geoCZone->vertexDataAsPoint2D()[1].set(xy2.x(),xy2.y());
    	geoCZone->vertexDataAsPoint2D()[2].set(xy3.x(),xy3.y());
    	geoCZone->vertexDataAsPoint2D()[3].set(xy4.x(),xy4.y());
    
            QSGGeometryNode *contrastZone = new QSGGeometryNode;    // create contrastZone node
    	contrastZone->setGeometry(geoCZone);
      	contrastZone->setFlag(QSGNode::OwnsGeometry);
     	contrastZone->setFlag(QSGNode::OwnsMaterial);
     	contrastZone->setMaterial(cm); 	
    
            
            QSGGeometry *geoZn = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);      // create normal zone geometry
    	geoZn->setLineWidth(3);
            geoZn->setDrawingMode(QSGGeometry::DrawLineLoop);
    	geoZn->vertexDataAsPoint2D()[0].set(xy1.x(),xy1.y());
    	geoZn->vertexDataAsPoint2D()[1].set(xy2.x(),xy2.y());
    	geoZn->vertexDataAsPoint2D()[2].set(xy3.x(),xy3.y());
    	geoZn->vertexDataAsPoint2D()[3].set(xy4.x(),xy4.y());
    	
            QSGFlatColorMaterial *z = new QSGFlatColorMaterial;                 // create normal zone color
     	z->setColor(fgnd);
    
            QSGGeometryNode *zone = new QSGGeometryNode;                        // create normal zone mode
            zone->setGeometry(geoZn);   	
    	zone->setFlag(QSGNode::OwnsGeometry);
            zone->setFlag(QSGNode::OwnsMaterial);
            zone->setMaterial(z);	
    
            contrastZone->appendChildNode(zone);                                // make sure the contrastZone is drawn below the normal zone
            root->appendChildNode(contrastZone);
    	
    	i++;
         }
     } 
    return root;
    }
    

Log in to reply