Irrlicht embedded in a wxWidgets control

A forum to store posts deemed exceptionally wise and useful

Irrlicht embedded in a wxWidgets control

Postby mandrav » Sat Sep 02, 2006 3:35 pm

Seeing that many people are asking how to embed Irrlicht in a wxWidgets control (especially for wxGTK), I decided to make such a control (which I had already written) available to the public.

Grab it here.
Make sure to read the README contained in the archive.
Also, the source file contains doxygen-compatible documentation comments so you can run it through doxygen and get a nice documentation about it :).

If a mod believes this post is in the wrong forum, feel free to move it.

Enjoy,
Yiannis.
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby Eternl Knight » Sun Sep 03, 2006 12:10 am

This officially makes you my second favourite person today (fav is my wife who convinced my boys to buy me a Playstation 2 for Father's Day :) ).

This works for Linux & Windows or just Windows?

EDIT: It works for both, provided one is using wxGTK. This should make things a little easier to port :) Thanks

--EK
Eternl Knight
 
Posts: 313
Joined: Tue Nov 01, 2005 5:01 am

Postby kornerr » Fri Sep 08, 2006 10:22 am

I get segfault:
Code: Select all
(test:3084): Gdk-WARNING **: gdkdrawable-x11.c:971 drawable is not a pixmap or window
Segmentation fault


Code: Select all
- - - -
Panel::Panel (wxFrame *parent, wxWindowID id, wxSize size):
    wxPanel (parent, id, wxDefaultPosition, size, wxTAB_TRAVERSAL) {
    SIrrlichtCreationParameters param;
    wxStaticText *pnl = new wxStaticText (this, -1, wxEmptyString);
    pnl->SetBackgroundStyle (wxBG_STYLE_CUSTOM);
    GtkWidget *handle = pnl->GetHandle ();
    if (!handle)
        cout << "no handle\n";
    //GtkWidget *handle = this->GetHandle ();
    XID handle_id = GDK_WINDOW_XWINDOW (handle->window);
    Display *display = GDK_WINDOW_XDISPLAY (handle->window);
    core::stringc win_desc = (int)display;
    win_desc += ':';
    win_desc += (int)handle_id;
    param.WindowId = (long)win_desc.c_str ();
    param.DriverType = EDT_OPENGL;
    param.WindowSize = core::dimension2d<s32> (400, 300);
    dev = createDeviceEx (param);
    smgr = dev->getSceneManager ();
    drv = dev->getVideoDriver ();
    smgr->addCameraSceneNodeFPS (0, 10, 10);
    ISceneNode *cube = smgr->addCubeSceneNode (1);
    cube->setMaterialFlag (EMF_LIGHTING, false);
    cube->setMaterialTexture (0, drv->getTexture ("media/rockwall.bmp"));
}
- - - -


And this:
Code: Select all
core::stringc dName = (long)mDisp;

doesn't work at all, becauss Irr can't create strings from longs.

What am I doing wrong?
Thanks.

PS: Can you provide a full workable demo?
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Postby mandrav » Fri Sep 08, 2006 10:41 am

I get segfault:


I don't :).
Seriously, this code has been tested on linux. As a matter of fact I had already pointed you to one of my posts where there's a screenshot of an editor using this under linux.

Anyone else who tried it and gets segfaults?

And this:
Code: Select all
core::stringc dName = (long)mDisp;

doesn't work at all, becauss Irr can't create strings from longs.


Do you really think so?
Here's one of the irr::core::string constructors:
Code: Select all
   //! Constructs a string from an int
   string(int number)
        {
        ...
        {
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby kornerr » Sat Sep 09, 2006 4:51 am

int != long int.
See:
Code: Select all
kornerr@kornerr:~/cpp/irr/wx$ make
g++ -o test editor.cpp `wx-config --cxxflags`  -I"/usr/X11/include" -I"/usr/local/include/irrlicht" -g -Wall -I"/usr/include/gtk-2.0" -I"/usr/include/glib-2.0" -I"/usr/lib/glib-2.0/include" -I"/usr/include/pango-1.0" -I"/usr/lib/gtk-2.0/include" -I"/usr/include/atk-1.0" `wx-config --libs` -L"/usr/X11/lib" -L"/usr/local/lib" -lIrrlicht -lGL -lGLU -lXxf86vm -lXext -lX11
editor.cpp: In constructor `Panel::Panel(wxFrame*, int, wxSize)':
editor.cpp:56: error: conversion from `long int' to `irr::core::string<c8,
   irr::core::irrAllocator<c8> >' is ambiguous
/usr/local/include/irrlicht/irrString.h:62: error: candidates are:
   irr::core::string<T, TAlloc>::string(int) [with T = c8, TAlloc =
   irr::core::irrAllocator<c8>]
/usr/local/include/irrlicht/irrString.h:53: error:
   irr::core::string<T, TAlloc>::string(double) [with T = c8, TAlloc =
   irr::core::irrAllocator<c8>]
make: *** [test] Error 1

Which distro do you use? (mine is Slackware10.2)
Thanks.
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Postby mandrav » Sat Sep 09, 2006 6:41 am

int != long int


I know it's not :? . Especially on my AMD64 where I created and used this component.

Anyway, maybe something has changed in Irrlicht? Let me check again because back when I created it I was using 0.14 and it compiled and worked fine.
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby kornerr » Sat Sep 09, 2006 7:35 am

Don't forget to tell me what distro you use.
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Postby hybrid » Sat Sep 09, 2006 9:11 am

Yes, I've added the double to string conversion. Now several types are not automatically recognized anymore. Cast numbers either to int or double.
hybrid
Admin
 
Posts: 14089
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany

Postby mandrav » Sat Sep 09, 2006 12:01 pm

hybrid wrote:Cast numbers either to int or double.


I see. The point is that int!=long in AMD64 systems so it's not going to cut it...
Is it possible to add the long conversion too?
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby jonasrf » Sat Sep 09, 2006 10:40 pm

kornerr wrote:PS: Can you provide a full workable demo?


That would be great if you could. I must be a total idiot but I couldn't figure out what you ment in the readme file. Do I stick this in a panel, or were? If so could you tell me how to do that. I'm very new at wxwidgets, so I'm only familiar with wxframe.
jonasrf
 
Posts: 25
Joined: Fri Jan 13, 2006 6:18 am

Postby kornerr » Sun Sep 17, 2006 8:56 am

I just added
Code: Select all
if (handle->window == 0)
        cout << "no window\n";

and indeed, there's simply no pointer.

And what's the use of this:
Code: Select all
wxStaticText* pnl = new wxStaticText(this, -1, wxEmptyString);

How is text supposed to be Irrlicht window?
I tried wxPanel, although handle->window is still null.
You definetely need to give us the full workable demo.
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Postby mandrav » Sun Sep 17, 2006 10:20 am

kornerr wrote:I just added
Code: Select all
if (handle->window == 0)
        cout << "no window\n";

and indeed, there's simply no pointer.

And what's the use of this:
Code: Select all
wxStaticText* pnl = new wxStaticText(this, -1, wxEmptyString);

How is text supposed to be Irrlicht window?
I tried wxPanel, although handle->window is still null.
You definetely need to give us the full workable demo.


I can understand the fact that you may lack some basic wx knowledege regarding cross-platform gotchas, but you didn't state your knowledge level so I have no clue.

Did you bother to read the accompanying README?
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby kornerr » Tue Sep 19, 2006 9:56 am

I did bother. Ok, let's see:
Code: Select all
Usage quick-mini-turorial:

int irrID = wxNewId();
wxIrrlicht* irrWin = new wxIrrlicht(this, irrID);
try
{
    irrWin->Init();
    irrWin->StartRendering();
}
catch (const char* c)
{
    wxMessageBox(_("Could not initialise wxIrrlicht: ") + wxString(c, wxConvUTF8),
                 _("Error"),
                 wxICON_ERROR);
}

Constructor only sets some variables necessary for rendering.
Then Init:
Code: Select all
void wxIrrlicht::Init(irr::SIrrlichtCreationParameters* init_params)
{
    SIrrlichtCreationParameters params;
    params.DriverType = EDT_OPENGL; // default to OpenGL driver if no init_params specified

    SIrrlichtCreationParameters* actual_params = init_params ? init_params : &params;
    dimension2d<s32> irrSize(GetClientSize().GetX(), GetClientSize().GetY());
    actual_params->WindowSize = irrSize;

    // initialize Irrlicht in this window
#ifdef LINUX
    wxStaticText* pnl = new wxStaticText(this, -1, wxEmptyString);
    pnl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);

    GtkWidget* handle = pnl->GetHandle();
    if (!handle)
        return;
    XID xHandle = GDK_WINDOW_XWINDOW(handle->window);
    Display* mDisp = GDK_WINDOW_XDISPLAY(handle->window);
    core::stringc dName = (long)mDisp;
    dName += ':';
    dName += (int)xHandle;
    actual_params->WindowId = (long)dName.c_str();
#else
    actual_params->WindowId = (long)this->GetHandle();
#endif

    m_pDevice = createDeviceEx(*actual_params);

    // sanity check
    if (!m_pDevice)
        throw "Can't create Irrlicht device!";

    // setup the Irrlicht event receiver
    wxIrrlichtLogEventReceiver* recv = new wxIrrlichtLogEventReceiver(this);
    m_pDevice->setEventReceiver(recv);

    // keep pointers to graphics driver, scene manager and gui environment handy
        m_pDriver = m_pDevice->getVideoDriver();
        m_pSceneManager = m_pDevice->getSceneManager();
        m_pGuiEnvironment = m_pDevice->getGUIEnvironment();

    // create scene
    OnCreateScene();

    // initialise the driver with the window size
    m_pDriver->OnResize(irrSize);
}

It fails on XID xHandle = GDK_WINDOW_XWINDOW(handle->window);
because handle->window is null. That's what I'm talking about. Isn't it clear, or does it make me a wx noob telling this?
If it's not null for you, JUST show full workable application, is it so hard?
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Postby mandrav » Tue Sep 19, 2006 12:49 pm

kornerr wrote:I did bother. Ok, let's see:


Is it by accident that you selectively copy parts of the README, or is it intentional?
Let me quote the part of the README that you didn't post (and seems you didn't even read):

wxIrrlicht README wrote:Note that under Linux, you must call wxIrrlicht::Init() after the parent window
has been activated the first time. Until then, the GTK window handles returned by wxWidgets are invalid.


In simple words, this means that you should either call Init() inside the parent window's activate event handler (just once, the first time), or that you should call it from wxApp::OnInit(), right after you create your main frame.

kornerr wrote:Isn't it clear, or does it make me a wx noob telling this?
If it's not null for you, JUST show full workable application, is it so hard?


It's not hard, but I don't have it available here. Add to that the fact that you clearly didn't read all the documentation.
If you ask me one question that is really not answered in the docs, I will gladly help you.
mandrav
 
Posts: 117
Joined: Sat Aug 27, 2005 8:29 pm

Postby kornerr » Tue Sep 19, 2006 4:13 pm

lol, i indeed didn't read that last part :)
so i have:
Code: Select all
bool App::OnInit () {
        frame = new Frame  ("wx + irr", wxDefaultPosition, wxSize (800, 600));
        frame->CenterOnScreen ();

        SIrrlichtCreationParameters param;
        wxStaticText *pnl = new wxStaticText (frame, -1, wxEmptyString);
        pnl->SetBackgroundStyle (wxBG_STYLE_CUSTOM);
        GtkWidget *handle = pnl->GetHandle ();
        //this->SetBackgroundStyle (wxBG_STYLE_CUSTOM);
        //GtkWidget *handle = 0;
        //handle = frame->GetHandle ();
        if (handle == 0)
                cout << "no handle\n";
        if (handle->window == 0)
                cout << "no window\n";
        XID handle_id = GDK_WINDOW_XWINDOW (handle->window);
        Display *display = GDK_WINDOW_XDISPLAY (handle->window);
        core::stringc win_desc = (int)display;
        win_desc += ':';
        win_desc += (int)handle_id;
        param.WindowId = (long)win_desc.c_str ();
        param.DriverType = EDT_OPENGL;
        param.WindowSize = core::dimension2d<s32> (400, 300);
        dev = createDeviceEx (param);
        smgr = dev->getSceneManager ();
        drv = dev->getVideoDriver ();
        smgr->addCameraSceneNodeFPS (0, 10, 10);
        ISceneNode *cube = smgr->addCubeSceneNode (1);
        cube->setMaterialFlag (EMF_LIGHTING, false);
        cube->setMaterialTexture (0, drv->getTexture ("media/rockwall.bmp"));
        return true;
}

no nulls now, but irr window is created separate again :(
what am i doing wrong now?
thanks.
Open Source all the way, baby ;)
OSRPG
User avatar
kornerr
 
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo

Next

Return to FAQs, Tutorials, Howtos, and external tool lists

Who is online

Users browsing this forum: No registered users and 0 guests