Ven
Ven

Reputation: 247

Methods that call QGLContext::makeCurrent()

I am trying to use QGLWidget in our App. I have cretaed a derived class from QGLWidget . I am updating the Texture(using glTexSubImage2D) from a seperate thread and drwaing the texture(using glTexCoord2i ..) in paintGL from GUI thread.

The problem I am facing is that I am getting "QGLContext::makeCurrent() : wglMakeCurrent failed: The requested resource is in use" when I resize the window or minimize or maximize, even though I have overridden initializeGL,resizeGL,paintGL methods and calling doneCurrent before leaving these methods.

Can someone help me in understanding what are the other methods needs to be overridden to fix this issue.

Thank you. Ven

Here is the template of my code

#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();
}

Upvotes: 0

Views: 5366

Answers (2)

Christian Rau
Christian Rau

Reputation: 45948

You don't call makeCurrent in paintGL, initializeGL or resizeGL, it is called for you by Qt beforehand. Likewise you shouldn't call doneCurrent at the end because the surrounding framework might need the context to still be current (in fact there is rarely a case where you really need call doneCurrent).

In the same way you don't reimplement resizeEvent to get resizing information. That's what resizeGL is for, which is called automatically by QGLWidget::resizeEvent, wrapped by a makeCurrent call.

So just change your code to this:

#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();
}

Upvotes: 1

Oleg Titov
Oleg Titov

Reputation: 1140

You should not call makeCurrent() or doneCurrent() inside paintGL(), resizeGL() or initializeGL() since OpenGL context is managed by Qt and already made/done current there.

Upvotes: 2

Related Questions