0

我正在尝试在我们的应用程序中使用 QGLWidget。我从 QGLWidget 创建了一个派生类。我正在从一个单独的线程更新纹理(使用 glTexSubImage2D),并从 GUI 线程在 paintGL 中绘制纹理(使用 glTexCoord2i ..)。

我面临的问题是,当我调整窗口大小或最小化或最大化时,我得到“QGLContext::makeCurrent() : wglMakeCurrent failed: The requested resource is in use”,即使我已经覆盖了 initializeGL、resizeGL、paintGL 方法和在离开这些方法之前调用 doneCurrent。

有人可以帮助我了解需要覆盖哪些其他方法来解决此问题。

谢谢你。文

这是我的代码模板

#include "MyGlTexture.h" //my texture has pure open Gl code..it doesnt have qgl related code
#include <QGLWidget>

class MyGLWidget
   : public QGLWidget
{
   Q_OBJECT

   MyGLWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
   virtual ~MyGLWidget();

public slots:

   void updateTexure(QImage *img);

protected:   

   void initializeGL ();
   void resizeGL(int w, int h);
   void paintGL ();

   MyGlTexture m_Texture;
   QMutex m_DrawMutex;
};
MyGLWidget::MyGLWidget(QWidget *parent, Qt::WindowFlags f )
   : QGLWidget( parent,0, f)
{
 //some gl init code

}
MyGLWidget::~MyGLWidget()
{
//cleanup
}

void MyGLWidget::initializeGL ()
{
 ...........
 ...........
 m_Texture.Init(screenRect.width(),screenRect.height(), GL_TEXTURE_2D, GL_RGB);
}

void MyGLWidget::resizeGL(int width, int height)
{
   m_DrawMutex.lock();
   makeCurrent();
   //some code to get window size
   .................
   ...................   
   doneCurrent();
   m_DrawMutex.unlock();
}

//Updated by GUI Thread
void MyGLWidget::paintGL ()
{
   m_DrawMutex.lock();
   makeCurrent();

   m_Texure.Draw();

   doneCurrent();
   m_DrawMutex.unlock();
}
///Image Update thread
void MyGLWidget::updateTexure(QImage *img)
{
   m_DrawMutex.lock();
   makeCurrent();
   m_Texure.Update(img);
   doneCurrent();
   m_DrawMutex.unlock();
   //emit update singal which calls piantGL() to draw the texture
   update();
}
4

2 回答 2

2

你不应该在paintGL()、resizeGL() 或initializeGL() 中调用makeCurrent() 或doneCurrent(),因为OpenGL 上下文是由Qt 管理的并且已经在那里制作/完成。

于 2012-12-05T12:21:21.080 回答
1

你不调用makeCurrent,或者paintGL,它是由 Qt 预先为你调用的。同样,您不应该在最后调用,因为周围的框架可能需要上下文仍然是最新的(实际上很少有真正需要调用的情况)。initializeGLresizeGLdoneCurrentdoneCurrent

以同样的方式,您无需重新实现resizeEvent以获取调整大小信息。这resizeGL就是 for,由 自动调用QGLWidget::resizeEvent,由调用包裹makeCurrent

所以只需将您的代码更改为:

#include "MyGlTexture.h" //my texture has pure open Gl code..it doesnt have qgl related code
#include <QGLWidget>

class MyGLWidget
   : public QGLWidget
{
   Q_OBJECT

   MyGLWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
   virtual ~MyGLWidget();

public slots:

   void updateTexure(QImage *img);

protected:   

   void initializeGL ();
   void resizeGL(int w, int h);  
   void paintGL ();

   MyGlTexture m_Texture;
   QMutex m_DrawMutex;
};
MyGLWidget::MyGLWidget(QWidget *parent, Qt::WindowFlags f )
   : QGLWidget( parent,0, f)
{
   //some gl init code

}
MyGLWidget::~MyGLWidget()
{
   //cleanup
}

void MyGLWidget::initializeGL ()
{
   ...........
   ...........
   m_Texture.Init(screenRect.width(),screenRect.height(), GL_TEXTURE_2D, GL_RGB);
}

void MyGLWidget::resizeGL(int width, int height)
{
   QMutexLocker locker(&m_DrawMutex);
   //some Gl code
}
//Updated by GUI Thread
void MyGLWidget::paintGL ()
{
   QMutexLocker locker(&m_DrawMutex);
   m_DrawMutex.Draw();       // Huh, should this be m_Texture?
}
///Image Update thread
void MyGLWidget::updateTexure(QImage *img)
{
   // Ok, here we need it, but still no need for doneCurrent
   makeCurrent();

   QMutexLocker locker(&m_DrawMutex);
   m_DrawMutex.Update(img);  // Huh, should this be m_Texture?

   //emit update singal which schedules piantGL() to be called!
   update();
}
于 2012-12-05T12:21:45.060 回答