Multithreading QThread中具有共享QOpenGLContext的qPaint-新版本上的seg故障
我正在尝试学习如何使用Qt执行线程化gl,以便在一个单独的线程中卸载大量QPaint绘图。我在主gui线程中有一个QGLWidget,它从vbo中绘制一些线并显示纹理。在QGLWidget的initializeGL()函数中,我创建了一个QOffscreenSurface、QOpenGLContext和一个QThread,然后将QOpenGLContext移动到新的QThread。GLWidget的上下文和QOpenGLContext设置为共享。QThread启动后,它将创建一个QGLFramebufferObject作为QPaint的绘制设备。当QPaint完成时,威胁会向QGLWidget发出信号,以使用fbo的完成纹理重新绘制 在英伟达开源Kuuntuu 14.04机上,如果有很多绘图,程序SEG故障,并可以删除视频驱动程序。如果使用QPainter绘制的图形很少,则一切正常。在Nexus 4、Kubuntu 14.04、英特尔第二代核心和英特尔82945G/GZ Kubuntu 14.04上看起来不错。我怀疑新潮只是对我未知的错误不那么宽容Multithreading QThread中具有共享QOpenGLContext的qPaint-新版本上的seg故障,multithreading,qt,opengl,qt5,Multithreading,Qt,Opengl,Qt5,我正在尝试学习如何使用Qt执行线程化gl,以便在一个单独的线程中卸载大量QPaint绘图。我在主gui线程中有一个QGLWidget,它从vbo中绘制一些线并显示纹理。在QGLWidget的initializeGL()函数中,我创建了一个QOffscreenSurface、QOpenGLContext和一个QThread,然后将QOpenGLContext移动到新的QThread。GLWidget的上下文和QOpenGLContext设置为共享。QThread启动后,它将创建一个QGLFrame
nouveau: kernel rejected pushbuf: Invalid argument
nouveau: ch0: krec 0 pushes 3 bufs 12 relocs 0
nouveau: ch0: buf 00000000 00000002 00000004 00000004 00000000<\br>
nouveau: ch0: buf 00000001 00000013 00000002 00000000 00000002
nouveau: ch0: buf 00000002 00000016 00000002 00000002 00000000
nouveau: ch0: buf 00000003 00000007 00000002 00000002 00000000
nouveau: ch0: buf 00000004 0000000a 00000002 00000002 00000000
nouveau: ch0: buf 00000005 0000000b 00000002 00000002 00000000
nouveau: ch0: buf 00000006 00000008 00000002 00000002 00000000
nouveau: ch0: buf 00000007 00000006 00000004 00000000 00000004
nouveau: ch0: buf 00000008 00000003 00000004 00000004 00000000
nouveau: ch0: buf 00000009 0000000e 00000002 00000002 00000000
nouveau: ch0: buf 0000000a 00000017 00000002 00000000 00000002
nouveau: ch0: buf 0000000b 00000018 00000002 00000000 00000002
Segmentation fault (core dumped)
main.h
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLShader>
#include <QTimer>
#include "textThread.h"
class glview : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit glview(QWidget *parent = 0);
~glview();
QSize sizeHint() const;
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
private:
QTimer repaintTimer;
QGLShaderProgram *program, *txtovlp;
textThread *maketext;
quint32 vbo_id[2];
private slots:
void repaint(void);
};
#包括
#包括
#包括
#包括
#包括“textThread.h”
类glview:公共QGLWidget,受保护的QGLFunctions
{
Q_对象
公众:
显式glview(QWidget*parent=0);
~glview();
QSize sizeHint()常量;
受保护的:
void initializeGL();
无效尺寸(整数w,整数h);
void paintGL();
私人:
QTimer重绘定时器;
QGLShaderProgram*程序,*txtovlp;
textThread*maketext;
quint32 vbo_id[2];
专用插槽:
无效重新喷漆(无效);
};
main.cpp
#include <QApplication>
#include "main.h"
struct vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
}__attribute__((packed)) line_geo[] = {
// x, y, z, r, g, b
{1, 1, 0, 1, 0, 0},
{1, 2, 0, 0, 1, 0},
{1, 2, 0, 0, 1, 0},
{2, 2, 0, 1, 0, 0},
{2, 2, 0, 1, 0, 0},
{2, 1, 0, 0, 1, 0},
{2, 1, 0, 0, 1, 0},
{1, 1, 0, 1, 0, 0},
};
struct txtr_vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat tx;
GLfloat ty;
}__attribute__((packed)) txtr_geo[] = {
// x, y, z, tx,ty
{3, 1, 0, 0, 0},
{3, 2, 0, 0, 1},
{4, 2, 0, 1, 1},
{4, 1, 0, 1, 0},
};
glview::glview(QWidget *parent) : QGLWidget(parent)
{
connect(&repaintTimer, SIGNAL(timeout()), this, SLOT(repaint()));
repaintTimer.start(20);
}
glview::~glview()
{
delete maketext->context;
delete maketext->offscrnsf;
delete maketext;
delete program;
delete txtovlp;
}
QSize glview::sizeHint() const
{
return QSize(500, 300);
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::white);
QGLShader *vshader = new QGLShader(QGLShader::Vertex, this);
const char *vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec4 colour;\n"
"varying mediump vec4 f_colour;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" f_colour = colour;\n"
"}\n";
vshader->compileSourceCode(vsrc);
QGLShader *fshader = new QGLShader(QGLShader::Fragment, this);
const char *fsrc =
"varying mediump vec4 f_colour;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = f_colour;\n"
"}\n";
fshader->compileSourceCode(fsrc);
program = new QGLShaderProgram(this);
program->addShader(vshader);
program->addShader(fshader);
program->link();
QGLShader *txtovlp_vshader = new QGLShader(QGLShader::Vertex, this);
const char *txtovlp_vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec2 texCoord;\n"
"varying mediump vec2 texc;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" texc = texCoord;\n"
"}\n";
txtovlp_vshader->compileSourceCode(txtovlp_vsrc);
QGLShader *txtovlp_fshader = new QGLShader(QGLShader::Fragment, this);
const char *txtovlp_fsrc =
"uniform sampler2D texture;\n"
"varying mediump vec2 texc;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(texture, texc.st);\n"
"}\n";
txtovlp_fshader->compileSourceCode(txtovlp_fsrc);
txtovlp = new QGLShaderProgram(this);
txtovlp->addShader(txtovlp_vshader);
txtovlp->addShader(txtovlp_fshader);
txtovlp->link();
glGenBuffers(2, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(line_geo), line_geo, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(txtr_geo), txtr_geo, GL_STATIC_DRAW);
glEnable(GL_DEPTH_TEST);
doneCurrent();
maketext = new textThread;
maketext->offscrnsf = new QOffscreenSurface();
maketext->offscrnsf->create();
if (!maketext->offscrnsf->isValid()) {
qDebug() << "Surface Failed";
exit(1);
}
maketext->context = new QOpenGLContext();
maketext->context->setShareContext(this->context()->contextHandle());
maketext->context->create();
if (!maketext->context->isValid()) {
qDebug() << "Context Failed";
exit(1);
}
if (!maketext->context->areSharing(this->context()->contextHandle(), maketext->context)) {
qDebug() << "Sharing Failed";
exit(1);
}
maketext->context->moveToThread(maketext);
//connect(maketext, SIGNAL(finished()), this, SLOT(repaint()));
connect(maketext, SIGNAL(finished()), this, SLOT(repaint()), Qt::QueuedConnection);
maketext->start();
}
void glview::resizeGL(int w, int h)
{
makeCurrent();
glViewport(0, 0, w, h);
}
void glview::repaint(void)
{
repaintTimer.start(20);
updateGL();
}
void glview::paintGL()
{
static quint32 i;
i++;
printf("Pa");
makeCurrent();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.ortho(0, 5, 0, 3, -1, 1);
program->bind();
program->setUniformValue("matrix", matrix);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
int vertexLocation = program->attributeLocation("vertex");
program->enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), 0);
int colourLocation = program->attributeLocation("colour");
program->enableAttributeArray(colourLocation);
glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), ((char*)NULL + 12));
glDrawArrays(GL_LINES, 0, sizeof(line_geo) / sizeof(struct vrtx));
txtovlp->bind();
txtovlp->setUniformValue("matrix", matrix);
maketext->textLock.lock();
if (maketext->done) {
maketext->textLock.unlock();
//qDebug() << "Painting with text" << i;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBindTexture(GL_TEXTURE_2D, maketext->texture_id);
int txtr_vertexLocation = txtovlp->attributeLocation("vertex");
txtovlp->enableAttributeArray(txtr_vertexLocation);
glVertexAttribPointer(txtr_vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), 0);
int texCoordLocation = txtovlp->attributeLocation("texCoord");
txtovlp->enableAttributeArray(texCoordLocation);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), ((char*)NULL + 12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
else {
maketext->textLock.unlock();
//qDebug() << "Painting" << i;
}
glFlush();
printf("int\n");
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication app(argc, argv);
glview widget;
widget.show();
return app.exec();
}
#包括
#包括“main.h”
结构vrtx{
GLX;
GLY;
GLZ;
GLR;
GLG;
GLB;
}__属性uuu((压缩))行_geo[]={
//x,y,z,r,g,b
{1, 1, 0, 1, 0, 0},
{1, 2, 0, 0, 1, 0},
{1, 2, 0, 0, 1, 0},
{2, 2, 0, 1, 0, 0},
{2, 2, 0, 1, 0, 0},
{2, 1, 0, 0, 1, 0},
{2, 1, 0, 0, 1, 0},
{1, 1, 0, 1, 0, 0},
};
结构txtr\U vrtx{
GLX;
GLY;
GLZ;
GLTX;
GLTY;
}__属性(压缩)txtr\u geo[]={
//x,y,z,tx,ty
{3, 1, 0, 0, 0},
{3, 2, 0, 0, 1},
{4, 2, 0, 1, 1},
{4, 1, 0, 1, 0},
};
glview::glview(QWidget*父项):QGLWidget(父项)
{
连接(&重新绘制计时器,信号(超时()),此,插槽(重新绘制());
重新绘制计时器。启动(20);
}
glview::~glview()
{
删除maketext->context;
删除maketext->offscrnsf;
删除maketext;
删除程序;
删除txtovlp;
}
QSize glview::sizeHint()常量
{
返回QSize(500300);
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::白色);
QGLShader*vshader=新的QGLShader(QGLShader::Vertex,this);
常量字符*vsrc=
“属性highp vec4顶点;\n”
“属性mediump vec4 color;\n”
“不同的mediump vec4 f_颜色;\n”
“统一mediump mat4矩阵;\n”
“作废主(作废)\n”
“{\n”
“gl_位置=矩阵*顶点;\n”
“f_color=color;\n”
“}\n”;
vshader->compileSourceCode(vsrc);
QGLShader*fshader=新的QGLShader(QGLShader::Fragment,this);
常量字符*fsrc=
“不同的mediump vec4 f_颜色;\n”
“作废主(作废)\n”
“{\n”
“gl\u FragColor=f\u color;\n”
“}\n”;
fshader->compileSourceCode(fsrc);
程序=新的QGLShaderProgram(本程序);
程序->添加着色器(vshader);
程序->添加着色器(fshader);
程序->链接();
QGLShader*txtovlp_vshader=新的QGLShader(QGLShader::Vertex,this);
常量字符*txtovlp\u vsrc=
“属性highp vec4顶点;\n”
“属性mediump vec2 texCoord;\n”
“可变介质矢量2 texc;\n”
“统一mediump mat4矩阵;\n”
“作废主(作废)\n”
“{\n”
“gl_位置=矩阵*顶点;\n”
“texc=texCoord;\n”
“}\n”;
txtovlp_vshader->编译源代码(txtovlp_vsrc);
QGLShader*txtovlp_fshader=新的QGLShader(QGLShader::Fragment,this);
常量字符*txtovlp_fsrc=
“二维纹理的均匀采样;\n”
“可变介质矢量2 texc;\n”
“作废主(作废)\n”
“{\n”
gl_FragColor=texture2D(纹理,texc.st);\n
“}\n”;
txtovlp_fshader->编译资源代码(txtovlp_fsrc);
txtovlp=新的QGLShaderProgram(本程序);
txtovlp->addShader(txtovlp_vshader);
txtovlp->addShader(txtovlp_fshader);
txtovlp->link();
glGenBuffers(2,vbo_id);
glBindBuffer(GL_数组_BUFFER,vbo_id[0]);
glBufferData(GL_数组_缓冲区、sizeof(line_geo)、line_geo、GL_静态_绘图);
glBindBuffer(GL_数组_BUFFER,vbo_id[1]);
glBufferData(GL_数组_缓冲区、sizeof(txtr_geo)、txtr_geo、GL_静态_绘图);
glEnable(GLU深度试验);
doneCurrent();
maketext=新的textThread;
maketext->offscrnsf=新QOffscreenSurface();
maketext->offscrnsf->create();
如果(!maketext->offscrnsf->isValid()){
qDebug()上下文=新的QOpenGLContext();
maketext->context->setShareContext(此->context()->contextHandle());
maketext->context->create();
如果(!maketext->context->isValid()){
qDebug()context->areSharing(此->context()->contextHandle(),maketext->context)){
qDebug()上下文->移动到线程(maketext);
//连接(maketext,信号(finished()),此,插槽(repaint());
连接(maketext,SIGNAL(finished()),this,SLOT(repaint()),Qt::QueuedConnection);
maketext->start();
}
void glview::resizeGL(int w,int h)
{
makeCurrent();
glViewport(0,0,w,h);
}
void glview::重新绘制(void)
{
重新绘制计时器。启动(20);
updateGL();
}
void glview::paintGL()
{
静态电压;
i++;
printf(“Pa”);
makeCurrent();
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
QMatrix4x4矩阵;
矩阵正交(0,5,0,3,-1,1);
程序->绑定();
程序->设置统一值(“矩阵”,矩阵);
#include <QApplication>
#include "main.h"
struct vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
}__attribute__((packed)) line_geo[] = {
// x, y, z, r, g, b
{1, 1, 0, 1, 0, 0},
{1, 2, 0, 0, 1, 0},
{1, 2, 0, 0, 1, 0},
{2, 2, 0, 1, 0, 0},
{2, 2, 0, 1, 0, 0},
{2, 1, 0, 0, 1, 0},
{2, 1, 0, 0, 1, 0},
{1, 1, 0, 1, 0, 0},
};
struct txtr_vrtx {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat tx;
GLfloat ty;
}__attribute__((packed)) txtr_geo[] = {
// x, y, z, tx,ty
{3, 1, 0, 0, 0},
{3, 2, 0, 0, 1},
{4, 2, 0, 1, 1},
{4, 1, 0, 1, 0},
};
glview::glview(QWidget *parent) : QGLWidget(parent)
{
connect(&repaintTimer, SIGNAL(timeout()), this, SLOT(repaint()));
repaintTimer.start(20);
}
glview::~glview()
{
delete maketext->context;
delete maketext->offscrnsf;
delete maketext;
delete program;
delete txtovlp;
}
QSize glview::sizeHint() const
{
return QSize(500, 300);
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::white);
QGLShader *vshader = new QGLShader(QGLShader::Vertex, this);
const char *vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec4 colour;\n"
"varying mediump vec4 f_colour;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" f_colour = colour;\n"
"}\n";
vshader->compileSourceCode(vsrc);
QGLShader *fshader = new QGLShader(QGLShader::Fragment, this);
const char *fsrc =
"varying mediump vec4 f_colour;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = f_colour;\n"
"}\n";
fshader->compileSourceCode(fsrc);
program = new QGLShaderProgram(this);
program->addShader(vshader);
program->addShader(fshader);
program->link();
QGLShader *txtovlp_vshader = new QGLShader(QGLShader::Vertex, this);
const char *txtovlp_vsrc =
"attribute highp vec4 vertex;\n"
"attribute mediump vec2 texCoord;\n"
"varying mediump vec2 texc;\n"
"uniform mediump mat4 matrix;\n"
"void main(void)\n"
"{\n"
" gl_Position = matrix * vertex;\n"
" texc = texCoord;\n"
"}\n";
txtovlp_vshader->compileSourceCode(txtovlp_vsrc);
QGLShader *txtovlp_fshader = new QGLShader(QGLShader::Fragment, this);
const char *txtovlp_fsrc =
"uniform sampler2D texture;\n"
"varying mediump vec2 texc;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = texture2D(texture, texc.st);\n"
"}\n";
txtovlp_fshader->compileSourceCode(txtovlp_fsrc);
txtovlp = new QGLShaderProgram(this);
txtovlp->addShader(txtovlp_vshader);
txtovlp->addShader(txtovlp_fshader);
txtovlp->link();
glGenBuffers(2, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(line_geo), line_geo, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(txtr_geo), txtr_geo, GL_STATIC_DRAW);
glEnable(GL_DEPTH_TEST);
doneCurrent();
maketext = new textThread;
maketext->offscrnsf = new QOffscreenSurface();
maketext->offscrnsf->create();
if (!maketext->offscrnsf->isValid()) {
qDebug() << "Surface Failed";
exit(1);
}
maketext->context = new QOpenGLContext();
maketext->context->setShareContext(this->context()->contextHandle());
maketext->context->create();
if (!maketext->context->isValid()) {
qDebug() << "Context Failed";
exit(1);
}
if (!maketext->context->areSharing(this->context()->contextHandle(), maketext->context)) {
qDebug() << "Sharing Failed";
exit(1);
}
maketext->context->moveToThread(maketext);
//connect(maketext, SIGNAL(finished()), this, SLOT(repaint()));
connect(maketext, SIGNAL(finished()), this, SLOT(repaint()), Qt::QueuedConnection);
maketext->start();
}
void glview::resizeGL(int w, int h)
{
makeCurrent();
glViewport(0, 0, w, h);
}
void glview::repaint(void)
{
repaintTimer.start(20);
updateGL();
}
void glview::paintGL()
{
static quint32 i;
i++;
printf("Pa");
makeCurrent();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 matrix;
matrix.ortho(0, 5, 0, 3, -1, 1);
program->bind();
program->setUniformValue("matrix", matrix);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
int vertexLocation = program->attributeLocation("vertex");
program->enableAttributeArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), 0);
int colourLocation = program->attributeLocation("colour");
program->enableAttributeArray(colourLocation);
glVertexAttribPointer(colourLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct vrtx), ((char*)NULL + 12));
glDrawArrays(GL_LINES, 0, sizeof(line_geo) / sizeof(struct vrtx));
txtovlp->bind();
txtovlp->setUniformValue("matrix", matrix);
maketext->textLock.lock();
if (maketext->done) {
maketext->textLock.unlock();
//qDebug() << "Painting with text" << i;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBindTexture(GL_TEXTURE_2D, maketext->texture_id);
int txtr_vertexLocation = txtovlp->attributeLocation("vertex");
txtovlp->enableAttributeArray(txtr_vertexLocation);
glVertexAttribPointer(txtr_vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), 0);
int texCoordLocation = txtovlp->attributeLocation("texCoord");
txtovlp->enableAttributeArray(texCoordLocation);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), ((char*)NULL + 12));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
else {
maketext->textLock.unlock();
//qDebug() << "Painting" << i;
}
glFlush();
printf("int\n");
}
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication app(argc, argv);
glview widget;
widget.show();
return app.exec();
}
#ifndef textThread_h
#define textThread_h
#include <QThread>
#include <QMutex>
#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QGLFramebufferObject>
#include <QFont>
#include <QDebug>
class textThread : public QThread
{
Q_OBJECT
public:
textThread();
~textThread();
QMutex textLock;
QOffscreenSurface *offscrnsf;
QOpenGLContext *context;
bool done;
quint32 texture_id;
signals:
void finished(void);
protected:
void run();
private:
QGLFramebufferObject *fbo;
QFont font;
};
#endif
#include <QPainter>
#include "textThread.h"
#define QPAINT_A_LOT
textThread::textThread()
{
done = 0;
fbo = NULL;
font.setFamily("Helvetica");
}
textThread::~textThread()
{
delete fbo;
}
void textThread::run()
{
context->makeCurrent(offscrnsf);
qDebug() << "Thread";
if (!fbo)
fbo = new QGLFramebufferObject(100, 100, GL_TEXTURE_2D);
fbo->bind();
texture_id = fbo->texture();
QPainter painter(fbo);
font.setPointSize(20);
painter.setFont(font);
painter.eraseRect(0,0,100,100);
painter.setPen(Qt::blue);
#ifdef QPAINT_A_LOT
quint32 i;
for (i=0; i<140000; i++) {
//if (!(i%32768))
if (!(i%1024))
qDebug() << i;
painter.drawText(0, 60, "FBO");
}
#else
painter.drawText(0, 60, "FBO");
sleep(1);
#endif
painter.end();
fbo->release();
context->doneCurrent();
textLock.lock();
done = 1;
textLock.unlock();
emit finished();
}