我正在尝试将现代 OS X 支持添加到 OpenTK 框架。 Mac OS Lion 支持 OpenGL 3.2 Core 上下文。我可以使用CGL成功获取它。但是,我找不到将上下文绑定到 Carbon 窗口的直接方法。
以前的 OpenTK 实现使用
aglSetDrawable
方法。 CGL 没有公开的替代方案,尽管它有类似的 未记录的 CGLSetSurface。任何使用它的尝试都会返回错误代码 1001,我找不到相关描述。
在 Carbon 车窗上安装 GL 3.2 有什么帮助吗?
我不能说我已经尝试过这个,但你也许可以通过使用包含 NSOpenGLView 的 HICOcoaView (它将采用可以从 CGLContext 创建的 NSOpenGLContext )来使其工作。
AGL 本身已被弃用,并且不太可能从 Apple 收到任何进一步的更新。 CGL 不适用于窗口上下文。从长远来看,使用 Cocoa 是 OS X 上的最佳途径。
正如其他人所指出的,Apple 不提供任何“官方”API 来将 CGL 上下文绑定到视图,而无需通过 NSOpenGLContext 中介(您甚至不需要创建完整的 NSOpenGLLView,您所需要的只是您所使用的 NSOpenGLContext可以绑定到您选择的任何 NSView)。如果您只是想让事情正常运转,这是最好的方法。
现在,如果您对未记录的方式感兴趣,请系好安全带:首先,Apple 为您提供的将 FBO 绑定到屏幕的唯一官方方式是通过 CGLSetFullScreenOnDisplay(),正如有人提到的here。但这还不是故事的结局。正如您所注意到的,有一个
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 层肯定会打破苹果为其兼容性层所做的任何假设。