0

アプリでQGLWidgetを使用しようとしています。QGLWidgetから派生クラスを作成しました。別のスレッドから(glTexSubImage2Dを使用して)Textureを更新し、GUIスレッドからpaintGLで(glTexCoord2i ..を使用して)テクスチャを描画しています。

私が直面している問題は、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

OpenGL コンテキストは Qt によって管理されており、既に作成/完了されているため、paintGL()、resizeGL()、または initializeGL() 内で makeCurrent() または doneCurrent() を呼び出さないでください。

于 2012-12-05T12:21:21.080 に答える
1

makeCurrent、またはpaintGLを呼び出す必要はありません。事前に Qt によって呼び出されます。同様に、最後に呼び出しを行うべきではありません。これは、周囲のフレームワークがコンテキストを現在のままにしておく必要がある場合があるためです (実際、本当に call が必要になるケースはめったにありません)。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 に答える