glsl qt 着色器程序

Posted

技术标签:

【中文标题】glsl qt 着色器程序【英文标题】:glsl qt shader program 【发布时间】:2018-04-11 14:48:55 【问题描述】:

您能帮我编写正确的着色器程序(glsl),以使 QTpainterPath 适应 SceneGraph。节点的几何三角形确定,但我无法为阴影画笔样式编写正确的着色器材质。

1. pathNode.cpp

#include <QtQuick/QSGSimpleMaterialShader>
#include <QtQuick/QSGTexture>
#include <QtQuick/QQuickWindow>

#include <private/qtriangulator_p.h>
#include <QPainterPath>

#include "pathNode.h"

#define TEXTURE_SIZE 64

struct BrushMaterial

    ~BrushMaterial() 
        delete texture;
    

    QColor          color;
    QSGTexture*     texture;
;

class BrushShader : public QSGSimpleMaterialShader<BrushMaterial>

    QSG_DECLARE_SIMPLE_SHADER(BrushShader, BrushMaterial)

public:
    BrushShader() : 
        id_color(-1), 
        id_texture(-1),
        id_textureSize(-1)
    
        setShaderSourceFile(QOpenGLShader::Vertex, ":/shaders/brush.vsh");
        setShaderSourceFile(QOpenGLShader::Fragment, ":/shaders/brush.fsh");
    

    QList<QByteArray> attributes() const
    
        return QList<QByteArray>() << "aVertex" << "aTexCoord";
    

    void updateState(const BrushMaterial *m, const BrushMaterial *)
    
        // Set the color
        program()->setUniformValue(id_color, m->color);

        // Bind the texture and set program to use texture unit 0 (the default)
        m->texture->bind();

        // Then set the texture size so we can adjust the texture coordinates accordingly in the
        // vertex shader..
        QSize s = m->texture->textureSize();
        program()->setUniformValue(id_textureSize, QSizeF(1.0 / s.width(), 1.0 / s.height()));
    

    void resolveUniforms()
    
        id_texture = program()->uniformLocation("texture");
        id_textureSize = program()->uniformLocation("textureSize");
        id_color = program()->uniformLocation("color");

        // We will only use texture unit 0, so set it only once.
        program()->setUniformValue(id_texture, 0);
    

private:
    int id_color;
    int id_texture;
    int id_textureSize;
;

PathNode::PathNode(QSGTexture* texture,const QColor& color)
    : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 0, 0, GL_UNSIGNED_INT)

    setGeometry(&m_geometry);
    m_geometry.setDrawingMode(GL_TRIANGLES);

    QSGSimpleMaterial<BrushMaterial>* m = BrushShader::createMaterial();

    m->state()->texture = texture;
    m->state()->color = color;
    m->setFlag(QSGMaterial::Blending);

    setMaterial(m);
    setFlag(OwnsMaterial, true);


void PathNode::update(const QPainterPath& path)

    const QTriangleSet triangles qTriangulate(path) ;

    // Fill vertex buffer
    m_geometry.allocate(triangles.vertices.size() / 2, triangles.indices.size());
    QSGGeometry::TexturedPoint2D *vertex = m_geometry.vertexDataAsTexturedPoint2D();
    for (int i = 0; i < m_geometry.vertexCount(); ++i)
        vertex[i].set(triangles.vertices.at(2 * i), triangles.vertices.at(2 * i + 1), 1, 0);

    // Fill index buffer
    uint *indices = m_geometry.indexDataAsUInt();
    if (triangles.indices.type() != QVertexIndexVector::UnsignedInt)
        qFatal("Unexpected geometry index type");
    memcpy(indices, triangles.indices.data(), triangles.indices.size() * sizeof(*indices));

    markDirty(QSGNode::DirtyGeometry);

2.PathNode.h

#pragma once

#include <QSGGeometryNode>

class PathNode : public QSGGeometryNode

    QSGGeometry             m_geometry;

public:
    PathNode(QSGTexture* texture, const QColor& color);

    void update(const QPainterPath& path);
;

3.brush.vsh

attribute highp vec4 aVertex;
attribute highp vec2 aTexCoord;

uniform highp mat4 qt_Matrix;
uniform highp vec2 textureSize;

varying highp vec2 vTexCoord;
varying lowp vec2 vShadeCoord;

void main() 
    gl_Position = qt_Matrix * aVertex;
    vTexCoord = aVertex.xy * textureSize;
    vShadeCoord = aTexCoord;

    brush.fsh

    uniform sampler2D texture;
    uniform lowp float qt_Opacity;
    uniform lowp vec4 color;
    
    varying highp vec2 vTexCoord;
    
    void main()
    
        lowp vec4 shade = texture2D(texture, vTexCoord) ;
        lowp vec4 c = vec4(color.xyz * shade.xyz, 1.0);
        gl_FragColor = c * qt_Opacity;
    
    

主要的问题是用彩色背景绘制的阴影,但我想要透明背景。

github代码链接:painterPath_QSGNode

【问题讨论】:

【参考方案1】:

只需为项目分配透明颜色即可。

在 main.cpp 的第 50 行,更改:

fillBrush.setColor(Qt::red);

到:

fillBrush.setColor(Qt::transparent);

【讨论】:

这是我得到的结果:imgur。还是我误解了您想要获得的内容? 我需要用红色十字线填充路径,但没有背景。现在我有红色填充,交叉线较浅。 对不起,你能制作一张你想要的结果的模型图吗? 主要目标是像QBrush样式一样填充节点。

以上是关于glsl qt 着色器程序的主要内容,如果未能解决你的问题,请参考以下文章

Qt & OpenGL OS X:山狮上的 GLSL 着色器版本只有 120

第二篇: WebGL 着色器和GLSL

GLSL 问题:一个程序中有多个着色器

GLSL/C++:自定义着色器的默认行为

有啥方法可以调试 GLSL 着色器?

如果未绑定,统一值是不是保留在 GLSL 着色器中?