在Carbon窗口上创建OpenGL 3.2上下文(OS Lion,Mono)

8
我正在尝试为OpenTK框架添加现代的OS X支持。 Mac OS Lion支持OpenGL 3.2核心上下文,我可以通过使用CGL来成功获取它。然而,我无法找到一种直接将上下文绑定到Carbon窗口的方法。
以前的OpenTK实现使用了aglSetDrawable方法。CGL没有公开的替代方法,即使它有一个类似的未公开的CGLSetSurface。任何尝试使用它的企图都会返回错误代码1001,但我找不到其描述。
有没有帮助在Carbon窗口上获得GL 3.2的方法?

我还没有使用过Lion,也没有使用过OpenGL 3.2上下文。不管怎样,在CGL中设置上下文的常见方法是CGLSetCurrentContext。也许那个可以用? - moka
@moka。上下文本身是没问题的。问题是如何在不使用Cocoa的情况下将其附加到窗口。 - kvark
2个回答

1

我不能说我已经尝试过这个,但是你可以尝试使用一个HICocoaView包含一个NSOpenGLView来使其工作(它将需要一个从CGLContext创建的NSOpenGLContext)。

AGL本身已经过时,不太可能从Apple获得任何进一步的更新。CGL不适用于窗口上下文。从长远来看,在OS X上使用Cocoa是最好的方法。


感谢您的答复,@Stefan。我知道现在Cocoa是首选。然而,我需要从Mono访问这些功能,所以Objective-C信号真的很难处理。如果有人有使用简单C接口管理NSOpenGLView上下文的库会很有帮助... - kvark
你可以将Objective-C代码封装在C++类中,这就是wxWidgets或Qt所做的。HICocoaView已经有一个纯C接口,因此您只需要包装一些对NSOpenGLView的调用即可。 - Stefan Werner
AGL 整体上是否已经被弃用?我注意到它的某些部分在 10.7 中已经被弃用,但除此之外没有其他的信息... - user269597

0
正如其他人所指出的,苹果没有提供任何“官方”的API来将CGL上下文绑定到视图,而不经过NSOpenGLContext中介(你甚至不需要创建一个完整的NSOpenGLLView,你只需要NSOpenGLContext,你可以将其绑定到任何你选择的NSView上)。如果你只是想让事情正常工作,这是最好的方法。
现在,如果你对未记录的方法感兴趣,那就准备好了:首先,苹果唯一官方提供的将FBO绑定到屏幕的方法是通过CGLSetFullScreenOnDisplay(),正如有人在这里提到的here。但这并不是故事的结束。正如你所注意到的,有一个CGLSetSurface,在内部,XQuartz使用这个方法(通过苹果提供的libXplugin库)将一个OpenGL上下文直接绑定到一个CGWindow,而不需要任何Cocoa机制干扰。正如在这个mailing list thread中提到的。
我们还可以从这篇文章中了解它所需的参数。
引用: 好的,xp_attach_gl_context只是CGLSetSurface()的一个包装器,它是一个内部函数,正是我们在这里试图做的事情。如果它返回任何错误,xp_attach_gl_context将返回错误值。
CGLSetSurface只需要一个上下文、连接ID、窗口ID和表面ID。
上下文直接从输入传递给xp_attach_gl_context,而xp_surface_id输入传递给xp_attach_gl_context,将映射到传递给CGLSetSurface的wid / sid。
幸运的是,其他人已经为我们做了一些逆向工程。你可以在RetroArch drivers中看到他们的使用方式。
static CGSSurfaceID attach_gl_context_to_window(CGLContextObj glCtx,
   CGSWindowID wid, int *width, int *height)
{
    CFArrayRef wins;
    CFDictionaryRef win, bnd;
    GLint params = 0;
    Float64 w = 0, h = 0;
    CGSSurfaceID sid = 0;
    CGSConnectionID cid = CGSMainConnectionID();

    printf("cid:%d wid:%d\n", cid, wid);

    /* determine window size */
    /* FIXME/TODO - CGWindowListCopyWindowInfo was introduced on OSX 10.5,
     * find alternative for lower versions. */
    wins = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, wid); /* expect one result only */
    win = (CFDictionaryRef)CFArrayGetValueAtIndex(wins, 0);
    bnd = (CFDictionaryRef)CFDictionaryGetValue(win, kCGWindowBounds);
    CFNumberGetValue((CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)bnd, CFSTR("Width")),
       kCFNumberFloat64Type, &w);
    CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(bnd, CFSTR("Height")),
       kCFNumberFloat64Type, &h);
    CFRelease(wins);

    /* create a surface. */
    if(CGSAddSurface(cid, wid, &sid) != kCGErrorSuccess)
    {
       printf("ERR: no surface\n");
    }
    printf("sid:%d\n", sid);

    /* set surface size, and order it frontmost */
    if(CGSSetSurfaceBounds(cid, wid, sid, CGRectMake(0, 0, w, h)) != kCGErrorSuccess)
       printf("ERR: cant set bounds\n");
    if(CGSOrderSurface(cid, wid, sid, 1, 0) != kCGErrorSuccess)
       printf("ERR: cant order front\n");

    /* attach context to the surface */
    if(CGLSetSurface(glCtx, cid, wid, sid) != kCGErrorSuccess)
    {
       printf("ERR: cant set surface\n");
    }

    /* check drawable */
    CGLGetParameter(glCtx, kCGLCPHasDrawable, &params);
    if(params != 1)
    {
       printf("ERR: no drawable\n");
    }

    *width  = (int)w;
    *height = (int)h;

    return sid;
}


另外一个人也独立地在https://handmade.network/forums/wip/t/2408-very_minimal_osx_platform_layer_experiments发现了同样的事情。
但是要注意,当你这样做的时候,你会失去很多Cocoa层所带来的好处。像高分辨率缩放这样的功能将不再“自动适应”,而且如果现代macOS上的OpenGL已经不受支持,那么绕过Cocoa层肯定会破坏苹果为其兼容性层所做的任何假设。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接