Qt - как сделать один поток для загрузки текстуры, а другой поток для запуска paintGL () - PullRequest
2 голосов
/ 23 апреля 2019

Я создал один поток, который будет использоваться для загрузки текстур из изображений, а другой поток для рисования изображений на экране с помощью paintGL().Но исключение выдается.

  1. Нужен ли замок или замки?Я обеспокоен тем, что могут быть проблемы, вызванные использованием блокировок, потому что эти два потока делают разные вещи, но используют одни и те же ресурсы.

  2. Как я могу делиться контекстами в QOpenGLWidget способом?

Модель памяти

Модель многопоточности, которую использует OpenGL, основана на одном факте: один и тот же контекст OpenGL не может быть текущим в несколькихтемы одновременно.Хотя у вас может быть несколько контекстов OpenGL, текущих в нескольких потоках, вы не можете манипулировать одним контекстом одновременно из двух потоков.

Я добавил QOpenGLWidget::makeCurrent() в initializeGL() и QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts) вmain(), но не работает.Это кажется более сложным, чем просто добавление этих операторов.

MyOpenGLWidget.cpp

void MyOpenGLWidget::initializeGL()
{
    QMutexLocker LOCKER(&mutext);

    QOpenGLWidget::makeCurrent();
    QOpenGLFunctions::initializeOpenGLFunctions();
    // some other code here
}

void MyOpenGLWidget::loadTexture()
{
    if (eof == true)
        return;
    QMutexLocker LOCKER(&mutext);

    img_data = SOIL_load_image(path, &width, &height, &channels, SOIL_LOAD_RGB);
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &texture); // Access violation reading location thrown
    // some other code here
}

void MyOpenGLWidget::paintGL()
{
    QMutexLocker LOCKER(&mutext);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

MyGLThread.cpp

void MyGLThread::init(MyOpenGLWidget* widget)
{
    gl_widget = widget;
}

void MyGLThread::loadTexture()
{
    gl_widget->loadTexture();
}

void MyGLThread::run()
{
    while (true) {

        if (!gl_widget)
            continue;
        // some other code
        loadTexture();
        msleep(30);
    }
}

MyMainWindow.cpp

MyMainWindow::MyMainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    gl = new MyOpenGLWidget(this);
    gl_thread = new MyGLThread();
    gl_thread->init(gl);
    gl_thread->start();
    // some other code
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...