Page 1 of 1

Undefined createDevice() reference

Posted: Tue Oct 19, 2010 12:52 am
by Markhor
Hello. New problem: I am trying to make my own GUI, just a button to test it...and I get this problem. It says there is an undefined reference to the createDevice() thing.
Here is my code. It occurs, per Code::Blocks, that the problem is on line 114.

Code: Select all

#include "include\irrlicht.h"
#include "include\driverChoice.h"
#include <iostream>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std;

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif



	// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
	IrrlichtDevice *device;
	s32				counter;

};

// Define some values that we'll use to identify individual GUI controls.
enum
{
	GUI_ID_BUTTON//its a BUTTON!
};

class MyEventReceiver : public IEventReceiver
{
public:
	MyEventReceiver(SAppContext & context) : Context(context) { }

	virtual bool OnEvent(const SEvent& event)
	{
		if (event.EventType == EET_GUI_EVENT)
		{
			s32 id = event.GUIEvent.Caller->getID();
			IGUIEnvironment* env = Context.device->getGUIEnvironment();

			switch(event.GUIEvent.EventType)
			{


			/*
			If a button was clicked, it could be one of 'our'
			three buttons. If it is the first, we shut down the engine.
			If it is the second, we create a little window with some
			text on it. We also add a string to the list box to log
			what happened. And if it is the third button, we create
			a file open dialog, and add also this as string to the list box.
			That's all for the event receiver.
			*/
			case EGET_BUTTON_CLICKED:
				switch(id)
				{


				case GUI_ID_BUTTON:
					{

					Context.counter += 30;
					if (Context.counter > 200)
						Context.counter = 0;

					IGUIWindow* window = env->addWindow(
						rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
						false, // modal?
						L"Test window");

					env->addStaticText(L"Please close me",
						rect<s32>(35,35,140,50),
						true, // border?
						false, // wordwrap?
						window);
					}
					return true;



				default:
					return false;
				}
				break;

			default:
				break;
			}
		}

		return false;
	}

private:
	SAppContext & Context;
};

int main(){

// ask user for driver
	video::E_DRIVER_TYPE driverType=driverChoiceConsole();
	if (driverType==video::EDT_COUNT)
		return 1;

	// create device and exit if creation failed

IrrlichtDevice *device =
		createDevice(driverType, dimension2d<u32>(640, 480),
		16, false, false);

	if (device == 0)
		return 1; // could not create selected driver.

video::IVideoDriver* driver = device->getVideoDriver();
	IGUIEnvironment* env = device->getGUIEnvironment();

env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_BUTTON,
			L"New Window", L"Launches a new Window");

SAppContext context;
	context.device = device;
	context.counter = 0;


// Then create the event receiver, giving it that context structure.
	MyEventReceiver receiver(context);

	// And tell the device to use our custom event receiver.
	device->setEventReceiver(&receiver);

/*	printf("Please select the driver you want for this example:\n"\
		" (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\
		" (d) Burning's Software Renderer\n (e) Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	cin >> i;

	switch(i)
	{
		case 'a': driverType = EDT_OPENGL;   break;
		case 'b': driverType = EDT_DIRECT3D9;break;
		case 'c': driverType = EDT_DIRECT3D8;break;
		case 'd': driverType = EDT_BURNINGSVIDEO;break;
		case 'e': driverType = EDT_SOFTWARE; break;
		case 'f': driverType = EDT_NULL;     break;
		default: return 1;
	}

	// create device and exit if creation failed

	IrrlichtDevice *device =
		createDevice(driverType, dimension2d<u32>(640, 480));

	if (device == 0)
		return 1; // could not create selected driver.
*/
   while(device->run() && driver)
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, SColor(0,200,200,200));

		env->drawAll();

		driver->endScene();
	}

	device->drop();

	return 0;
}

Posted: Tue Oct 19, 2010 2:07 am
by lazerblade
You're definitely calling createDevice() the right way.

It must be a problem with the build.
Can you supply your code::blocks build/compilation details?

Posted: Tue Oct 19, 2010 9:35 am
by Markhor
I'm compiling it under debug and there is nothing checked. But it doesn't work under either debug or release. Course it's MinGW, most recent automated installer. Otherwise the project has the "show all warnings" thing checked.

Posted: Tue Oct 19, 2010 9:49 am
by greenya
Not completely sure, but I believe it doesn't work because of compiler optimization, it frees memory of local "context" variable just after:

Code: Select all

MyEventReceiver receiver(context); 
because its not used at all to the end of main(). Inside MyEventReceiver on some OnEvent() call "Context" value becomes invalid.

I would suggest you to remove "&" sign at all. Then it should work, because it will copy the value.

Posted: Tue Oct 19, 2010 10:07 am
by serengeor
is it safe by anyhow to do what Markhor did?

Code: Select all

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std; 
Since std namespace holds same things like string and list, and maybe some others that irrlichts core namespace has.

Posted: Tue Oct 19, 2010 11:19 am
by Markhor
serengeor wrote:is it safe by anyhow to do what Markhor did?

Code: Select all

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace std; 
Since std namespace holds same things like string and list, and maybe some others that irrlichts core namespace has.
I commented that standard line, since I don't need it for this application. It made no change to this but I'm 99.9% sure it makes no difference.

greenya: where do I remove it? I tried to remove a few and it wasn't running, but it did like to mess with it a bit. Just saving to that variable.

Posted: Tue Oct 19, 2010 11:25 am
by greenya
Markhor wrote: greenya: where do I remove it? I tried to remove a few and it wasn't running, but it did like to mess with it a bit. Just saving to that variable.
I was talking about removing "&" in next two places:

Code: Select all

private: 
   SAppContext & Context; 

Code: Select all

MyEventReceiver(SAppContext & context) : Context(context) { } 

Posted: Tue Oct 19, 2010 11:37 am
by Markhor
Edit: cool, fixed it by linking the library file for the compiler. I had the wrong one! XD

Anyways it works. Now I can work on going further.