0

我正在尝试绘制几个可以从相机流式传输视频的 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));
}

难道我做错了什么?谢谢你的帮助

4

0 回答 0