Недопустимые ошибки при работе OpenGL на отдельном входном потоке - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть метод «checkErrors», прикрепленный ко всем компонентам проекта, так что я могу вызвать «checkErrors (« Имя контекста »)», и он сообщит мне, какие ошибки (если таковые имеются) произошли до этого момента.Метод выглядит следующим образом: (print - это мой собственный метод, просто интерпретируйте его как простой printf)

void checkErrors(std::string context="Unknwon Context") {
    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR)
    {
        print("OpenGL Error:");
        print("\t CONTEXT: " + context);
        if (err == GL_INVALID_ENUM) print("\t TYPE: Invalid Enum");
        else if (err == GL_INVALID_VALUE) print("\t TYPE: Invalid Value");
        else if (err == GL_INVALID_OPERATION) print("\t TYPE: Invalid Operation");
        else if (err == GL_OUT_OF_MEMORY) print("\t TYPE: Out of Memory");
        else if (err == GL_INVALID_FRAMEBUFFER_OPERATION) print("\t TYPE: Invalid Framebuffer Operation");
        else if (err == GL_CONTEXT_LOST) print("\t TYPE: Context Lost");
        else print("\t TYPE: Undefined Error");
    }
}

Я запускаю отдельный поток, который принимает данные из терминала / консоли и изменяет заблокированные переменныеза мьютексом, который изменяет программу соответственно.Функция / метод выглядит следующим образом:

void Engine::console() {
    std::string input;
    while (true)
    {
        std::cin >> input;

        settingMutex.lock();

        if (input == "something") doSomething();
        // More possible console command here...
        else print(this, "Unknwon Command");

        checkErrors("Console Command");

        settingMutex.unlock();
    }
}

Затем я запускаю эту функцию в отдельном потоке незадолго до запуска основного цикла рендеринга:

consoleThread = std::thread(&Engine::console, this);
consoleThread.detach();

//Render loop:
while (!window->shouldClose())
{
    settingMutex.lock();

    //Some stuff here...

    // render
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //Objects are drawn here...

    settingMutex.unlock();

    glfwSwapBuffers(window->getGLFWwindow());
    glfwPollEvents();

    checkErrors("Engine Loop");
}

Все работает так, как я планировалк.Объекты отрисовываются правильно, и рендер-цикл не выдает ошибок.

Если я закомментирую 'checkErrors ("Console Command") "в функции console (), мои команды ввода будут делать именно то, что должныaswell.

Однако, если я не прокомментирую эту строку, независимо от того, какую строку я ввожу, я, по сути, получаю бесконечно много ошибок «недопустимая операция», поступающих из контекста «Консольная команда» в качестве вывода.

Я могу даже удалить все из функции console (), кроме вызова checkErrors, и я все еще получаю бесконечный поток ошибок недопустимых операций.Между тем, Render-Loop продолжает работать без ошибок.

У меня такое ощущение, что контекст OpenGL не существует вне основного потока, поэтому простой вызов glGetError в отдельном потоке приводит к недопустимой ошибке операции,но я не смог подтвердить это.

У кого-нибудь есть понимание того, что здесь происходит?

1 Ответ

0 голосов
/ 08 ноября 2018

Различные потоки не разделяют контекст OpenGL, созданный в одном из них, что означает, что когда вы помещаете консоль в новый поток, вызов glGetError() не имеет базового контекста и выдает исключение.

...