Introduction to PyOgre
Original version by Clay Culver
Updated by Andy as part of the Python-Ogre project
Table of contents
Thank you for trying Python-Ogre We have been working hard trying to bring Python-Ogre to a stable and usable state, and have made this happen for the Windows and Linux ports — with OSx comming soon. There are a few things you should know before getting started with the rest of the tutorials though, and this page should give you a crash course in everything you need to know before starting to work with Python-Ogre.
Brief History and Why SWIG <Outdated>
Ogre is a 3D rendering engine written entirely in C++. It supports an impressive feature set, and has been used with great success to create even more impressive games. Ogre has had Python bindings for a very long time using Boost.Python. These bindings changed ownership over time as people gained and lost interest in maintaining them.
In early 2005, I was approached by Federico Di Gregorio (fog), who wanted to get the Boost.Python version of PyOgre working under Linux. This may sound like a simple task, since both Ogre and Boost.Python are cross platform libraries, but it turned out to be an extraordinarily daunting task due to the complexity of Ogre. The generated interface wrappers needed large amounts of manual editing to compile under even the most recent versions of GCC. After literally a month of hard from myself and fog (mostly fog), we were at the end of the rope. Boost.Python does some very nice things, but its template magic just could not understand some of the constructs that Ogre used. Fog then approached me with the idea of doing a complete rewrite using SWIG instead of using Boost.Python. He finally convinced me, and we began work in early April 2005 to rewrite the library. I'm very happy with the results.
PyOgre Binds C++
The most important thing to remember about PyOgre is that it is a binding of a C++ library. Ogre is extraordinarily fast and flexible, and PyOgre inherits that speed and flexibility from its parent project. Since Ogre is cross platform, this gives the immediate advantage that PyOgre is also cross platform. It will currently run under Windows and Linux, and we have heard reports that it is possible to compile and run it under Mac OS X. However since neither myself or fog use a Mac (and no one has stepped up to offer help in that area), there is no direct support (or packages) for it.
This speed and flexibility comes at a price though. Ogre is certainly a C++ library, and even though we have done what we can to make it more Pythonic (such as changing get/set methods into Python properties, wrapping iterators, etc), there will always be parts of the library where it could look a lot better had it been implemented in pure Python. If you find a part of the library that you think could use polishing, let us know. The second problem with binding a C++ library is that there is the possibility of hard crashes (segfaults under Linux, memory access violations under Windows). These should hopefully be few and far between, and we fix these every time we find one. I just wanted you to be aware that this can happen, and that we'll fix it as soon as possible if you https://developer.berlios.de/bugs/?group_id=3464 open a bug or post in the forum describing the problem.
We have built this library using SWIG, and SWIG sometimes does some strange things. They do not really affect the normal use of the library (and you can safely ignore all of them), and you should never actually run into them, but I wanted to mention what they were in case you run across them and ask "what the heck is this for?".
Swig does not generate a coherent Python/C module that is imported. Instead it generates a Python/C module that requires a large amount of Python code to drive it. This is what you will see if you actually open up and inspect the ogre.py that is imported. A few things to note:
SWIG adds a few additional members to each class. The "thisown" variable is either true or false depending on if Python or C++ owns the particular variable. This is used for freeing allocated memory. Some classes also have disown methods as well. This does something similar to the "thisown" variable, but calling it has consequences when you are dealing with C++ callbacks. In general, you should never modify "thisown" or call disown, and forgetting they ever exist is probably the safest thing to do.
SWIG also creates a Ptr class for each C++ class. So the class Entity will have a corresponding EntityPtr, the Node class has a NodePtr class. These are for internal SWIG mechanics, and you should just ignore them. They should never actually be returned from any function or needed as a parameter for any function.
Both Ogre and CEGUI are huge libraries with expansive documentation. Keeping the library up to date with exactly correct docstrings would be near impossible. Instead we rely on the C++ Ogre API reference for our API documentation. With this said, the library does have docstrings which are very helpful.
For functions, it gives the parameters and return values. This gives you a quick idea of how to use a function. If you need to know what the function actually does, you should consult the Ogre API reference. For example, lets say you needed to know information about SceneNode.rotate. You can consult the builtin help to see what parameters you need to call it with:
>>> help(ogre.SceneNode.rotate) Help on method rotate in module pyogre.ogre: rotate(*args) unbound pyogre.ogre.SceneNode method rotate(self, Vector3 axis, Radian angle, TransformSpace relativeTo=TS_LOCAL) rotate(self, Vector3 axis, Radian angle) rotate(self, Quaternion q, TransformSpace relativeTo=TS_LOCAL) rotate(self, Quaternion q)
If you have a question about how to use it, then you can consult the API reference for SceneNode, which contains a description of what the function actually does:
virtual void rotate (const Vector3 &axis, const Radian &angle, TransformSpace relativeTo=TS_LOCAL) Rotate the node around an arbitrary axis. virtual void rotate (const Quaternion &q, TransformSpace relativeTo=TS_LOCAL) Rotate the node around an aritrary axis using a Quarternion.
As I mentioned before, all of the get/set methods in Ogre have been wrapped into attributes. So if you are trying to use a get/set method you see in the C++ API Reference, just assign it directly instead of trying to call the methods:
# You could do it this way:
sceneNode.position = ogre.Vector3(100, 200, -150) # But this is nicer: sceneNode.position = (100, 200, -150) # python tuples can be used instead of Vectors
If you are unsure of an attribute, use the builtin help on it:
Help on property:
Node.position -> Ogre::Vector3 This is equivalent to calling the C++ Ogre methods: get: Ogre::Vector3 Node::getPosition() set: void Node::setPosition(Ogre::Vector3)
We have debated putting the actual C++ API reference into PyOgre itself, but this would require a very large overhead in space/memory that the library would take up, and we would have to jump through a lot of hoops to make SWIG generate the proper docstrings. We still plan to come back to this at a future date to try to make the docstrings more useful, but right now we are focusing on other issues with PyOgre.
Versions and API Stability
PyOgre actually consists of two libraries. The first being http://www.ogre3d.org Ogre (which is a 3D rendering engine), the second is http://www.cegui.org.uk CEGUI (which is an embedded GUI system). These two projects are independent of each other, and they are at differing levels of stability.
Ogre has been marked stable as of release 1.0.0. The core API will not change on a patch revision (meaning it won't change from 1.0.0 to 1.0.1, but it does change from 1.0.0 to 1.1.0). This means that PyOgre should not change on patch revisions either, but we are at the mercy of Ogre maintainers for that.
CEGUI is not as old, and has not been marked stable. They can, and frequently do, break interfaces of the library. Be aware of this if you decide to use CEGUI.
Also note that Ogre and CEGUI are completely independent of each other. You can use Ogre with a different widget set (or write your own). You can also use CEGUI with PyOpenGL instead of Ogre.
GUIs and Other Libraries
A quick note about GUIs. Ogre can take care of creating a window for you on whatever platform you are using. If you do not wish to use that feature, you may create your own window and embed PyOgre within it. There are demos in the demos/ directory which show you how to embed PyOgre in a wxPython window. I believe fog has also had good success using pyGTK as a GUI system for PyOgre as well.
If you are looking for an embedded GUI (something that runs from within the rendering environment), you should use CEGUI. I do not know of any other embedded GUI that works with Ogre.
Speeding up PyOgre
Some people go on and on about trying to optimize and speed up their PyOgre applications. I believe pyogre is already faster at 3D rendering than other Python 3D engines. However, if you are still concerned there are really only two things you need to know. First of all pysco (a Python JITer) works great with PyOgre. It can speed up the execution of python code by an astonishing amount. The second thing you need to know is that the overhead in calling any ogre function is significant. So you should probably keep most of your math operations in psyco optimized code. Or, if you are really concerned about it, push your heavy math operations in C/C++ code.
The best way to get help is to ask in the PyOgre forums. I can't promise that fog and I know everything about Ogre, but we try our best at figuring out what the problem is and how to fix it. Also, since C++ Ogre code can be converted very easily into python code, if we can't solve the problem the easiest thing to do is to ask in the C++ Ogre forums and the response you get there can easily be translated into their equivalent Python constructs.
Thanks, and enjoy PyOgre.
Alias: Introduction to PyOgre