The callbacks could be function pointers in the global scope. We could load orx with our plugin and then set those function pointers to our C# callbacks. Wouldn't that work?
I've done it.
Just rewrote a fake GLFW that exports a function.
orx.dll exports my function and i've just to map it into c#
Now the hard work begins...i've to implement in c# all the glfw functions that were called by orx.
--- edit ---
Enis, to answer you, i've what you wrote, just organized the callbacks into a structure so c# sends the structure filled with right pointers, and the plugin does a memcpy to it's own copy.
I can receive all callbacks from the C# side. Now all I have to do is to re-implement the OpenGL window in C#, and all tha black magic stuff the GLFW was doing for window handling and managing.
The cooking recipe wanted:
- 500 gr of fake GLFW plugin with a new exported (__dllexport) API used to save a structure full of functions pointer to call back when orx calls needed GLFE functions.
- 20 gr of C++ native library to implement nasty orx starter (needed because I could not rewrite orx_execute in c# due to _orxDebug_init and other stuff.
- 1500 gr of prepared orx imports for C#
- 300 gr of prepared orx interface library imports for C#
Take all an mix for 5 developing hours, then place fresh on the plate and have fun preparing the sausage.
I'm watching your progress with excitement, and looking forward to tasting what you're baking for us!
Meanwhile, I've made a strange observation: (at least in linux)
When you statically link some functions into an executable, it's not possible to redirect these functions using LD_PRELOAD. This, I guess, would be expected by anyone familiar with what I'm talking about. But my strange observation happens when you try to statically link a function in a shared object, and then later LD_PRELOAD that function. Magically, even though the shared object has been compiled to link it statically, the functions in the pre-loaded shared objects replace the original ones!
Now, is it just me, or does that mean that we can inject our glfw fake implementations simply through an LD_PRELOAD (and hopefully windows and mac equivalents)?
Writing a fake GLFW seemed to me as the best way from the start. I did not consider it could be done in C# and dynamically loaded at run time. Simply amazing :woohoo: .
Out of curiosity what are you planning to use to implement an opengl control in C#?
Yep, but in those cases you need a separate DLL anyway, so why not load it as a plugin the way it was meant to be?
On Windows, the problem isn't that bad anyway. We can distribute the orx.dll modified to accommodate the editor. Likewise in Mac OS. In Linux, however, we have to force the user to build from source. That in theory, means that we need to distribute the orx source entirely, the version that is known to build with our plugin. With the LD_PRELOAD approach, we will need to either:
- Distribute no native binaries at all (if C# can inject its callbacks as symbols)
- Distribute a libFakeGLFW.so to be preloaded. This is possible, because a dummy shared library will only depend on glibc and other very fundamental stuff that is probably the same on all linux systems.
- Distribute a very simple source code to compile libFakeGLFW.so, but it will be VERY simple to generate it since it has no dependencies. Just a .c file to compile (We'll probably do that before starting the studio for the first time.)
All of this really simplifies our source tree and the build process. It's also much more future-proof on all platforms.
@graag: I'm going to use the Tao library that is an importer of OpenGL functions. I supports other GL libraries too. You can see here http://www.mono-project.com/Tao
@grey: to my knowledge there are 2 ways do implement the same thing in windows.
The first one is the same used in some trainers for games : trojian dll.
You must provide a fake dll with the same name to the one you're emulating and the same exports. This dll must be in the same path of executable and it's used to override only wanted functions.
The second is hooking. You can patch the loaded dll and inject your functions.
In the first case it's impossible to use only C# as you need a native dll.
In the second case it's possible to do that in C#, but it's platform dependent and it's really a mess.
C# it's not the tool born to make memory patching and function hooking
None of the mentioned functions would work in our case because when you compile with "embedded" orx option there is no plugin.dll and no glfw.dll.
If none of this functions exports symbols it's not possible to make any function hooking as it's damn hard to get the address of the functions you wanna hook.
@enis: abour your points: C# can inject but as said, for embedded compilations, it's really long and hard.
If the linux distro is an lsb you could be right. What about different glibc versions? there are more than one glibc out there.
We could distribute the library ready to link, and link it ony on installation, but as i said, on my "old" machine it takes 30 seconds to build orx and less than 5 to build my fake glfw.
Why become crazy about that?
Today I don't have much time to work on the callbacks side. I guess I'll ask you a lot of opengl stuff to understand a pair of things
right now I have a semi-working orx window.
All compiles, all callbacks are called, the opengl window is up and running and I implemented quite all glfw functions needed by the orxDisplay, orxMouse, orxJoystick and orxKeyboards plugins.
I still have to clean a lot of stuff because I had to use platform dependent stuff but it will be easy to correct.
If I find the time, this evening I try to port bounce and scroll demos in C# to see if they work.
As you can see in the attached image, I can load Grey's config file, and display it with the new plugin.
I sill have to take care about few details to improve the usability of the OrxWidget class (the one that's rendering the scene) and I have to solve a little bug about resizing (may be I missed something from glfw).
The example it's only 3 lines of code:
OrxNative.orxViewport_CreateFromConfig("Viewport");
OrxNative.orxConfig_Load("StaticScene.ini");
OrxNative.orxObject_CreateFromConfig("Scene");
During the week I hope to give you more good news.
--- edit ---
I corrected a bit the resizing. I still have a problem.
When I resize the window, I see the contents are zooming.
Do you have any idea?
I'm at 50% of the library to interface orx library from managed code.
I ported all the public structures and all functions based on version 1.3 (because I used code from Ocean).
I'd like to synch all my imported functions with all the functions the actual orx code exports.
Tomorrow I think I'll have a fully working library that could allow full usage of orx calling the APIs from C#.
The other 50% I'd like to do is to divide the code in classes. I mean orxViewport_Create should be a "Create" static method of orxViewport class and should return a new instance of orxViewport.
That could allow a cleaner OO coding if compared to the actual call to orxNative.orxViewport_Create().
I'd be really happy if someone could help me discovering changes in:
- exported orx apis
- public structures
- enums
All I need is a test file with the names of modified things in a human readable format, rather than a diff file
Id love to get a copy of what you've already got done on the wrapper if at all possible? I've been looking into doing this myself but adding to your work seems the smarter idea to me
There's also http://code.orx-project.org if you want to host your work (can even be private) on bitbucket as part of the orx team effort. No obligation though.
@Grey: no propblem about sharing my code, but give me just a pair of days (may be just one) to complete the first part.
I forgot to tell you all that there's a little disadvantage in using C# with orx.
You have to recompile orx to make it to don't use fastcall calling convention (__orxFREEBASIC__ does it).
As stated by Microsoft documentation for .NET 4.5 the FastCall calling convention is not supported.
Some guys at Microsoft said that the benfit of the fastcall calling convention on modern machines is trascurable or, in some cases, it could slow the execution more than a cdecl or stdcall.
@iarwain: I'm not a repository geek, and I don't know how to use git or mercurial or bitbucket.
Since you gave me write permissions, I would use sourceforge if possible.
May be I could create a folder in a branch...as soon as I decide the name of the library
Some guys at Microsoft said that the benfit of the fastcall calling convention on modern machines is trascurable or, in some cases, it could slow the execution more than a cdecl or stdcall.
I'd be curious to see the source as I can't think of any way fastcall could be slower than stdcall (and even less than cdecl).
As we speak of modern architectures, all the recent 64bit ABIs (windows64, system v amd64 / linux64, ...) have all removed the multiple calling convention standards and have opted for a unique one akin to fastcall.
I'm not a repository geek, and I don't know how to use git or mercurial or bitbucket.
Since you gave me write permissions, I would use sourceforge if possible.
May be I could create a folder in a branch...as soon as I decide the name of the library
Sure, but I was planning on putting the svn repository on read-only for history purposes and there's no more development happening there. Everything has been moved to http://code.orx-project.org.
I'm using mercurial for orx/scroll myself but sausage is using git for his own projects, for example.
It also makes work and sharing between multi-contributors much more easy and practical than svn did.
If you're curious I'd recommend http://hginit.com for a smooth transition.
Hey Ainvar, happy to get even an incomplete copy honestly; I've a weekend ahead with only my tethered phone for internet (1.4kb/s MAX) so I'm more than happy to use my time to hack on orx + c#
By the way; I hope to use your work as a basis for making a 'wrapper' like Scroll. ie: not just a direct wrapper, but rather a 'tools and features' system on top of orx. Just in case you're curious why I am so interested.
Some guys at Microsoft said that the benfit of the fastcall calling convention on modern machines is trascurable or, in some cases, it could slow the execution more than a cdecl or stdcall.
I'd be curious to see the source as I can't think of any way fastcall could be slower than stdcall (and even less than cdecl).
As we speak of modern architectures, all the recent 64bit ABIs (windows64, system v amd64 / linux64, ...) have all removed the multiple calling convention standards and have opted for a unique one akin to fastcall.
I'm not a repository geek, and I don't know how to use git or mercurial or bitbucket.
Since you gave me write permissions, I would use sourceforge if possible.
May be I could create a folder in a branch...as soon as I decide the name of the library
Sure, but I was planning on putting the svn repository on read-only for history purposes and there's no more development happening there. Everything has been moved to http://code.orx-project.org.
I'm using mercurial for orx/scroll myself but sausage is using git for his own projects, for example.
It also makes work and sharing between multi-contributors much more easy and practical than svn did.
If you're curious I'd recommend http://hginit.com for a smooth transition.
Grey, it seems we're on the same boat but with slightly different destinations
Me too I was thinking about a scroll like library, but before all I'd like to:
1 - import all orx functions
2 - build classes as wrappers orx modules
3 - build a scroll-like binding system
Actually I'm near completion of point 1 and I've done a pair of classes of point 2 just for testing.
We could join our forces to complete point 2 and 3 (and correct point 1 where needed) in order to haev a fully functional library.
I need this library to have a full orx integration inside OrxStudio.
Basic function import is good but a binding system is much more better.
haha, looks like we're definitely headed in the same direction. I would be happy to collaborate on this, as I hope to use the library directly in game-dev, rather than indirectly (through Orx Studio) and the two uses seem like a good match to me.
I wanted to say that I don't remember where I read about fastcall but I remember the poster (it was on a forum) was a M$ Visual C++ Team guy.
Anyway, the problem is still that .NET does not support fastcall on 32 bit
And about hginit I wanted to say it's really well done, idiot proof...so with a some (huge) effort I could be able to understand some basics
When it will be the time to release something I'll try to use it.
And about hginit I wanted to say it's really well done, idiot proof...so with a some (huge) effort I could be able to understand some basics
When it will be the time to release something I'll try to use it.
Well, if you have any questions regarding hg or orx's repository, don't hesitate!
a first version of the C# wrapper for orx is available.
It's called NetOrx and you can find it here: https://bitbucket.org/orx/netorx
To use it you must compile orx using __orxFREEBASIC__.
We still have to solve a problem with delegate relocation so if you need to use callback, declare a static method and then use it in orx.
Example:
declare the static event handler:
private static orxEVENT_HANDLER objEvtHandler = new orxEVENT_HANDLER(OnObjectEvent);
Use it with orx:
orxEvent.AddHandler(orxEVENT_TYPE.orxEVENT_TYPE_OBJECT, objEvtHandler);
and implement the handler, of course:
public static orxSTATUS OnObjectEvent(orxEVENT_Ptr _pstEvent)
{
return orxSTATUS.orxSTATUS_SUCCESS;
}
The code can't be considered as tested.
We're going to clean it to make it more C#-ish and we need some users to use/test it.
Comments
Just rewrote a fake GLFW that exports a function.
orx.dll exports my function and i've just to map it into c#
Now the hard work begins...i've to implement in c# all the glfw functions that were called by orx.
--- edit ---
Enis, to answer you, i've what you wrote, just organized the callbacks into a structure so c# sends the structure filled with right pointers, and the plugin does a memcpy to it's own copy.
Cheers
I can receive all callbacks from the C# side. Now all I have to do is to re-implement the OpenGL window in C#, and all tha black magic stuff the GLFW was doing for window handling and managing.
The cooking recipe wanted:
- 500 gr of fake GLFW plugin with a new exported (__dllexport) API used to save a structure full of functions pointer to call back when orx calls needed GLFE functions.
- 20 gr of C++ native library to implement nasty orx starter (needed because I could not rewrite orx_execute in c# due to _orxDebug_init and other stuff.
- 1500 gr of prepared orx imports for C#
- 300 gr of prepared orx interface library imports for C#
Take all an mix for 5 developing hours, then place fresh on the plate and have fun preparing the sausage.
Cheers
I'm watching your progress with excitement, and looking forward to tasting what you're baking for us!
Meanwhile, I've made a strange observation: (at least in linux)
When you statically link some functions into an executable, it's not possible to redirect these functions using LD_PRELOAD. This, I guess, would be expected by anyone familiar with what I'm talking about. But my strange observation happens when you try to statically link a function in a shared object, and then later LD_PRELOAD that function. Magically, even though the shared object has been compiled to link it statically, the functions in the pre-loaded shared objects replace the original ones!
To be explicit, here's what I've tried:
Now, is it just me, or does that mean that we can inject our glfw fake implementations simply through an LD_PRELOAD (and hopefully windows and mac equivalents)?
Writing a fake GLFW seemed to me as the best way from the start. I did not consider it could be done in C# and dynamically loaded at run time. Simply amazing :woohoo: .
Out of curiosity what are you planning to use to implement an opengl control in C#?
Cheers,
Graag
There are options on windows, none good though
Edit: by the way, awesome project guys, Looking forward to seeing what comes out of it. (c# bindings *drool*)
On Windows, the problem isn't that bad anyway. We can distribute the orx.dll modified to accommodate the editor. Likewise in Mac OS. In Linux, however, we have to force the user to build from source. That in theory, means that we need to distribute the orx source entirely, the version that is known to build with our plugin. With the LD_PRELOAD approach, we will need to either:
- Distribute no native binaries at all (if C# can inject its callbacks as symbols)
- Distribute a libFakeGLFW.so to be preloaded. This is possible, because a dummy shared library will only depend on glibc and other very fundamental stuff that is probably the same on all linux systems.
- Distribute a very simple source code to compile libFakeGLFW.so, but it will be VERY simple to generate it since it has no dependencies. Just a .c file to compile (We'll probably do that before starting the studio for the first time.)
All of this really simplifies our source tree and the build process. It's also much more future-proof on all platforms.
@grey: to my knowledge there are 2 ways do implement the same thing in windows.
The first one is the same used in some trainers for games : trojian dll.
You must provide a fake dll with the same name to the one you're emulating and the same exports. This dll must be in the same path of executable and it's used to override only wanted functions.
The second is hooking. You can patch the loaded dll and inject your functions.
In the first case it's impossible to use only C# as you need a native dll.
In the second case it's possible to do that in C#, but it's platform dependent and it's really a mess.
C# it's not the tool born to make memory patching and function hooking
None of the mentioned functions would work in our case because when you compile with "embedded" orx option there is no plugin.dll and no glfw.dll.
If none of this functions exports symbols it's not possible to make any function hooking as it's damn hard to get the address of the functions you wanna hook.
@enis: abour your points: C# can inject but as said, for embedded compilations, it's really long and hard.
If the linux distro is an lsb you could be right. What about different glibc versions? there are more than one glibc out there.
We could distribute the library ready to link, and link it ony on installation, but as i said, on my "old" machine it takes 30 seconds to build orx and less than 5 to build my fake glfw.
Why become crazy about that?
Today I don't have much time to work on the callbacks side. I guess I'll ask you a lot of opengl stuff to understand a pair of things
Cheers
right now I have a semi-working orx window.
All compiles, all callbacks are called, the opengl window is up and running and I implemented quite all glfw functions needed by the orxDisplay, orxMouse, orxJoystick and orxKeyboards plugins.
I still have to clean a lot of stuff because I had to use platform dependent stuff but it will be easy to correct.
If I find the time, this evening I try to port bounce and scroll demos in C# to see if they work.
Bye bye
As you can see in the attached image, I can load Grey's config file, and display it with the new plugin.
I sill have to take care about few details to improve the usability of the OrxWidget class (the one that's rendering the scene) and I have to solve a little bug about resizing (may be I missed something from glfw).
The example it's only 3 lines of code:
OrxNative.orxViewport_CreateFromConfig("Viewport");
OrxNative.orxConfig_Load("StaticScene.ini");
OrxNative.orxObject_CreateFromConfig("Scene");
During the week I hope to give you more good news.
--- edit ---
I corrected a bit the resizing. I still have a problem.
When I resize the window, I see the contents are zooming.
Do you have any idea?
Bye Bye
Looking forward to trying it out
Cheers
Good luck.
I'm at 50% of the library to interface orx library from managed code.
I ported all the public structures and all functions based on version 1.3 (because I used code from Ocean).
I'd like to synch all my imported functions with all the functions the actual orx code exports.
Tomorrow I think I'll have a fully working library that could allow full usage of orx calling the APIs from C#.
The other 50% I'd like to do is to divide the code in classes. I mean orxViewport_Create should be a "Create" static method of orxViewport class and should return a new instance of orxViewport.
That could allow a cleaner OO coding if compared to the actual call to orxNative.orxViewport_Create().
I'd be really happy if someone could help me discovering changes in:
- exported orx apis
- public structures
- enums
All I need is a test file with the names of modified things in a human readable format, rather than a diff file
Cheers
I forgot to tell you all that there's a little disadvantage in using C# with orx.
You have to recompile orx to make it to don't use fastcall calling convention (__orxFREEBASIC__ does it).
As stated by Microsoft documentation for .NET 4.5 the FastCall calling convention is not supported.
Some guys at Microsoft said that the benfit of the fastcall calling convention on modern machines is trascurable or, in some cases, it could slow the execution more than a cdecl or stdcall.
@iarwain: I'm not a repository geek, and I don't know how to use git or mercurial or bitbucket.
Since you gave me write permissions, I would use sourceforge if possible.
May be I could create a folder in a branch...as soon as I decide the name of the library
I'd be curious to see the source as I can't think of any way fastcall could be slower than stdcall (and even less than cdecl).
As we speak of modern architectures, all the recent 64bit ABIs (windows64, system v amd64 / linux64, ...) have all removed the multiple calling convention standards and have opted for a unique one akin to fastcall.
Sure, but I was planning on putting the svn repository on read-only for history purposes and there's no more development happening there. Everything has been moved to http://code.orx-project.org.
I'm using mercurial for orx/scroll myself but sausage is using git for his own projects, for example.
It also makes work and sharing between multi-contributors much more easy and practical than svn did.
If you're curious I'd recommend http://hginit.com for a smooth transition.
By the way; I hope to use your work as a basis for making a 'wrapper' like Scroll. ie: not just a direct wrapper, but rather a 'tools and features' system on top of orx. Just in case you're curious why I am so interested.
Me too I was thinking about a scroll like library, but before all I'd like to:
1 - import all orx functions
2 - build classes as wrappers orx modules
3 - build a scroll-like binding system
Actually I'm near completion of point 1 and I've done a pair of classes of point 2 just for testing.
We could join our forces to complete point 2 and 3 (and correct point 1 where needed) in order to haev a fully functional library.
I need this library to have a full orx integration inside OrxStudio.
Basic function import is good but a binding system is much more better.
Cheers.
I wanted to say that I don't remember where I read about fastcall but I remember the poster (it was on a forum) was a M$ Visual C++ Team guy.
Anyway, the problem is still that .NET does not support fastcall on 32 bit
And about hginit I wanted to say it's really well done, idiot proof...so with a some (huge) effort I could be able to understand some basics
When it will be the time to release something I'll try to use it.
Bye bye
Well, if you have any questions regarding hg or orx's repository, don't hesitate!
a first version of the C# wrapper for orx is available.
It's called NetOrx and you can find it here: https://bitbucket.org/orx/netorx
To use it you must compile orx using __orxFREEBASIC__.
We still have to solve a problem with delegate relocation so if you need to use callback, declare a static method and then use it in orx.
Example:
declare the static event handler:
private static orxEVENT_HANDLER objEvtHandler = new orxEVENT_HANDLER(OnObjectEvent);
Use it with orx:
orxEvent.AddHandler(orxEVENT_TYPE.orxEVENT_TYPE_OBJECT, objEvtHandler);
and implement the handler, of course:
public static orxSTATUS OnObjectEvent(orxEVENT_Ptr _pstEvent)
{
return orxSTATUS.orxSTATUS_SUCCESS;
}
The code can't be considered as tested.
We're going to clean it to make it more C#-ish and we need some users to use/test it.
Ciao!