QWidget::createWindowContainer() access violation
-
Hello all,
I've been vexed by this issue for a couple days now, and I don't really know what else to try. My issue is that I'm trying to get Ogre3D 1.9 and Qt 5.3 to work together and up to this point it seems to be going well. I'm creating a QWindow to hold the OpenGL drawing surface, and am switching contexts between Qt and Ogre since I can't get a straight OpenGL context from Qt.The contexts are created in this function:
@void CGraphicsManager::createContexts()
{
m_p_qt_gl_context = QOpenGLContext::currentContext();m_p_ogre_gl_context = new QOpenGLContext();
m_p_ogre_gl_context->setFormat(m_p_qt_window->requestedFormat());
m_p_ogre_gl_context->setShareContext(m_p_qt_gl_context);
bool created = m_p_ogre_gl_context->create();
if (!created)
{
std::exception ogre_context_err("!!! Fatal Error: Ogre's QOpenGLContext failed to be created!");
throw ogre_context_err;
}}@
And are switched in these functions:
@void CGraphicsManager::activateOgreContext()
{
m_p_qt_gl_context->doneCurrent();m_p_ogre_gl_context->makeCurrent(reinterpret_cast<QSurface*>(m_p_qt_window));
}void CGraphicsManager::deactivateOgreContext()
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);// unbind all possible remaining buffers; just to be on safe side
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
glBindBuffer(GL_COPY_READ_BUFFER, 0);
glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
// m_p_ogre_gl_context->functions()->glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
// m_p_ogre_gl_context->functions()->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
glBindBuffer(GL_UNIFORM_BUFFER, 0);m_p_ogre_gl_context->doneCurrent();
m_p_qt_gl_context->makeCurrent(reinterpret_cast<QSurface*>(m_p_qt_window));
}@Those functions are called while initializing Ogre in this function:
@CGraphicsManager::CGraphicsManager(QWindow* qt_window/* config options here */)
: m_p_qt_window(qt_window)
{
//Create the ogre and Qt contexts
try
{
createContexts();
}
catch(std::exception& e)
{
CLogger::Instance()->writeError(std::string("Fatal Error: ") + e.what());throw;
}
//activate ogre context
activateOgreContext();try
{
m_p_ogre_root = new Ogre::Root("","","ogre.log");//loadPlugins(); m_p_ogre_root->loadPlugin("RenderSystem_GL_d"); const Ogre::RenderSystemList& render_system = m_p_ogre_root->getAvailableRenderers(); Ogre::RenderSystemList::const_iterator itr = render_system.begin(); m_p_ogre_root->setRenderSystem(*itr); m_p_ogre_root->initialise(false);
}
catch(Ogre::Exception& e)
{
throw;
}Ogre::NameValuePairList options;
//These are required for working with Qt.
options["externalGLControl"] = "true";
options["currentGLContext"] = "true";try
{
m_p_ogre_window = m_p_ogre_root->createRenderWindow("Test",
1024,
768,
false,
&options);
}
catch(Ogre::Exception& e)
{
std::exception ogre_win_fail(e.what());
throw ogre_win_fail;
}m_p_ogre_window->setVisible(true);
m_p_ogre_window->update(false);deactivateOgreContext();
}@Now my QWindow which is a class called COpenGLWindow that inherits from QWindow which is constructed like this:
@COpenGLWindow::COpenGLWindow(QWindow *parent)
: QWindow(parent)
{
this->setSurfaceType(QSurface::SurfaceType::OpenGLSurface);QSurfaceFormat format;
format.setMajorVersion(4);
format.setMinorVersion(2);
format.setDepthBufferSize(24);
format.setProfile(QSurfaceFormat::CoreProfile);
this->setFormat(format);this->setHeight(768);
this->setWidth(1024);
this->create();QOpenGLContext* context = new QOpenGLContext();
context->setFormat(this->requestedFormat());
bool created = context->create();if (!created || !context->isValid())
{
std::exception err("QOpenGLContext creation failed! COpenGLWindow()");
throw err;
}
else
{
context->makeCurrent(this);
CLogger::Instance()->writeStatus(std::string("Qt OpenGL Context version: ") +
std::to_string(context->format().majorVersion()) +
std::string(".") +
std::to_string(context->format().minorVersion()));
}glewExperimental = TRUE;
glewInit();
}@And then my MainWindow does a simple QWidget::createWindowContainer() to add the OpenGLWindow to the primary window.
Yet I get an access violation during the createWindowContainer() function call that seems to be coming from the OpenGLWindow. Using external OpenGL libraries is a real pain in the rear, even when using a library that can draw to an external context. Really hoping someone here can help me out.
-
Can you give us the backtrace after the access violation?
-
Well I'm not sure what the problem exactly is. But can you try using QQuickWidget instead of QWidget::createWindowContainer() ?
I'm saying this since it's mentioned "here":http://blog.qt.digia.com/blog/2014/07/02/qt-weekly-16-qquickwidget/?utm_source=rssutm_medium=rssutm_campaign=qt-weekly-16-qquickwidget to prefer QQuickWidget. Scroll to Summary at the bottom. Anyway the whole article is worth to read. -
[quote author="p3c0" date="1404543049"]Well I'm not sure what the problem exactly is. But can you try using QQuickWidget instead of QWidget::createWindowContainer() ?[/quote]QQuickWidget is for Qt Quick UIs, not raw OpenGL surfaces like what Dar13 is using
-
Since you place your GL window in a widget anyway wouldn't it be easier to use QGLWidget?
As for switching context. I imagine this won't be very efficient anyway. Have you tried to get the handle to the Qt created OpenGL context via native methods eg. wglGetCurrentContext and use that with Ogre?