Okay, I've come back to this problem after a little break and ran the last code I posted again, and realized it did in fact replicate the flicker! Just happens intermittently (like almost every time but not all, and size of the flicker is different each time). I cut off some of the fat from my example to reduce it down to the bare minimum. The 2 second sleep is there to show that the flicker happens immediately after the 2 seconds are up, aka it occurs when the shader load happens. Also, the shader involved doesn't matter, it can be a blank fragment shader but it needs to exist.
Here is a slow motion gif of what is happening. It is very frustrating to see this so often and not know what to do to fix it! (Its very slowed down. The real timing is a 1 frame flicker)
https://gfycat.com/ComfortableDigitalAssassinbug
I am using boost 1_59_0 and sfml 2.4.2 and this is a release build
#include <SFML/Graphics.hpp>
#include <boost/thread.hpp>
#include <iostream>
boost::thread *loadingThread;
sf::Texture tex;
sf::RenderWindow *window;
using namespace sf;
using namespace std;
RenderTexture *preScreenTex;
sf::Shader speedBarShader;
void Load()
{
sleep(sf::seconds( 2 ));
if (!speedBarShader.loadFromFile("speedbar_shader.frag", sf::Shader::Fragment))
{
cout << "speed bar SHADER NOT LOADING CORRECTLY" << endl;
}
while (true);
}
int main()
{
window = new RenderWindow(sf::VideoMode(1920, 1080), "Breakneck", sf::Style::Fullscreen);
window->setVerticalSyncEnabled(true);
preScreenTex = new RenderTexture;
preScreenTex->create(1920, 1080);
preScreenTex->clear();
int frame = 0;
bool quit = false;
sf::Event ev;
loadingThread = NULL;
while (!quit)
{
while (window->pollEvent(ev))
{
}
preScreenTex->clear(Color::Black);
window->clear(Color::Red);
if (loadingThread != NULL)
{
preScreenTex->clear(Color::Green);
}
if (frame == 60 * 3)
{
loadingThread = new boost::thread(&Load);
}
preScreenTex->display();
sf::Sprite spr;
spr.setTexture(preScreenTex->getTexture());
window->draw(spr);
window->display();
++frame;
}
return 0;
}
I couldn't run your code at all, since you're using global initialize SFML resources, which isn't allowed and instantly crashes most of the time. I would highly recommend to stay away from global variables in general, whether initialized at global scope or not, they break scoping and make it hard or impossible to reason about the application flow.
So I changed your code around and also replaced boost::thread with std::thread.
Now the code works "fine" on my machine, i.e. no flickers. However since you're using OpenGL from two different threads (yes, loading a shader already does OpenGL calls (https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/Shader.cpp#L826)), you will have to deal with proper context activation, I suggest reading the whole OpenGL tutorial, but especially the part about threading: https://www.sfml-dev.org/tutorials/2.5/window-opengl.php#rendering-from-threads
Modified code:
#include <SFML/Graphics.hpp>
#include <thread>
#include <iostream>
std::thread* loadingThread;
sf::RenderWindow* window;
sf::RenderTexture *preScreenTex;
sf::Shader* speedBarShader;
void Load()
{
sleep(sf::seconds(2));
if (!speedBarShader->loadFromFile("speedbar_shader.frag", sf::Shader::Fragment))
{
std::cout << "speed bar SHADER NOT LOADING CORRECTLY\n";
}
while (true);
}
int main()
{
window = new sf::RenderWindow(sf::VideoMode(1920, 1080), "Breakneck", sf::Style::Fullscreen);
window->setVerticalSyncEnabled(true);
preScreenTex = new sf::RenderTexture;
preScreenTex->create(1920, 1080);
preScreenTex->clear();
speedBarShader = new sf::Shader();
int frame = 0;
bool quit = false;
sf::Event ev;
loadingThread = NULL;
while (!quit)
{
while (window->pollEvent(ev))
{
}
preScreenTex->clear(sf::Color::Black);
window->clear(sf::Color::Red);
if (loadingThread != NULL)
{
preScreenTex->clear(sf::Color::Green);
}
if (frame == 60 * 3)
{
loadingThread = new std::thread(&Load);
}
preScreenTex->display();
sf::Sprite spr;
spr.setTexture(preScreenTex->getTexture());
window->draw(spr);
window->display();
++frame;
}
}