Si vous créez une NSView
et une NSOpenGLContext
personnalisée sur macOS Mojave, la fenêtre ne sera pas restituée tant qu'elle n'aura pas été redimensionnée. Mais tout fonctionne si vous utilisez plutôt NSOpenGLView
. Je vois beaucoup de piratages qui redimensionnent la fenêtre par programme ( http://people.bath.ac.uk/abscjkw/ComputerPrograms/C++programs/OpenGL/MojaveOpenGL. cpp ) avant d’y avoir rendu ou appelez deux fois le [NSOpenGLContext update]
( https://github.com/go-gl/glfw/pull/229/commits/9e6129a572227a13ff9acb4904443d2ae7d66e77 ), mais ils semblent vraiment douteux et peu fiables.
J'ai désassemblé les frameworks Apple et découvert qu'ils avaient changé le fonctionnement du rendu OpenGL sur Mojave. Il semble que même si vous désactivez la sauvegarde par couches en définissant la variable NSView
de wantsLayer
sur NO
, NSView
continue de créer et de joindre une couche à votre vue sur Mojave. Redimensionner la fenêtre avant de la rendre fonctionne car cela entraîne généralement un appel à [NSOpenGLContext update]
. L'appel de la mise à jour à deux reprises fonctionne, car dans la première image, NSView
n'a pas de couche attachée et la méthode de mise à jour ne fait rien mais sur la deuxième image, la couche est là et [NSOpenGLContext update]
initialise réellement le framebuffer.
La solution consiste donc à appeler le [NSOpenGLContext update]
manuellement chaque fois que la couche de la NSView
est définie, comme ceci:
@interface OpenGLView: ViewMacOS
{
NSOpenGLContext* _openGLContext;
}
@end
@implementation OpenGLView
-(void)setLayer:(CALayer*)layer
{
[super setLayer:layer];
[_openGLContext update];
}
@end
Je l'ai testé et cela fonctionne à la fois sur Mojave et sur les anciennes versions de macOS ([NSView setLayer:]
n'est pas appelé sur macOS 10.13 et les versions antérieures). Voici le commit complet que j'ai fait pour le moteur Ouzel: https://github.com/elnormous/ouzel/commit/7e708636189d970bad6b013ecd5375cfe693f3f3
Sur ma sous-classe NSView qui gère NSOpenGLContext manuellement, je devais appeler NSView.displayIfNeeded au lieu de NSView.display pour l’échange de mémoire tampon. Le remplacement de NSView.setLayer et l'appel de NSOpenGLContext.update n'ont pas aidé.
Veuillez noter que mon utilisation est similaire à SDL, où j'utilise une boucle d'exécution personnalisée. Ce n'est donc peut-être pas le cas dans le programme affiches.