For a long time I've been in the awkward position of being a C# lover, yet also loving graphics programming.
I've tried doing my own engines, and have done some things that are pretty decent (imho), but well, making your own engine is time consuming. I know I can do it, but my free time isn't limitless. So not long ago I decided to use existing engines.
To my knowledge the only native C# choice is Axiom. It's a good engine, it's only problem is that the C# port of CEGUI seems to be broken/bugged. And since I know from previous experience how much coding a gui sucks, this was enough to make me lose interest. Axiom's development seems far less active than Ogre's anyways.
So I tried using Ogre via managed c++. This worked well, up to a point. Namely, RenderWindow.isClosed always returns true in managed c++. I've seen it mentioned before, and the dev who replied was uncertain as to what caused this. I've looked at the source myself, and see no reason for it. I was able to run Ogre in a .NET form, but I thought, if something that trivial doesn't work, what else will I find doesn't work?
Enter an unmanaged wrapper. Ironically, it consists of making a simple c front end for ogre and sticking it in a DLL. Then you can call those c functions from c# (or any other language capable of external declarations). It's not hard to do with visual studio. Create an unmanaged DLL project. Configure the project like you would any Ogre application, and you'll be presented with a DLL main function.
The tricky part is making functions external. Declare this in an include file somewhere:
- Code: Select all
#define export extern "C" __declspec(dllexport)
Then create a wrapper (Camera in this case):
- Code: Select all
#pragma once
#include "Ogre.h"
#include "export.h"
using namespace Ogre;
export void CameraLookAt( Camera * camera, float x, float y, float z )
{
camera->lookAt( x, y, z );
}
Then from C# you can access it as so:
- Code: Select all
using System;
using System.Security;
using System.Runtime.InteropServices;
namespace OgreNet
{
public class Camera
{
protected IntPtr Unmanaged;
public Camera( IntPtr ptr )
{
this.Unmanaged = ptr;
}
[DllImport("Ogre.Glue.dll", EntryPoint="CameraLookAt"), SuppressUnmanagedCodeSecurity]
private static extern void _LookAt( IntPtr camera, float x, float y, float z );
public void LookAt( float x, float y, float z )
{
_LookAt( this.Unmanaged, x, y, z );
}
}
}
Naturally you'd also need to wrap a SceneManager to obtain a pointer to a camera object.
I know this is ugly, and those of you who hate wrappers are probably laughing, but there are a few good things to say about it.
1) The performance loss from wrappers on a modern computer is negligable anyways.
2) Most of the cpu intensive stuff is going on internally in the Ogre library anyways, the wrapper is just needed to set things up and make changes each frame.
3) Development time, development time, development time. Coding is fast in c#s simpler syntax, and debugging a .NET application is WAY easier.
4) Using an unmanaged wrapper would allow for crossplatform goodness (mono doesn't have a managed c++ compiler yet and probably won't for some time).
5) It works, perfectly. No annoying inexplicable bugs like in managed c++.
This is just a test case for now. At some point I'm going to try whipping up a program that parses through Ogre's source and generates the source for the wrapper from it. That would be a lot of work, but less than manually wrapping it function by function, class by class.
Thoughts? Naturally if you don't use .NET this won't interest you, but I've seen lots of posts by .NET users inquiring about this sort of thing.






