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 着色器程序的主要内容,如果未能解决你的问题,请参考以下文章