我在 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;
};
立方体.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;
};
最佳答案
Open gl 上下文是全局的,但您可以像这样在 2 个查看器之间显式共享上下文
QGLViewer ( QGLContext * context,
QWidget * parent = 0,
const QGLWidget * shareWidget = 0,
Qt::WindowFlags flags = 0
)
根据文档
Same as QGLViewer(), but a QGLContext can be provided so that viewers share GL contexts, even with QGLContext sub-classes (use shareWidget otherwise).
所以首先检查你创建类的顺序。因为多维数据集可能正在调用 opengl 函数,而您的 View 仍然不完整 如果在 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();
}
我没有测试过这段代码,但它应该会改变初始化的顺序。
关于c++ - 在 Qt 的外部类中使用 OpenGL 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27360450/