Golden Oldie: Fullscreen troubles

Oldtimer
Posts: 832
Joined: 2002.09
Post: #1
Hi all,
A while back, I noticed that my fullscreen/windowed toggling setup didn't work on systems below a certain Tiger. Then, the setup was to use a single context with NSOpenGLPFAFullScreen set for both the window and fullscreen, but that is (contrary to documentation) broken below Tiger.

So, I rewrote and rewrote and rewrote and now I can't get the fullscreen to work. That is, switching works fine, but I only get flickering "noise". The screen is jumbled with parts of the Finder, random textures and that blinks on and off in a very epilepsy-inducing way. What I'm doing is creating two contexts, attaching the window one to the view, and keeping the fullscreen one around. When I switch, I just call -setFullscreen on the fullscreen context and make it the current context. The contexts are shared, but I'm kind of worrying that the GL state doesn't make it across. So, I tried to call -copyAttributes:withMask: (something that I haven't seen anyone else do, by the way) and that didn't help much.

t3h source, edited for brevity:

Code:
-(BOOL) switchToFullscreenWithResolution: (NSSize) resolution shouldFade: (BOOL) shouldFade
{
    BOOL result;
    // Find a suitable mode given resolution and depth
    CFDictionaryRef fullScreenMode =
       CGDisplayBestModeForParameters
     (kCGDirectMainDisplay,
      colorDepth,
     (int)resolution.width, (int)resolution.height, NULL);

    // Fading out, omitted
    
    CGDisplayErr e = CGCaptureAllDisplays();
    
    [fullscreenContext setFullScreen];
    [fullscreenContext makeCurrentContext];
    
    // Hide the menu bar in fullscreen
    [NSMenu setMenuBarVisible: NO];

    return YES;
}

...and the context creation:

Code:
-(BOOL) setPixelFormatWithColorDepth: (GLuint) _cDepth
                          depthDepth: (GLuint) _dDepth
                             stencil: (BOOL) _stencil
                        accumulation: (BOOL) _accum
{
    NSOpenGLPixelFormatAttribute attributes[] =
    {
        NSOpenGLPFAWindow,
        NSOpenGLPFASingleRenderer,
        NSOpenGLPFANoRecovery,
        NSOpenGLPFAScreenMask,
             CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay),
        NSOpenGLPFAAccelerated,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) _cDepth,
        NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute) _dDepth,
        NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute) ((_stencil) ? 8 : 0),
        NSOpenGLPFAAccumSize, (NSOpenGLPixelFormatAttribute) ((_accum) ? 8 : 0),
        (NSOpenGLPixelFormatAttribute) 0
    };
    
    // Set up windowed pixel format
    NSOpenGLPixelFormat* windowedPixelFormat =
       [[[NSOpenGLPixelFormat alloc] initWithAttributes: attributes] autorelease];
    if (!windowedPixelFormat) return NO;
    
    NSOpenGLContext *newWinCtx =
      [[NSOpenGLContext alloc] initWithFormat: windowedPixelFormat
                                               shareContext: [self openGLContext]];
    if (!newWinCtx)
    {
        Log (ERR, BMSTR("Could not create new windowed GL context"));
        return NO;
    }

    // Set up fullscreen pixel format
    attributes[0] = NSOpenGLPFAFullScreen;
    NSOpenGLPixelFormat* fullscreenPixelFormat =
       [[[NSOpenGLPixelFormat alloc] initWithAttributes: attributes] autorelease];
    if (!fullscreenPixelFormat) return NO;
    
     NSOpenGLContext *newFSCtx =
       [[NSOpenGLContext alloc] initWithFormat: fullscreenPixelFormat
                                               shareContext: fullscreenContext];
    if (!newFSCtx)
    {
        Log (ERR, BMSTR("Could not create new fullscreen GL context"));
        return NO;
    }
    
    [fullscreenContext release];
    fullscreenContext = newFSCtx;
    
    colorDepth = _cDepth;
        
    // Update this view's context and connect them
    [self setOpenGLContext: newWinCtx];
        
    return YES;
}

Is something obviously, glaringly wrong?

EDIT: I hate the CODE boxes. Sorry about that.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #2
Grab the source for Shoot Things. It does exactly what you're trying to do (two contexts) and works on all configs.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Or the example from http://onesadcookie.com/book , which also works everywhere.

GL objects (textures, display lists, etc) are shared, state (bound textures, matrix stack, etc) is not. I've generally found that it's easiest to set that stuff up each frame to allow easy switching of contexts.
Quote this message in a reply
Oldtimer
Posts: 832
Joined: 2002.09
Post: #4
Thanks to both of you. Working off your examples, I managed to rewrite my GL context handling code, got it to work flawlessly in an isolated application, but not when it is inserted into my engine. I've broken something else, somewhere else. So, I'm re-writing it step by step, inside the engine now. Let's see if that yields anything.
Quote this message in a reply
Oldtimer
Posts: 832
Joined: 2002.09
Post: #5
Sigh, I've banged my head against this for a couple of weeks now, and it turns out that copyAttributes:fromContext doesn't copy client states - i.e. my projection matrix didn't make it through the copy.

Might be a heads-up for other people who cache their projection/model view matrices in a setup routine.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenAL install troubles m3the01 3 3,193 Feb 20, 2009 12:46 PM
Last Post: DaveJ
  Bit Depth troubles Jones 2 2,417 Aug 21, 2006 01:20 PM
Last Post: Jones
  Troubles compiling... InflamedSpirit 11 4,805 Jul 2, 2005 08:41 AM
Last Post: Malarkey
  Material Troubles Nick 2 2,576 Apr 12, 2005 06:39 AM
Last Post: Nick
  Fullscreen troubles (Cocoa) DJBlufire 5 3,231 Dec 12, 2003 11:36 PM
Last Post: kelvin