Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Work with QOpenGLWidget in multiThread

Work with QOpenGLWidget in multiThread

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 2 Posters 4.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Miyoku
    wrote on last edited by Miyoku
    #3
    This post is deleted!
    jsulmJ 1 Reply Last reply
    0
    • M Miyoku

      This post is deleted!

      jsulmJ Online
      jsulmJ Online
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #4

      @Miyoku I don't think you need a loop to capture video from a camera. How do you capture the video? Using http://doc.qt.io/qt-5/qcamera.html ? You should use the asynchronous nature of Qt as much as possible to avoid using multithreading.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply
      0
      • jsulmJ jsulm

        @Miyoku Why do you need more than one thread?

        M Offline
        M Offline
        Miyoku
        wrote on last edited by
        #5
        This post is deleted!
        1 Reply Last reply
        0
        • jsulmJ jsulm

          @Miyoku I don't think you need a loop to capture video from a camera. How do you capture the video? Using http://doc.qt.io/qt-5/qcamera.html ? You should use the asynchronous nature of Qt as much as possible to avoid using multithreading.

          M Offline
          M Offline
          Miyoku
          wrote on last edited by
          #6

          @jsulm sorry for the double post, i'm deleting one of them.
          For your answer, in fact i'm using a specific hardware, the SDI Quadro input to get 4 SDI input and capture them thanks to the GPU.
          I don't know how the QCamera work, but do you think it's working with SDI input?

          jsulmJ 1 Reply Last reply
          0
          • M Miyoku

            @jsulm sorry for the double post, i'm deleting one of them.
            For your answer, in fact i'm using a specific hardware, the SDI Quadro input to get 4 SDI input and capture them thanks to the GPU.
            I don't know how the QCamera work, but do you think it's working with SDI input?

            jsulmJ Online
            jsulmJ Online
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #7

            @Miyoku I don't know whether it works with your camera, but you can try.
            If not, then maybe you can capture the video in an extra thread but hen send the frames via a signal to main thread where you show the frames then. The problem is: in Qt you are only allow to access UI directly from main thread.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            M 1 Reply Last reply
            0
            • jsulmJ jsulm

              @Miyoku I don't know whether it works with your camera, but you can try.
              If not, then maybe you can capture the video in an extra thread but hen send the frames via a signal to main thread where you show the frames then. The problem is: in Qt you are only allow to access UI directly from main thread.

              M Offline
              M Offline
              Miyoku
              wrote on last edited by
              #8

              @jsulm Ok, so here I'm quite stuck, if i want to use an OpenGLWidget, it's because my driver capture the video stream in GLTexture, so the frame are in the GPU not in the CPU. But in order to capture them, i need an OpenGLContext active (which i've succeed to pass to my thread with movetothread) but if i have to make the display in the main thread, it will create a conflict.

              jsulmJ 1 Reply Last reply
              0
              • M Miyoku

                @jsulm Ok, so here I'm quite stuck, if i want to use an OpenGLWidget, it's because my driver capture the video stream in GLTexture, so the frame are in the GPU not in the CPU. But in order to capture them, i need an OpenGLContext active (which i've succeed to pass to my thread with movetothread) but if i have to make the display in the main thread, it will create a conflict.

                jsulmJ Online
                jsulmJ Online
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #9

                @Miyoku Maybe you can get rid of the loop using a QTimer in main thread?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                M 2 Replies Last reply
                0
                • jsulmJ jsulm

                  @Miyoku Maybe you can get rid of the loop using a QTimer in main thread?

                  M Offline
                  M Offline
                  Miyoku
                  wrote on last edited by
                  #10

                  @jsulm That could work indeed! didn't think about that, I'm going to try that thanks

                  1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @Miyoku Maybe you can get rid of the loop using a QTimer in main thread?

                    M Offline
                    M Offline
                    Miyoku
                    wrote on last edited by
                    #11

                    @jsulm I've changed my way of doing, i'm now using a QTimer to capture the frame. But i still have no feedback from the display. I'm wondering if my way of using the QOpenGLWidget is right.

                    int C_anccap::LoopAnimation()
                    {
                        Owidget->makeCurrent();
                    
                        if (this->CaptureVideo() != GL_FAILURE_NV)
                        {
                            if (this->rec[0].isStarted) {
                                glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->rec[0].pixels.get());
                            }
                        }
                        if (C_anccap::exit) {
                            this->Shutdown();
                            return FALSE;
                        }
                        return TRUE;
                    }
                    
                    
                    void MyOpenGLWidget::initializeGL()
                    {
                        initializeOpenGLFunctions();
                        glClearColor(1.0f,1.0f,1.0f,1.0f);
                        context()->create();
                        makeCurrent();
                        c = new C_anccap();
                        c->CaptureCall(this);
                    }
                    
                    void MyOpenGLWidget::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();
                    
                    }
                    
                    void MyOpenGLWidget::paintGL()
                    {
                        //QPainter p(this);
                        // p.beginNativePainting();
                         c->DisplayVideo();
                        // p.endNativePainting();
                    }
                    void MyOpenGLWidget::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);
                    }
                    
                    GLboolean C_anccap::DisplayVideo()
                    {
                    	//
                    	// Draw texture contents to graphics window.
                    	//
                        //widget->makeCurrent();
                    	// Reset view parameters
                    	glViewport(0, 0, m_windowWidth, m_windowHeight);
                    	glMatrixMode(GL_PROJECTION);
                    	glLoadIdentity();
                        glOrtho(0.0, (GLdouble) m_windowWidth, 0.0, (GLdouble) m_windowHeight, -1, 1);
                    	glMatrixMode(GL_MODELVIEW);
                    	glLoadIdentity();
                    
                    	// Draw contents of each video texture
                    	glEnable(GL_TEXTURE_RECTANGLE_NV);  
                    
                    	// Set draw color
                    	glColor3f(1.0f, 1.0f, 1.0f);
                    
                    	// Draw captured streams to graphics window.
                    	switch(m_SDIin.GetNumVideoObjects()) {
                    		case 1:
                    		drawOne();
                    		break;
                    		case 2:
                    		drawTwo();
                    		break;
                    		case 3:
                    		drawThree();
                    		break;
                    		case 4:
                    		drawFour();
                    		break;
                    		default:
                    		drawOne();
                    	};
                    
                    GLvoid C_anccap::drawOne()
                    {
                    	// Enable texture
                    	glEnable(GL_TEXTURE_RECTANGLE_NV);  
                    	
                    	// Bind texture object for first video stream
                    	glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_SDIin.GetTextureObjectHandle(0));  
                    
                    	// Draw textured quad in lower left quadrant of graphics window.
                    	glBegin(GL_QUADS);
                    	glTexCoord2f(0.0, 0.0); glVertex2f(-1, -1); 
                    	glTexCoord2f(0.0, (GLfloat)m_videoHeight); glVertex2f(-1, 1); 
                    	glTexCoord2f((GLfloat)m_videoWidth, (GLfloat)m_videoHeight); glVertex2f(1, 1); 
                    	glTexCoord2f((GLfloat)m_videoWidth, 0.0); glVertex2f(1, -1); 
                    	glEnd();
                    	GLenum g = glGetError();
                    	assert(glGetError() == GL_NO_ERROR);
                    
                    	// Disable texture
                    	glDisable(GL_TEXTURE_RECTANGLE_NV);
                    }
                    

                    I'm dropping all the code required for the display. Maybe you'll see some errors in the way i'm using it.
                    To precise, MyOpenGLWidget inherit QOpenGLWidget.
                    I'm quite sure that i'm capturing the frame because the nvidia driver send no error, i just can't manage to display them

                    M 1 Reply Last reply
                    0
                    • M Miyoku

                      @jsulm I've changed my way of doing, i'm now using a QTimer to capture the frame. But i still have no feedback from the display. I'm wondering if my way of using the QOpenGLWidget is right.

                      int C_anccap::LoopAnimation()
                      {
                          Owidget->makeCurrent();
                      
                          if (this->CaptureVideo() != GL_FAILURE_NV)
                          {
                              if (this->rec[0].isStarted) {
                                  glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, GL_UNSIGNED_BYTE, this->rec[0].pixels.get());
                              }
                          }
                          if (C_anccap::exit) {
                              this->Shutdown();
                              return FALSE;
                          }
                          return TRUE;
                      }
                      
                      
                      void MyOpenGLWidget::initializeGL()
                      {
                          initializeOpenGLFunctions();
                          glClearColor(1.0f,1.0f,1.0f,1.0f);
                          context()->create();
                          makeCurrent();
                          c = new C_anccap();
                          c->CaptureCall(this);
                      }
                      
                      void MyOpenGLWidget::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();
                      
                      }
                      
                      void MyOpenGLWidget::paintGL()
                      {
                          //QPainter p(this);
                          // p.beginNativePainting();
                           c->DisplayVideo();
                          // p.endNativePainting();
                      }
                      void MyOpenGLWidget::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);
                      }
                      
                      GLboolean C_anccap::DisplayVideo()
                      {
                      	//
                      	// Draw texture contents to graphics window.
                      	//
                          //widget->makeCurrent();
                      	// Reset view parameters
                      	glViewport(0, 0, m_windowWidth, m_windowHeight);
                      	glMatrixMode(GL_PROJECTION);
                      	glLoadIdentity();
                          glOrtho(0.0, (GLdouble) m_windowWidth, 0.0, (GLdouble) m_windowHeight, -1, 1);
                      	glMatrixMode(GL_MODELVIEW);
                      	glLoadIdentity();
                      
                      	// Draw contents of each video texture
                      	glEnable(GL_TEXTURE_RECTANGLE_NV);  
                      
                      	// Set draw color
                      	glColor3f(1.0f, 1.0f, 1.0f);
                      
                      	// Draw captured streams to graphics window.
                      	switch(m_SDIin.GetNumVideoObjects()) {
                      		case 1:
                      		drawOne();
                      		break;
                      		case 2:
                      		drawTwo();
                      		break;
                      		case 3:
                      		drawThree();
                      		break;
                      		case 4:
                      		drawFour();
                      		break;
                      		default:
                      		drawOne();
                      	};
                      
                      GLvoid C_anccap::drawOne()
                      {
                      	// Enable texture
                      	glEnable(GL_TEXTURE_RECTANGLE_NV);  
                      	
                      	// Bind texture object for first video stream
                      	glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_SDIin.GetTextureObjectHandle(0));  
                      
                      	// Draw textured quad in lower left quadrant of graphics window.
                      	glBegin(GL_QUADS);
                      	glTexCoord2f(0.0, 0.0); glVertex2f(-1, -1); 
                      	glTexCoord2f(0.0, (GLfloat)m_videoHeight); glVertex2f(-1, 1); 
                      	glTexCoord2f((GLfloat)m_videoWidth, (GLfloat)m_videoHeight); glVertex2f(1, 1); 
                      	glTexCoord2f((GLfloat)m_videoWidth, 0.0); glVertex2f(1, -1); 
                      	glEnd();
                      	GLenum g = glGetError();
                      	assert(glGetError() == GL_NO_ERROR);
                      
                      	// Disable texture
                      	glDisable(GL_TEXTURE_RECTANGLE_NV);
                      }
                      

                      I'm dropping all the code required for the display. Maybe you'll see some errors in the way i'm using it.
                      To precise, MyOpenGLWidget inherit QOpenGLWidget.
                      I'm quite sure that i'm capturing the frame because the nvidia driver send no error, i just can't manage to display them

                      M Offline
                      M Offline
                      Miyoku
                      wrote on last edited by
                      #12

                      @Miyoku NeverMind i succeed to make it appears thanks, a lot, i just need to make it refresh every frame. I will do it with a timer.
                      Thanks a lot for your time

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved