我基本上想做的是创建QGLWidget的一个实例(或更确切地说是QGLWidget的派生类),将其添加到QMainWindow,然后从任何地方访问QGLWidget的渲染上下文在我的QTCreator程序中可以在我选择的任何地方调用裸OpenGL。

我尝试过的事情:

1)创建一个称为QGLWidgetOGLWidget子类,并将其变成单例,然后尝试将单例类“ OGLWidget”子类化。我以为这将使我能够访问OGLWidget单例正在使用的相同渲染上下文,但是它不起作用。

2)使用构造函数QGLWidget(QWidget * parent, QGLWidget * shared, Qt::WindowFlags)。为此,我尝试将单例对象转换为QGLWidget,然后在将QGLWidget子类化为另一个名为“ Display”的类时将其粘贴到此构造函数中。我尝试在每个类openGl调用之前调用makeCurrent,但是只有原始单例会绘制。我还检查了isSharing,并返回true。

最佳答案

首先,尽管signal \ slots是Qt的强大功能,但是由于增加了开销和渲染顺序问题,我永远不会在渲染例程中使用它们。尤其是后者。此外,没有必要按照您的建议进行操作。
因此,我认为将渲染例程分散到整个项目中的想法是一个非常糟糕的想法。
我在自己的项目中所做的工作如下:

我派生的QGLWidget拥有一个Renderer类,该类已实现为Singleton。它包含几个函数中的所有OpenGl调用。我创建了一个系统,其中所有可绘制的内容均来自同一基类。当我想渲染时,我建立了一个渲染队列,并使用自定义排序功能将其实现为priority_queue。是时候渲染帧了,我只保留poppin和渲染,直到队列为空。
使用事件驱动的渲染系统执行此操作,同时保持正确的渲染顺序可能会使您发疯。

为了完整起见,我的(简化的)QGLWidget定义:

#include <QtOpenGL/QGLWidget>

#include "global.h"
#include "renderer.h"

/**
 * Derivation of QGLWidget.
 */
class Engine : public QGLWidget
{
    Q_OBJECT
private:
    Renderer* renderer;
private slots:
    void renderTimeout(); // my render-loop is timer based
    void onTap(QMouseEvent* qme);
    void onMove(QMouseEvent* qme);
protected:
    void initializeGL();
    void resizeGL(int w, int h);
    /* for debugging I use QPainter for drawing overlays,
     * so I can't use PaintGL */
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent* qme);
    void mouseMoveEvent(QMouseEvent* qme);
public:
    Engine( QWidget* parent = 0 );
    ~Engine();
signals:
    void tapOccurred(QMouseEvent* qme);
    void moveOccurred(QMouseEvent* qme);
};

10-06 14:14