PDA

View Full Version : Update QGL Widget on different Thread



miyoku157
24th May 2017, 10:01
Hi,

Here is my problem, I'm trying to update the QGLWidget from an other thread. But when i try i got this warning:
"QOpenGLContext::swapBuffers() called without corresponding makeCurrent()"

I want to retrieve a video stream from a camera and display it on a QGLWidget. With the NVAPI, i fill one image in a GLTexture each frame. That's what i want to display. (and i have displayed it without update it in a thread)
But as i need to update it continously for the stream, i want to do it in a stream.

Here is my code:


#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QGLWidget *parent) :
QGLWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}

Widget::~Widget()
{

nv.cleanupVideo();
th.join();
delete ui;
}

void Widget::initializeGL(){
glewInit();
//Initialize the capture of the camera
nv = NVConfig();
this->contextGL = wglGetCurrentContext();
nv.GlobalInit();
nv.LockDevice(GetDC((HWND)this->winId()),this->contextGL);
//Unbind the OpenGL context from this thread.
wglMakeCurrent(0, 0);
//Launch the capture on an other thread
th = std::thread(&Widget::updateGL,this);
}

void Widget::resizeGL(int w, int h){
if(h==0)
h =1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
perspectiveGL(45.0f,w/h,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

/*
* The capture will fill a GL Texture 1280*720; GL_RGBA
*
*/
void Widget::updateGL(){
//Start the capture, the previous OpenGL is bind again with
// wglMakeCurrent(GetDC((HWND)this->winId()),this->contextGL)
nv.StartCapture(GetDC((HWND)this->winId()),this->contextGL);
}

void Widget::paintGL(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1.5f,0.0f,-6.0f);
glBegin(GL_QUADS);
glTexCoord2f(0,1.0f);
glVertex3f(0,0,0);
glTexCoord2f(0,0);
glVertex3f(0,1.0f,0);
glTexCoord2f(1.0f,0);
glVertex3f(1.0f,1.0f,0);
glTexCoord2f(1.0f,1.0f);
glVertex3f(1.0f,0,0);
glEnd();


}

void Widget::perspectiveGL(GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar){
const GLdouble pi = 3.1415926535897932384626433832795;
GLdouble fW, fH;
fH = tan( fovY / 360 * pi) * zNear;
fW = fH * aspect;
glFrustum( -fW,fW,-fH,fH,zNear,zFar);
}

wysota
2nd June 2017, 10:11
You need to make the GL context current to bind it to the thread. When you're done, you can release the context with a corresponding call.