Переместить QOpenContextGL в QT

Я пытаюсь нарисовать несколько QOpenGLWidget, которые могут транслировать видео с камеры. В настоящее время я могу это сделать, но это очень медленно, потому что только один поток выполняет захват и отрисовку 4 виджетов. Поэтому я в основном думал об использовании другого потока для моего виджета. Но у меня много проблем с ошибкой: «не удается сделать QOpenGLContext текущим в другом потоке». Я перемещаю контекст в поток, поэтому не понимаю;

#include "glwidget.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QMouseEvent>

GLWidget::GLWidget(QWidget *parent)
    : QOpenGLWidget(parent),
      clearColor(Qt::black),
      program(0)
{
    memset(textures, 0, sizeof(textures));

}

GLWidget::~GLWidget()
{
    makeCurrent();
    vbo.destroy();
    for (int i = 0; i < 6; ++i)
        delete textures[i];
    delete program;
    doneCurrent();
}

void GLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glewInit();
    nvc = NVConfig();
    nvc.GlobalInit();
    nv= NVGL(nvc.l_vioConfig,GetDC((HWND)this->winId()));
    makeObject();

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc =
        "attribute highp vec4 vertex;\n"
        "attribute mediump vec4 texCoord;\n"
        "varying mediump vec4 texc;\n"
        "uniform mediump mat4 matrix;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = matrix * vertex;\n"
        "    texc = texCoord;\n"
        "}\n";
    vshader->compileSourceCode(vsrc);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
        "uniform sampler2D texture;\n"
        "varying mediump vec4 texc;\n"
        "void main(void)\n"
        "{\n"
        "    gl_FragColor = texture2D(texture, texc.st);\n"
        "}\n";
    fshader->compileSourceCode(fsrc);

    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);
    program->bindAttributeLocation("vertex", PROGRAM_VERTEX_ATTRIBUTE);
    program->bindAttributeLocation("texCoord", PROGRAM_TEXCOORD_ATTRIBUTE);
    program->link();
    program->bind();
    program->setUniformValue("texture", 0);

// Start the threading process
    th = new QThread(this);
    tm = new QTimer(0);
    tm->setInterval(16);
    connect(tm,SIGNAL(timeout()),this,SLOT(Tick()));
    doneCurrent();
    context()->moveToThread(th);
    tm->moveToThread(th);
    th->start();
}

void GLWidget::paintGL()
{
    glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QMatrix4x4 m;
    m.ortho(-1, 1, 1.f, -1.f, 1.0f, 20.0f);
    m.translate(0.0f, 0.0f, -10.0f);
    program->setUniformValue("matrix", m);
    program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
    program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
    program->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 3, 5 * sizeof(GLfloat));
    program->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 3 * sizeof(GLfloat), 2, 5 * sizeof(GLfloat));
    glBindTexture(GL_TEXTURE_2D,nv.m_videoTexture);
    glDrawArrays(GL_TRIANGLE_FAN, 0 * 4, 4);
}


void GLWidget::Tick()
{
    nv.StartCapture();// OpenGL Context required to do the capture
    update(); //Update the widget

}

void GLWidget::resizeGL(int width, int height)
{
    int side = qMin(width, height);
    glViewport((width), (height), side, side);
}
//Create the rectangle to draw the texture
void GLWidget::makeObject()
{
    static const int coords[1][4][3] = {
        { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } }
    };
    textures[0] = new QOpenGLTexture(QImage(QString("C:/Users/BOOM/Documents/textures/images/side1.png")));
    QVector<GLfloat> vertData;
    for (int i = 0; i < 1; ++i) {
        for (int j = 0; j < 4; ++j) {
            // vertex position
            vertData.append(coords[i][j][0]);
            vertData.append(coords[i][j][1]);
            vertData.append(coords[i][j][2]);
            // texture coordinate
            vertData.append(j == 0 || j == 3);
            vertData.append(j == 0 || j == 1);
        }
    }

    vbo.create();
    vbo.bind();
    vbo.allocate(vertData.constData(), vertData.count() * sizeof(GLfloat));
}

Я делаю что-то неправильно? Спасибо за вашу помощь


person Community    schedule 13.06.2017    source источник