C++ 有没有办法在gtk'以外的线程上运行opengl命令;用户界面线程?

C++ 有没有办法在gtk'以外的线程上运行opengl命令;用户界面线程?,c++,multithreading,opengl,gtk3,C++,Multithreading,Opengl,Gtk3,我正在从事一个项目,该项目要求从另一个线程创建管道并呈现对gtk的glarea的调用 我使用环氧树脂作为gl装载机。我还在windows系统上使用mingw的gtk+构建。使用示例三角形代码,创建管道并使用glarea的realize和render信号进行渲染是可行的。但是在另一个线程上的任何gl调用都会导致应用程序崩溃 下面是渲染和线程逻辑。我仍然使用realize信号配置管道,但是渲染是在不同的线程上完成的 窗口类 #包括“window.h” #包括 #包括 名称空间M { Window::

我正在从事一个项目,该项目要求从另一个线程创建管道并呈现对gtk的glarea的调用

我使用环氧树脂作为gl装载机。我还在windows系统上使用mingw的gtk+构建。使用示例三角形代码,创建管道并使用glarea的
realize
render
信号进行渲染是可行的。但是在另一个线程上的任何gl调用都会导致应用程序崩溃

下面是渲染和线程逻辑。我仍然使用
realize
信号配置管道,但是渲染是在不同的线程上完成的

窗口类

#包括“window.h”
#包括
#包括
名称空间M
{
Window::Window()
{
设置边框宽度(6);
设置默认大小(640480);
_框。设置_间距(6);
添加(_框);
_box.pack_end(ngl,Gtk::pack_EXPAND_小部件);//ngl:GLArea变量
显示全部();
thread=std::thread([this]{render();});
}
void Window::render()
{
使用名称空间std::chrono_文本;
std::此线程::睡眠时间(5s);
ngl.renderTri();
}
}
一个班级

#包括“glarea.h”
名称空间M
{
眩光a::眩光a()
:_分(0分),
_颜色(0),
_矩阵(0),
_IsButton3已按下(错误),
_isKeyWPressed(假),
_isKeyAPressed(假),
_IsKeypressed(假),
_isKeyDPressed(假)
{
设置_有_窗口(假);
//重要的是明确地允许在GLArea上发生事件!
_添加事件(Gdk::指针\u运动\u掩码)
|Gdk::按钮\按下\掩模
|Gdk::按钮释放掩码
|Gdk::按键按钮掩码
|Gdk::按键(释放屏蔽);
pack_end(_glArea,Gtk::pack_EXPAND_WIDGET);
_眩光A.信号_实现().连接(
sigc::mem_fun(*this,&GLArea::realize));
//重要的是,unrealize信号调用我们的处理程序进行清理
//调用默认未实现处理程序之前的GL资源*,因此
//“假”。
_眩光A.信号_未实现().连接(
sigc::mem_-fun(*this,&GLArea::unreaze),false);
/*_glArea.signal_render().connect(
sigc::mem_-fun(*this,&GLArea::render))*/
_眩光A.信号\按键\按下事件().连接(
sigc::mem_-fun(*此,&GLArea::on_-key\u-press\u事件),false);
_眩光。信号\按键\释放\事件()。连接(
sigc::mem\u fun(*此,&GLArea::on\u key\u release\u事件),false);
//抓住焦点,无论发生什么,都能获得所有关键事件!
_眩光。设置焦距(真);
_眩光。抓住焦点();
显示全部();
}
GLArea::~GLArea()
{
}
void GLArea::renderTri()
{
while(true)
{
GLArea::render();
_glArea.queue_draw();
}
}
bool GLArea::render()
{
试一试{
_glArea.make_current();
_glArea.if_error()时抛出_;
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
//draw();
如果(_isKeyWPressed){
_矩阵[13]+=0.01;
}
如果(_isKeyAPressed){
_矩阵[12]=0.01;
}
如果(_i按下键){
_矩阵[13]=0.01;
}
如果(_isKeyDPressed){
_矩阵[12]+=0.01;
}
glUniformMatrix4fv(_矩阵位置,1,GL_假,_矩阵);
gldrawArray(GL_三角形,0,3);
返回true;
}捕获(const Gdk::GLError&error){
标准:cerr

不幸的是-不,OpenGL上下文不是线程安全的,并且只能与创建它的线程一起使用。@VictorGubin:这不完全正确。是的,OpenGL是单线程的,并且不是线程安全的。线程和gl上下文之间存在1-1连接。但是您可以将上下文重新分配给任何其他线程(
wglMakeCurrent
在windows上)。只要确保所有内容都正确同步,就应该可以从不同的线程进行渲染。@BDL注释是我预期的结果。我还使用了opentk的多线程渲染,每次都通过调用
MakeCurrent()将上下文分配给当前线程
由渲染器公开。但不使用gtk