QOpenGLWidget shared context not working
-
Hello,
I have some problem with sharing context for my second QOpenGLWidget window.
My project works more than 1 year (was on QGLWidget, migrated on 5.4 release) I had some troubles with it, somehow I solved it, but same tactic is not working on my next window. What I'm trying to do is simple render whole stuff without editing tools etc. Just for preview. Seems QOpenGLShaderProgram is main problematic in my case "QOpenGLShaderProgram::bind: program is not valid in the current context."
*
My QApplication class constructor:
@Application::Application(int& argc, char* argv)
: QApplication(argc, argv)
{
setAttribute(Qt::AA_ShareOpenGLContexts);setOrganizationDomain(QString(VER_COMPANYDOMAIN_STR)); setOrganizationName(QString(VER_COMPANYNAME_STR)); setApplicationName(QString(VER_PRODUCTNAME_STR)); setApplicationVersion(QString(VER_FILEVERSION_STR)); settings = new QSettings(this); translator = new QTranslator(this); translator->load(getSetting("language", QLocale::system().name()).toString(), ":/languages/", QString(), ".qlg"); installTranslator(translator); qsrand((uint)QTime::currentTime().msec()); mainWindow = new MainWindow(); mainWindow->showMaximized();
}@
in mainWindow I set as centralWidget my main QOpenGLWidget called MapView.
MapView constructor:
@MapView::MapView(World* mWorld,..., QWidget* parent)
: QOpenGLWidget(parent)
, world(mWorld)
, camera(new Camera(this))
, ...
{
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); camera->setPosition(QVector3D(250.0f, 10.0f, 250.0f)); camera->setViewCenter(QVector3D(250.0f, 10.0f, 249.0f)); camera->setUpVector(QVector3D(0.0f, 1.0f, 0.0f)); world->setCamera(camera); startTimer(16);
}@
MapView initializeGL:
@void MapView::initializeGL()
{
this->makeCurrent();initializeOpenGLFunctions(); QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); this->context()->setFormat(format); world->initialize(this->context(), size()); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); // just testing new depth func glClearColor(0.65f, 0.77f, 1.0f, 1.0f);
}@
World initialize:
@void World::initialize(QOpenGLContext* context, QSize fboSize)
{
GLfuncs = context->versionFunctions<QOpenGLFunctions_4_2_Core>();if(!GLfuncs) { qFatal(QObject::tr("Requires OpenGL >= 4.2").toLatin1().data()); exit(1); } GLfuncs->initializeOpenGLFunctions(); ....
}@
and now second QOpenGLWidget (problematic one)
@MapExplorer::MapExplorer(World* mWorld, QWidget* parent)
: QOpenGLWidget(parent)
, world(mWorld)
, camera(new Camera(this))
, ...
{
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); camera->setPosition(QVector3D(250.0f, 10.0f, 250.0f)); camera->setViewCenter(QVector3D(250.0f, 10.0f, 249.0f)); camera->setUpVector(QVector3D(0.0f, 1.0f, 0.0f)); startTimer(16);
}@
MapExplorer initializeGL:
@void MapExplorer::initializeGL()
{
this->makeCurrent();initializeOpenGLFunctions(); QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); this->context()->setFormat(format); qDebug() << (QOpenGLContext::currentContext() == this->context()); // return true glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); // just testing new depth func glClearColor(0.65f, 0.77f, 1.0f, 1.0f);
}@
QOpenGLShaderProgram's are created inside World class, I can't find problem where is my context is not sharing, I didn't find how to set manual created context or how to assign him to second one (take context from first set to second).
Thanks for any idea!
Regards, glararan.
-
main() create Application app; app.exec();
Application create main window
Main window create MapView (QOpenGLWidget) and also MapExplorer (QOpenGLWidget) so they should have same parent (main window) but mapview is central widget of main window and MapExplorer is in second window created from main window by@MapExplorer m = new MapExplorer(world, this);
m.show();@ -
I get an idea how to solve this. I will use QOpenGLContext for World and call that context->makeCurrent() but makeCurrent need argument QSurface, any idea how to get it from QOpenGLWidget? If I pass mapView->context()->surface() it gets bugged somehow and my QOpenGLFunctions stops working correct, it dont get correct pointer.
-
Hi, once again
I made progress! Currently main problem is that MapView is just black screen I think its caused by different context.
I changed mapView->context()->surface() to new QOffscreenSurface for MapView, so its running, I can see FPS counter etc, just not see objects which should be rendered.
Application class unchanged...
MapView constructor:
@MapView::MapView(World* mWorld, QWidget* parent)
: QOpenGLWidget(parent)
, world(mWorld)
, camera(new Camera(this))
, ...
{
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);QSurfaceFormat format; format.setDepthBufferSize(24); format.setMajorVersion(4); format.setMinorVersion(3); format.setSamples(4); format.setProfile(QSurfaceFormat::CoreProfile); format.setOption(QSurfaceFormat::DebugContext); QSurfaceFormat::setDefaultFormat(format); surface = new QOffscreenSurface(); surface->setFormat(format); surface->create(); qDebug() << "surface validation:" << surface->isValid(); // return true // Initialize the camera position and orientation camera->setPosition(QVector3D(250.0f, 10.0f, 250.0f)); camera->setViewCenter(QVector3D(250.0f, 10.0f, 249.0f)); camera->setUpVector(QVector3D(0.0f, 1.0f, 0.0f)); // Assign camera to World world->setCamera(camera); startTimer(16);
}@
MapView intializeGL:
@void MapView::initializeGL()
{
QOpenGLContext* _context = world->getContext();qDebug() << _context->makeCurrent(surface); // return true qDebug() << _context->isValid() << (QOpenGLContext::currentContext() == _context); // return true true initializeOpenGLFunctions(); // its still working? or have I call gl funcs from world? // Initialize World world->initialize(/*this->context(),*/ size(), worldCoords); // Initialize camera shader camera->initialize(); // Enable depth testing world->getGLFunctions()->glEnable(GL_DEPTH_TEST); world->getGLFunctions()->glEnable(GL_CULL_FACE); world->getGLFunctions()->glDepthFunc(GL_LEQUAL); // just testing new depth func world->getGLFunctions()->glClearColor(0.65f, 0.77f, 1.0f, 1.0f);
}@
MapView paintGL: I think there is some problem
@void MapView::paintGL()
{
world->getContext()->makeCurrent(surface);world->getGLFunctions()->glDrawBuffer(GL_FRONT); world->getGLFunctions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); world->draw(...); //world->getContext()->swapBuffers(surface); // not working even uncommented
}@
World initialize:
@void World::initialize(/QOpenGLContext context,*/ QSize fboSize, bool** mapCoords)
{
GLfuncs = context->versionFunctions<QOpenGLFunctions_4_2_Core>();if(!GLfuncs) { qDebug() << QObject::tr("Requires OpenGL >= 4.2"); qFatal(QObject::tr("Requires OpenGL >= 4.2").toLatin1().data()); exit(1); } GLfuncs->initializeOpenGLFunctions(); ...
}@
I don't know what next to do.
Thanks for help!