C++ 在渲染线程上执行opengl调用时,如何消除抛出的异常?
我想从渲染线程调用OpenGL函数。我有一个简单的std::函数队列 其思想是将来自主线程的命令排队,当调用C++ 在渲染线程上执行opengl调用时,如何消除抛出的异常?,c++,multithreading,opengl,C++,Multithreading,Opengl,我想从渲染线程调用OpenGL函数。我有一个简单的std::函数队列 其思想是将来自主线程的命令排队,当调用Flush()时,通知渲染线程并执行在Flush()之前排队的命令 struct CommandQueue { 作废提交(std::函数命令) { commandQueue.push_back(std::move(command)); } bool Execute() { std::唯一锁(互斥锁); wait(lock,[this](){return!commandsToExecute.
Flush()
时,通知渲染线程并执行在Flush()之前排队的命令
struct CommandQueue
{
作废提交(std::函数命令)
{
commandQueue.push_back(std::move(command));
}
bool Execute()
{
std::唯一锁(互斥锁);
wait(lock,[this](){return!commandsToExecute.empty()| | quit;});
auto-cmds=std::move(commandsToExecute);
lock.unlock();
if(cmds.empty()){
返回false;
}
用于(自动&cmd:cmds){
cmd();
}
返回true;
}
无效刷新()
{
{
std::锁定保护(互斥);
commandsToExecute=std::move(commandQueue);
}
cv.通知_one();
}
作废退出()
{
{
std::锁定保护(互斥);
退出=真;
}
cv.通知_one();
}
bool-quit=false;
std::互斥互斥;
std::条件变量cv;
向量命令队列;
std::向量命令执行;
};
OpenGL上下文是在渲染线程上创建的
static void OpenGLLogMessage(GLenum源、GLenum类型、GLuint id、GLenum严重性、GLsizei长度、常量GLchar*消息、常量void*用户参数)
{
如果(严重性!=总帐调试严重性通知){
std::cout无法从多个线程调用OpenGL(默认情况下),因此其上下文始终仅附加到一个线程。若要更改附件,请在要进行GL调用的线程上使用SDL\u GL\u MakeCurrent
在您的情况下,应将以下内容添加到渲染线程:
SDL\u GL\u MakeCurrent(窗口、上下文);
不相关,您正确地完成了这一部分,我在您的代码中遗漏了这一部分。
编辑
我相信您必须为每个线程重新初始化库,请尝试:
queue.Submit([&](){
gladLoadGLLoader(SDL_GL_GetProcAddress);
SDL_GL_MakeCurrent(窗口、上下文);
});
您没有检查任何返回值,您真的应该检查。我会尝试,但上下文是在渲染线程上创建的,所以该线程上的上下文不应该是当前的吗?正如我所怀疑的,我刚刚尝试过,结果不是肯定的。仍然是相同的错误。@BrodaJarek3不确定SDL,但对于GLFW,您至少必须调用它有一次,因为新的新上下文没有附加到任何内容。@BrodaJarek3哦,我错过了您已经在调用它,对不起,在这种情况下,我不知道问题出在哪里,也许可以检查所有SDL函数是否返回0?@BrodaJarek3编辑了答案,还有一个想法:)希望是这样。我的意思是,有些事情搞砸了。您想重新初始化G吗LAD似乎可以工作,但在几次运行后,同样的事情发生了。看起来在main
循环中排队的命令比在程序启动时排队一次的命令执行得更早,有时它会按它应该的方式执行。因此,我认为这更像是队列写入错误的方式。在o点有回溯吗崩溃?你有单线程版本的代码可以工作吗?很容易将其转换为单线程模式。要么删除queue.Submit()
并直接在这些lambda中执行代码,要么在queue.Flush()之后的主循环中使用queue.execute()
.Backtrace,你的意思是,调用堆栈中的内容?你可能想读取。基本上,你的commandQueue向量处于未指定的状态。向它推送新值可能会产生奇怪的结果。好的,它可能处于未指定的状态,但在.clear()
之后应该可以。在下面的回答中,我们已经讨论了.clear>()
并不能解决问题。我确实清除了每个向量,只是为了500%确定。我也没有移动,而是尝试复制。同样的错误。