Journal

By Steve Challis

Recent Entries

Archive

RSS/Atom

Home

Projects

Taking OpenGL Fullscreen with Cocoa

7 months ago — 4 Comments — Permalink

  • opengl
  • cocoa
  • objective-c
  • xcode
  • interface-builder
  • how-to

This is a quick how-to on dynamically making a Cocoa OpenGL view fullscreen. It’s pretty simple really - when the user initiates fullscreen, we call a method on our view which creates a new borderless window on top of all other windows and sets the contents to be our view. For this, I’m going to go ahead and assume that you have created a custom OpenGLView and have instantiated it in a regular NSWindow.

We’ll start off by adding a few variables to the view interface. These will allow us to keep track of the non-fullscreen starting window and our newly created fullscreen window, as well as which state we are in. It is important to keep track of the starting window so that we know where to restore the view to when switching away from fullscreen.

@interface MyOpenGLView : NSOpenGLView {
    NSWindow *fullscreenWindow;
    NSWindow *startingWindow;
    BOOL fullscreenOn;
}

@property (assign) IBOutlet NSWindow *startingWindow;

- (IBAction) toggleFullscreen:(id)sender;

Now, in the implementation we synthesize startingWindow so that we have access to it:

@synthesize startingWindow;

Also in the implementation, the toggleFullscreen method should look something like this:

- (IBAction) toggleFullScreen:(id)sender {
    if( fullscreenOn == true ) {
        [fullscreenWindow close];
        [startingWindow setAcceptsMouseMovedEvents:YES];
        [startingWindow setContentView: self];
        [startingWindow makeKeyAndOrderFront: self];
        [startingWindow makeFirstResponder: self];
        fullscreenOn = false;
    }
    else  {
        NSRect frame = [[NSScreen mainScreen] frame];
        // Instantiate new borderless window
        fullscreenWindow = [[NSWindow alloc]
                            initWithContentRect:frame
                            styleMask:NSBorderlessWindowMask
                            backing:NSBackingStoreBuffered
                            defer: NO];
        [startingWindow setAcceptsMouseMovedEvents:NO];
        if(fullscreenWindow != nil) {
            // Set the options for our new fullscreen window
            [fullscreenWindow setTitle: @"Full Screen"];            
            [fullscreenWindow setReleasedWhenClosed: YES];
            [fullscreenWindow setAcceptsMouseMovedEvents:YES];
            [fullscreenWindow setContentView: self];
            [fullscreenWindow makeKeyAndOrderFront:self ];
            // By setting the window level to just beneath the screensaver,
            // only this window will be visible (no menu bar or dock)
            [fullscreenWindow setLevel: NSScreenSaverWindowLevel-1];
            [fullscreenWindow makeFirstResponder:self];
            fullscreenOn = true;
        } else {
            NSLog(@"Error: could not create fullscreen window!");
        }
    }
}

We can now tie everything together in Interface Builder by hooking up the startingWindow outlet to our main window:

Connect the view outlet to out main window

And finally, create a menu option which we hook up to the toggleFullscreen action of our view:

Connect the fullscreen menu option to the toggleFullscreen action of our view

Save, rebuild and enjoy fullscreen goodness!

Note To Self

7 months ago — 0 Comments — Permalink

  • fyp
  • cocoa
  • depth-buffer
  • opengl
  • xcode
  • interface-builder

Don’t forget to set the depth buffer in Interface Builder. For some reason, setting it in the custom OpenGLView class doesn’t do anything.

« NewerOlder »

Log in

Powered by Mumblr – a basic Django tumblelog application that uses MongoDB with MongoEngine. Fork it on Github. Designed and developed by Harry Marr and Steve Challis.

Unless otherwise noted, everything here is available under the Creative Commons Attribution-Share Alike 3.0 license. Sharing is fucking cool.

Home / Projects / Recent / Archive / RSS /