Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-125214

There is no equivalent to glBlendEquation in QSGMaterialShader

    XMLWordPrintable

Details

    • iOS/tvOS/watchOS, macOS, Windows
    • b41e8dc84 (dev)

    Description

      I’m porting an app from Qt 5.15 to Qt 6.7 but I’m stumbling on the fact that there is no equivalent to blend equation in OpenGL.
       
      To achieve blending mode between nodes, I was using a mix between glBlendFunc and glBlendEquation:
       

      switch (material->blendMode)
          {
              case Normal:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_ADD);
                  break;
              case Screen:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_SRC_COLOR, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_ADD);
                  break;
              case HardLight:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_DST_COLOR, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_ADD);
                  break;
              case SoftLight:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_ADD);
                  break;
              case Overlay:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_SRC_COLOR, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_MAX);
                  break;
              case Difference:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_SRC_COLOR, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
                  break;
              case Exclusion:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_ONE, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_SUBTRACT);
                  break;
              case Subtract:
                  QOpenGLContext::currentContext()->functions()->glBlendFunc(GL_ONE, GL_ONE);
                  QOpenGLContext::currentContext()->functions()->glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
                  break;
          }

      But in the newest version of QSGMaterialShader class documentation it says:
       
      "The shader pipeline state changes are less often used. One use case is materials that wish to use a specific blend mode. The relevant function is updateGraphicsPipelineState(). This function is not called unless the QSGMaterialShader has opted in by setting the flag UpdatesGraphicsPipelineState. The task of the function is to update the GraphicsPipelineState struct instance that is passed to it with the desired changes. Currently only blending and culling-related features are available, other states cannot be controlled by materials.”
       
      So I’m now trying to use 
       
      bool QSGMaterialShader::updateGraphicsPipelineState(QSGMaterialShader::RenderState &state, QSGMaterialShader::GraphicsPipelineState *ps, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
       

      switch (material->blendMode)
          {
              case Normal:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::One;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::OneMinusSrcAlpha;
                  break;
              case Screen:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::SrcColor;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::One;
                  break;
              case HardLight:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::DstColor;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::One;
                  break;
              case SoftLight:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::OneMinusDstColor;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::One;
                  break;
              case Overlay:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::SrcColor;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::One;
                  break;
              case Difference:
                  ps->srcColor = QSGMaterialShader::GraphicsPipelineState::SrcColor;
                  ps->dstColor = QSGMaterialShader::GraphicsPipelineState::One;
                  break;
          } 

       
      Where the blendEquation GL_FUNC_ADD was used, it seems to be working.
       
      But when I get to modes like Overlay and Difference, where the SRC and DST are the same, without a blend equation, I don’t know how to do it.
       
      I really need support to blend equation in order to complete the app port to Qt 6. Thank you!

      Attachments

        1. exclusion-old.jpg
          515 kB
          Nuno Santos
        2. difference-new.jpg
          107 kB
          Nuno Santos
        3. difference-old.jpg
          613 kB
          Nuno Santos
        4. exclusion-new.jpg
          128 kB
          Nuno Santos
        For Gerrit Dashboard: QTBUG-125214
        # Subject Branch Project Status CR V

        Activity

          People

            lagocs Laszlo Agocs
            sinosoidal Nuno Santos
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes