在Qt中的外部类中使用OpenGL上下文

时间:2014-12-08 14:42:03

标签: c++ qt opengl

我在Qt中有一个继承自QGLViewer的窗口。如果我在该类中创建任何着色器程序,QGLShaderProgram myShader一切正常。

但是,我开始将一些渲染调用移动到具有draw()调用的类之外​​的类,并且事情已经破坏。

应用程序编译正常且没有错误,但在执行时我收到错误The program has unexpectedly finished

我发现在Qt4到Qt5周围,着色器类发生了变化,是Qt5中使用的QOpenGLShaderProgram。我试了一下,发生了同样的问题,然而我收到了不同的错误消息QOpenGLFunctions created with a non-current context

这让我觉得当从一个与实际绘图的类没有直接关系的类调用OpenGL函数时,OpenGL上下文会“丢失”。

如何在所有类中显示上下文?一般来说,我的代码看起来像

MyViewer.hpp

class MyViewer : public QGLViewer
{
   MyViewer(const QGLFormat format);
   ~MyViewer();

protected:
   init();
   draw()
   {
      // Clear color buffer and depth buffer
      // Do stuff
      m_cube.render();
   }
private:
   ...
   ...

   Cube m_cube;
};

Cube.cpp

class Cube
{
public:
   Cube()
   {
      m_shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertex.glsl");
      m_shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragment.glsl");
      m_shaderProgram.link();

      //Initialize VAO and VBOs
   }

   void render(){ // render OpenGL calls }

private:
   QGLShaderProgram m_shaderProgram;
};

1 个答案:

答案 0 :(得分:0)

Open gl上下文是全局的,但您可以在两个查看器之间明确共享上下文

QGLViewer   (   QGLContext *    context,
        QWidget *   parent = 0,
        const QGLWidget *   shareWidget = 0,
        Qt::WindowFlags     flags = 0 
    )   

根据执行情况

  

与QGLViewer()相同,但可以提供QGLContext以便查看者   共享GL上下文,即使使用QGLContext子类(使用shareWidget)   否则)。

首先检查你创建的课程中的顺序。因为Cube可能会调用opengl函数,而你的vieuwer仍然不完整 如果在QGLviewer创建上下文之前调用opengl函数,则会出错。

如果是这样,快速解决方法是在你的立方体构造中创建一个新的Qglcontext并将其传递给他们的观众。

否则这样做

Cube() {}; // empty cube constructor
void InitShaders()
   {
      m_shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertex.glsl");
      m_shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragment.glsl");
      m_shaderProgram.link();

      //Initialize VAO and VBOs
   }

并在我的观察者的构造函数中

MyViewer(const QGLFormat format){
    cube.initShaders();

}

我没有测试过这段代码,但它应该改变初始化的顺序。