Ollhax's picture

Cocoa bindings

Hi there! I need Cocoa support to get the GTKSharp GLWidget working on MacOS, so I've been tinkering a bit with my old experimental code for this. I got contexts working, and I think it might be useful to have official support for this. If it's interesting, I have some questions on how to best integrate this to the project:

1. Is there a need for a full Cocoa implementation? I.e. window handling and so on. Seems to me that the SDL implementation could be the default way of doing this, and the Cocoa support could go only as far as creating contexts. That would at least patch up the missing functionality for the time being.

2. Should the Cocoa and Carbon support exist side by side ? We'll probably never see a Windows Forms update with a Cocoa backend, so Carbon support may be useful. Perhaps a "PreferLegacy" option in ToolkitOptions?

3. Is there a better way to interface obj-c code from C# than a wrapper library? I've created a small C library that simply sends the NSOpenGL* messages, it works but it feels like there should be a better way of doing this...

Best regards,
/Olle


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Ollhax's picture

New test implementation, works on Mac/PC:

https://github.com/Ollhax/opentk/tree/cocoa

Build and run the GtkTest program to see the working widget. All changes to OpenTK and the widget itself is included.

the Fiddler's picture
Quote:

Hi there! I need Cocoa support to get the GTKSharp GLWidget working on MacOS, so I've been tinkering a bit with my old experimental code for this. I got contexts working, and I think it might be useful to have official support for this. If it's interesting, I have some questions on how to best integrate this to the project:

If I understand correctly, you are constructing a window through GTK# and wish to combine that with a Cocoa-based OpenTK GraphicsContext. Is that right?

In that case, you have two options:

  • Create the OpenGL outside OpenTK as an external GraphicsContext. Example code
  • Modify OpenTK to support Cocoa.
Quote:

1. Is there a need for a full Cocoa implementation? I.e. window handling and so on. Seems to me that the SDL implementation could be the default way of doing this, and the Cocoa support could go only as far as creating contexts. That would at least patch up the missing functionality for the time being.

As a long-term goal, a complete Cocoa backend for OpenTK would be desirable, as the Carbon backend is an evolutionary dead-end. Fortunately, SDL2 works great in most cases, so this is not as big of an issue now as it was in e.g. 2012.

The good news is that only two APIs would need to be rewritten for Cocoa: IGraphicsContext and INativeWindow. A Cocoa-backed IGraphicsContext already brings us halfway there.

I would definitely help anyone willing to put in the effort, but I currently lack the time to implement this on my own.

Quote:

2. Should the Cocoa and Carbon support exist side by side ? We'll probably never see a Windows Forms update with a Cocoa backend, so Carbon support may be useful. Perhaps a "PreferLegacy" option in ToolkitOptions?

Given a complete Cocoa backend, then the Carbon backend would be dropped from OpenTK (~120KB of dead code.) In that case, OpenTK.GLControl would be taught to construct its own GraphicsContext via AGL or CGL. The code already exists, so it's a simple matter of moving it from OpenTK.dll to OpenTK.GLControl.dll.

Quote:

3. Is there a better way to interface obj-c code from C# than a wrapper library? I've created a small C library that simply sends the NSOpenGL* messages, it works but it feels like there should be a better way of doing this...

This is the crux of the issue, and the reason why there is no Cocoa backend yet.

MonoMac / Xamarin.Mac use objc_MsgSend and its variants to communicate with NS* APIs. This avoids the C wrapper library, but still requires a FFI layer to smooth over the ABI differences (which are significant, and differ between x86 and x64.) The relevant code is available here: https://github.com/mono/monomac/tree/master/src/ObjCRuntime

Instead of a C wrapper, it would be easier to link against MonoMac and implement IGraphicsContext in terms of that. This would avoid both the native dependency and the complexity of implementing Cocoa bindings from scratch.

Ollhax's picture

Thanks, very helpful input. I've started playing around with MonoMac, seems like it might do the trick.

However, the compiled assembly is pretty large (7 MB), will this be a problem? Also, what's the best way of linking to it?

the Fiddler's picture

There are two ways to reduce application size:

Short-term, the simplest way be to run monolinker on your application binary:

monolinker -a Application.exe

This will try to strip unused code from OpenTK.dll and any other referenced assembly. Both MonoMac and OpenTK (as of 1.1) are compatible with the monolinker, but third-party dlls that rely on reflection might need some massaging.

Longer-term, OpenTK would integrate a subset of MonoMac directly into its codebase. All platform backends work like this, i.e. each OpenTK.Platform.* namespace includes a minimal platform binding for the APIs used by OpenTK. This is why you can compile an OpenTK app on Mac and run it e.g. on Windows without recompilation.

In any case, the first step would be to have a working backend. Reducing the application size & dependencies becomes a much simpler task afterwards.

Ollhax's picture

Alrighty, I've got it to the same point I had it before (working contexts) but using MonoMac instead of my own wrapper. Gonna take a look at window handling the next couple of days.

Ollhax's picture

Okay, got a Cocoa window up and running! Got some fixes left to do, e.g. fixing some fullscreen issues, polled input, shared contexts and so on, but basic window handling seems to be working.

the Fiddler's picture

This is awesome! Let me know if I can somehow be of help.

Ollhax's picture

Any feedback on the implementation so far is welcome, and guidande on what needs to be done before you'd consider it ready for release. These are the remaining tasks that I can think of right now:

* Fix polled input
* Fix shared contexts
* Consider another fullscreen implementation (current has a few bugs, does not work the same way as windows fullscreen (e.g. menu bar when you move up the cursor, long animation) and requires MacOS 10.7)
* Retina screen support (untested now)
* Test on some real world applications (need some help here)
* Figure out which MacOS version to target. Current minimum is 10.7, but think 10.6 is still fairly common.
* Extract everything needed from Monomac and move into OpenTK, remove Monomac.dll dependency.
* Remove Carbon-specific stuff
* Carbon implementation for the GLControl

winterhell's picture

Would this make SDL2 redundant and having all OpenGL versions exposed on OS X directly from OpenTK?

Ollhax's picture
winterhell wrote:

Would this make SDL2 redundant and having all OpenGL versions exposed on OS X directly from OpenTK?

Yes, you'll be able to create OpenGL contexts up to the version supported by Mac OS. Think it's 4.1 in Mavericks.