I have a "checkErrors" method attached to all components of the Project so that I can call 'checkErrors("Context Name")' and it will tell me what errors (if any) have occurred up to that point. The method looks like this: (print is a method of my own, just interpret it as a simple printf)
void checkErrors(std::string context="Unknwon Context") {
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
{
print("OpenGL Error:");
print("\t CONTEXT: " + context);
if (err == GL_INVALID_ENUM) print("\t TYPE: Invalid Enum");
else if (err == GL_INVALID_VALUE) print("\t TYPE: Invalid Value");
else if (err == GL_INVALID_OPERATION) print("\t TYPE: Invalid Operation");
else if (err == GL_OUT_OF_MEMORY) print("\t TYPE: Out of Memory");
else if (err == GL_INVALID_FRAMEBUFFER_OPERATION) print("\t TYPE: Invalid Framebuffer Operation");
else if (err == GL_CONTEXT_LOST) print("\t TYPE: Context Lost");
else print("\t TYPE: Undefined Error");
}
}
I am running a separate thread that takes input from the terminal/console and changes variables locked behind a mutex that alter the program respectively. The function/method looks like this:
void Engine::console() {
std::string input;
while (true)
{
std::cin >> input;
settingMutex.lock();
if (input == "something") doSomething();
// More possible console command here...
else print(this, "Unknwon Command");
checkErrors("Console Command");
settingMutex.unlock();
}
}
I then start this function on a separate thread shortly before starting the main Render-Loop:
consoleThread = std::thread(&Engine::console, this);
consoleThread.detach();
//Render loop:
while (!window->shouldClose())
{
settingMutex.lock();
//Some stuff here...
// render
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Objects are drawn here...
settingMutex.unlock();
glfwSwapBuffers(window->getGLFWwindow());
glfwPollEvents();
checkErrors("Engine Loop");
}
Everything works as I intended it to. The objects are being drawn correctly and the Render-Loop outputs no errors.
If I comment out the 'checkErrors("Console Command")' in the console() function, my input commands do exactly what they should aswell.
However, if I don't comment that line out, no matter what string I enter, I essentially get infinitely many "Invalid Operation" Errors, coming from the "Console Command" context as output.
I can even remove everything from the console() function except for the checkErrors call and I still get an endless stream of Invalid Operation Errors. The Render-Loop, meanwhile keeps going completely error free.
I have a feeling that the OpenGL context doesn't exist outside the main thread, so simply calling glGetError on a separate thread results in an invalid operation error, but I haven't been able to confirm it.
Anybody have insight as to what is happening here?
Different threads do not share OpenGL context created in one of them, which means, when you are putting the console on a new thread, the call to glGetError()
has no base context, and produces an exception.