2016-07-20 81 views
-1

我正在试图制作一个使用qt和QOpenGLFunctions的screengrabber。我的code seg在funcs = context-> functions();这段代码并不是真的很棒,也没有线程化,定时器在如此小的时间间隔内并不精确,但它比我计划使用的代码更像是一个概念证明。据我所知,我需要使用这些QOpenGLFunctions,以便它能够在Windows上使用ANGLE。这将有助于,因为Windows只附带opengl 1.0,我宁愿不使用它,并通过ANGLE使用directx。我已经在所有工具包上使用QT 5.5.1到5.7在Ubuntu 16.04 LTS和Windows 10上进行了测试。Qt OpenGL函数seg fault

构造:

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
ui->setupUi(this); 
//QOpenGLContext *context = new QOpenGLContext(); 
QOpenGLContext *context = QOpenGLContext::CurrentContext(); 
//I only want to use glreadpixels. I don't need the rest of opengl. This may not be necessary. 
QSurfaceFormat format; 
format.setRenderableType(QSurfaceFormat::OpenGL); 
format.setDepthBufferSize(32); 
format.setVersion(4,5); 
format.setSamples(4); 
format.setProfile(QSurfaceFormat::CompatibilityProfile); 
context->setFormat(format); 
context->create(); 

funcs = context->functions(); //seg faults here 
funcs->initializeOpenGLFunctions(); 
connect(timer, SIGNAL(timeout()), this, SLOT(grabScreen())); 
connect(timer2, SIGNAL(timeout()),this, SLOT(quit())); 

timer->setTimerType(Qt::PreciseTimer); 
timer2->setTimerType(Qt::PreciseTimer); 
timer2->start(10000); //10 sec 
timer->start(1000/60); //60 fps 

}

grabScreen:

void MainWindow::grabScreen() 
{ 
//this method it too slow for anything more than one Monitor at 60 fps. 
//this->originalPixmap = this->primary->grabWindow(0,0,0,1920,1080); 



//this method is fast. Did 120 FPS no problem. It doesn't use the QtOpenGLFunctions. Less portable? 
//QImage image(1920,1080,QImage::Format_RGBA8888); 
//glReadPixels(0,0,1920,1080,GL_RGBA,GL_UNSIGNED_BYTE, image.bits());//not writing to the image bits 

QImage image(1920,1080,QImage::Format_RGBA8888); 
funcs->glReadPixels(0,0,1920,1080,GL_RGBA,GL_UNSIGNED_BYTE, image.bits()); 

frameCount++; 
if(frameCount % 10 == 0) //update preview label 
{ 
    //ui->label->setPixmap(QPixmap::fromImage(image.scaled(ui->label->size()))); 
    ui->label->setPixmap(originalPixmap.scaled(ui->label->size())); 
    //qDebug() << QString("Frame: " + frameCount); 
} 

}

我的另一个问题与此代码是由于某种原因,非QT glreadpixels不写到qimage.bits()。

+1

does'context-> create();'return true or false? – PeterT

+0

'我的代码段错误'好的,当然,接下来的事情是打开调试器,调用崩溃并在调试模式下运行堆栈跟踪。它向你展示了什么? –

+0

context.create()返回false。所以这可能是问题所在。发生seg错误,它只是在编译指令队列中提供编译代码的位置。只是说造成它的指令的地址。 –

回答

0

您可能应该使您的上下文更新或使用QOpenGLContext::currentContext。你也应该检查你的应用程序实际上是否使用OpenGL。

如果您不特别需要使用OpenGL,而您只想获得QMainWindow之类的QWidget镜头,则可能需要查看QWidget::render

+0

我在上下文中创建了当前上下文,并将其更改为openGL 4.5,以便尝试它。我没有在我的应用程序中使用openGL。我真的只是用它来捕捉屏幕,因为[Screenshot Example](http://doc.qt.io/qt-5/qtwidgets-desktop-screenshot-example.html)方法太慢了。 –

+0

glReadPixels读取与gl上下文关联的窗口内的像素。如果你的应用程序不使用OpenGL,它将不会返回这些像素。如果你想要整个屏幕,你需要询问OS或X11。关于Linux的问题,有很多问题:http://stackoverflow.com/questions/2607010/linux-how-to-capture-screen-and-simulate-mouse-movements。 –