c++ - QOpenGLWidget draw 2D texture in another thread -


i tried draw qopenglwidget in thread , here code:

// widget.h class qglcanvas;  class framerenderer: public qthread {     q_object public:     framerenderer(qglcanvas *parent);     void run() q_decl_override;     void stop();     void initialize();     void updateframe(std::shared_ptr<cv::mat> frame);      qglcanvas *parent_;     std::atomic<bool> thread_run_;     bool initialize_;     gluint texture_;     std::shared_ptr<cv::mat> frame_;         qmutex mutex_; };  class qglcanvas : public qopenglwidget, protected qopenglfunctions {     q_object public:     qglcanvas(qwidget* parent = null);      virtual void initializegl();     virtual void paintgl();     virtual void resizegl(int width, int height);      void showimage(std::shared_ptr<cv::mat> frame);      // opengl rendering thread     framerenderer* render_thread_;     qtimer* render_timer_;  private slots:     void startrendering(); };   //widget.cpp #include "widget.h" framerenderer::framerenderer(qglcanvas* parent): qthread(), parent_(parent) {     thread_run_ = true;     initialize_ = false;      frame_ = std::make_shared<cv::mat>();     cv::mat img = cv::imread("./res/no_image.jpg");     *frame_ = img; }  void framerenderer::stop() {     thread_run_ = false; }  void framerenderer::initialize() {     if(initialize_)         return;      glgentextures(1, &texture_);     glbindtexture(gl_texture_2d, texture_);     gltexparameteri(gl_texture_2d, gl_texture_mag_filter, gl_nearest);     gltexparameteri(gl_texture_2d, gl_texture_min_filter, gl_nearest);     glteximage2d(gl_texture_2d, 0, gl_rgb, frame_->cols,          frame_->rows, 0, gl_rgb, gl_unsigned_byte,          null);     glbindtexture(gl_texture_2d, 0);      initialize_ = true; }  void framerenderer::run() {     while(true)     {         qmutexlocker lock(&mutex_);         if(!thread_run_)             break;          parent_->makecurrent();        if(!initialize_)            initialize();          int width = parent_->width(), height = parent_->height();         glviewport(0, 0, width, height);         glclearcolor(0, 0, 1, 1);         gldisable(gl_depth_test);         glenable(gl_texture_2d);         glbindtexture(gl_texture_2d, texture_);         gltexsubimage2d(gl_texture_2d, 0, 0, 0, frame_->cols,                    frame_->rows,  gl_rgb, gl_unsigned_byte,                    frame_->data);          glbegin(gl_quads);           gltexcoord2f(0.0f, 1.0f); glvertex3f(0, 0, 0.0f);           gltexcoord2f(1.0f, 1.0f); glvertex3f(width, 0.0f, 0.0f);           gltexcoord2f(1.0f, 0.0f); glvertex3f(width, height,  0.0f);           gltexcoord2f(0.0f, 0.0f); glvertex3f(0,  height,  0.0f);         glend();         gldisable(gl_texture_2d);         parent_->donecurrent();         qmetaobject::invokemethod(parent_, "update");         msleep(40);     } }  void framerenderer::updateframe(std::shared_ptr<cv::mat> frame) {     qmutexlocker lock(&mutex_);     frame_ = frame; }     qglcanvas::qglcanvas(qwidget* parent)     : qopenglwidget(parent) {     render_timer_ = new qtimer(this);     qobject::connect(render_timer_, signal(timeout()), this, slot(startrendering()));     render_timer_->start(1000); }  void qglcanvas::initializegl() {  }  void qglcanvas::resizegl(int width, int height) {    //stop qglwidget standard behavior }  void qglcanvas::paintgl() {  }  void qglcanvas::startrendering() {     donecurrent();     render_thread_ = new framerenderer(this);     context()->movetothread(render_thread_);     render_thread_->start(); }  void qglcanvas::showimage(std::shared_ptr<cv::mat> frame) {     if(render_thread_)         render_thread_->updateframe(frame); }   // main.cpp #include "widget.h" #include <qapplication> int main(int argc, char *argv[]) {     qapplication app(argc, argv);     // check threaded opengl supported.     if (!qopenglcontext::supportsthreadedopengl())     {         std::cerr << "threaded opengl not supported" << std::endl;         return exit_failure;     }      // set wanted surface format.     qsurfaceformat format;     format.setdepthbuffersize(16);     format.setversion(4, 4);     format.setprofile(qsurfaceformat::coreprofile);     qsurfaceformat::setdefaultformat(format);      // calculate position of widget. widget should     // located center @ center of desktop.     const qdesktopwidget* desktop = qapplication::desktop();     const qsize size(720, 576);     const qpoint position(         desktop->width()  / 2 - size.width()  / 2,         desktop->height() / 2 - size.height() / 2);      // create opengl widget     std::shared_ptr<qglcanvas> widget = std::make_shared<qglcanvas>();     widget->resize(size);     widget->move(position);     widget->show();     return app.exec(); } 

the problem got error:

cannot make qopenglcontext current in thread.

i had similar code structure using qglwidget. when changed qopenglwidget, cannot work.


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -