开发者

Refresh a NSOpenGLView within a loop without letting go of the main runloop in Cocoa

I am building an Cocoa/OpenGL app, for periods of about 2 second at a time, I need to control every video frame as well as writing to a digital IO device. If after I make the openGL calls I let go of the main thread (like if I make the openGL calls inside a 开发者_开发知识库timer fire-method with an interval of like 0.01 Sec) openGLview is refreshed with every call to glFinish().

But If I instead keep the main thread busy like in a 2 second long while loop, openGl calls won't work (surprisingly the first call to glFinish() would work but the rest won't). The documentation says that glFinish should block the thread until the gl commands are executed. Can anybody please help me understand what is going on here or provide a solution to this problem. To make it clear, I want to present 200 frames one after another without missing a frame and marking each frame refresh by writing to a digital IO port (I don't have a problem with this) all on Snow Leopard.


This is not quite my department - pretty vanilla NSOpenGLView user myself - but from the Mac OpenGL docs it looks like you might want to use a CVDisplayLink (Q&A1385) for this. Even if that won't do it, the other stuff there should probably help.

EDIT

I've only done some basic testing on this, but it looks like you can do what you want as long as you first set the correct OpenGL context and then swap buffers after each frame (assuming you're using a double buffered context):

// inside an NSOpenGLView subclass, somewhere outside the usual drawing loop
- (void) drawMultipleFrames
{
    // it might be advisable to also do a [self lockFocus] here,
    // although it seems to work without that in my simple tests

    [[self openGLContext] makeCurrentContext];

    // ... set up common OpenGL state ...

    for ( i = 0; i < LOTS_OF_FRAMES; ++i )
    {
        // ... draw your frame ...

        glFinish();
        glSwapAPPLE();
    }

    // unlockFocus here if locked earlier
}

I previously tried using [[self openGLContext] flushBuffer] at the end of each frame instead -- that doesn't need glSwapAPPLE but doesn't block like glFinish so you might get frames trampling over one another. This seems to work OK with other apps, runs in the background etc, but of course YMMV.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜