Hi all,
I've been working on a project that uses Irrlicht inside a Qt window and I've had a few problems, mainly the lack of MacOSX support (and I don't have any experience with programming on MacOSX to implement this). So after looking at the Irrlicht source code, I've came up with an idea: forget the platform specific code in the IrrlichtDevice classes and instead use the widget toolkit to manage the geometry and input events. Then when the window wants to draw itself, you manually create an CSceneManager and one of the subclasses of IVideoDriver and use Irrlicht to draw. You can think of it as implementing a new IrrlichtDevice..
I've already managed to draw an Irrlicht scene to a QGLWidget on both MacOSX and Linux using this method and it solved some other minor problems that I've been having. I haven't managed to get this working on Windows, due to linking problems (I had to declare irr::os::createFileSystem and the other such create* functions, because they are not part of irrlicht.h).
So my question is, what do you think of this approach? My thoughs are summarized below.
Advantages
* Works on MacOSX
* Geometry is handled by the toolkit, so no problems with weird offsets and resizing.
* Better integration with the toolkit. (ei: there are some things that I cannot do in Qt when I use CreationParams.WIndowId, like draw Qt widgets on top of the Irrlicht window)
Disadvantages
* Requires more code to be written (ei: I had to implement by own CCursorControl class that used Qt's platform independent classes to dictate the mouse position. Also I had to copy the code for postEventFromUser).
* Requires functions (createFileSystem, createDriver...) that are not in irrlicht.h, which is causing me trouble when linking on Windows.
* Switching from and Irrlicht window to external window to will not be a matter of adding one line,
* More complicated.
As you can see, there are some pretty big disadvantages to this method. So I'm not entirely sure if the advantages make up for them, which is why I am writing this post asking for some discussion.
PS: For those interested, you can see the code here:
http://amelia.svn.sourceforge.net/viewv ... iew=markup
http://amelia.svn.sourceforge.net/viewv ... iew=markup
Idea: Alternative Way To Use Irrlicht In External Winodows
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Implementing a new device is definitely a viable way to support special things of another platform. However, it depends on what you want to achieve. Moreover, we did not yet specify all requirements a device must meet.
But, the most obious reason to create a new device is when your main render window cannot be created on a specific platform. Because that's the most important thing the device has to do. Additionally, it handles the I/O, but that's just because it's not yet properly factored out.
BTW: The devices are not necessarily platform specific. We already have a completely cross-platform SDL device, and also the Linux device would be better named to X11Device.
And you might avoid the include problems by adding the device to the library, because then you can have better access to the internal functions.
But, the most obious reason to create a new device is when your main render window cannot be created on a specific platform. Because that's the most important thing the device has to do. Additionally, it handles the I/O, but that's just because it's not yet properly factored out.
BTW: The devices are not necessarily platform specific. We already have a completely cross-platform SDL device, and also the Linux device would be better named to X11Device.
And you might avoid the include problems by adding the device to the library, because then you can have better access to the internal functions.
That actually might be quite a clean and flexible solution to what I'm trying to do. Basically, all I have to do is create a new irrlicht device that , given a valid (an usable) window handle, creates the filesystem, GUI driver and other internal classes. Actually, the Stub driver seems to do this. All that has to be done is to move the createDriver() (which has almost the same code in each of the already existing drivers) to the Stub device.hybrid wrote:Implementing a new device is definitely a viable way to support special things of another platform. However, it depends on what you want to achieve. Moreover, we did not yet specify all requirements a device must meet.
But, the most obious reason to create a new device is when your main render window cannot be created on a specific platform. Because that's the most important thing the device has to do. Additionally, it handles the I/O, but that's just because it's not yet properly factored out.
BTW: The devices are not necessarily platform specific. We already have a completely cross-platform SDL device, and also the Linux device would be better named to X11Device.
And you might avoid the include problems by adding the device to the library, because then you can have better access to the internal functions.
This doesn't seem like a lot of change to the Irrlicht code base and it would be useful to have the Stub device available in the public API to create custom devices. So would it be possible to include this in an official Irrlicht release?
I am going to play around with using the Stub device to implement what I talked about in my first post, and I'll let you know how it goes.
Also, it would be nice if the stub device class was made accessible by public, so we could create our new devices
Hi all,
Sorry for the delayed reply, but I didn't have time to play around with this because of final exams. However I did try some things now.
First to answer to your question about why I don't want to include my Qt Irrlicht device in Irrlicht core. Compiling Qt applications is a bit complicated, especially when dealing with a static makefile or a VC++ project. On many systems the libraries can be located in different non-standard places (even on Linux), which would make it a big of a bother for every user (that wants Qt) to modify his Makefile, depending on where the libraries are located. Also to take full advantage of Qt's features (ei: signal and slots), one has to run a Qt preprocessor on the header code, which I don't even know how to manually add to VC++. In summary, having to compile against the Qt libraries is quite a lot of bother for people that want it using Irrlicht's current build system.
Also I've tried to play around with the idea of a CIrrDeviceExternal class, that given a window id, creates the driver, file system and so on. Basically what I described in my first post. It can also use the cursor control written for the platform (ei: I included CirrDeviceLinux.h and used the CursorControl defined there).
However the problem I run into was that the software drivers did no longer work, because they require platform specific code to display the rendered image on a screen. To solve this, I would have to copy and paste the presentImage code from the other CIrrDevice* classes, which does not seem like a very nice solution.
Furthermore, the only difference between the other CIrrDevice* classes and my CIrrDeviceExternal class is that they (in case of Linux and OpenGL driver on Windows) don't use the supplied window Id directly, but instead create a new "child window" in order to enable OpenGL support in the window. So what I've decided to do now is to try to modify the current CIrrDevice* classes such that they do not have to create a new child window and instead use the supplied window id directly.
That so far worked quite well for me, if the supplied window id already had OpenGL support enabled (ei: I had to use QGLWidget instead of QWidget as my base).
Sorry for the delayed reply, but I didn't have time to play around with this because of final exams. However I did try some things now.
First to answer to your question about why I don't want to include my Qt Irrlicht device in Irrlicht core. Compiling Qt applications is a bit complicated, especially when dealing with a static makefile or a VC++ project. On many systems the libraries can be located in different non-standard places (even on Linux), which would make it a big of a bother for every user (that wants Qt) to modify his Makefile, depending on where the libraries are located. Also to take full advantage of Qt's features (ei: signal and slots), one has to run a Qt preprocessor on the header code, which I don't even know how to manually add to VC++. In summary, having to compile against the Qt libraries is quite a lot of bother for people that want it using Irrlicht's current build system.
Also I've tried to play around with the idea of a CIrrDeviceExternal class, that given a window id, creates the driver, file system and so on. Basically what I described in my first post. It can also use the cursor control written for the platform (ei: I included CirrDeviceLinux.h and used the CursorControl defined there).
However the problem I run into was that the software drivers did no longer work, because they require platform specific code to display the rendered image on a screen. To solve this, I would have to copy and paste the presentImage code from the other CIrrDevice* classes, which does not seem like a very nice solution.
Furthermore, the only difference between the other CIrrDevice* classes and my CIrrDeviceExternal class is that they (in case of Linux and OpenGL driver on Windows) don't use the supplied window Id directly, but instead create a new "child window" in order to enable OpenGL support in the window. So what I've decided to do now is to try to modify the current CIrrDevice* classes such that they do not have to create a new child window and instead use the supplied window id directly.
That so far worked quite well for me, if the supplied window id already had OpenGL support enabled (ei: I had to use QGLWidget instead of QWidget as my base).
Just to be clear, the current implementation of Irrlicht creates a new window and attaches it to the existing supplied window. I wanted to instead of creating a new window to use the supplied window. I was hoping that this would solve some problems I've been having with geometry of the window on Linux and a certain OpenGL rendering problem. This was just to be a slight modification to the current implementation.hybrid wrote:Well, that's a far better idea It could also be integrated into Irrlicht by adding another SIrrCreationParam... However, I'm still not sure what are the pros and cons of this new window
Anyways, the problem I've run into now is that to have MacOSX support, I have to make sure that the WindowId in SIrrCreationParam is a valid Cocoa window. However, Qt uses Carbon with Cocoa support on Mac OS X Lepoard, but I only have Tiger to do my work on. So basically it would be very hard for me to use external window with Qt on Mac OS X. That's why I don't think it makes much sense for me to pursue this right now.
What I'm thinking of doing now is trying to implement a Qt specific IrrlichtDevice, as described in the posts above. I mentioned that the main problem with this was that compiling application that use Qt is quite a bother. However, I think that a way to get around this is to add a build system, like autoconf or cmake, that will set everything up.
I think that adding a build system to Irrlicht would help other things, like making it easier (ok, it's not really hard now) to compile against system jpeg/png libraries, pick a device or switch between static/dynamic building.
I'm a big fan of CMake, because it is quite easy to setup and not only it creates Makefiles, but also VC++ projects, CodeBlocks projects and XCode projects, which is what Irrlicht uses now. Is this something that the Irrlicht dev team would be interested in?
There is one major disadvantage you missed:
Let me know if I mis-interpeted what you're saying, but doesn't this create a new dependency? One of the main reasons I choose Irrlicht was its lack of dependencies. Adding another dependency like Qt Widgets would make it significantly harder to port to another system (EG: iPhone) unless we somehow bypassed all the Qt Widget stuff for thoose systems.
--
Also, regarding your hope to draw Qt Widgets on top of Irrlich's window: not a good idea.
Back when I was still using Game Maker more, I used/created dlls that put things on top of Game Maker's windows (EG: standard windows windows like buttons or checkboxes) and it was chaos.
On some systems, the buttons and stuff didn't even show up, on others they were solid black, on others they left images behind. (EG: You check the checkbox then uncheck it, but it doesn't apear to uncheck. Or another example were slider bars, they left millions of slider grabbers behind when you dragged them.)
Imo: We should just keep enhancing the current Irrlicht GUI items, although I don't think it is a particularly high priority since they aren't all that useful in games. (Since a game developer will probably program thier own menus and such)
~DtD
Let me know if I mis-interpeted what you're saying, but doesn't this create a new dependency? One of the main reasons I choose Irrlicht was its lack of dependencies. Adding another dependency like Qt Widgets would make it significantly harder to port to another system (EG: iPhone) unless we somehow bypassed all the Qt Widget stuff for thoose systems.
--
Also, regarding your hope to draw Qt Widgets on top of Irrlich's window: not a good idea.
Back when I was still using Game Maker more, I used/created dlls that put things on top of Game Maker's windows (EG: standard windows windows like buttons or checkboxes) and it was chaos.
On some systems, the buttons and stuff didn't even show up, on others they were solid black, on others they left images behind. (EG: You check the checkbox then uncheck it, but it doesn't apear to uncheck. Or another example were slider bars, they left millions of slider grabbers behind when you dragged them.)
Imo: We should just keep enhancing the current Irrlicht GUI items, although I don't think it is a particularly high priority since they aren't all that useful in games. (Since a game developer will probably program thier own menus and such)
~DtD