I\'ve got a program that calls to EGL in C++. I want to make the same call in C#, but there doesn\'t seem to be an equivalent concept in C#.
I\'m getting a read/write ac
I think that the parameter type is definitely wrong.
For a complete example, you should read the DeviceContext implementation in https://github.com/luca-piccioni/OpenGL.Net/blob/master/OpenGL.Net/NativeDeviceContext.cs. You should also see where this code is called, so you get the actual calls sequence needed to initialize EGL: - factory method: https://github.com/luca-piccioni/OpenGL.Net/blob/master/OpenGL.Net/DeviceContextFactory.cs - control integration: https://github.com/luca-piccioni/OpenGL.Net/blob/master/OpenGL.Net/GlControl.cs
As you can see, the handle is the Control.Handle property. Probably the actual value to pass is dependent on the current OS implementing EGL, but it should be an handle of the window (or control) hosting the drawing results.
Alternatively, you can check the actual EGL method implementation, and follow the parameter usage untill to the actual DirectX call, just I did at that time.
Typically I believe this would be a System.Windows.Forms.Control...
It is a painfully wrong assumption. Making sense of the typing requires writing three books, pretty hard to do in an SO answer. If you actually intend to do this from a Winforms app then stop right now, that can never work.
OpenGL uses very loose typing, the arguments to their api functions are nothing much more than void*
, a raw pointer. Which makes it very flexible but it is really important what the pointer actually points to. If the client program and the video adapter interface don't agree about that in the slightest way then your program will build just fine but will crash and burn in completely undiagnosable way at runtime. A major reason why Microsoft abandoned OpenGL and decided to create their own, DirectX was the result.
Which uses pointers as well but they are the smarter kind, they support type discovery at runtime. They are IUnknown
pointers, its QueryInterface() method permits finding out if an object supports a specific expected interface. The flavor you see being used here is the exact same kind of pointer, IInspectable
is a slightly smarter version than IUnknown and the base interface implemented by all WinRT classes. You really do have to pass an IInspectable* since that is what the ANGLE port expects.
You'd generally expect that you could just pass an ICoreWindow
interface pointer and be done with it, that's the WinRT interface for a window. The renderer however requires more information than just the ICoreWindow. Not exactly sure why, I think it has something to do with resolution Independence in WinRT. It also needs to know the surface size and scaling factor.
Problem is, OpenGL doesn't have a way to pass that info. So the Microsoft programmer used a very hokey hack, instead of adding a function to pass this info he ab/used the ability to pass any kind of IInspectable*, he passes a IMap<String^, IInspectable*>
pointer. Basically a property bag, CoreWindowNativeWindow.cpp in the ANGLE port digs the properties out of the bag again in its CoreWindowNativeWindow::initialize() function.
PropertySet is a concrete class in the C++ language projection that implements IMap<K, V>
. Do note it is specific to C++, in C# you'd use a Dictionary<string, IntPtr>
instead. The language projection built into the CLR automatically maps a managed dictionary to the native IMap interface.
Oh joy, more IntPtrs. IInspectable* is completely hidden in the language projection you use in C#, that doesn't make it easy. I'm 98% sure that you can use Marshal.GetIUnknownForObject() to obtain a pointer that works, even though it is wrong flavor. Since the C++ code does the right thing and uses QueryInterface :) You must call Marshal.Release() afterwards to clean up, not doing so causes a memory leak.
Do note that there are strong overtones of you doing the wrong thing. I think you are, Microsoft provided this ANGLE fork only for one reason. They tried to make it easy for companies to port their iOS game to WinRT/UWP. Kinda necessary to fill the store with the kind of games that customers like. The ANGLE port was only ever intended to be easy to use from code that started in ObjectiveC or C++, the kind of languages used to write these games.
They could have made it a lot easier to use the library from languages like Javascript or C#, they didn't because it wasn't necessary. If you have to translate a metric mile of C++ code that uses OpenGL to C# then it is pretty likely you'd be much better off when you use DirectX instead. Expect more of this type mapping trouble with other functions and be weary of an experimental HoloLens port.