Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [SOLVED] QSGVertexColorMaterial alpha value not working?
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QSGVertexColorMaterial alpha value not working?

Scheduled Pinned Locked Moved QML and Qt Quick
5 Posts 3 Posters 3.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    lukalease
    wrote on last edited by
    #1

    I have a custom geometry that uses a QSGVertexColorMaterial to give each vertex in the geometry a rgba value. The rbg value is set as expected, but the alpha value has no affect if there is a background color set for anything behind the custom geometry. I modified the "Scene Graph - Custom" example to demonstrate this issue.

    In beziercurve.cpp I changed the updatePaintNode function to use a QSGVertexColorMaterial instead of a QSGFlatColorMaterial as follows:

    @
    QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
    {
    QSGGeometryNode *node = 0;
    QSGGeometry *geometry = 0;

    if (!oldNode) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), m_segmentCount);
        geometry->setLineWidth(2);
        geometry->setDrawingMode(GL_LINE_STRIP);
        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);
    

    // QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
    // material->setColor(QColor(255, 0, 0));
    QSGVertexColorMaterial *material = new QSGVertexColorMaterial;
    node->setMaterial(material);
    node->setFlag(QSGNode::OwnsMaterial);
    } else {
    node = static_cast<QSGGeometryNode *>(oldNode);
    geometry = node->geometry();
    geometry->allocate(m_segmentCount);
    }

    QRectF bounds = boundingRect();
    

    // QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    QSGGeometry::ColoredPoint2D *vertices = geometry->vertexDataAsColoredPoint2D();
    for (int i = 0; i < m_segmentCount; ++i) {
    qreal t = i / qreal(m_segmentCount - 1);
    qreal invt = 1 - t;

        QPointF pos = invt * invt * invt * m_p1
                    + 3 * invt * invt * t * m_p2
                    + 3 * invt * t * t * m_p3
                    + t * t * t * m_p4;
    
        float x = bounds.x() + pos.x() * bounds.width();
        float y = bounds.y() + pos.y() * bounds.height();
    
        vertices[i].set(x, y, 255, 0, 0, 0);
    }
    
    node->markDirty(QSGNode::DirtyGeometry);
    return node;
    

    }
    @

    In main.qml I changed the root QML element from an Item to a Rectangle in order to add a background color as follows:

    @
    Rectangle {
    width: 300
    height: 200

    // Comment this line out and it works,
    color: "black"
    
    BezierCurve {
        id: line
        anchors.fill: parent
        anchors.margins: 20
    
        property real t
        SequentialAnimation on t {
            NumberAnimation { to: 1; duration: 2000; easing.type: Easing.InOutQuad }
            NumberAnimation { to: 0; duration: 2000; easing.type: Easing.InOutQuad }
            loops: Animation.Infinite
        }
    
        p2: Qt.point(t, 1 - t)
        p3: Qt.point(1 - t, t)
    }
    
    Text {
        anchors.bottom: line.bottom
    
        x: 20
        width: parent.width - 40
        wrapMode: Text.WordWrap
    
        text: "This curve is a custom scene graph item, implemented using GL_LINE_STRIP"
    }
    

    }
    @

    If you remove the 'color' property from the rectangle, the alpha value in the vertex data works as expected. If the 'color' property is set, the alpha value has no effect.

    Can somebody explain why? Perhaps this is a bug or perhaps I don't understand how the QSGVertexColorMaterial is supposed to work.

    Thanks in advance

    1 Reply Last reply
    0
    • O Offline
      O Offline
      ooooooooo
      wrote on last edited by
      #2

      Hi there - I've been having the same problem. Vertex alpha is ignored if if you have a colored rectangle in the background. Did you ever find a solution?

      Cheers,
      Ben.

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lukalease
        wrote on last edited by
        #3

        This was a while ago so I apologize that I don't remember all of the details. To solve this problem, I wrote my own QSGMaterial and QSGMaterialShader subclasses to replace QSGVertexColorMaterial and QSGVertexColorMaterialShader. I used the QSGFlatColorMaterial and QSGVertexColorMaterial source code as a starting point.

        I turned the color in the vertex shader from an attribute to a uniform value so I could explicitly set it in updateState() like so:

        @
        const QColor &c = newMaterial->color();

        if (oldMaterial == 0 || c != oldMaterial->color())
        {
            QVector4D v(c.redF(), c.greenF(), c.blueF(), c.alphaF());
            program()->setUniformValue(m_color_id, v);
        }
        

        @

        I never got a chance to focus too much on this problem. I ended up not needing this code and moved on to something else. It was a good exercise though since I was able to learn how QSGMaterial works.

        1 Reply Last reply
        0
        • slettaS Offline
          slettaS Offline
          sletta
          wrote on last edited by
          #4

          The color you are specifying is r=255, g=0, b=0, a=0 (aka invisible red)

          The blend mode used by the scene graph is glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) which gives you premultiplied blending. A "valid" color in premultiplied mode must have r <= a (same for g and b of course). If it doesn't, then that color channel will overflow, giving you additive blending instead.

          So... There is no bug, but you need to specify the colors as premultiplied. The docs could probably be a bit more helpful in this regard :)

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lukalease
            wrote on last edited by
            #5

            That makes sense. Thanks for the answer :)

            I confirmed what you said by switching the background color to white (so I can see a black line) and the vertex color to r=0, g=0, b=0, a=0 (invisible black). Now when I switch a from 0 to 255 I get what I was expecting.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved