如何使用GLFW轮询libdispatch块中的事件? [英] How to use GLFW to poll for events in a libdispatch block?

查看:135
本文介绍了如何使用GLFW轮询libdispatch块中的事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按照如何在libdispatch中使用GLUT的答案?,我现在使用的是GLFW - —

Following up on the answer to How to use GLUT with libdispatch?, I'm now using GLFW instead —

以下代码设置了一个窗口,设置了一个计时器以轮询事件,并随着时间的流逝,使渲染更新入队:

The following code sets up a window, sets up a timer to poll for events, and, over time, enqueues render updates:

#include <dispatch/dispatch.h>
#include <GL/glfw.h>

float t=0;

int main(void)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        glfwInit();
        glfwDisable(GLFW_AUTO_POLL_EVENTS);
        glfwOpenWindow(320,200,8,8,8,8,8,0,GLFW_WINDOW);
    });

    // Periodically process window events --- this isn't working.
    dispatch_source_t windowEventTimer;
    windowEventTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    uint64_t nanoseconds = 100 * NSEC_PER_MSEC;
    dispatch_source_set_timer(windowEventTimer, dispatch_time(DISPATCH_TIME_NOW, nanoseconds), nanoseconds, 0);
    dispatch_source_set_event_handler(windowEventTimer, ^{
        glfwPollEvents();
    });
    dispatch_resume(windowEventTimer);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for(int i=0;i<200;++i)
        {
            // Enqueue a rendering update.
            dispatch_async(dispatch_get_main_queue(), ^{
                glClearColor (0.2f, 0.2f, 0.4f, 1.0f);
                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glColor3f (1.0, 0.7, 0.7); 
                glBegin( GL_LINES );
                    glVertex3f(0,0,0);
                    glVertex3f(t+=0.02,.1,0);
                glEnd();

                glfwSwapBuffers();
            });
            // Wait a bit, to simulate complex calculations.
            sleep(1);
        }
    });

    dispatch_main();
}

动画将按预期更新,但是窗口框架没有绘制,并且窗口不响应事件.

The animation updates as expected, but the window frame does not draw, and the window does not respond to events.

推荐答案

浏览GLFW源,我认为我发现了问题:由GLFW创建的可可窗口的运行循环需要从线程0执行,但是GLFW不需要确保在线程0上发生_glfwPlatformPollEvents().(在

Digging through the GLFW source, I think I found the problem: the runloop of the Cocoa window created by GLFW needs to execute from Thread 0, but GLFW does not ensure that _glfwPlatformPollEvents() happens on Thread 0. (Identical symptoms were reported on this question about executing a Cocoa GUI on a thread other than 0.)

一种解决方法是使用CoreFoundation用来处理CFRunLoop内部主要libdispatch队列的相同私有接口.

A workaround is to use the same private interface CoreFoundation uses to process the main libdispatch queue from inside a CFRunLoop.

如果我将上面代码中的dispatch_main()调用替换为:

If I replace the dispatch_main() call in the above code with this:

while(1)
{
    _dispatch_main_queue_callback_4CF(NULL);
    usleep(10000);
}

...它按预期方式工作-绘制窗口框架,并且窗口处理事件.

...it works as expected — the window frame draws, and the window processes events.

我试图改善这种骇人听闻的情况,

Trying to improve this hacky situation, I:

  • filed a feature request to make this a public libdispatch API
  • requested that the GLFW documentation be updated to mention which thread is needed for Mac events.

这篇关于如何使用GLFW轮询libdispatch块中的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆