Python bindings, anyone?
Hi there, I've just started writing bindings for Ruby, using Swig, for the Mac. I hit a problem trying to wrap createDevice. I havejustinian wrote:I recently started work on a SWIG python binding for Irrlicht, for my own uses. If anyone's interested, let me know.. there's not too much there so far, but it at least runs the basic model-loading example.
This is a direct wrapping of the Irrlicht API for Python, not a framework or other engine with Python bindings. I'm aiming to make it pythonic at least on a basic level (eg, being able to pass a tuple of ints for a vector2d<s32>, etc) but not so far as pyOgre went with things (eg, making set/get methods into properties, straying from the C++ API to make it more pythonic..).
If anyone else has gotten further than I have on something similar, I'd also love to see what they've got!
Code: Select all
IrrlichtDevice* createDevice(
video::E_DRIVER_TYPE deviceType = video::EDT_SOFTWARE,
const core::dimension2d<s32>& windowSize = core::dimension2d<s32>(640,480),
u32 bits = 16,
bool fullscreen = false,
bool stencilbuffer=false,
bool vsync=false,
IEventReceiver* receiver = 0,
const char* sdk_version_do_not_use = IRRLICHT_SDK_VERSION);
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_0(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_1(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_2(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_3(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_4(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_5(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_6(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_7(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
irrlicht_wrapper.cpp: In function ‘VALUE _wrap_createDevice__SWIG_8(int, VALUE*, VALUE)’:
irrlicht_wrapper.cpp error: ‘createDevice’ is not a member of ‘irr’
Any clues?
try addingmacdonag wrote:That's within "namespace irr {}" of course.
Code: Select all
using namespace irr;
-------------------------------------
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
Nope, that wasn't it, it was already within that namespace. What actually was the problem was that I had an empty, local, irrlicht.h. So it actually wasn't pulling in the real irrlicht.h. Doh!zenaku wrote:try addingmacdonag wrote:That's within "namespace irr {}" of course.
Code: Select all
using namespace irr;
Getting a bit further now, but when loading the module into Ruby, I get the error:
dyld: NSLinkModule() error
dyld: Symbol not found: __ZNK3irr4core8aabbox3dIfE7isEmptyEv
Referenced from: ./irrlicht.bundle
Expected in: flat namespace
...It's a long shot, but anyone know what this could be related to?
dyld: NSLinkModule() error
dyld: Symbol not found: __ZNK3irr4core8aabbox3dIfE7isEmptyEv
Referenced from: ./irrlicht.bundle
Expected in: flat namespace
...It's a long shot, but anyone know what this could be related to?
....it turns out that including aabbox3d.h into the building of the library resolves this issue.macdonag wrote:Getting a bit further now, but when loading the module into Ruby, I get the error:
dyld: NSLinkModule() error
dyld: Symbol not found: __ZNK3irr4core8aabbox3dIfE7isEmptyEv
Referenced from: ./irrlicht.bundle
Expected in: flat namespace
...It's a long shot, but anyone know what this could be related to?
But I've got another one - how does anyone else wrap this:
Code: Select all
virtual void setWindowCaption(const wchar_t* text) = 0;
./test.rb:7:in `setWindowCaption': wrong argument type String (expected Data) (TypeError)
from ./test.rb:7
When making IrrLua, I had similar problems. My binding generator (tolua++) only understands std::string as a string type.macdonag wrote:
But I've got another one - how does anyone else wrap this:I haven't seen any info on wrapping wide chars. Does the wrapping method depend on the language we're wrapping for? I've seen the following error when attempting to use the wrapped version:Code: Select all
virtual void setWindowCaption(const wchar_t* text) = 0;
./test.rb:7:in `setWindowCaption': wrong argument type String (expected Data) (TypeError)
from ./test.rb:7
To make it work, I had to create wrapping classes for the strings.
I have a C++ method that looks like
Code: Select all
namespace irr
{
namespace cast
{
wchar *to_wchar_t_ptr(std::string s); //creates new wchar string from std::string
void delete_t_wchar_ptr(wchar *p); //deletes the wchar string
}
}
Then I have Lua code which wraps the raw binding.
Code: Select all
local _SetWindowCaption = irr.IrrlichtDevice.setWindowCaption
function irr.IrrlichtDevice:setWindowCaption(text)
text = text or ""
local caption = irr.cast.to_wchar_t_ptr(text)
_SetWindowCaption(self, caption)
irr.cast.delete_wchar_t_ptr(caption)
end
Hope this helps.
-------------------------------------
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
-
- Posts: 67
- Joined: Wed Aug 02, 2006 1:47 am
Jirr and Jython for Python bindings
Another possibility for python bindings is to juse jirr (http://sourceforge.net/projects/jirr/), the Java binding for Irrlicht, combined with Jython, which is a Python interpreter written in Java.anoki wrote:Pinball ...
i think it is great if you update venom to 1.1 .
It is working very well and why recode everything.
My c++ is really bad so i think that maybe i can do some
python coding or the website.
Python is a great language and it is used now in many
huge commercial projects like Civilisation 4.
Using Jython you just write Python code but you can access all Java libraries as if they were Python packages. So, theoretically, with Jython you could write Python and control irrlicht by calling the Jirr functions which then call the underlying Irrlicht C++ code.
Advantages:
* No need to maintain separate binding like Venom. We leverage off of the existing Jirr bindings.
* The Jython interpreter is pure Java byte code, so it can be distributed via Java Web Start (your Python code is distributed as *.py / *.pyc files along with the Jython interpreter). Your Python game, interpreted by the Jython interpreter, can then be started with a single click from the web. See http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=10247 for information on Java Web Start and Irrlicht.
Disadvantages:
* Maybe slightly slower (but actually Jython, a Java-implementation of Python, is supposed to be comparable in speed to a C-implementation of Python)
Now I haven't TRIED Jython and Irrlicht yet, but it seems attractive and theoretically it should worok. I'm going to give it a shot on the weekend. Anyone else interested, please try and post here how it goes.
-
- Posts: 67
- Joined: Wed Aug 02, 2006 1:47 am
It works: Python bindings through Jython and JIrr
I just wanted to report that I can successfully control Irrlicht through Python by using Jython and Jirr as I mentioned in my previous post.
Jython is a Python interpreter written in Java, instead of C. This means that Jython can access Java libraries, including Jirr.
I tested this on Ubuntu Breezy Linux. I still have some problems with Jirr crashing when certain functions are called (commented below with the word ERROR). This has nothing to do with Jython.
After getting Jirr (mostly) working, I then ran Jython 2.1 as follows:
The runme.jy file is basically a Python translation of Jirr's TestHelloWorld.java:
So as you can see, with Jython we can write Python code and call the Jirr Java API functions which connect to Irrlicht.
Jython lags a bit behind CPython (currently Jython is 2.1, while CPython is at 2.4), and it isn't 100% compatible (but it's like 99%) - there are some minor differences in socket handling, threads, etc. Now, if you absolutely must use CPython because of some special module not accessible through Jython, then my solution won't help you.
But if you're willing to use Jython, and you just want to write Python code to control Irrlicht, then Jython->Jirr->Irrlicht is a workable solution.
The Jirr bindings are generated with SWIG so they are likely to be easy to keep up-to-date. No changes to Jirr are needed to access it from Jython. That's the nice thing about this solution: the Java binding effectively gives us both a Java and Python binding through Jython.
Jython is a Python interpreter written in Java, instead of C. This means that Jython can access Java libraries, including Jirr.
I tested this on Ubuntu Breezy Linux. I still have some problems with Jirr crashing when certain functions are called (commented below with the word ERROR). This has nothing to do with Jython.
After getting Jirr (mostly) working, I then ran Jython 2.1 as follows:
Code: Select all
CLASSPATH=.:./lib/irrlicht.jar JAVA_OPTIONS="-Djava.library.path=." jython runme.jy
Code: Select all
true = 1
false = 0
null = None
from net.sf.jirr import *
import java
java.lang.System.loadLibrary("jirr")
device = Jirr.createDeviceJava(E_DRIVER_TYPE.EDT_OPENGL, 640, 480, 16, false, false, false, null)
device.setWindowCaption("jython irrlicht demo")
driver = device.getVideoDriver()
smgr = device.getSceneManager()
guienv = device.getGUIEnvironment()
text = "Hello World! This is the Irrlicht Software engine for Java!"
rect = recti(10, 10, 280, 30)
staticText = guienv.addStaticText(text, rect, true, true, null, -1)
mesh = smgr.getMesh("../media/sydney.md2")
node = smgr.addAnimatedMeshSceneNode(mesh, null, -1, vector3df(0,0,0), vector3df(0,0,0), vector3df(1,1,1))
if (node != null):
pass
# ERROR node.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, false)
# ERROR node.setFrameLoop(0, 99999)
# ERROR node.setMaterialTexture(0, driver.getTexture("../media/sydney.bmp"))
smgr.addCameraSceneNode(null, vector3df(0,10,-60), vector3df(0,0,0), -1)
step = 100
counter = 0
diff = 0
timer1 = java.lang.System.currentTimeMillis()
timer2 = 0
while(device.run()):
a = 0
r = 100
g = 100
b = 100
driver.beginScene(true, true, SColor(a, r, g, b))
smgr.drawAll()
guienv.drawAll()
driver.endScene()
counter = counter + 1
if (counter >= step):
timer2 = java.lang.System.currentTimeMillis()
diff = 1000.0 / ((timer2 - timer1) / float(step))
counter = 0
timer1 = java.lang.System.currentTimeMillis()
text = "This is the Irrlicht Software engine for Java! FPS: " + str(diff)
#ERROR staticText.setText(text)
device.closeDevice()
Jython lags a bit behind CPython (currently Jython is 2.1, while CPython is at 2.4), and it isn't 100% compatible (but it's like 99%) - there are some minor differences in socket handling, threads, etc. Now, if you absolutely must use CPython because of some special module not accessible through Jython, then my solution won't help you.
But if you're willing to use Jython, and you just want to write Python code to control Irrlicht, then Jython->Jirr->Irrlicht is a workable solution.
The Jirr bindings are generated with SWIG so they are likely to be easy to keep up-to-date. No changes to Jirr are needed to access it from Jython. That's the nice thing about this solution: the Java binding effectively gives us both a Java and Python binding through Jython.
On a swig note, I've got something for Ruby, but there are a few holes left. One of them is SEvent in IEventReceiver.h. There is an anonymous nested union. Swig claims such a construct is not supported:
Warning(312): Nested union not currently supported (ignored).
How has anyone else gotten around this? I could write an accessor for each element in the union, but was hoping there'd be something a little more elegant.
Warning(312): Nested union not currently supported (ignored).
How has anyone else gotten around this? I could write an accessor for each element in the union, but was hoping there'd be something a little more elegant.
There is no constructable EventReceiver class in Irrlicht. You are supposed to derive your own class. If you are making a language binding that supports events, you are going to have to derive your own class too.macdonag wrote:On a swig note, I've got something for Ruby, but there are a few holes left. One of them is SEvent in IEventReceiver.h. There is an anonymous nested union. Swig claims such a construct is not supported:
Warning(312): Nested union not currently supported (ignored).
How has anyone else gotten around this? I could write an accessor for each element in the union, but was hoping there'd be something a little more elegant.
Since you have to derive your own class anyway, you can also redefine how SEvent is handled and dispatched to your script. You don't really need your script to understand IEventReceiver or SEvent, only your derived class needs to.
SWiG probably doesn't support nested unions becuase most of the languages it binds to have no similar construct. In IrrLua, SEvent is a Lua table. Lua doesn't not have anything like a union, so I derived a class from IEventReceiver and then convert the SEvent to a lua table which the script uses. I then call the script and pass in the table.
-------------------------------------
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
IrrLua - a Lua binding for Irrlicht
http://irrlua.sourceforge.net/
The solution I've come up with is to extend the SEvent class with some accessors for the items in the union:
I also had to use a director for IEventReceiver, to allow Swig to generate the necessary code for me to create handlers within my scripts. As can be seen, I didn't wrap KeyInput.Char. It was giving me grief about wchar_t, and since I don't need it right now, I've not bothered looking further. This chunk of code does more than enough for now!
Thanks.
Code: Select all
%feature("director") IEventReceiver;
%include "IEventreceiver.h"
%extend irr::SEvent {
gui::IGUIElement* guiCaller() { return self->GUIEvent.Caller; }
gui::EGUI_EVENT_TYPE guiEventType() { return self->GUIEvent.EventType; }
s32 mouseX() { return self->MouseInput.X; }
s32 mouseY() { return self->MouseInput.Y; }
f32 mouseWheel() { return self->MouseInput.Wheel; }
EMOUSE_INPUT_EVENT mouseEvent() { return self->MouseInput.Event; }
//wchar_t keyChar() { return self->KeyInput.Char; }
EKEY_CODE keyKey() { return self->KeyInput.Key; }
bool keyPressedDown() { return self->KeyInput.PressedDown; }
bool keyShift() { return self->KeyInput.Shift; }
bool keyControl() { return self->KeyInput.Control; }
const c8* logText() { return self->LogEvent.Text; }
ELOG_LEVEL logLevel() { return self->LogEvent.Level; }
s32 userData1() { return self->UserEvent.UserData1; }
s32 userData2() { return self->UserEvent.UserData2; }
f32 userData3() { return self->UserEvent.UserData3; }
}
Thanks.
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Despite the fact that Java is pretty well suited as a language for beginners it is not that easy to really code efficient in Java. There are really many pitfalls which can easily make very good algorithms way slower than manual execution
But if you adhere to some professional Java programming guides, maybe apply some profiling (and maybe use Java 6 beta instead of Java 5) you can make programs that are more than competetive. One of my students just wrote a simulator in Java which outperforms all others from that field by at least one order of magnitude.
Graphical applications are a different thing, but even Swing apps can be responsive
But if you adhere to some professional Java programming guides, maybe apply some profiling (and maybe use Java 6 beta instead of Java 5) you can make programs that are more than competetive. One of my students just wrote a simulator in Java which outperforms all others from that field by at least one order of magnitude.
Graphical applications are a different thing, but even Swing apps can be responsive