正如其他人所指出的,苹果没有提供任何“官方”的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);
wins = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, wid);
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);
if(CGSAddSurface(cid, wid, &sid) != kCGErrorSuccess)
{
printf("ERR: no surface\n");
}
printf("sid:%d\n", sid);
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");
if(CGLSetSurface(glCtx, cid, wid, sid) != kCGErrorSuccess)
{
printf("ERR: cant set surface\n");
}
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发现了同样的事情。
但是要注意,当你这样做的时候,你会失去很多Cocoa层所带来的好处。像高分辨率缩放这样的功能将不再“自动适应”,而且如果现代macOS上的OpenGL已经不受支持,那么绕过Cocoa层肯定会破坏苹果为其兼容性层所做的任何假设。