为QGraphicsItem创建着色器程序

问题描述

| 我有一个QGraphicsScene,其中添加了QGraphicsItem。在QGraphicsItem中,我渲染了OpenGL ES 2.0的问候三角形示例中使用的三角形。问题是,如果我在除
QGraphicsItem::paint(QPainter *painter,const qstyleOptionGraphicsItem *option,QWidget *widget)
函数以外的任何地方创建和编译着色器,它们将不会被编译。我知道您应该启用GL渲染上下文,但是当我将视口设置为GLWidget时不会发生这种情况吗?我尝试了各种方法,例如在QGraphicsItem构造函数或QGraphicsScene中编译它们,并将QGraphicsItem设置为父级(我知道它们是非常愚蠢的事情),但是(显然)没有任何效果。在我看来,最合乎逻辑的方法是在QGraphicsItem类中创建一个initShaders()函数,并在场景中创建该项目后调用它,但这也行不通。     

解决方法

        创建QGraphicsView的派生类。覆盖setupViewport(QWidget * viewport)以初始化着色器。这将使您在编译着色器时确保上下文是最新的。但是,它要求在图形视图上调用setViewport()之前将项目添加到场景。
void MyGraphicsView::setupViewport(QWidget *viewport)
{
    QGLWidget *glWidget = qobject_cast<QGLWidget*>(viewport);
    if (glWidget) {
        glWidget->makeCurrent();
        foreach (QGraphicsItem *item,scene()->items())
        {
            MyGraphicsShaderItem *glItem = qgraphicsitem_cast<MyGraphicsShaderItem*>(item);
            if (glItem)
                glItem->initShader();
        }
        glWidget->doneCurrent();
    }
}