Irrlicht embedded in a wxWidgets control

A forum to store posts deemed exceptionally wise and useful
stef_
Posts: 53
Joined: Tue Apr 18, 2006 9:39 pm
Contact:

Post by stef_ »

I'm happy to post here my testbed application hoping that someone
like hybrid commits a complete solution in svn :) obviously
not my quick and dirty one...

Feel free to improve this example...

Code: Select all

#include <unistd.h>
#include <iostream>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;

static IAnimatedMeshSceneNode* node;
static bool running;

static void destroy_handler(GtkWidget *widget, gpointer data)
{
	running = false;
}

static void buttons_handler(GtkWidget *widget, gpointer data)
{
	int bdata;

	bdata = *(int *)data;
	switch (bdata) {
	case(scene::EMAT_STAND):
		node->setFrameLoop(1,320);
		break;

	case(scene::EMAT_RUN):
		node->setMD2Animation(scene::EMAT_RUN);
		break;

	case(scene::EMAT_JUMP):
		node->setMD2Animation(scene::EMAT_JUMP);
		break;
	}
}

int main (int argc, char **argv)
{
	// gtk stuff
	GtkWidget *window, *fix, *drawing_area, *button;
	char mode, *blabels[] = { "Stand", "Run", "Jump" };
	int i, bdata[] = { scene::EMAT_STAND, scene::EMAT_RUN, scene::EMAT_JUMP };
	// irrlicht stuff
	SIrrlichtCreationParameters params;
	IrrlichtDevice *device;
	IVideoDriver *driver;
	ISceneManager *smgr;
	IGUIEnvironment *guienv;
	IAnimatedMesh *mesh;
	ICameraSceneNode *cam;

	printf("Please select the mode you want for this example:\n"\
		" (g)tk only\n"\
		" (i)rrlicht only\n"\
		" (m)ixed gtk & irrlicht\n\n");

	std::cin >> mode;

	/* ==================
	 *     init gtk
	 * ================== */

	if (mode == 'g' || mode == 'm') {
		gtk_init(&argc, &argv);
		window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
		gtk_window_set_title(GTK_WINDOW(window), "gtk & irrlicht testbed");
		gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
		g_signal_connect(G_OBJECT(window), "destroy",
				 G_CALLBACK(destroy_handler), NULL);
		// container
		fix = gtk_fixed_new();
		gtk_container_add(GTK_CONTAINER(window), fix);
		// drawing_area
		drawing_area = gtk_drawing_area_new();
		gtk_widget_set_size_request(drawing_area, 320, 240);
		gtk_fixed_put(GTK_FIXED(fix), drawing_area, 0, 0);
		// buttons
		for (i = 0; i < 3; i ++) {
			button = gtk_button_new_with_label(blabels[i]);
			gtk_widget_set_size_request(button, 100, 30);
			if (mode == 'm')
				g_signal_connect(G_OBJECT(button), "released",
					 	 G_CALLBACK(buttons_handler),
						 &bdata[i]);
			gtk_fixed_put(GTK_FIXED(fix), button, 120 * i, 320);

		}
		// show
		gtk_widget_show_all(window);
	}

        /* ==================
         *   init irrlicht
         * ================== */

	if (mode == 'm') {
		params.display = GDK_WINDOW_XDISPLAY(drawing_area->window);
		params.xid = GDK_WINDOW_XWINDOW (drawing_area->window);
	}
	if (mode == 'm' || mode == 'i') {
		params.DriverType = EDT_OPENGL;
		params.WindowSize = dimension2d<s32>(320, 240);
		device = createDeviceEx(params); 
		driver = device->getVideoDriver();
		smgr = device->getSceneManager();
		guienv = device->getGUIEnvironment();
		guienv->addStaticText(L"Hello World!", rect<int>(0,0,50,20), true);
		mesh = smgr->getMesh("./sydney.md2");
		node = smgr->addAnimatedMeshSceneNode(mesh);
		node->setMaterialFlag(EMF_LIGHTING, false);
		node->setFrameLoop(1,320);
		node->setPosition(vector3df(0, 0, 0));
		node->setMaterialTexture(0, driver->getTexture("./sydney.bmp"));
		cam = smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
		cam->setPosition(vector3df(0,0,50));
		cam->setTarget(vector3df(0,0,0));
		cam->setInputReceiverEnabled(false);
	}

        /* ==================
         *     run
         * ================== */

	running = true;
	while (running) {
		if (mode == 'i' || mode == 'm' ) {
			device->run();
			driver->beginScene(true, true, SColor(255,100,101,140));
			smgr->drawAll();
			guienv->drawAll();
			driver->endScene();
		}
		if (mode == 'g' || mode == 'm')
			gtk_main_iteration_do(FALSE);
		// don't use all cpu
		usleep(10000);
	}

	return 0;
}
Bye
kornerr
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo
Contact:

Post by kornerr »

Cool, stef_. Although I'm really noob in GTK, so I get linkage errors.
Please, provide Makefile and if the neccesary modules aren't compiled in that Makefile tell me how to compile them separately, because I don't know *cpp's which refer to #include'd *h's.
Thanks.
Open Source all the way, baby ;)
OSRPG
kornerr
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo
Contact:

Post by kornerr »

I figured out how to compile it, I had to link it with (in case of Slackware) libgtk-x11-2.0 and libXx86vm. But mixed mode doesn't work:

Code: Select all

kornerr@kornerr:~/cpp/irr/gtk$ ./test 
Please select the mode you want for this example:
 (g)tk only
 (i)rrlicht only
 (m)ixed gtk & irrlicht

m
Irrlicht Engine version 1.2
Linux 2.6.17-mm6 #1 PREEMPT Tue Oct 24 12:19:49 KRAST 2006 i686
The program 'test' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadMatch (invalid parameter attributes)'.
  (Details: serial 166 error_code 8 request_code 143 minor_code 31)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)
Any ideas?
Thanks.

EDIT
My Makefile:

Code: Select all

test: irr_gtk.cpp
        g++ -o test irr_gtk.cpp -lgtk-x11-2.0 -lIrrlicht -lGL -lGLU -lXxf86vm -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 -I/usr/include/cairo -L/usr/lib -L/usr/X11/lib

clean:
        rm -f test *~
Open Source all the way, baby ;)
OSRPG
stef_
Posts: 53
Joined: Tue Apr 18, 2006 9:39 pm
Contact:

Post by stef_ »

> Please, provide Makefile and if the neccesary modules aren't compiled in that Makefile tell me how to compile them separately, because I don't know *cpp's which refer to #include'd *h's.

Mhm, every time a library comes with a pkg-config file I use it when compiling. Of course gtk (as well as all other gnome libs)
comes with a .pc file, so simply add `pkg-config gtk+-2.0 --cflags --libs` to a irrlicht/examples Makefile.
BTW all .pc files are in /usr/lib/pkgconfig/.

> But mixed mode doesn't work:
Compile irrlicht in debug mode and do a step by step in CIrrDeviceLinux::createWindow or (if you don't want to recompile all irrlicht
library) add some debug printf in CIrrDeviceLinux::createWindow (your
problem should be there).

Bye
kornerr
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo
Contact:

Post by kornerr »

It works ok with software2 driver! COOL!
But with OpenGL it crashes:

Code: Select all

kornerr@kornerr:~/cpp/irr/gtk$ ./test 
Please select the mode you want for this example:
 (g)tk only
 (i)rrlicht only
 (m)ixed gtk & irrlicht

m
Irrlicht Engine version 1.2
Linux 2.6.17-mm6 #1 PREEMPT Tue Oct 24 12:19:49 KRAST 2006 i686
Creating X window...
XErrorEvent: BadMatch (invalid parameter attributes)
XErrorEvent: GLXBadDrawable
Could not make context current.
Using renderer: OpenGL 
Segmentation fault
Any ideas?
Thanks.
Open Source all the way, baby ;)
OSRPG
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

It's required to have the window with certain OpenGL settings, or proceed with the OpenGL setup found in the createWindow function. Something is missing in your case which leads to a mismatch, e.g. in color format.
kornerr
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo
Contact:

Post by kornerr »

I wish someone who knows the issues this well could make Irrlicht work with OpenGL in GTK...
Open Source all the way, baby ;)
OSRPG
stef_
Posts: 53
Joined: Tue Apr 18, 2006 9:39 pm
Contact:

Post by stef_ »

Mhm, I'm reading a little more CIrrDeviceLinux.cpp::createWindow(...)
and by now I can also say "my path" inside this function.

There is a section like this (pseudocode):

Code: Select all

        if (DriverType==video::EDT_OPENGL) {
                isAvailableGLX = glXQueryExtension(...)
                glXQueryVersion(..., &maior, &minor)
                if (major==1 && minor>2) {
                        glXChooseFBConfig(...)
                        UseGLXWindow=true;
                        visual = glXGetVisualFromFBConfig(...)
                } else {
                        visual = glXChooseVisual(...)       <<<<<<<
                }
        }
        ...
        colormap = XCreateColormap(...)
        ...
        if (isAvailableGLX && DriverType==video::EDT_OPENGL)
        if (UseGLXWindow) {
        } else {
                 Context = glXCreateContext(....);    <<<<<<<
        }
I have marked with "<<<<<<<" my path.
for me major = 1 and minor = 2 and so UseGLXWindow is always false.
Is it the same for you?
Where is your visual configured?

Bye
kornerr
Posts: 245
Joined: Thu Jul 06, 2006 9:57 am
Location: Russia, Siberia, Kemerovo
Contact:

Post by kornerr »

In my case major == 1 && minor == 3, so UseGLXWindow is true for me.
And my path is:

Code: Select all

        if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
        {
            if (major==1 && minor>2)
            {
            - - - -
                if (configList)
                {
                    glxFBConfig=configList[0];
                    XFree(configList);
                    UseGLXWindow=true;
                    printf ("here visual\n");
                    visual = glXGetVisualFromFBConfig(display,glxFBConfig);
                }
            }
            else
            {
            - - - -
            }
Thanks.
Open Source all the way, baby ;)
OSRPG
netpipe
Posts: 669
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Post by netpipe »

http://www.xup.in/dl,36628258/irrGTK.7z/ << working linux version.
Image
netpipe
Posts: 669
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Post by netpipe »

here is an allmost working implimentation of wx under linux

for some reason unknown to me

Code: Select all

Display* mDisp = GDK_WINDOW_XDISPLAY(handle->window); crashes the program

but the GDK_WINDOW_XWINDOW(handle->window); works fine
http://www.xup.in/dl,96837020/AgEditor-wx.7z/
Post Reply