[Interest] Using QSGMaterial & QSGMaterialShader with multiple shaders

Nuno Santos nuno.santos at imaginando.pt
Thu Feb 18 22:49:53 CET 2021


Lazlo,

Thank you very much for your reply.

This will definitely definitely help. I will get back here if I don’t make any progress in the next couple of days.

Thank you very much!

Best regards,

Nuno

> On 17 Feb 2021, at 11:19, Laszlo Agocs <laszlo.agocs at qt.io> wrote:
> 
> Hi Nuno,
> 
> Check your implementation of type(). It should return something unique for all the different 'source' values (i.e. for every different vertex+fragment shader combinations). Right now, with the same static type object is returns, VSMaterial::createShader() is only ever called once, so all instances of VSMaterial will use the same VSMaterialShader regardless of the different fragment shader code in 'source', which explains the effect you are seeing.
> 
> An example of a dynamic implementation of type() you are looking for can be found in ShaderEffect:
> https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickopenglshadereffectnode.cpp?h=5.15#n389 <https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickopenglshadereffectnode.cpp?h=5.15#n389>
> https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickopenglshadereffectnode.cpp?h=5.15#n453 <https://code.qt.io/cgit/qt/qtdeclarative.git/tree/src/quick/items/qquickopenglshadereffectnode.cpp?h=5.15#n453>
> 
> Best regards,
> Laszlo
> 
> From: Interest <interest-bounces at qt-project.org> on behalf of Nuno Santos <nuno.santos at imaginando.pt>
> Sent: Monday, February 15, 2021 3:36 PM
> To: interestqt-project.org <interest at qt-project.org>
> Subject: [Interest] Using QSGMaterial & QSGMaterialShader with multiple shaders
>  
> Hi,
> 
> I’m trying to make a shader gallery using a GridView where the model is an array of shaders path.
> 
> Then, a custom QQuickView, instantiates a custom QSGGeometryNode with a material that extends QSGMaterial. The QSGMaterial creates the shader:
> 
> I’m having a problem though. All the items draw the first shader in the list. Shader A draws everything red, shader B draws everything blue.
> 
> If model = [A, B], the two items show as red, if I swap the model order to [B, A], the two items show blue.
> 
> I’ve added debug and there are classes being instantiated correctly for each item, and the right shader source is being used for each one, but it seems that only the first shader that is passed to the model seems to be loaded or active.
> 
> Is there any gotcha in the way QSGMateria and QSGMaterialShader are used?
> 
> Code for material and material shader are included below.
> 
> Thanks!
> 
> Nuno
> 
> VSMaterial::VSMaterial(QString source) :
>     _source(source)
> {
>     setFlag(RequiresFullMatrixExceptTranslate, true);
>     setFlag(Blending, true);
> }
> 
> int VSMaterial::compare(const QSGMaterial *other) const
> {
>     Q_UNUSED(other)
> 
>     return 0;
> }
> 
> QSGMaterialType *VSMaterial::type() const
> {
>     static QSGMaterialType type;
> 
>     return &type;
> }
> 
> QSGMaterialShader *VSMaterial::createShader() const
> {
>     return new VSMaterialShader(_source);
> }
> 
> VSMaterialShader::VSMaterialShader(QString source)
>     : QSGMaterialShader()
> {
>     setShaderSourceFile(QOpenGLShader::Vertex, QString(":/shaders/rectangle.vert")); 
>     setShaderSourceFile(QOpenGLShader::Fragment, source);
> }
> 
> void VSMaterialShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
> {
>     Q_UNUSED(newEffect)
> 
>     if (state.isOpacityDirty())
>         program()->setUniformValue(m_opacityLoc, state.opacity());
> 
>     if (state.isMatrixDirty())
>         program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
> 
>     if (oldEffect == 0)
>     {
>         // The viewport is constant, so set the pixel size uniform only once.
>         QRect r = state.viewportRect();
>         program()->setUniformValue(m_pixelSizeLoc, 2.0f / r.width(), 2.0f / r.height());
>     }
> 
>     VSMaterial *material = static_cast<VSMaterial*>(newEffect);
> 
>     program()->setUniformValue(_idPositionX, material->positionX);
>     program()->setUniformValue(_idPositionY, material->positionY);
> }
> 
> const char * const *VSMaterialShader::attributeNames() const
> {
>     static char const *const attributes[] = {
>         "vertex",
>         "vertexColor",
>         "vertexOffset",
>         0
>     };
> 
>     return attributes;
> }
> 
> void VSMaterialShader::initialize()
> {
>     m_matrixLoc = program()->uniformLocation("matrix");
>     m_opacityLoc = program()->uniformLocation("opacity");
>     m_pixelSizeLoc = program()->uniformLocation("pixelSize");
> 
>     _idPositionX = program()->uniformLocation("positionX");
>     _idPositionY = program()->uniformLocation("positionY");
> }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20210218/dcbe961d/attachment.html>


More information about the Interest mailing list