Подкласс NSOpenGLView не отображает в Мохаве - PullRequest
0 голосов
/ 18 ноября 2018

Я столкнулся с очень странной ошибкой при компиляции с Xcode 10 против фреймворков Mojave.

Получается, что OpenGL перестает показывать. Похоже, что он действительно где-то там (слой наложения перекрывает его?) Как видимый при быстром обновлении видимой области окна (!) Или при минимизации (снимок, используемый эффектом джинна, показывает это!)

Самое странное, что я использую почти идентичный класс для другого проекта, и он прекрасно работает при сборке для Mojave!

Я вижу решения с отправкой обновления в OpenGLContext для тех, кто использует отдельный контекст, но это простой подкласс для NSOpenGLView. В этом случае разветвление SpriteBuilder для Cocos2D.

Я попытался обновить базовый контекст, настроить представление для поддержки высокого разрешения и попытаться предотвратить создание вспомогательного слоя. Пока ничего не получалось.

код:

@implementation CCGLView {
    NSMutableArray *_fences;
}

- (id) initWithFrame:(NSRect)frameRect
{
    self = [self initWithFrame:frameRect shareContext:nil];
    return self;
}

- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context
{
    NSOpenGLPixelFormatAttribute attribs[] =
    {
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFADepthSize, 24,
        0
    };

    NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];

    if (!pixelFormat)
        CCLOG(@"No OpenGL pixel format");

    if ((self = [super initWithFrame:frameRect pixelFormat:pixelFormat])) {

        if (context) [self setOpenGLContext:context];

    }

    return self;
}

- (void) prepareOpenGL
{
    [super prepareOpenGL];

    // Make this openGL context current to the thread
    // (i.e. all openGL on this thread calls will go to this context)
    [[self openGLContext] makeCurrentContext];

    // Synchronize buffer swaps with vertical refresh rate
    GLint swapInt = 1;
    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];  

}

- (NSUInteger) depthFormat
{
    return 24;
}

- (void) reshape
{
    [self lockOpenGLContext];

    NSRect rect = [self convertRectToBacking:self.bounds];

    CCDirector *director = [CCDirector sharedDirector];
    [director reshapeProjection: NSSizeToCGSize(rect.size) ];

    if (director.runningScene) { 
       [director drawScene];
    }
    [self unlockOpenGLContext];
}


- (void)lockOpenGLContext
{
    NSOpenGLContext *glContext = [self openGLContext];
    NSAssert( glContext, @"FATAL: could not get openGL context");

    [glContext makeCurrentContext];
    CGLLockContext([glContext CGLContextObj]);  
}

-(void) unlockOpenGLContext
{
    NSOpenGLContext *glContext = [self openGLContext];
    NSAssert( glContext, @"FATAL: could not get openGL context");

    CGLUnlockContext([glContext CGLContextObj]);
}

// Find or make a fence that is ready to use.
-(CCGLViewFence *)getReadyFence
{
    // First checkf oldest (first in the array) fence is ready again.
    CCGLViewFence *fence = _fences.firstObject;;
    if(fence.isReady){
        // Remove the fence so it can be inserted at the end of the queue again.
        [_fences removeObjectAtIndex:0];
        return fence;
    } else {
        // No existing fences ready. Make a new one.
        return [[CCGLViewFence alloc] init];
    }
}

-(void)addFrameCompletionHandler:(dispatch_block_t)handler
{
    if(_fences == nil){
        _fences = [NSMutableArray arrayWithObject:[[CCGLViewFence alloc] init]];
    }

    CCGLViewFence *fence = _fences.lastObject;
    if(!fence.isReady){
        fence = [self getReadyFence];
        [_fences addObject:fence];
    }

    [fence.handlers addObject:handler];
}

-(void)beginFrame
{
    [self lockOpenGLContext];
}

-(void)presentFrame
{
    {
        CCGLViewFence *fence = _fences.lastObject;
        if(fence.isReady){
            // If the fence is ready to be added, insert a sync point for it.
            [fence insertFence];
        }
    }

    [self.openGLContext flushBuffer];

    // Check the fences for completion.
    for(CCGLViewFence *fence in _fences){
        if(fence.isComplete){
            for(dispatch_block_t handler in fence.handlers) handler();
            [fence.handlers removeAllObjects];
        } else {
            break;
        }
    }

    [self unlockOpenGLContext];
}

-(GLuint)fbo
{
    return 0;
}
@end    
...