如何从Qt4传递OpenGL上下文?

时间:2011-12-04 02:28:04

标签: c++ qt opengl qt4

我目前正在使用LeadWerks 2引擎开发游戏,我决定使用Qt4作为GUI和窗口管理器。我想要做的是创建一个Qt QGLWidget窗口,并在其中运行LeadWerks引擎。 有一些建立基本QGLWidget应用程序here的信息。

我真的很难理解如何做到这一点。我可以在LeadWerks引擎中创建一个自定义GL缓冲区,我相信我需要做的是给缓冲区创建GL上下文Qt。 至于LeadWerks方面,我需要做的主要事情是调用一个名为CreateCustomBuffer的方法并传递一些东西:

virtual void Buffer :: CreateCustom(byte * getsize,byte * makecurrent)

创建并返回一个新的自定义缓冲区。 GetSize(定义为void _stdcall GetSize(int * width,int * height))和MakeCurrent(定义为void _stdcall MakeCurrent(void))是缓冲区的回调函数。 GetSize应该返回(通过更改指针提供的值)使用的custum OpenGL缓冲区/上下文的大小。 MakeCurrent应将自定义缓冲区设置为当前的OpenGL上下文。

1 个答案:

答案 0 :(得分:1)

  

和MakeCurrent(定义为void _stdcall MakeCurrent(void))是缓冲区的回调函数

如果我理解正确,只要LeadWerks希望上下文变为活动状态(它本身不管理它),就会调用此回调,类似 getsize 回调是获取大小可用的窗口。所以通常你会用它来激活你可以访问的另一个界面的上下文。

不幸的是,这些回调不允许传递指针,这意味着,您无法传递QGLWidget类实例指针,因此您可以将调用委托给类成员函数。无法将用户数据传递给回调是API设计错误的一个标志,因为它会使事情变得困难,否则就会很容易。

有一个名为 ffcall 的库,它提供了一种解决此问题的机制http://www.gnu.org/s/libffcall/callback.html

所以你要写一个委托函数

void qglwidget_makecurrent(void *data, va_list alist)
{
    GQLWidget *widget = (QGLWidget*) data;
    widget->makeCurrent();
}

void qglwidget_getsize(void *data, va_list alist)
{
    int *widthptr, *heightptr;
    GQLWidget *widget = (QGLWidget*) data;
    va_start_ptr(alist, void);
    widthptr = va_arg_ptr(alist, int*);
    heightptr = va_arg_ptr(alist, int*);
    va_return_void(alist);
    *widthptr = widget->width();
    *heightptr = widget->height();
}

创建回调包装器(如在QGLWidget派生类'构造函数中)作为类成员变量:

class MyGLWidget : QGLWidget {
/* ... */
    __TR_function qglwidget_makecurrent_callback;
    __TR_function qglwidget_getsize_callback;
}

MyGLWidget::MyGLWidget() {
    qglwidget_makecurrent_callback = alloc_callback(qglwidget_makecurrent, (void)this);
    qglwidget_getsize_callback = alloc_callback(qglwidget_makecurrent, (void*)this);
}

那些你可以传递给LeadEngine的人:

buffer->CreateCustom((void(*)(int, int))qglwidget_getsize_callback, (void(*)(void))qglwidget_makecurrent_callback);