MOGRE Next Generation!

Marioko

16-02-2008 00:00:08

Ok.. i created this thread specially to talk about MOGRE future, in a previous thread (the multi-thread issues thread) i said that will be nice make MOGRE again from scrath avoiding all the bad things that actually have. The main topic is MOGRE without touching OGRE (C++) code. Like anothers plugins or addons for OGRE, the next generation of MOGRE will only need pure C++/CLI code and references to OGRE's libs.

This will be a huge project, but is totally posible and if we work hard we could make it.

An important starting point that we already had is Cpp2Java tool, its can make a xml file with all the OGRE headers descriptions. Basically we will only need build another and better AutoWrapper tool (we can reutilize the current, but i think is easier a new one) that can generate MOGRE C++/CLI headers and implementation code. In that way is how Ogre4j is created. Only a tool for generate code without touch OGRE.

I expect suggestion and comments, specially about design stuff and ideas about this. Also if this project start, we will need more people to code.

Ahh. The code name of this project is MogreNG (next gen..) :P

Thanks 8)

PD: Sorry my english :roll:

dodongoxp

16-02-2008 03:16:39

impressive!! :D

pin

16-02-2008 08:26:57

MogreNG (next gen..)

Why do we need a new name? Can't it stay to Mogre?
The current release is 1.4.6 right? make the new release 1.4.6.1 and add a mention in the wiki how things are different in the new release (for those who care, I'm sure most don't) The name doesn't make the library better/cooler. A newb won't understand what' you're talking about anyways. Lets say in a couple months you decide to make more changes on how Mogre works, how are you going to call it MogrLNG (Mogre Latest Next Generation)? I vote for sticking to Mogre

pin

16-02-2008 08:29:15

Everyone knows what Mogre is let's not change that

Marioko

16-02-2008 13:40:53

The code name of this project is MogreNG
CODE NAME.. means codename or alias or whatever.. not the real name, offcourse the name will be the same: MOGRE hahaha :D

It just for make the diference.... 8)

pin

16-02-2008 17:12:33

The code name of this project is MogreNG
CODE NAME.. means codename or alias or whatever.. not the real name, offcourse the name will be the same: MOGRE hahaha :D

It just for make the diference.... 8)


got it. It's nice if you don't change the name of the project

dodongoxp

16-02-2008 19:34:06

yeah.. code names are just internal names that makes references to a specific version commonly under development.. like the visual studios .. 2005 was whidbey and 2008 was orcas.. just as there is ogre dagon, eihort and shogoth

vista was called longhorn for some time

so the new version of mogre can be called MogreNG as a reference to the new built from scratch mogre project and not the actual version of mogre..

codenames usually are removed when the products gets his final name or simply is replaced with the product version as it was with visual studio


just to clear the things out 8)

daedius

16-02-2008 20:55:04

I think you could totally rock the community if you made this wrapper work for both Mac and Linux as well. Do you think its possible with this new approach?

Game_Ender

16-02-2008 21:13:24

That sounds like a cool idea. If you use the same technique as Ogre4J then the result will be cross platform. Which would be very cool. Heck you could even use IronPython with it.

Marioko

16-02-2008 23:05:58

The problem with cross platform is Mono (.NET for linux) dont support C++/CLI or something like it.. Ogre4j is cross platform because Java is cross platform (windows, linux,mac,solaris,..)

Game_Ender

17-02-2008 02:02:32

Wait, why would you use C++/CLI? How do you think Ogre4J does it? It uses the cross platform JNI interface. You can do same thing with the CLR's ability to call native C libraries. The first version of Ogre for the CLR (OgreDotNet) used SWIG to generate the needed C wrappers, it was able to run on Linux just fine.

daedius

17-02-2008 02:32:30

Nods, yes, I remember this as well, SWIG being the foundational key the OgreDotNet. I think crossplatform support of Mogre into mono is really what is needed to take this project to the next level. Does anyone here know at a highlevel what it would take to accomplish such a feat?

Marioko

17-02-2008 14:48:38

The big diference between JNI, Native C calls and C++/CLI is last one (c++/cli) can mix native and managed code in the same file, using c++ style language and the final assembly can be use it in any .NET CLR language. In this way the performance is better, because the compiler is diferent than C# compiler and make better optimizations to IL code.

About SWIG, ¿why do you think that OgreDotNet is died?? the last comment in its forums was in octuber 2007. Read this: http://www.ogre3d.org/wiki/index.php/OG ... connection

In our case we need to do the same that OGRE-MOGRE interconnection, but without touch OGRE code.

I know that cross platform mogre is need it, but make MOGRE for linux or mac means another project. If mono could support mix C++ native unmanaged code with managed code we could make it. I was reading in mono-project and their programmers are working in that.. :roll:

Zool

17-02-2008 16:10:33

In our case we need to do the same that OGRE-MOGRE interconnection, but without touch OGRE code.
How are you going to do the same "OGRE-MOGRE interconnection" without touching Ogre's source, I mean are you sure it's possible ?
Any ideas on the technical details ?

Marioko

17-02-2008 17:26:42

that is the question!! i dont know yet, but the solution must be over there :D

That is the reason of this topic 8)

Zool

17-02-2008 19:28:53

Ok, but let's assume for a moment that the things described in the "OGRE-MOGRE interconnection" are not possible without modifying Ogre (or else why would the creator of Mogre get into the trouble of maintaining a separate Ogre codebase), should Mogre continue without them ?

For example (as described in the "OGRE-MOGRE interconnection" page):
MovableObject object = sceneNode.GetAttachedObject(0);
if (object is Entity)
{
...
}
else if (object is Camera)
{
...
}
else
{
...
}

This works with the current Mogre version. Now, let's assume again that the new version doesn't modify Ogre, thus the object returned is of class 'MovableObject', how can we get the real subclass ?

One way is to add an explicit cast overloading function in Mogre code so that the developer can do this:

Camera cam = (Camera)object;
which will internally create a new 'Camera' object and pass it the native pointer from 'object'. But what if 'object' is not really a 'Camera' ? A check should be added in the internal cast conversion function that uses dynamic_cast<>, so that if the native object is not of the right class, then an exception will be raised.

So, to sum up, the options are:
-Go with the modified Ogre
-Advantage: "OGRE-MOGRE interconnection" works great as it is now
-Disadvantage: Maintaining a separate Ogre build is trouble

-Go with unmodified Ogre:
-Advantage: Using Ogre from Ogre SDK, no separate build
-Disadvantage: Performance hit; 1) new objects created for each function call and for cast conversions, 2) expensive dynamic_cast<> to keep the castings safe (maybe keep dynamic_cast<> only for debug build, and remove it from release, and keep faith that the program won't get screwed by a wrong cast)

Any thoughts on the above ?

Marioko

17-02-2008 19:49:28

thanks for your comment.. i was thinking in the same..

i repeat it again, this thread is exactly for that, see if we can build a better mogre, if not then i continue mantaining current implementation. Disadvantages you write are real, and is an important thing to think. About Mogre creator (Bekas) we dont know when he come back.

In this fase, we are looking if this project is realizable and that kind of post are very useful. :D

[EDIT]
BTW, the inheritance problem can be solved using another design, but i dont know yet is that is more expensive.. in next comment i try to explain this aproach..

Kodachi_Garou

18-02-2008 11:50:43

Hi all,

I've been away for a few days, but I think there are some very important points on the table that we have to clear up for MogreNG to go forward.

I've had some previous experience with the design of wrappers for the .NET environment both in function-call type libraries and object oriented libraries and there are some critical design points I've encountered in both types (OGRE is of course an object oriented library).

One of the main problems any object oriented wrapper has to solve is how to establish a 1:1 mapping from unmanaged pointers to managed wrapper instances.

This means that when an unmanaged object from the library is first created, a corresponding wrapper instance is also created and is the same throughout the lifetime of the object.

The main obstacle to doing this are the unmanaged containers, since they can keep pointers to unmanaged objects even if the managed wrapper instances go out of scope. The easiest way to solve this is to create a GCHandle referencing the wrapper instance and store its pointer somewhere in unmanaged memory, as close to the unmanaged object as possible, so we can retrieve it anywhere in the code using just the native pointer. The GCHandle can also stop the garbage collection from collecting the managed wrapper instance as long as the handle is active. When the explicit destruction methods are called, the GCHandle can finally be freed and the GC will collect the wrapper instance.

In some libraries this can be very easy, since it is often common practice to provide place-holder pointers called "UserData" or something like that where we can put the GCHandle pointers.

Unfortunately, OGRE doesn't seem to provide these place holder pointers for all its objects. Some classes have it, like the MovableObject, but not all of them. The MOGRE way uses the possibility of modifying the OGRE source code to automatically inject these hooks onto the library, using them to assure that all its wrapper instances are the same.

This is indeed a very clever way, and I don't see it as a real issue, as long as the code can be automatically generated from OGRE's original source. I would be more concerned with cleaning up the source code as it is, to ensure that there are no more bugs or inconsistencies deriving from all the obscure macro expansions.

Without these kinds of hooks, the wrapper itself will become much more complicated and probably suffer from a severe decrease in performance, since additional methods must be called in to solve the 1:1 mapping.

I'll try and think about it some more, though, and I'll keep in touch as the discussion evolves.

Best regards,

Gonçalo

Zool

18-02-2008 13:38:20

Another point for keeping the modified Ogre is this:

Every Ogre object gets this destructor (from CLRObject.h)
virtual ~CLRObject()
{
if (_handle != 0)
{
_FreeCLRObject(_handle);
_handle = 0;
}
}


_FreeCLRObject is (from CLRObject.cpp)
void _FreeCLRObject(void* handle)
{
GCHandle g = __VOIDPTR_TO_GCHANDLE(handle);
if (g.Target != nullptr)
{
// Set _native pointer of CLR object to 0
static_cast<Mogre::Implementation::Wrapper^>(g.Target)->_native = 0;
// Dispose the CLR object
delete g.Target;
}
g.Free();
}

So when an Ogre object is destroyed and there is a managed wrapper for it already created, the managed object gets disposed and its native pointer is set to null.

This is useful because if you keep a managed wrapper around and its native object is destroyed from the Ogre side, the next time you try to use it you'll get a NullReferenceException (since the native pointer will be 0), instead of using a native pointer that is not valid anymore (big no no).

Marioko

18-02-2008 16:24:02

i was reading more about this... Zool and Kodachi_Garou are right, the main problem is the 1:1 relation and destroying object . I was thinking in create a NativePointer/ManagedPointer map in managed side (C++/CLI) where keys are native pointers and values are managed pointers, then when a native container like Ogre::SceneManager return a native pointer like Ogre::SceneNode we just need find in the map the managed reference. Something like:


node* = scnMgr->getSomething("name"); //native
mngNode^ = map->get(node); //managed
return mngNode;


But i dont know if that is slower than current implementation... :d

This only "can solve" one part of the problem 1:1, but we cant know yet when the native object is destroyed. Mmm but the only idea i have right now is create native proxy subclass with just a destructor, this destructor notify managed wrapper and map the destroy event.. :oops:

These are only simple ideas, in this moment the main solution is keep ogre with modified code but improve its code like Kodachi_Garou and Zool said.