NSGL fullscreen toggling
This works mostly, it fades to black changes the screen res then fades into the opengl context, which is great (but took me way too long), the problem though is it works once.
If you go to fullscreen and back then try to go to fullscreen again it fades alright and looks like its working but at the end it jumps back to the previous screen res and there's no fullscreen context.
Some pointers would be very helpful because im not sure if what im doing here is even right at all, thanks in advance.
If you go to fullscreen and back then try to go to fullscreen again it fades alright and looks like its working but at the end it jumps back to the previous screen res and there's no fullscreen context.
Some pointers would be very helpful because im not sure if what im doing here is even right at all, thanks in advance.
Code:
- (IBAction)toggleFullscreen:(id)sender
{
CGError cgError;
CGDisplayErr displayError;
CGDisplayReservationInterval seconds;
CGDisplayFadeReservationToken enterFullScreenToken;
CFDictionaryRef desktopMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
CFDictionaryRef fullScreenMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, 32, 640, 480, NULL);
seconds = 2.0;
if(fullscreen) {
[fullScreenGLContext clearDrawable];
[[self openGLContext] makeCurrentContext];
CGDisplaySwitchToMode(kCGDirectMainDisplay, desktopMode);
CGReleaseAllDisplays();
fullscreen = NO;
}
else {
CGAcquireDisplayFadeReservation(seconds, &enterFullScreenToken);
cgError = CGDisplayFade(enterFullScreenToken, seconds, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true);
if(cgError != kCGErrorSuccess) {
NSLog(@"Cannot fade display");
CGReleaseDisplayFadeReservation(enterFullScreenToken);
return;
}
CGReleaseDisplayFadeReservation(enterFullScreenToken);
CGCaptureAllDisplays();
if(displayError != CGDisplayNoErr) {
NSLog(@"Cannot capture displays for fullscreen mode");
return;
}
[fullScreenGLContext setFullScreen];
[fullScreenGLContext makeCurrentContext];
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
[[NSOpenGLContext currentContext] flushBuffer];
CGAcquireDisplayFadeReservation(seconds, &enterFullScreenToken);
cgError = CGDisplayFade(enterFullScreenToken, seconds, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, true);
if(cgError != kCGErrorSuccess) {
NSLog(@"Cannot fade display 2");
CGReleaseDisplayFadeReservation(enterFullScreenToken);
return;
}
CGReleaseDisplayFadeReservation(enterFullScreenToken);
fullscreen = YES;
}
[my_application setFullscreen:fullscreen];
}
Sir, e^iπ + 1 = 0, hence God exists; reply!
Dig dig dig dig...
Last time I checked, this code works flawlessly. Just cut out the stuff about the click-catching window, the gl, and viewport initializations stuff.
Last time I checked, this code works flawlessly. Just cut out the stuff about the click-catching window, the gl, and viewport initializations stuff.
Code:
CFDictionaryRef savedMode;
NSOpenGLContext *fullscreenContext;
Code:
- (void)initFullscreen {
NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFASingleRenderer,
NSOpenGLPFAColorSize, CGDisplayBitsPerPixel(kCGDirectMainDisplay),
NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
NSOpenGLPFAFullScreen,
NULL };
NSOpenGLPixelFormat *nsglFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr]; [nsglFormat autorelease];
NSAssert(nsglFormat,@"Pixel format is nil"); // If the format isn't valid...
fullscreenContext = [[NSOpenGLContext alloc] initWithFormat:nsglFormat shareContext:[self openGLContext]];
[self initContext:fullscreenContext];
//[fullscreenContext copyAttributesFromContext:[self openGLContext] withMask:GL_ALL_ATTRIB_BITS];
}
- (void)enterFullscreen {
if (isFullscreen) return;
NSRect frame = _viewRect;
savedMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
CFDictionaryRef newMode =
CGDisplayBestModeForParameters(kCGDirectMainDisplay,
_viewDepth,
frame.size.width, frame.size.height,
NULL);
NSAssert(newMode, @"Couldn't find display mode");
//fade out
CGDisplayReservationInterval seconds = 2.0;
CGDisplayFadeReservationToken newToken;
CGAcquireDisplayFadeReservation(seconds, &newToken); // reserve display hardware time
CGDisplayFade(newToken,
0.3, // 0.3 seconds
kCGDisplayBlendNormal, // Starting state
kCGDisplayBlendSolidColor, // Ending state
0.0, 0.0, 0.0, // black
true); // wait for completion
CGDisplayCapture(kCGDirectMainDisplay); //capture main display
//Switch to selected resolution.
CGDisplayErr err = CGDisplaySwitchToMode(kCGDirectMainDisplay, newMode);
NSAssert(err == CGDisplayNoErr, @"Error switching resolution.");
int newWidth = [[(NSDictionary*)newMode objectForKey:(NSString *)kCGDisplayWidth] intValue];
int newHeight = [[(NSDictionary*)newMode objectForKey:(NSString *)kCGDisplayHeight] intValue];
glDisable(GL_TEXTURE_2D);
[self initFullscreen];
[fullscreenContext setFullScreen]; //set openGL context to draw to screen
glEnable(GL_TEXTURE_2D);
isFullscreen = YES;
frame.origin = NSMakePoint((newWidth-frame.size.width)/2,(newHeight-frame.size.height)/2);
[fullscreenContext makeCurrentContext];
glClearColor(0,0,0,0);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);
[fullscreenContext flushBuffer];
glClear(GL_COLOR_BUFFER_BIT);
[fullscreenContext flushBuffer];
glEnable(GL_TEXTURE_2D);
glClearColor([backgroundColor redComponent],
[backgroundColor greenComponent],
[backgroundColor blueComponent],
[backgroundColor alphaComponent]);
glViewport((GLint)frame.origin.x,
(GLint)frame.origin.y,
(GLint)frame.size.width,
(GLint)frame.size.height);
glScissor((GLint)frame.origin.x,
(GLint)frame.origin.y,
(GLint)frame.size.width,
(GLint)frame.size.height);
glEnable(GL_SCISSOR_TEST);
long enable[1] = {(long)1};
long swapRect[4] =
{ (long)frame.origin.x,
(long)frame.origin.y,
(long)frame.size.width,
(long)frame.size.height };
[fullscreenContext setValues:swapRect forParameter:NSOpenGLCPSwapRectangle];
[fullscreenContext setValues:enable forParameter:NSOpenGLCPSwapRectangleEnable];
//setup orthographic camera
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(_viewRect.origin.x,
_viewRect.origin.x+_viewRect.size.width,
_viewRect.origin.y,
_viewRect.origin.y+_viewRect.size.height);
frame.origin.y -= newHeight;
frame.origin.y += ([[NSScreen mainScreen] frame].size.height);
NSWindow *FullScreenWindow = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
_superView = [self superview];
myFrame = [self frame];
if(FullScreenWindow != nil) {
[FullScreenWindow setTitle: @"eventCatcher"];
[FullScreenWindow setReleasedWhenClosed: YES];
[FullScreenWindow setContentView: self];
[self setFrame:NSMakeRect(0,0,_viewRect.size.width,_viewRect.size.height)];
[FullScreenWindow setLevel: CGShieldingWindowLevel()];
[FullScreenWindow makeFirstResponder:self];
[FullScreenWindow makeKeyAndOrderFront:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(exitFullscreen)
name:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationHide)
name:NSApplicationWillHideNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationUnhide)
name:NSApplicationDidUnhideNotification
object:NSApp];
//[CBCursor setConstrainsToRect:frame];
}
[self setMouseVisible:mouseIsVisible];
[self display];
CGDisplayFade(newToken,
0.5, // 0.5 seconds
kCGDisplayBlendSolidColor, // Starting state
kCGDisplayBlendNormal, // Ending state
0.0, 0.0, 0.0, // black
false); // Don't wait for completion
CGReleaseDisplayFadeReservation(newToken);
[NSNotification postToDelegate:delegate
withSelector:@selector(viewDidEnterFullscreen:)
withName:CBViewDidEnterFullscreenNotification
object:self
userInfo:nil];
}
- (void)exitFullscreen {
if (!isFullscreen) return;
CGDisplayReservationInterval seconds = 2.0;
CGDisplayFadeReservationToken newToken;
CGAcquireDisplayFadeReservation(seconds, &newToken); // reserve display hardware time
CGDisplayFade(newToken,
0.3, // 0.3 seconds
kCGDisplayBlendNormal, // Starting state
kCGDisplayBlendSolidColor, // Ending state
0.0, 0.0, 0.0, // black
true); // wait for completion
NSWindow *FullscreenWindow = [self window];
[fullscreenContext clearDrawable];
[FullscreenWindow close];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSApplicationWillHideNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSApplicationDidUnhideNotification
object:NSApp];
CGDisplaySwitchToMode(kCGDirectMainDisplay, savedMode);
[_superView addSubview:self];
[self setFrame:myFrame];
[[self window] makeKeyAndOrderFront:self];
isFullscreen = NO;
//[CBCursor setConstrainsToRect:NSZeroRect];
[self display];
CGDisplayFade(newToken,
0.5, // 0.5 seconds
kCGDisplayBlendSolidColor, // Starting state
kCGDisplayBlendNormal, // Ending state
0.0, 0.0, 0.0, // black
true); // Don't wait for completion
CGReleaseDisplayFadeReservation(newToken);
CGDisplayRelease(kCGDirectMainDisplay);
[self setMouseVisible:mouseIsVisible];
[fullscreenContext release];
[NSNotification postToDelegate:delegate
withSelector:@selector(viewDidExitFullscreen:)
withName:CBViewDidExitFullscreenNotification
object:self
userInfo:nil];
}
- (void)applicationHide {
if (!isFullscreen) return;
CGDisplaySwitchToMode(kCGDirectMainDisplay, savedMode);
[fullscreenContext clearDrawable];
//[CBCursor setConstrainsToRect:NSZeroRect];
[[self window] orderOut:self];
CGDisplayRelease(kCGDirectMainDisplay);
}
- (void)applicationUnhide {
if (!isFullscreen) return;
NSRect frame = _viewRect;
[NSApp activateIgnoringOtherApps:YES];
CFDictionaryRef newMode =
CGDisplayBestModeForParameters(kCGDirectMainDisplay,
_viewDepth,
frame.size.width, frame.size.height,
NULL);
//fade out
CGDisplayReservationInterval seconds = 2.0;
CGDisplayFadeReservationToken newToken;
CGAcquireDisplayFadeReservation(seconds, &newToken); // reserve display hardware time
CGDisplayFade(newToken,
0.3, // 0.3 seconds
kCGDisplayBlendNormal, // Starting state
kCGDisplayBlendSolidColor, // Ending state
0.0, 0.0, 0.0, // black
true); // wait for completion
CGDisplayCapture(kCGDirectMainDisplay); //capture main display
//Switch to selected resolution.
/*CGDisplayErr err = */CGDisplaySwitchToMode(kCGDirectMainDisplay, newMode);
int newWidth = [[(NSDictionary*)newMode objectForKey:(NSString *)kCGDisplayWidth] intValue];
int newHeight = [[(NSDictionary*)newMode objectForKey:(NSString *)kCGDisplayHeight] intValue];
frame.origin = NSMakePoint((newWidth-frame.size.width)/2,(newHeight-frame.size.height)/2);
[fullscreenContext setFullScreen]; //set openGL context to draw to screen
[[self window] makeKeyAndOrderFront:self];
[fullscreenContext makeCurrentContext];
glClearColor(0,0,0,0);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT);
[fullscreenContext flushBuffer];
glClear(GL_COLOR_BUFFER_BIT);
[fullscreenContext flushBuffer];
glEnable(GL_TEXTURE_2D);
glClearColor([backgroundColor redComponent],
[backgroundColor greenComponent],
[backgroundColor blueComponent],
[backgroundColor alphaComponent]);
glViewport((GLint)frame.origin.x,
(GLint)frame.origin.y,
(GLint)frame.size.width,
(GLint)frame.size.height);
glScissor((GLint)frame.origin.x,
(GLint)frame.origin.y,
(GLint)frame.size.width,
(GLint)frame.size.height);
glEnable(GL_SCISSOR_TEST);
//[CBCursor setConstrainsToRect:frame];
[self display];
CGDisplayFade(newToken,
0.5, // 0.5 seconds
kCGDisplayBlendSolidColor, // Starting state
kCGDisplayBlendNormal, // Ending state
0.0, 0.0, 0.0, // black
false); // Don't wait for completion
CGReleaseDisplayFadeReservation(newToken);
}
---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
Thanks guys!
Its a lot of source code for me to try and understand just now but I think I can try and spot the difference between what im doing which is wrong and what the other sources are doing.

Its a lot of source code for me to try and understand just now but I think I can try and spot the difference between what im doing which is wrong and what the other sources are doing.
Sir, e^iπ + 1 = 0, hence God exists; reply!
I've taken to code to the bare minimum, it now just catures the display then changes the resolution. For some reason I am now not getting anything visual when in fullscreen mode.
Is there anything clearly wrong here or somthing i'm missing?
Is there anything clearly wrong here or somthing i'm missing?
Code:
- (IBAction)toggleFullscreen:(id)sender
{
CGError cgError;
CGDisplayErr displayError;
CGDisplayFadeReservationToken enterFullScreenToken;
CFDictionaryRef fullScreenMode;
if(fullscreen) {
NSLog(@"small mode");
[fullScreenGLContext clearDrawable];
[[self openGLContext] makeCurrentContext];
CGDisplaySwitchToMode(kCGDirectMainDisplay, desktopMode);
CGReleaseAllDisplays();
fullscreen = NO;
}
else {
NSLog(@"Big mode");
desktopMode = CGDisplayCurrentMode(kCGDirectMainDisplay); // desktopMode is an instance variable of the class so that It is kept for returning to later on
fullScreenMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, 32, 800, 600, NULL);
CGCaptureAllDisplays();
if(displayError != CGDisplayNoErr) {
NSLog(@"Cannot capture displays for fullscreen mode");
return;
}
displayError = CGDisplaySwitchToMode(kCGDirectMainDisplay, fullScreenMode);
if(displayError != CGDisplayNoErr) {
NSLog(@"Cannot switch to fullscreen mode");
return;
}
[fullScreenGLContext setFullScreen];
[fullScreenGLContext makeCurrentContext];
[self drawGL];
[[NSOpenGLContext currentContext] flushBuffer];
fullscreen = YES;
}
[my_application setFullscreen:fullscreen];
}
Sir, e^iπ + 1 = 0, hence God exists; reply!
maybe your -drawGL method is changing the context?
---Kelvin--
15.4" MacBook Pro revA
1.83GHz/2GB/250GB
I did have to make sure to use the right clear context function in my draw method ([[NSOpenGLContext currentContext] flushBuffer]
.
I've fixed it now Im still not sure what was going wrong but several minor problems added up to just make it not work at all, thanks for all the help again though

I've fixed it now Im still not sure what was going wrong but several minor problems added up to just make it not work at all, thanks for all the help again though

Sir, e^iπ + 1 = 0, hence God exists; reply!
Possibly Related Threads...
Thread: | Author | Replies: | Views: | Last Post | |
Modern fullscreen toggling | Fenris | 3 | 3,927 |
Dec 17, 2007 02:27 PM Last Post: Fenris |