OpenGL无法在macOS Mojave上呈现

问题描述 投票:4回答:3

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

macos opengl nsview nsopenglview nsopengl
3个回答
5
投票

我反汇编了Apple的框架,发现他们已经改变了OpenGL渲染在Mojave上的工作方式。看来即使你通过将NSViewwantsLayer设置为NO来禁用分层支持,NSView仍会在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


0
投票

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.