我正在尝试通过线程更新顶点缓冲区的内容。在线程函数内部,无法绑定缓冲区指向目标,或通过glMapBufferRange检索指针。我总是得到错误1282。外部线程函数一切工作良好。
while( t_con->out_loop )
{
Sleep( t_con->sleep_time );
if( t_con->in_loop )
{
t_con->count++; // thread counter up
EnterCriticalSection( &__cr_sec );
/*******************************************/
/* create the strings for the variables */
/*******************************************/
str_run = sfs_p->str_ptr;
sprintf( str_run, "%4.0f / %4.0f", __mou.pos.x, __mou.pos.y ); // actual mouse position
str_run += sfs_p->str_size;
sprintf( str_run, "%4.0f / %4.0f", __mou.old_pos.x, __mou.old_pos.y ); // old mouse position
str_run += sfs_p->str_size;
sprintf( str_run, "%4.0f / %4.0f", __mou.travel.x, __mou.travel.y ); // mouse travel delta
str_run += sfs_p->str_size;
sprintf( str_run, "%d", __mou.but_l ); // mouse button left
str_run += sfs_p->str_size;
sprintf( str_run, "%d", __mou.but_m ); // mouse button center
str_run += sfs_p->str_size;
sprintf( str_run, "%d", __mou.but_r ); // mouse buttom right
str_run += sfs_p->str_size;
sprintf( str_run, "%f", __mou.speed ); // mouse speed
/******************************************************************/
/* create a Vertex_Buffer_Struct with the chars geometry data */
/******************************************************************/
vx = SFS_to_Vx_Buf( sfs_p );
glBindBuffer( GL_ARRAY_BUFFER, m_dbg->vao->vx_b->id );
G_E_C;
// bind the buffer
gl_ptr = glMapBufferRange( GL_ARRAY_BUFFER, 0, 300, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ); // get the pointer
G_E_C;
Destroy_Vertex_Buffer_Struct( vx );
LeaveCriticalSection( &__cr_sec );
}
}
有什么建议吗?
除了@Ripi2的answe之外,必须注意的是,GL上下文在任何时候最多可以是线程上的最新上下文。实际上,必须先释放主线程上的上下文,然后任何辅助线程才能使其成为当前上下文。因此,在大多数情况下,在多个线程中使用单个OpenGL上下文既不方便也不高效。
我正在尝试通过线程更新顶点缓冲区的内容。在线程函数内部,不可能将缓冲区绑定到目标,也不可能通过
glMapBufferRange
检索指针。
有更好的选择,特别是:
-
只需将所有GL调用保留在一个线程中,并在GL线程中执行
glMapBufferRange
。当缓冲区被映射时,它是整个进程可写的,所以任何其他线程都可以填充它 -
使用多个总账上下文。每个线程都可以有自己的上下文,并始终保持最新状态。通过使用共享上下文,纹理、缓冲区等实际数据对象在上下文之间共享,因此您可以访问其他线程中GL上下文将使用的数据。
在任何情况下,您都需要在这些线程之间进行适当的同步,OpenGL同步对象可能会有所帮助。
只需在线程中调用SetCurrent()
命令或类似命令即可。
请记住,主线程(应用程序启动的地方(也是一个线程。因此,如果使用任何gl命令,它也需要SetCurrent()
。