0

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();
}
Ven
  • 247
  • 1
  • 5
  • 17
  • I have solved the problem...Need to override paintEvent and call done current in the end with the help of mutex(as shown in other methods).Remove lock and unlock in the paintGL – Ven Dec 10 '12 at 11:59

2 Answers2

2

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.

Oleg Titov
  • 1,040
  • 1
  • 8
  • 12
  • Thank You Oleg.Otherwise I am getting "QGLContext::makeCurrent() : wglMakeCurrent failed: The requested resource is in use" error continuously upon calling updateTexure.Hence blank screen... – Ven Dec 05 '12 at 12:49
  • I see you call makeCurrent() in updateTexture() slot and no doneCurrent(). Do you call it there? That may cause a problem. – Oleg Titov Dec 05 '12 at 15:31
  • BTW: do you really need OpenGL calls in both resizeGL() and resizeEvent() ? This looks weird. – Oleg Titov Dec 05 '12 at 15:32
  • I am calling doneCurrent() in updateTeture().Still I see the error when I resize the window.I removed Gl code form resizeGL() and removed resizeEvent() – Ven Dec 05 '12 at 15:37
  • Can you show modified code? There were too any modifications to understand what's in current version. – Oleg Titov Dec 05 '12 at 15:45
  • 1. GL initialization in constructor is weird. initializeGL() is created for this purpose. 2. What happens if you remove all makeCurrent() and doneCurrent() from paintGL(), resizeGL() and initializeGL()? It seems that your makeCurrent() does nothing, because the context is already current BUT doneCurrent() does its job in invalidating the context which is unexpected by Qt when it tries to do some GL calls like swapping buffers after paintGL(). – Oleg Titov Dec 05 '12 at 16:34
  • We get "QGLContext::makeCurrent() : wglMakeCurrent failed: The requested resource is in use" error upon calling updateTeture(). Because paintGL(), resizeGL() and initializeGL() will cal makeCurrent() implicitly and they will not call doneCurrent() once they leave the function.So when updateTeture() calls makeCurrent() we get the above error. – Ven Dec 05 '12 at 16:51
1

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();
}
Christian Rau
  • 43,206
  • 10
  • 106
  • 177
  • Thank you Christian.But the problem is that I am getting "QGLContext::makeCurrent() : wglMakeCurrent failed: The requested resource is in use" error continuously upon calling updateTexure.Hence blank screen... – Ven Dec 05 '12 at 12:45