You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在QtQuick中使用gl_PointCoord绘制点图元及启用GL_POINT_SPRITE方法

在QtQuick中启用GL_POINT_SPRITE解决gl_PointCoord失效问题

问题背景

你提供的绘制圆形点的片元着色器代码如下:

void main()
{
   float size = 0.5;
   vec2 center = vec2(0.5);
   vec2 d = gl_PointCoord - center;
   float distSquared = dot(d, d);

   if(distSquared < size * size)
       gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
   else
       discard;
}

但当前gl_PointCoord始终返回vec2(0.0, 0.0),核心原因是未启用GL_POINT_SPRITE功能。

具体解决步骤

在QtQuick中启用GL_POINT_SPRITE需要借助自定义渲染节点获取OpenGL上下文,手动开启该选项,常见实现方式有两种:

方式一:基于QQuickItem自定义渲染节点

自定义继承QQuickItem的类,重写updatePaintNode方法,在渲染节点初始化/更新阶段启用GL_POINT_SPRITE:

QSGNode* CustomPointSpriteItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*)
{
    QSGGeometryNode* node = static_cast<QSGGeometryNode*>(oldNode);
    if (!node) {
        // 初始化点几何结构
        node = new QSGGeometryNode;
        QSGGeometry* geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 1);
        geometry->setLineWidth(20); // 设置初始点大小
        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);
        
        // 设置材质
        QSGFlatColorMaterial* material = new QSGFlatColorMaterial;
        material->setColor(Qt::red);
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    }

    // 获取当前OpenGL上下文并启用POINT_SPRITE
    QOpenGLContext* ctx = QOpenGLContext::currentContext();
    if (ctx) {
        ctx->functions()->glEnable(GL_POINT_SPRITE);
        // 可选:若需要通过顶点着色器控制点大小,需同时启用该选项
        ctx->functions()->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
    }

    return node;
}

方式二:配合QQuick3D/自定义Shader材质

如果使用QtQuick 3D组件,可在自定义材质的初始化方法中启用该选项:

void CustomPointMaterial::initialize()
{
    QQuick3DMaterial::initialize();
    QOpenGLContext* ctx = QOpenGLContext::currentContext();
    if (ctx) {
        ctx->functions()->glEnable(GL_POINT_SPRITE);
    }
}

注意事项

  • 必须确保在OpenGL上下文有效的阶段调用glEnable,通常是渲染节点的更新或材质初始化阶段,避免因上下文无效导致调用失败。
  • 启用GL_POINT_SPRITE后,gl_PointCoord会正确返回点精灵内的坐标(范围(0.0,0.0)到(1.0,1.0)),你的片元着色器即可正常绘制圆形点。

内容的提问来源于stack exchange,提问作者Anton Taras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 13:35:47