6

如果您在 macOS Mojave 上创建NSView和自定义NSOpenGLContext,则在调整大小之前不会渲染窗口。但是,如果您改用它,一切都会起作用NSOpenGLView。我看到很多以编程方式调整窗口大小的黑客(http://people.bath.ac.uk/abscjkw/ComputerPrograms/C++programs/OpenGL/MojaveOpenGL.cpp),然后再渲染或调用[NSOpenGLContext update]两次(https:// github.com/go-gl/glfw/pull/229/commits/9e6129a572227a13ff9acb4904443d2ae7d66e77),但它们看起来真的很老套且不可靠。

4

3 回答 3

5

我反汇编了 Apple 的框架,发现它们改变了 OpenGL 渲染在 Mojave 上的工作方式。似乎即使您通过将NSView's设置wantsLayer为禁用分层支持NONSView仍然会创建图层并将其附加到您在 Mojave 上的视图中。在渲染到它之前调整窗口大小是可行的,因为这通常会导致调用[NSOpenGLContext update]. 调用更新两次是有效的,因为在第一帧NSView中没有附加任何图层,并且更新方法除了在第二帧上什么都不做,图层就在那里并且[NSOpenGLContext update]实际上初始化了帧缓冲区。

所以解决方案是在设置[NSOpenGLContext update]图层时手动调用NSView,如下所示:

@interface OpenGLView: ViewMacOS
{
    NSOpenGLContext* _openGLContext;
}
@end

@implementation OpenGLView

-(void)setLayer:(CALayer*)layer
{
    [super setLayer:layer];

    [_openGLContext update];
}

@end

我对其进行了测试,它可以在 Mojave 和旧版本的 macOS 上运行([NSView setLayer:]在 macOS 10.13 和旧版本上不被调用)。这是我为 Ouzel 引擎所做的完整提交:https ://github.com/elnormous/ouzel/commit/7e708636189d970bad6b013ecd5375cfe693f3f3

于 2018-10-22T22:22:30.693 回答
0

在手动管理 NSOpenGLContext 的 NSView 子类上,我需要调用 NSView.displayIfNeeded 而不是 NSView.display 来进行缓冲区交换。覆盖 NSView.setLayer 并调用 NSOpenGLContext.update 没有帮助。

请注意,我的用法就像使用自定义运行循环的 SDL,因此在海报程序中可能不是这种情况。

于 2019-01-28T22:51:23.197 回答
0

更新到 Mojave 10.14.3 和 Xcode 10.1 后,此问题已得到修复。

于 2019-03-09T11:53:02.980 回答