Hi All,
In my program I am using more that on GLWidget and all works fine but rendering is too slow.
Now I am trying to speed-up the rendering of a scene by using a thread to calculate the vertex list of one of the GLWidgets. It works but sometimes I see artifacts in the image and after about 30 seconds it always crashes the app. I read here (http://doc.qt.digia.com/qq/qq06-glim...glapplications) that it should be possible to do that but so far I am not able to get stable results. The thread gets called by the render() function to pass in an image which is the basis for the calculation of the vertex list. This happens about 30x per second.
There is also another thread (http://www.qtcentre.org/threads/3631...d-GUI-possible) which mentions that this should work but it does not.
Here is the code Thread I wrote:
class GLWaveformThread
: public QThread{
Q_OBJECT
public:
explicit GLWaveformThread(WaveformGLWidget *glWidget);
~GLWaveformThread();
void render(const Img::Image &image);
protected:
void run();
private:
bool restart;
bool abort;
WaveformGLWidget *myGLW;
};
GLWaveformThread::GLWaveformThread(WaveformGLWidget *glWidget) :
{
restart = false;
abort = false;
}
void GLWaveformThread
::render(QImage &image
) {
if(image.isEmpty())
return;
fPix = image;
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}
}
void GLWaveformThread::run()
{
forever {
mutex.lock(); //-----------
myGLW->makeCurrent();
glDeleteLists(myGLW->vectors(), 1);
glNewList(myGLW->vectors(), GL_COMPILE);
int w = fPix.width();
int h = fPix.height();
mutex.unlock(); //-----------
if (abort)
return;
glColor3f(.2, .1, .1);
for(int y = 0; y < h; y++)
{
glBegin(GL_LINE_STRIP);
for(int x=0; x < w; x++)
glVertex3f(...); // draw some lines
glEnd();
}
glEndList();
mutex.lock(); //-----------
myGLW->updateGL();
if (!restart)
condition.wait(&mutex);
restart = false;
mutex.unlock(); //-----------
}
}
class GLWaveformThread : public QThread
{
Q_OBJECT
public:
explicit GLWaveformThread(WaveformGLWidget *glWidget);
~GLWaveformThread();
void render(const Img::Image &image);
protected:
void run();
private:
QMutex mutex;
QWaitCondition condition;
bool restart;
bool abort;
QImage fPix;
WaveformGLWidget *myGLW;
};
GLWaveformThread::GLWaveformThread(WaveformGLWidget *glWidget) :
QThread(), myGLW(glWidget)
{
restart = false;
abort = false;
}
void GLWaveformThread::render(QImage &image)
{
QMutexLocker locker(&mutex);
if(image.isEmpty())
return;
fPix = image;
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
condition.wakeOne();
}
}
void GLWaveformThread::run()
{
forever {
mutex.lock(); //-----------
QImage in = fPix;
myGLW->makeCurrent();
glDeleteLists(myGLW->vectors(), 1);
glNewList(myGLW->vectors(), GL_COMPILE);
int w = fPix.width();
int h = fPix.height();
mutex.unlock(); //-----------
if (abort)
return;
glColor3f(.2, .1, .1);
for(int y = 0; y < h; y++)
{
glBegin(GL_LINE_STRIP);
for(int x=0; x < w; x++)
glVertex3f(...); // draw some lines
glEnd();
}
glEndList();
mutex.lock(); //-----------
myGLW->updateGL();
if (!restart)
condition.wait(&mutex);
restart = false;
mutex.unlock(); //-----------
}
}
To copy to clipboard, switch view to plain text mode
This is the code for the widget:
void WaveformGLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearAccum(0.0, 0.0, 0.0, 0.0);
myVectors = glGenLists(1);
}
void WaveformGLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void WaveformGLWidget::paintGL()
{
glPushMatrix();
makeCurrent();
glScalef(.6, 1.9, 1.0);
glTranslatef(-1.5,-.5,0.);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glCallList(myVectors);
glDisable(GL_BLEND);
glPopMatrix();
}
void WaveformGLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearAccum(0.0, 0.0, 0.0, 0.0);
myVectors = glGenLists(1);
}
void WaveformGLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void WaveformGLWidget::paintGL()
{
glPushMatrix();
makeCurrent();
glScalef(.6, 1.9, 1.0);
glTranslatef(-1.5,-.5,0.);
glClear(GL_COLOR_BUFFER_BIT);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glCallList(myVectors);
glDisable(GL_BLEND);
glPopMatrix();
}
To copy to clipboard, switch view to plain text mode
Thanks in advance
Markus
Bookmarks