PDA

View Full Version : Golden Oldie: Fullscreen troubles


Fenris
2006.07.24, 12:26 PM
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:


-(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:


-(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.

arekkusu
2006.07.24, 03:44 PM
Grab the source for Shoot Things (http://homepage.mac.com/arekkusu/SW/shootthings.html). It does exactly what you're trying to do (two contexts) and works on all configs.

OneSadCookie
2006.07.24, 05:37 PM
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.

Fenris
2006.07.27, 06:00 AM
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.

Fenris
2006.07.27, 06:42 PM
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.