Как передать контекст OpenGL из Qt4? - PullRequest
1 голос
/ 04 декабря 2011

В настоящее время я занимаюсь разработкой игры на движке LeadWerks 2, и я решил использовать Qt4 в качестве GUI и оконного менеджера.Я хочу создать окно Qt QGLWidget и запустить в нем движок LeadWerks.Здесь есть некоторая информация о создании базового приложения QGLWidget здесь .

Я действительно изо всех сил пытаюсь понять, как именно это сделать.Я могу создать собственный буфер GL в движке LeadWerks, и я считаю, что мне нужно дать этому буферу контекст 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 Ответ

1 голос
/ 04 декабря 2011

и 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...