Как правильно запустить поток рендеринга из класса с функцией внутри этого класса?

#c #multithreading #sfml

#c #многопоточность #sfml

Вопрос:

У меня есть эта ошибка в моем проекте с потоками, и я не знаю, как ее решить. Я попробовал std::thread и sf::Thread. Может кто-нибудь помочь, пожалуйста?

Я создаю объект анимации внутри основного класса и через функцию runThread() Я пытаюсь запустить поток внутри класса анимации.

Журнал ошибок: не удалось активировать контекст окна Не удалось активировать контекст OpenGL

Мое решение Основной класс

 int main()
{
    bool launchThreads = true;

    sf::RenderWindow window(sf::VideoMode( 800, 600), "Title" );


    Animation* anima = new Animation(window);
    

    sf::Event event;
    while(window.isOpen())
    { 
        while (window.pollEvent(event))
        {
            anima->handleEvent(event);
            if (event.type == sf::Event::Closed)
            {
                delete anima;
                anima = nullptr;

                window.close();
            }

        }
        window.clear(sf::Color::Black);
 

здесь я пытаюсь запустить этот поток:

     if (launchThreads)
    {
        anima->runThread();
        launchThreads = false;
    }


        window.display();
    }
    return 0;
}
 

Animation.h :

 class Animation
{
private:
    sf::RenderWindowamp; window;
    sf::RectangleShape* rectPtr;

    sf::Vector2f mousePos;

    sf::Thread thread;
public:
    Animation(sf::RenderWindowamp; window);

    void handleEvent(sf::Event event);

    void runThread();

    void handleDraw();

    ~Animation();
};
 

и Animation.cpp :

 Animation::Animation(sf::RenderWindowamp; window) : thread(amp;Animation::handleDraw, this), window(window),rectPtr(nullptr), mousePos()
{
    //sf::Thread thea(amp;handleDraw);
    //thread = thea;
    rectPtr = new sf::RectangleShape;
    rectPtr->setSize(sf::Vector2f(100, 100));
    rectPtr->setFillColor(sf::Color::Red);
}

void Animation::handleEvent(sf::Event event)
{
    switch (event.type)
    {
    case sf::Event::MouseMoved:
        mousePos = window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x, event.mouseMove.y));
        break;
    }
}

void Animation::runThread()
{
    thread.launch();
}

void Animation::handleDraw()
{

    for (size_t i = 0; i < 10; i  )
    {
        rectPtr->setPosition(i*110, 10);

        if (rectPtr->getGlobalBounds().contains(mousePos))
        {
            rectPtr->setFillColor(sf::Color::Yellow);
        }
        else rectPtr->setFillColor(sf::Color::Red);

        window.draw(*rectPtr);
    }
}

Animation::~Animation()
{
    thread.terminate();
    delete rectPtr;
    rectPtr = nullptr;

}
 

Решение:

Решение с перемещением функции window.display(); внутри handleDraw() и перемещением контекста там тоже с помощью window.setActive(); приложения показывает, что ему нужно. Но внутри консоли все те же ошибки.. Думаю, я могу их игнорировать.

Комментарии:

1. Какая строка кода выдает эту ошибку?

2. OT: обратите внимание, что это: : thread(amp;Animation::handleDraw, this) может быть немного хрупким. В вашем случае все в порядке, но правильность зависит от порядка определения переменных-членов Animation .

3. Ошибки выводятся на консоль после window.display(); выполняется из основного класса

4. честно говоря, я понятия не имею, как работает конструктор потоков, я нашел этот фрагмент кода здесь . И документация не имеет для меня никакого значения.

5. это действительно зависит от платформы и того, какой API вы используете. sfml обычно оборачивается вокруг OpenGL api . Например, некоторые платформы явно разрешают использовать только один поток, а контексты зависят от потока. но это не означает, что несколько контекстов могут принадлежать нескольким потокам, и они могут отображаться на одной поверхности. В других случаях поток рендеринга является highlander, может быть только один.