Я пытаюсь нарисовать несколько 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));
}
Я делаю что-то неправильно?
Спасибо за вашу помощь
Задача ещё не решена.
Других решений пока нет …