View Full Version : recompile the shader on runtime, like hot plug the new compiled shader

04-10-2015, 01:46 AM
I am spending too much time running the render engine when i do a small change on mu GLSL shaders.

I have implemented a method that runs on a separate thread and checks for shader file stamps to see if they are different. If they are then i recompile the shaders. I plan to do this in future with OS calls and remove this not very efficient method.

I have e problem however that i can not create the program. I get invalid error for some reasons and i dont know how to fix it the whole day. :S

I also noted that i get 0 when i want to create a shader even if the shader doesn't have errors.
Also do i need to set uniforms again ??

Thanks guys for help :D

GLuint ShaderProgram::createProgram(){

GLuint newProgramId = glCreateProgram();
if (newProgramId == 0){
log_.error(std::string("Failed to create new program: "));

checkForError(programName_.c_str(), "createProgram");
for (auto& i : shaders_){
glDetachShader(newProgramId, i.second.getId());
return 0;

for (auto& i : shaders_){
glAttachShader(newProgramId, i.second.getId());


GLint shaderStatus;
glGetProgramiv(newProgramId, GL_LINK_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE){

GLint infoLogLength;
glGetProgramiv(newProgramId, GL_INFO_LOG_LENGTH, &infoLogLength);

GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(newProgramId, infoLogLength, NULL, strInfoLog);
//fprintf(stderr, "Linker failure: %s\n", strInfoLog);
log_.error(std::string("Linker failure: ") + programName_ + ", " + strInfoLog + " program Id: " + std::to_string(newProgramId));

delete[] strInfoLog;
return -1;

checkForError(programName_.c_str(), "createProgram");

for (auto& i : shaders_){
glDetachShader(newProgramId, i.second.getId());

log_.info(std::string("New shader program created: ") + programName_ + " with ID " + std::to_string(newProgramId));
programId_ = newProgramId;

if (!isModifiedThread_)
isModifiedThread_ = new std::thread(&ShaderProgram::checkForModifyed, this, timer);
return programId_;

void ShaderProgram::checkForModifyed(int timer){

while (true){ // use mutex to break the stop the loop and finish thread exceuton to release resourses on program close
std::this_thread::sleep_for(std::chrono::seconds(t imer));

for (auto& i : shaders_){
if (i.second.isModified()){
log_.debug(std::string("Shader modified: ") + i.second.getPath());
//for (auto& j : shaders_){
// createShader(j.second.getType(), j.second.getPath());
createShader(i.second.getType(), i.second.getPath());

void ShaderProgram::startThread() {

void ShaderProgram::stopThread() {

04-10-2015, 02:24 AM
I have implemented a method that runs on a separate thread and checks for shader file stamps to see if they are different. If they are then i recompile the shaders.
Are you trying to compile the shaders in a different thread? If so, does that thread have a context bound to it? Does the context share data with the context used by the rendering thread?

04-10-2015, 03:47 AM
I do poll in a different thread for file chances so i guess there is no data shared. I forgot about that. I will check and post what I did

As for now my whole render engine is on one thread will i decide to implement culling before sending the draw command. This will be done probablly after i fix a bug with spot light, work on shadows a bit more, and use some more C++11

This is how i create the thread

isModifiedThread_ = new std::thread(&ShaderProgram::checkForModifyed, this, timer);

UPDATE: they do share all the data and i still get that Invalid operation :S. still looking to fix it but i have no clue now what is happening.
and this should share the data. I will write some code inside that thread instead of calling methods to compile shaders and see that will happen.

I have to go at training now but here is the link to github code https://github.com/lumx/GameEngine/blob/master/GameEngine/src/Core/Render/ShaderProgram.cpp. In mean time i will think for a solution but still it does not seem very obvious to me. Like usual the problem is in front on my eyes but i just cant see it :S

UPDATE2: Ok i guess i know what it is but i dont know how to fix it. When i pass the values to the thread those are copied and things get screwed up because i dont have a context bound. While looking at values in debugger i got tricked because the values were the same and i though i am referring to the same class and im not copying it but is seems that i do.

Now my problem is how to fix this syntactically in C++. I have no idea now. I treid also this but it is not working

isModifiedThread_ = new std::thread(ShaderProgram::checkForModifyed, std::ref(*this), timer);
and this one does not even compile

isModifiedThread_ = new std::thread(std::ref(&this->checkForModifyed), std::ref(*this), timer);