3

I am developing a document based application for Mac OS X. It's a kind of media player, but instead of playing audio or video files it is supposed to open text-files containing meta-data specifying OpenGL animations. I would like to mimic Apples QuickTime X window style. This means, i have to do all the window drawings myself, because Cocoa has no appropriate window style.

There is one thing which gives me headaches: The rounded corners usually to be found on Mac OS X windows. I tried using the borderless window mask and working some CGS magic - there are some private Apple headers which allow window shaping, but they are of course undocumented. I was able to cut rectangular holes in my windows edges, but i couldn't figure out how Apple achieves rounded corners.

Creating a transparent window and drawing the frame myself does not work, because an OpenGL viewport is always rectangular, and the only way to change it is to turn on NSOpenGLCPSurfaceOpacity for alpha transparency and using the stencil buffer or shaders to cut out the edges, which seems like a hell of a lot of overhead.

If i put an OpenGLView into a standard Cocoa window with titlebar, the bottom edges are rounded. It seems this is happening at the NSThemeFrame stage of the view hierarchy. Any ideas how this is done?

cargath
  • 832
  • 8
  • 18
  • 1
    Why do you assume that going the `NSOpenGLCPSurfaceOpacity` route will cause performance issues? Seems perfectly reasonable to me. Never assume. Test and Profile. – Rob Keniger Dec 07 '11 at 21:40
  • @Rob Because i did some research before posting my question. Turns out there are others who would can't seem to get the rounded corners right. People already tried `NSOpenGLSurfaceOpacity`, and they reported a big drop in performance. But i guess i'm out of options. – cargath Dec 08 '11 at 03:33
  • @cargath just because other people post about their inability to get something to work doesn't make it the gospel truth, how do you know that there isn't something else they are doing that is wrong, how do you know that there aren't thousands of other people not having problems and just *not* posting about their successes? Like Rob said, test and profile yourself! –  Dec 08 '11 at 21:55
  • @JarrodRoberson I did. Resizing gets extremely slow when creating textures for the stencil buffer to crop the corners. That's not surprising. Of course i could not redraw OpenGL while resizing, but that's not an ideal option either. – cargath Dec 08 '11 at 22:58

2 Answers2

1

Use a layer-backed view, and do your drawing in the CALayer on an invisible window. Layers include automatic handling of rounded corners and borders.


Background for CALayer is in the Core Animation Programming Guide. To create a layer for NSView, you need to call [view setWantsLayer:YES]. You would create a CAOpenGLLayer and assign it to the view using setLayer:.

See CALayerEssentials for sample code demonstrating how to use CAOpenGLLayer among other layer types.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Could you be a bit more specific? I haven't used CALayers before, so this is new to me - would i subclass a CAOpenGLLayer oder request a backing layer for my NSOpenGLView subclass? I can't seem to find any examples or tutorials that address my needs. – cargath Dec 07 '11 at 18:36
  • All i can find about CAOpenGLLayer is people having problems with them ;) Speed issues, picture artifacts etc – cargath Dec 07 '11 at 18:45
  • Well, i created a new Xcode project for testing purposes. I subclassed NSWindow to make it invisible and subclassed CAOpenGLLayer to do some OpenGL drawings. I then used IB to setup a new window using my NSWindow subclass and attached an NSView to it. I requested my CAOpenGLLayer subclass in my AppController code for this NSView. And it works, i could get it to draw into my window. Only it doesn't have rounded edges. – cargath Dec 08 '11 at 01:47
0

Since Robs suggestion didn't work and no one else contributed to the discussion i settled on using the stencil buffer to crop the windows corners. I did this by creating a texture from the windows background and rendering it into the stencil buffer, discarding all transparent pixels. Looks fine, but is slow when resizing the window :/

cargath
  • 832
  • 8
  • 18