Carbon 窗口上的 OpenGL 3.2 上下文(OS Lion、Mono)

发布于 2024-11-29 16:09:48 字数 582 浏览 2 评论 0原文

我正在尝试将现代 OS X 支持添加到 OpenTK 框架。 Mac OS Lion 支持 OpenGL 3.2 Core 上下文。我可以使用 CGL 成功获取它。但是,我找不到将上下文绑定到 Carbon 窗口的直接方法。

以前的 OpenTK 实现使用 aglSetDrawable 方法。 CGL 没有公开提供替代方案,尽管它有类似的未记录的 CGLSetSurface。任何使用它的尝试都会返回错误代码 1001,我找不到该错误的描述。

在 Carbon 窗户上安装 GL 3.2 有什么帮助吗?

I'm trying to add modern OS X support to OpenTK framework.
Mac OS Lion supports OpenGL 3.2 Core context. I can successfully obtain it by using CGL. However, I can't find a straight way to bind the context to a Carbon window.

Previous OpenTK implementation used aglSetDrawable method. CGL doesn't publicly have an alternative, even though it has a similar undocumented CGLSetSurface. Any attempts to use it return error code 1001, which I can't find a description for.

Any help of getting GL 3.2 on a Carbon window?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

剧终人散尽 2024-12-06 16:09:48

我不能说我已经尝试过这个,但您也许可以通过使用包含 NSOpenGLView 的 HICOcoaView (它将采用可以从 CGLContext 创建的 NSOpenGLContext )来使其工作。

AGL 本身已被弃用,并且不太可能从 Apple 收到任何进一步的更新。 CGL 不适用于窗口上下文。从长远来看,使用 Cocoa 是 OS X 上的最佳途径。

I can't say I have tried this, but you might be able to get it to work by using a HICocoaView containing an NSOpenGLView (which will take an NSOpenGLContext that can be created froma CGLContext).

AGL itself is deprecated and unlikely to receive any further updates from Apple. CGL is not intended for windowed contexts. In the long run, using Cocoa is the best route on OS X.

以为你会在 2024-12-06 16:09:48

正如其他人所指出的,Apple 不提供任何“官方”API 来将 CGL 上下文绑定到视图,而无需通过 NSOpenGLContext 中介(您甚至不需要创建完整的 NSOpenGLLView,您所需要的只是 NSOpenGLContext,您可以绑定到您选择的任何 NSView)。如果你只是想让事情顺利进行,这是最好的方法。

现在,如果您对未记录的方式感兴趣,请系好安全带:首先,Apple 为您提供的将 FBO 绑定到屏幕的唯一官方方式是通过 CGLSetFullScreenOnDisplay(),正如有人提到的apple.com/forums/thread/53878" rel="nofollow noreferrer">此处。但这还不是故事的结局。正如您所指出的,有一个CGLSetSurface,并且 XQuartz 在内部使用它(通过 Apple 提供的 libXplugin 库)将 opengl 上下文直接绑定到 CGWindow,而无需任何 cocoa 机器妨碍。正如邮件列表主题中提到的,

我们还可以从 这篇文章

好吧,xp_attach_gl_context 只是 CGLSetSurface() 的包装,它是一个内部函数,用于完成我们在这里尝试做的事情。如果返回任何错误,xp_attach_gl_context 将返回错误值。

CGLSetSurface 只需要一个上下文、连接 ID、窗口 ID 和
表面ID。

上下文直接从输入传递到 xp_attach_gl_context,
xp_attach_gl_context 的 xp_surface_id 输入映射到 wid /
sid 传递给 CGLSetSurface。

幸运的是,其他人已经为我们做了一些逆向工程。您可以在 RetroArch 驱动程序中看到它们如下利用它:

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, ¶ms);
    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

但请注意,当你这样做时,你会失去可可层给你带来的很多好处。像 hiDPI 缩放之类的东西不再“正常工作”,如果现代 macOS 上的 OpenGL 还没有得到足够的支持,那么绕过 Cocoa 层肯定会打破苹果对其兼容性层所做的任何假设。

As others have noted, Apple does not provide any "official" API to bind a CGL context to a view without going through the NSOpenGLContext intermediary (you don't even need to create a full NSOpenGLLView, all you need is the NSOpenGLContext which you can bind to any NSView of your choice). If you just want to get things working, that is the best approach.

Now if you're interested in the undocumented way, buckle up: First, the only official way Apple gives you to bind the FBO to a screen is via CGLSetFullScreenOnDisplay(), as someone mentioned here. But that's not the end of the story. As you noted there is a CGLSetSurface, and internally XQuartz uses this (via the libXplugin library that Apple provides) to bind an opengl context directly to a CGWindow without any cocoa machinery getting in the way. As mentioned in this mailing list thread

We can also learn more about the parameters it takes from this post.

Ok, well xp_attach_gl_context is just a wrapper around CGLSetSurface(), which is an internal function to do exactly what we're trying to do here. If it returns any error, xp_attach_gl_context returns bad value.

CGLSetSurface just takes a context, connection id, window ID, and
surface ID.

The context is passed straight from the input to xp_attach_gl_context,
and the xp_surface_id input to xp_attach_gl_context maps to the wid /
sid passed to CGLSetSurface.

Luckily others have already done some reverse-engineering for us. You can see in RetroArch drivers that they make use of this as follows:

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, ¶ms);
    if(params != 1)
    {
       printf("ERR: no drawable\n");
    }

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

    return sid;
}

and another person independently discovered the same in https://handmade.network/forums/wip/t/2408-very_minimal_osx_platform_layer_experiments.

But be aware that when you things like this, you lose a lot of the benefits that the Cocoa layer gives you. Things like hiDPI scaling no longer "just work", and if OpenGL on modern macOS wasn't unsupported enough, bypassing the Cocoa layer is surely going to break whatever assumptions Apple made for their compatibility layer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文