Существенная потеря производительности SFML, когда sf :: Window не создается - PullRequest
0 голосов
/ 29 мая 2020

Я пишу приложение для рисования нескольких фигур и сравнения изображений (подсчет значений пикселей). При рисовании и подсчете нити изображение не отображается. Gui реализовано в другом потоке. В настоящее время я обнаружил очень странную аномалию. Мой поток рисования и сравнения работает очень медленно, но когда я добавляю перед основным l oop sf::Window, у меня увеличивается производительность на x70, но добавление этих строк ломает мой GUI (вероятно, потому, что я создаю окно в другом потоке) *.

Я ищу способ увеличения производительности без использования sf::Window::create(...).

Полный пример:

    int main()
{
    // sf::Window window(sf::VideoMode(200, 200), "SFML");

    std::vector<sf::CircleShape> circles_;
    for (int i = 0; i < 200; i++)
    {
        sf::CircleShape circle(rand() % 50 + 10, 20);
        circle.setFillColor(sf::Color(rand() % 256, rand() % 256, rand() % 256, 128));
        circle.setPosition(rand() % (100), rand() % (100));
        circles_.push_back(circle);
    }
    sf::RenderTexture generated_texture;
    generated_texture.create(100, 100);
    sf::Clock clock;
    uint i = 0;
    while (i < 10)
    {

        for (auto &shape : circles_)
        {
            generated_texture.draw(shape);
        }
        i++;
    }
    double result = double(i) / clock.getElapsedTime().asSeconds();
    cout << "Result: " << result << " loops/sec";
    return 0;
}

* Для упрощения предположим, что у меня нет любой gui (в моем приложении это необязательно). Я просто хочу запустить приложение из командной строки.

1 Ответ

1 голос
/ 11 июня 2020

Я открыл проблему на SFML github и обнаружил, что это было вызвано активацией и деактивацией контекста, поэтому в данном случае вместо:

sf::Window window(sf::VideoMode(200, 200), "SFML");

должно быть

sf::Context some_context;.

Ссылка на исходный выпуск: https://github.com/SFML/SFML/issues/1672

Полный ответ:

«Когда sf::RenderTexture завершает рисование, он пытается восстановить состояние, которое было до вызова рисования. Поскольку это было состояние «без контекста», он будет многократно активировать и деактивировать контекст на каждой итерации. Это стандартное поведение для любого ресурса OpenGL, который может жить сам по себе, не обязательно имея окно.

Если вы хотите сделать что-нибудь, связанное с рендерингом, рекомендуется всегда иметь под рукой какую-то вещь, владеющую контекстом. Если вы не хотите sf::Window, тогда потребуется sf::Context.

Из-за природы OpenGL вы никогда не обойдете ограничение наличия какого-либо окна (видимого или нет), которое само владеет контекст. T именно так разработчики API разработали его 25 лет назад go. "

...