web-dev-qa-db-fra.com

OpenGL ne rend pas sur macOS Mojave

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.

4
Elviss Strazdins

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

3
Elviss Strazdins

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.

0
GenericPtr