How do I pass an OpenGL context from Qt4?

家住魔仙堡 提交于 2019-12-13 00:34:41

问题


I'm currently developing a game in the LeadWerks 2 engine and I've decided to use Qt4 as the GUI and window manager. What I want to do is create a Qt QGLWidget window and have the LeadWerks engine run inside of that. There is some information of building a basic QGLWidget application here.

I'm really struggling to understand how to do this exactly. I can create a custom GL buffer within the LeadWerks engine and I believe what I need to do is give that buffer the GL context Qt created. As for the LeadWerks side of things, the main thing I need to do is call a method called CreateCustomBuffer and pass it a few things:

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

Creates and returns a new custom buffer. GetSize (defined as void _stdcall GetSize(int* width, int* height)) and MakeCurrent (defined as void _stdcall MakeCurrent(void)) are callback functions for the buffer. GetSize should return (by changing the value provided with a pointer) the size of the custum OpenGL buffer/context used. MakeCurrent should set the custom buffer as the current OpenGL context.


回答1:


and MakeCurrent (defined as void _stdcall MakeCurrent(void)) are callback functions for the buffer

If I understand it correct, this callback will be called whenever LeadWerks wants the context to become active (it doesn't manage it itself then), similar the getsize callback is to obtain the size of the available window. So normally you'd use this to activate the context from another interface you've access for.

Unfortunately those callbacks don't allow for passing a pointer, which means, you can't pass the QGLWidget class instance pointer, so that you could delegate the call to a class member function. Not being able to pass user data to callbacks is a sign of bad API design, because it makes things hard, which would be easy otherwise.

There is a library called ffcall which provides a mechanism to get around this http://www.gnu.org/s/libffcall/callback.html

So you'd write a delegator function

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();
}

create callback wrappers (as in your QGLWidget derives class' constructor) as class member variables:

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);
}

And those you can pass to LeadEngine:

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


来源:https://stackoverflow.com/questions/8372791/how-do-i-pass-an-opengl-context-from-qt4

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!