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