#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, может быть только один.