单独输入线程上的 OpenGL 无效操作错误
OpenGL Invalid Operation Errors on separate Input Thread
我有一个 "checkErrors" 方法附加到项目的所有组件,这样我就可以调用 'checkErrors("Context Name")',它会告诉我到目前为止发生了什么错误(如果有的话)。方法看起来是这样的:(print是我自己的一个方法,就理解为简单的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");
}
}
我是 运行 一个单独的线程,它从 terminal/console 获取输入并更改锁定在互斥体后面的变量,这些变量分别改变程序。 function/method 看起来像这样:
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();
}
}
然后我在启动主渲染循环前不久在一个单独的线程上启动这个函数:
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");
}
一切如我所愿。对象被正确绘制并且渲染循环输出没有错误。
如果我在 console() 函数中注释掉 'checkErrors("Console Command")',我的输入命令也会完全按照它们应该的方式执行。
但是,如果我不注释掉那一行,无论我输入什么字符串,我基本上都会得到无限多的 "Invalid Operation" 错误,来自 "Console Command" 上下文作为输出。
我什至可以从 console() 函数中删除除 checkErrors 调用之外的所有内容,但我仍然会收到无穷无尽的无效操作错误。渲染循环,同时保持完全无错误。
感觉OpenGL上下文不存在于主线程之外,所以简单地在单独的线程上调用glGetError会导致无效操作错误,但我无法确认。
有人知道这里发生了什么吗?
不同的线程不共享在其中一个线程中创建的 OpenGL 上下文,这意味着,当您将控制台放在新线程上时,对 glGetError()
的调用没有基础上下文,并会产生异常。
我有一个 "checkErrors" 方法附加到项目的所有组件,这样我就可以调用 'checkErrors("Context Name")',它会告诉我到目前为止发生了什么错误(如果有的话)。方法看起来是这样的:(print是我自己的一个方法,就理解为简单的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");
}
}
我是 运行 一个单独的线程,它从 terminal/console 获取输入并更改锁定在互斥体后面的变量,这些变量分别改变程序。 function/method 看起来像这样:
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();
}
}
然后我在启动主渲染循环前不久在一个单独的线程上启动这个函数:
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");
}
一切如我所愿。对象被正确绘制并且渲染循环输出没有错误。
如果我在 console() 函数中注释掉 'checkErrors("Console Command")',我的输入命令也会完全按照它们应该的方式执行。
但是,如果我不注释掉那一行,无论我输入什么字符串,我基本上都会得到无限多的 "Invalid Operation" 错误,来自 "Console Command" 上下文作为输出。
我什至可以从 console() 函数中删除除 checkErrors 调用之外的所有内容,但我仍然会收到无穷无尽的无效操作错误。渲染循环,同时保持完全无错误。
感觉OpenGL上下文不存在于主线程之外,所以简单地在单独的线程上调用glGetError会导致无效操作错误,但我无法确认。
有人知道这里发生了什么吗?
不同的线程不共享在其中一个线程中创建的 OpenGL 上下文,这意味着,当您将控制台放在新线程上时,对 glGetError()
的调用没有基础上下文,并会产生异常。