Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Problem with sf::Shader and async texture load (since SFML 2.4)  (Read 2483 times)

0 Members and 1 Guest are viewing this topic.

Ungod

  • Newbie
  • *
  • Posts: 44
    • View Profile
Problem with sf::Shader and async texture load (since SFML 2.4)
« on: January 12, 2017, 07:21:41 pm »
Hi guys.

After upgrading to SFML-version 2.4.1, I noticed that existing code doesnt work anymore. More specific: Code in my asset-manager that loads sf::Textures via std::async in another thread. It took me some time to realize, that the problem isnt the loading itself. Strangely the error occurs, if I load a sf::shader (sync load) before I load the texture (async load).
Note that the following error did not occur with my previous version (2.3.2).

Whats the error: When opening a window after doing the above initialisations, the window freezes/does not react instead of showing the loaded texture.

This freezing does not occur when i remove the line where the shader is loaded. It does also not occur if I create a sf::Context at the begin of the load(...) method that is called async. However, an empty window is opened in that case and the sprite isnt shown.

How to reproduce (simplest example I could figure out):
#include <SFML/Graphics.hpp>
#include <future>

void load(sf::Texture& tex, sf::Sprite& sprite, const std::string path)
{
    tex.loadFromFile(path);
    sprite.setTexture(tex);
}

int main()
{
    sf::RenderWindow window;
    sf::Texture tex;
    sf::Sprite sprite;
    sf::Shader shader;

   //load shader in the main thread
    shader.loadFromFile("shader.vert", sf::Shader::Vertex);

    //load the texture in a secondary thread
    std::future<void> future = std::async(std::launch::async, [&tex, &sprite] ()
                                          { load(tex, sprite, "test.png"); });

    window.create( {800,600,32}, "async_testing" );
    window.setFramerateLimit(60);
    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();

        if (future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)  //test if async loading is done
            window.draw(sprite);

        window.display();
    }
    return 0;
}
 

To test it use an arbitrary png file and a simple pass-through vertex-shader. If you have non by hand:
void main() {
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

    gl_TexCoord[0] = gl_MultiTexCoord0;

    gl_FrontColor = gl_Color;
}
 

Please tell me whether you can reproduce that and how I could fix it.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Problem with sf::Shader and async texture load (since SFML 2.4)
« Reply #1 on: January 12, 2017, 09:46:19 pm »
The fix for this is waiting to be merged into 2.4.2 here. Feel free to test it and report if it fixes your issue.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Ungod

  • Newbie
  • *
  • Posts: 44
    • View Profile
Re: Problem with sf::Shader and async texture load (since SFML 2.4)
« Reply #2 on: January 12, 2017, 10:20:32 pm »
This fixes my above example, as well as my original code. Great, thanks!

Is this branch safe to use until the merge took place?