OpenGL не рендерится на MacOS Mojave

Если вы создаете NSView и обычай NSOpenGLContext в MacOS Mojave окно не отображается до тех пор, пока оно не будет изменено. Но все работает, если вы используете 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), но они кажутся действительно хакерскими и ненадежными.

1 ответ

Решение

Я разобрал фреймворки Apple и обнаружил, что они изменили работу рендеринга OpenGL в Mojave. Кажется, что даже если вы отключите многоуровневую поддержку, установив NSView"s wantsLayer в NO, NSView все еще создает и присоединяет слой к вашему виду на Мохаве. Изменение размера окна перед его рендерингом работает, потому что это обычно приводит к вызову [NSOpenGLContext update], Вызов обновления дважды работает, потому что в первом кадре NSView слой не привязан к нему, а метод update ничего не делает, кроме второго кадра, слой там и [NSOpenGLContext update] фактически инициализирует кадровый буфер.

Таким образом, решение состоит в том, чтобы позвонить [NSOpenGLContext update] вручную всякий раз, когда слой NSView устанавливается так:

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

@implementation OpenGLView

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

    [_openGLContext update];
}

@end

Я протестировал его, и он работает как на Мохаве, так и на старых версиях MacOS ([NSView setLayer:] не вызывается в macOS 10.13 и более старых версиях). Вот полный коммит, который я сделал для движка Ouzel: https://github.com/elnormous/ouzel/commit/7e708636189d970bad6b013ecd5375cfe693f3f3

На моем подклассе NSView, который управляет NSOpenGLContext вручную, мне нужно было вызвать NSView.displayIfNeeded вместо NSView.display для замены буфера. Переопределение NSView.setLayer и вызов NSOpenGLContext.update не помогли.

Обратите внимание, что мое использование похоже на SDL, где я использую пользовательский цикл выполнения, так что это может быть не так в программе постеров.

После обновления до Mojave 10.14.3 и Xcode 10.1 эта проблема была исправлена.

Другие вопросы по тегам