OpenTK Mac OS X support.
Posted Tuesday, 18 March, 2008 - 16:39 by kanato in
Well, I thought I would let you know I've been working on writing support for Mac OS X for OpenTK. I've successfully wrapped window creation and event processing through the Carbon API. I need to work on keyboard and mouse event processions, then AGL wrapping, then I think I'll be to the point where I can integrate with OpenTK. Hopefully I can get there by early next week.




Comments
Mar 18
18:13:34Re: OpenTK Mac OS X support.
posted by the FiddlerAwesome news! Let me know if you need help with anything.
Mar 19
05:16:11Re: OpenTK Mac OS X support.
posted by kanatoWhat's the rule on converting GL* types to c# types? I'm guessing GLint -> int is ok, but is GLboolean -> bool ok? Or do I need to use an int type?
Edit: nevermind, I see it's defined as unsigned char in the headers.
Do you have any tips on Marshalling? I think I understand that I need to pin arrays to a fixed pointer to marshal them, but I don't know if there are any other gotchas.
Mar 19
06:04:00Re: OpenTK Mac OS X support.
posted by the FiddlerAs a rule of thumb, just write a
DllImportwith the correct signature and let the runtime handle the details for you (pinning etc), unless it is performance-critical code.For example:
#define bool char
typedef struct { ... } SomeStruct;
bool Foo(SomeStruct *data);
// C# - whichever of the following makes the most sense
[DllImport("library")]
bool Foo(SomeStruct[] data);
// or, if SomeStruct is a struct (i.e. value object):
[DllImport("library")]
bool Foo(ref SomeStruct data);
// or, if SomeStruct is a class (i.e. reference object):
[DllImport("library")]
bool Foo(SomeStruct data);
This should cover just about 90% of all p/invoke cases.
Void pointers can be turned into
IntPtrs, and char arrays should be made intostrings (in parameters) orStringBuilders (out parameters). Generally, the biggest issue is converting structs with unions or embedded arrays/strings - just make a post if anything strange shows up ;)Another complication has to do with 64bit datatypes: do
ints change bitness from 32- to 64bit compilers (i.e. 32bit on 32bit compilers and 64bit on 64bit compilers)? If so, int parameters should be defined asIntPtrs, which is a bit ugly (but necessary).Mar 25
21:39:39Re: OpenTK Mac OS X support.
posted by kanatoOk, here is a patch which adds preliminary MacOS X support: http://agate.sourceforge.net/download/macos.patch
This patch should be considered preliminary, and not for production use. Keyboard support is incomplete, and there are some exceptions when windows are closed, and I haven't gotten GLControl to work right yet. So I don't recommend commiting this to SVN right now.
I put everything in a MacOS folder and namespace, instead of the OSX folder / namespace. The reasoning for this is that since CarbonLib predates OSX, it should be possible, with a bit of work, to add support for Mac OS 9. I don't have a Mac which can run OS 9 however, and there is no official support from Mono for Mac OS prior to 10.3 or so. So that may not ever be a reality. Plus I think MacOS is easier to read than OSX. But if you don't like it, I can change everything to using OSX instead.
I've wrapped Agl context creation, Carbon window creation, mouse and keyboard events. Several of the examples work (Simple Window, Immediate mode, Display Lists, Fonts, Text, Texture Mapping). There are some artifacts with the text, just above and below the glyphs. I think this might be related to artifacts mentioned in other threads on the forum.
Apparently my MacMini only supports OpenGL 1.2, so VBO and GLSL don't work. The GLU Tesselate example doesn't work, and I'm not sure why. Other GLU functions like Glu.LookAt work, and extension loading for GLU seems to work.
Things that need to be resolved with GameWindow:
A couple of other thoughts:
Have you thought of abstracting all the platform stuff to some sort of class factory? Rather than have lines like "if (Configuration.RunningOnOSX)" all over the place, just have a static class in Platform, which a hidden implementation object that each platform implements, and it just creates whatever objects are necessary. If you are interested, I can code this up, it won't take long.
I noticed when the GameWindow is closed, the run loop is terminated by throwing an exception. Is this really the best way to do it? I would think setting a flag to terminate the loop would be better. I also noticed if you aren't using GameWindow.Run but a custom run loop, then this exception is difficult to deal with, because the exception itself is not public, so you have to catch a base exception and either deal with, swallow, or rethrow exceptions that are of a different type.
Well, let me know what you think. If there are coding style / naming issues, let me know and I will fix them.
Mar 25
21:22:36Re: OpenTK Mac OS X support.
posted by kanatoOh, one other thing I wanted to ask. Is there support for the type of event handling where the user clicks the close box, and the program asks if they want to save before quitting (or something like that). I already have support for this sort of thing written into the carbon wrapper, so that it can cancel a window close event if the program / user input requires it.
Mar 25
21:27:35Re: OpenTK Mac OS X support.
posted by objarniFantastic work kanato!
Mar 25
03:23:29Re: OpenTK Mac OS X support.
posted by kanatoI just ran the GLSL example, and it gives an error message about requiring OpenGL 2.0 and says it will abort, but then it runs anyway. Looking at the extensions supported by my card, I see things like:
gl_apple_vertex_program_evaluators
gl_arb_fragment_program
gl_arb_fragment_shader
gl_arb_shader_objects
gl_arb_shading_language_100
gl_arb_vertex_program
gl_arb_vertex_shader
gl_version_1_1
gl_version_1_2
but no other gl_versions are listed.
And my the OpenGL driver info listed is
Intel GMA 950 OpenGL Engine, Intel Inc., 1.2 APPLE-1.4.56
So shaders are supported, even though I don't have higher than OpenGL 1.2 ?
Mar 26
05:23:07Re: OpenTK Mac OS X support.
posted by kanatoOk, just one more thing for today, then I will wait for responses :P
I have mapped the OpenAL dlls to their OSX equivalents, but I know nothing about OpenAL. Are there any example programs which use OpenTK with OpenAL that I can test out? If I run the Example launcher and run AudioContext Test four times in a row, this is the output I see:
Enumerating audio devices.
Testing AudioContext functions.
AudioContext.CurrentContext...
AttributeSize: 12
4103 0 25189928 0 0 0 0 0 0 0 0 0
Launching example: Examples.TestApp
Testing AudioContext functions.
AudioContext.CurrentContext...
AttributeSize: 9
4103 0 40 0 0 0 0 0 0
Launching example: Examples.TestApp
Testing AudioContext functions.
AudioContext.CurrentContext...
AttributeSize: 3
4103 0 0
Launching example: Examples.TestApp
Testing AudioContext functions.
AudioContext.CurrentContext...
AttributeSize: 3
4103 0 0
I don't know if that's good or not. And it's strange that the output changes after the first two runs.
Mar 26
05:44:00Re: OpenTK Mac OS X support.
posted by the FiddlerGreat work! I won't have time to review the code for another 24 hours or so, but I can respond to your questions :)
[MacOS vs OSX]
No problem, MacOS looks better too.
[Font artifacts]
This has to do with sampling/texture coordinates, it happens on some cards/drivers but not on others. I'll loosen the packing by 1 pixel - this should take care of these artifacts.
[GLU tesselate]
This looks like a Mono problem (doesn't work on Linux either), but I haven't bothered to investigate yet. I'm looking for a managed alternative - if one exists, I'll be happy to see GLU go away.
[Window close event]
The implementation is a bit hairy. There are three ways to close the window:
GameWindow.Exit. This terminates the main loop. Then the Unload event is fired, the context is disposed andINativeGLWindow.DestroyWindow()is called. Finally, all pending events are processed untilGameWindow.Existsbecomes false.INativeGLWindow.ProcessEventsdetects this and raises theINativeGLWindow.Destroyevent, which is handled byGameWindow.glWindow_Destroy.GameWindow.glWindow_DestroyvallsGameWindow.Exitand the rest work out as above.GameWindow.Dispose. This callsGraphicsContext.DisposeandINativeGLWindow.Dispose, but I haven't worked out the details yet (presumably it should callGameWindow.Exitinstead).[Window resize event]
GL.Viewportgenerally belongs to aGameWindow.Resizeevent handler. As long as OnResizeInternal is called, the resize event will be raised.(The On*Internal methods will potentially perform some bookkeeping before raising the actual events. They also make sure that things will work correctly if the user overrides the On* methods - e.g. OnUpdate - and forgets to call
base.OnUpdate).[Class factory for platforms]
I was planning to do this, but I didn't think a MacOS port would become reality so soon. :)
I think you have such a system in place for AgateLib? I'd be very interested in such an implementation.
[GameWindowExitException]
It is the only way (I know of) to stop the main loop asynchronously. I.e:
{
if opengl version < 2.0
Exit();
use opengl 2.0
}
Exit() must stop control before it reaches the "use opengl 2.0" line (otherwise it will crash!). To the best of my knowledge, an exception is the only method to achieve this.
I added this exception very reluctantly, but I really cannot see a better way.
If you have a custom main loop, the solution is simple: don't call Exit() (Exit() is specific to the Run() method - should document this better). Since you have control over the main loop, you are free to use a flag (or any other method you can think of).
[Exit event with cancel support]
I'm planning to add this, so this code is useful.
[GLSL]
Intel GMA 950 OpenGL Engine, Intel Inc., 1.2 APPLE-1.4.56
OpenTK reports the version from GL.GetString(): "1.2 APPLE-1.4.56" - I don't know if there's a better way.
I'll update the app to test for GLSL support explicitly, instead of relying on gl_version_2_0 being available.
[OpenAL]
This doesn't look very good. The attributes look bogus - they should contain things like frequency (44100) etc. At least it doesn't crash :)
I'm still working on
AudioContext. Should have a couple of examples ready later today, that test audio playback and audio effects.Mar 26
19:26:42Re: OpenTK Mac OS X support.
posted by kanatoOk, I figured out the closing and resize events issues. In AGL, when a window is resized, aglUpdateContext needs to be called on the context. It looks like inorder to do that, either IGraphicsContext or IGraphicsContextInternal needs to have an Update method. The only other way I see to do it would be to expose the implementation of GraphicsContext, at least internally.
I guess I was a bit thrown off with the close event integration because if you're running your own event loop there is no event that is raised when the native window is closed. But that can be resolved easily by making GameWindow.ExitInternal call an event. I'll submit a patch for that later.
Mar 29
22:25:26Re: OpenTK Mac OS X support.
posted by kanatoOk, I've updated the patch here (same link):
http://agate.sourceforge.net/download/macos.patch
This adds Mac OS X support for the GameWindow object. I've also added the class factory for each OS to simplify the creation of implementation objects.
I added to Context objects an Update method, because AGL requires that aglUpdateContext be called on the context when its host window changes size.
Fullscreen is not supported yet, but discovery of display devices and supported resolutions is. I'm not quite sure where to go with fullscreen support, because the model seems different than Windows or X11. Fullscreen support does not require that one creates a window that covers the screen area, in Mac OS you can simply acquire the display device, and either attach an AGL context to the full screen, or write directly to the framebuffer. AGL also includes a convenience method aglSetFullScreen where you tell it the parameters you want and it just does it. At the moment, I am unsure which approach is best.
GLControl is not supported yet either. For some reason, I cannot get any GL drawing to show up on a WinForms control. In spite of this, through the context creation for it no errors or inappropriate null values are reported. I think this might a Mono/WinForms issue, but I am not sure right now.
Also some of the stability issues from the last version of the patch are fixed. There is a weird issue where if four game windows are openned in succession (ie. by running four examples), there is a crash when the window title is set. I am still working to resolve this.
Also, in GameWindow.cs: Added code in ExitInternal so that if GameWindow.Run() is not used, then an event is raised instead.
Mar 29
22:47:21Re: OpenTK Mac OS X support.
posted by the FiddlerThanks. Maybe you could raise the question on MacOS winforms+opengl at #monodev (irc.gnome.org), someone is bound to know how to do this.
I'm going to branch OpenTK as soon as 0.9.1 is out, and apply the patch. (Not doing it right now, in order to add the wave decoder and OpenAL examples first). Looks great.
Mar 30
18:33:16Re: OpenTK Mac OS X support.
posted by kanatoThat's a good idea. I'll do that once the patch is applied, so I can refer people to the code.
Apr 26
17:25:40Re: OpenTK Mac OS X support.
posted by objarniAny news on this "hot topic" :) ?
Apr 26
18:46:11Re: OpenTK Mac OS X support.
posted by kanatoNot much. I have followed the SVN updates, and some stuff was added to INativeGLWindow (WindowState and WindowBorder), so I have updated my OSX implementation to implement these properties, so that it at least compiles but I have not had much time to make the settings work. I am sort of waiting for the 0.9.1 release when Fiddler said he would branch OpenTK for this patch; it would be good to have this under version control before I put a lot more work into it.
Jun 13
22:55:39Re: OpenTK Mac OS X support.
posted by ZowchAny updates on this? I was hoping to play around with a pet project on my new Mac, and maybe see what I could do to help this along, but the patch here doesn't even apply against trunk anymore after the GL reorganization and whatnot.
I'd love to do what I can to help this along. :)
Jun 16
03:23:23Re: OpenTK Mac OS X support.
posted by kanatoThere's a branch that's made specifically for the macos port. Look in the SVN under the branches folder. I've updated the patch too, it should work when applied to the macos branch. I've sent Fiddler a message about committing it but he hasn't responded yet.
Jun 30
22:50:00Re: OpenTK Mac OS X support.
posted by the FiddlerThe patch doesn't apply cleanly to the macos branch - it looks like the OpenTK.Platform.Factory class is missing. Wild shot: maybe you need to
svn addthe source file first?Jul 02
05:58:28Re: OpenTK Mac OS X support.
posted by kanatohmm.. I thought I had fixed that. I will try to get it fixed in the next couple of days.
Jul 03
21:47:21Re: OpenTK Mac OS X support.
posted by kanatoWell, that's what happens when I use svn from the command line on my mac instead of tortoise svn on windows, and I forget about all the stuff that tortoise has kept track of, like all the files that got added. It should work now, I've reuploaded the patch, reapplied it to the macos branch and tested it on my mac, and it seems to work now.
Also, it seems the OpenAL example works now, so either some bug was fixed in the OpenTK code since I tried it out, or some system software update fixed something on my mac.
Jul 03
23:25:54Re: OpenTK Mac OS X support.
posted by the FiddlerThanks, I'll check this in tomorrow.
I've made a simple change in AudioContext to mimic Alut.Init() behavior: the latter always calls Alc.OpenDevice() without any parameters (which opens the default device). AudioContext on the other hand first enumerates all available devices then open the default one, unless otherwise specified. Unfortunately it seems that actually specifying the default device leads to a crash - which can be avoided by not specifying any device at all.
Now that I think of it, maybe AudioContext is passing unicode data when OpenAL is expecting ascii - better check if this is the case.
Jul 13
18:07:37Re: OpenTK Mac OS X support.
posted by kanatoAny progress or issues with this?