C++ help

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

C++ help

Post by abecks »

Can someone help me out? Im trying to improve my knowledge of C++ and organize my code a little. To start I'd like to put the driver choice as seen in the examples in a seperate function, in a seperate file. This the way ive done it, without success:

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include "driver.cpp"

using namespace irr;


#pragma comment(lib, "Irrlicht.lib")


int main()
{

    driverType = askdriver();

and inside driver.cpp

Code: Select all

int askdriver()
{


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

	char i;
	std::cin >> i;

	enum driverType;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_SOFTWARE2;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 1;
	}	
	return driverType;
}
Problem is you cant return an enum in an int function. Im used to doing these kind of function calls with integers only, so with enums and strings I'm useless. Feel free to tell me how much of a complete idiot I am, but if you can help me out, please do.
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

In your function definition, you have int, which specifies the return type, but you are trying to return an E_DRIVER_TYPE so you should be good by changing int to video::E_DRIVER TYPE which is telling your program that you are returning a driver type.

Code: Select all

video::E_DRIVER_TYPE askdriver()
{


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

   char i;
   std::cin >> i;

   enum driverType;

   switch(i)
   {
      case 'a': driverType = video::EDT_DIRECT3D9;break;
      case 'b': driverType = video::EDT_DIRECT3D8;break;
      case 'c': driverType = video::EDT_OPENGL;   break;
      case 'd': driverType = video::EDT_SOFTWARE; break;
      case 'e': driverType = video::EDT_SOFTWARE2;break;
      case 'f': driverType = video::EDT_NULL;     break;
      default: return 1;
   }   
   return driverType;
} 
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

Thanks for the help, progress is good :) Still having a problem though:

D:\irrlicht-1.0\examples\myengine\driver.cpp(27) : error C2440: 'return' : cannot convert from 'const int' to 'enum irr::video::E_DRIVER_TYPE'
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
D:\irrlicht-1.0\examples\myengine\main.cpp(13) : error C2065: 'driverType' : undeclared identifier
driver.cpp
D:\irrlicht-1.0\examples\myengine\driver.cpp(27) : error C2440: 'return' : cannot convert from 'const int' to 'enum irr::video::E_DRIVER_TYPE'
Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)

main.cpp

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include "driver.cpp"

using namespace irr;


#pragma comment(lib, "Irrlicht.lib")

int main()
{

	driverType = getDriver();
driver.cpp

Code: Select all

#include <iostream>
#include <irrlicht.h>

using namespace irr;


video::E_DRIVER_TYPE getDriver()
{
   printf("Please select the driver you want for this example:\n"\
      " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
      " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
      " (f) NullDevice\n (otherKey) exit\n\n");

   char i;
   std::cin >> i;

   video::E_DRIVER_TYPE driverType;

   switch(i)
   {
      case 'a': driverType = video::EDT_DIRECT3D9;break;
      case 'b': driverType = video::EDT_DIRECT3D8;break;
      case 'c': driverType = video::EDT_OPENGL;   break;
      case 'd': driverType = video::EDT_SOFTWARE; break;
      case 'e': driverType = video::EDT_SOFTWARE2;break;
      case 'f': driverType = video::EDT_NULL;     break;
      default: return 1;
   }   
   return driverType; 
}
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

You have to prototype all your functions that appear after main or within different include files.

At the top before int main(){ } but after the #include's and namespace put :

video::E_DRIVER_TYPE getDriver();

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include "driver.cpp"

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

video::E_DRIVER_TYPE getDriver();

int main()
{

   driverType = getDriver();
I just tested something similar myself, so I do know that returning an EDT Driver type works. The error is in the default section, you are returning an int, but you must return a driverType. The simplest thing here would be to just have default: driverType = video::EDT_DIRECT3D9 or whichever default driver you want your program to have. The longer option would be to implement the print f and switch statement into a while loop which will not allow the user to enter anything other than A,B,C,D,E, or F.

For now and for testing just go with:

Code: Select all

#include <iostream>
#include <irrlicht.h>

using namespace irr;


video::E_DRIVER_TYPE getDriver()
{
   printf("Please select the driver you want for this example:\n"\
      " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
      " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
      " (f) NullDevice\n (otherKey) exit\n\n");

   char i;
   std::cin >> i;

   video::E_DRIVER_TYPE driverType;

   switch(i)
   {
      case 'a': driverType = video::EDT_DIRECT3D9;break;
      case 'b': driverType = video::EDT_DIRECT3D8;break;
      case 'c': driverType = video::EDT_OPENGL;   break;
      case 'd': driverType = video::EDT_SOFTWARE; break;
      case 'e': driverType = video::EDT_SOFTWARE2;break;
      case 'f': driverType = video::EDT_NULL;     break;
      default: driverType = video::EDT_DIRECT3D9;
   }   
   return driverType;
}
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

Well I think I've hit the final problem.

D:\irrlicht-1.0\examples\myengine\main.cpp(15) : error C2065: 'driverType' : undeclared identifier

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include "driver.cpp"

using namespace irr;


#pragma comment(lib, "Irrlicht.lib")


video::E_DRIVER_TYPE getDriver(); 

int main()
{
	driverType = getDriver();
I tried to declare driverType a number of ways, even setting video::E_DRIVER_TYPE = getDriver(); directly... no luck. Any ideas?
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

Perhaps

video::E_DRIVER_TYPE driverType = getDriver(); :wink:

You have to declare driverType as something.

video::E_DRIVER_TYPE driverType = getDriver();

is pretty much the same as:

int mynumber = 6;

Not to insult your intelligence or anything, its just that I notice a lot of people who try to begin irrlicht without first knowing basic C++ which I personally feel is a must.
Last edited by zeno60 on Mon Jul 24, 2006 7:02 am, edited 1 time in total.
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

main.obj : error LNK2005: "enum irr::video::E_DRIVER_TYPE __cdecl getDriver(void)" (?getDriver@@YA?AW4E_DRIVER_TYPE@video@irr@@XZ) already defined in driver.obj
Engine.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

Ahh, silly me, Irrlicht already has a pre-defined function call for getDriver, you will have to rename your function to something else. Perhaps askDriver as you orginally had. And don't forget to change everywhere you had your getDriver() name, this includes in main, the prototype before main, and in the getDriver function definition.
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

Ah good catch... unfortunatelly... even after named it several times and finally to "askDriver45" I still get this error:

main.obj : error LNK2005: "enum irr::video::E_DRIVER_TYPE __cdecl askDriver45(void)" (?askDriver45@@YA?AW4E_DRIVER_TYPE@video@irr@@XZ) already defined in driver.obj
Engine.exe : fatal error LNK1169: one or more multiply defined symbols found
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

Strange, let me see if I can recreate it on my own using the above source or you can send your source code you are using.
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

main.cpp

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include "driver.cpp"

using namespace irr;


#pragma comment(lib, "Irrlicht.lib")


video::E_DRIVER_TYPE askDriver(); 

int main()
{
    video::E_DRIVER_TYPE driverType = askDriver();

	// create device and exit if creation failed

	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<s32>(1024, 768));

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

	/*
	Get a pointer to the video driver and the SceneManager so that
	we do not always have to write device->getVideoDriver() and
	device->getSceneManager().
	*/
	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

	/*
	To display the Quake 3 map, we first need to load it. Quake 3 maps
	are packed into .pk3 files wich are nothing other than .zip files.
	So we add the .pk3 file to our FileSystem. After it was added,
	we are able to read from the files in that archive as they would
	directly be stored on disk.
	*/
	device->getFileSystem()->addZipFileArchive("media/map-20kdm2.pk3");

	/* 
	Now we can load the mesh by calling getMesh(). We get a pointer returned
	to a IAnimatedMesh. As you know, Quake 3 maps are not really animated,
	they are only a huge chunk of static geometry with some materials
	attached. Hence the IAnimated mesh consists of only one frame,
	so we get the "first frame" of the "animation", which is our quake level
	and create an OctTree scene node with it, using addOctTreeSceneNode().
	The OctTree optimizes the scene a little bit, trying to draw only geometry
	which is currently visible. An alternative to the OctTree would be a 
	AnimatedMeshSceneNode, which would draw always the complete geometry of 
	the mesh, without optimization. Try it out: Write addAnimatedMeshSceneNode
	instead of addOctTreeSceneNode and compare the primitives drawed by the
	video driver. (There is a getPrimitiveCountDrawed() method in the 
	IVideoDriver class). Note that this optimization with the Octree is only
	useful when drawing huge meshes consiting of lots of geometry.
	*/
	scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
	scene::ISceneNode* node = 0;
	
	if (mesh)
		node = smgr->addOctTreeSceneNode(mesh->getMesh(0));

	/*
	Because the level was modelled not around the origin (0,0,0), we translate
	the whole level a little bit.
	*/
	scene::ITriangleSelector* selector = 0;
	if (node)
	{
		node->setPosition(core::vector3df(-1300,-144,-1249));

		selector = smgr->createOctTreeTriangleSelector(
			mesh->getMesh(0), node, 128);
		node->setTriangleSelector(selector);
		selector->drop();
	}	

	/*
	Now we only need a Camera to look at the Quake 3 map.
	And we want to create a user controlled camera. There are some
	different cameras available in the Irrlicht engine. For example the 
	Maya Camera which can be controlled compareable to the camera in Maya:
	Rotate with left mouse button pressed, Zoom with both buttons pressed,
	translate with right mouse button pressed. This could be created with
	addCameraSceneNodeMaya(). But for this example, we want to create a 
	camera which behaves like the ones in first person shooter games (FPS).
	*/
	scene::ICameraSceneNode* camera = 	
		camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);


	/* The follow code adds the collision detection for the camera. */
	scene::ISceneNodeAnimator* anim =
    smgr->createCollisionResponseAnimator(
		selector, camera, core::vector3df(30,50,30),
		core::vector3df(0,-3,0),
		core::vector3df(0,50,0));

	camera->addAnimator(anim);
	anim->drop();

	/*
	The mouse cursor needs not to be visible, so we make it invisible.
	*/

	device->getCursorControl()->setVisible(false);

	/*
	We have done everything, so lets draw it. We also write the current
	frames per second and the drawn primitives to the caption of the
	window. The 'if (device->isWindowActive())' line is optional, but 
	prevents the engine render to set the position of the mouse cursor 
	after task switching when other program are active.
	*/
	int lastFPS = -1;

	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, video::SColor(0,200,200,200));
		smgr->drawAll();
		driver->endScene();

		int fps = driver->getFPS();

		if (lastFPS != fps)
		{
			core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;

			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
	}

	/*
	In the end, delete the Irrlicht device.
	*/
	device->drop();
	
	return 0;
}

driver.cpp

Code: Select all

#include <iostream>
#include <irrlicht.h>

using namespace irr;


video::E_DRIVER_TYPE askDriver()
{
   printf("Please select the driver you want for this example:\n"\
      " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
      " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
      " (f) NullDevice\n (otherKey) exit\n\n");

   char i;
   std::cin >> i;

   video::E_DRIVER_TYPE driverPick;

   switch(i)
   {
      case 'a': driverPick = video::EDT_DIRECT3D9;break;
      case 'b': driverPick = video::EDT_DIRECT3D8;break;
      case 'c': driverPick = video::EDT_OPENGL;   break;
      case 'd': driverPick = video::EDT_SOFTWARE; break;
      case 'e': driverPick = video::EDT_SOFTWARE2;break;
      case 'f': driverPick = video::EDT_NULL;     break;
      default: return driverPick = video::EDT_DIRECT3D9;
   }   
   return driverPick; 
}
Just me modifying the Quake 3 Level Loader example.
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

Ok do you use DevCpp?

Because I think you need to link the irrlicht library. If you use devcpp, go to project->project options, then in the parameter tab, click add library or object. Then located the libirrlicht.a file.

Either in ../../../../Dev-Cpp/lib/libIrrlicht.a
or your irrlichtsdkfoler/lib/Win32-gc blah blah folder in which case I would suggest you copy and paste this into a Dev-Cpp/lib folder.

I also had to change askDriver to another name, I used myDriver()
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

Hmm, i use Visual C++ 6.0 and the VisualStudio library. I just tried it with the Win32 GCC library with no success. Even after renaming it to myDriver... Perhaps I need to switch compilers.
zeno60
Posts: 342
Joined: Sun May 21, 2006 2:48 am
Location: NC, USA
Contact:

Post by zeno60 »

I don't use VC++ myself, but I know that many on these forums do. I only know that removing the link to libirrlicht.a in Dev brought up the same error you described, re-linking it removed it, so i'm definetly thinking its because that file hasen't been linked properly.

I don't even have VC++ 6 to see if I can find out how it links, perhaps a search of the forums will bring something up?
abecks
Posts: 19
Joined: Fri Jul 21, 2006 2:38 am
Location: British Columbia, Canada
Contact:

Post by abecks »

To tell you the truth VC++ 6 is the biggest pile of a compiler and I've had nothing but linking errors when compiling other code i've found on this forum. My google research revealed a bunch of linker flaws in the way VC++ and VS do linking. Either way, theres alot of complaints against VC++, so I think I will switch to DevCpp, I found it on Sourceforge.
Post Reply