diff --git a/examples/01.HelloWorld/main.cpp b/examples/01.HelloWorld/main.cpp index 226bcf2c..1db38e55 100644 --- a/examples/01.HelloWorld/main.cpp +++ b/examples/01.HelloWorld/main.cpp @@ -1,39 +1,44 @@ /** Example 001 HelloWorld -This Tutorial shows how to set up the IDE for using the Irrlicht Engine and how +This tutorial shows how to set up the IDE for using the Irrlicht Engine and how to write a simple HelloWorld program with it. The program will show how to use the basics of the VideoDriver, the GUIEnvironment, and the SceneManager. Microsoft Visual Studio is used as an IDE, but you will also be able to understand everything if you are using a different one or even another -operating system than windows. +operating system than Windows. You have to include the header file in order to use the engine. The header file can be found in the Irrlicht Engine SDK directory \c include. To let the compiler find this header file, the directory where it is located has to be -specified. This is different for every IDE and compiler you use. Let's explain -shortly how to do this in Microsoft Visual Studio: +added in your project as include path. This is different for every IDE and +compiler you use. Let's explain shortly how to do this in Visual Studio 2010: -- If you use Version 6.0, select the Menu Extras -> Options. - Select the directories tab, and select the 'Include' Item in the combo box. - Add the \c include directory of the irrlicht engine folder to the list of - directories. Now the compiler will find the Irrlicht.h header file. We also - need the irrlicht.lib to be found, so stay in that dialog, select 'Libraries' - in the combo box and add the \c lib/VisualStudio directory. - \image html "vc6optionsdir.jpg" - \image latex "vc6optionsdir.jpg" - \image html "vc6include.jpg" - \image latex "vc6include.jpg" +- In Visual Studio 2010 select the Menu Project -> Properties. Select the + "C/C++" - "General" option, and select the "Additional Include Directories". + Add the \c include directory of the Irrlicht engine folder to the list of + directories. Now the compiler will find the irrlicht.h header file. We also + need the irrlicht.lib to be found, so select "Linker" - "General" and + add the \c lib/Win64-visualStudio or \c lib/Win32-visualStudio directory + to "Additional Library Directories". Which of the 2 Irrlicht versions you + chose depends on the target platform for your application (win32 or x64). + In your project properties you can see what your active solution platform + is, you can use the same one for Irrlicht. -- If your IDE is Visual Studio .NET, select Tools -> Options. - Select the projects entry and then select VC++ directories. Select 'show - directories for include files' in the combo box, and add the \c include - directory of the irrlicht engine folder to the list of directories. Now the - compiler will find the Irrlicht.h header file. We also need the irrlicht.lib - to be found, so stay in that dialog, select 'show directories for Library - files' and add the \c lib/VisualStudio directory. - \image html "vcnetinclude.jpg" - \image latex "vcnetinclude.jpg" +To be able to use the Irrlicht.DLL file, we need to link with the Irrlicht.lib. +In most IDE's you have to add irrlicht.lib (or irrlicht.a or irrlicht.so on +Linux) to your Linker input files. +For VisualStudio we can be lazy and use the pragma comment lib. +We also want to get rid of the console window, which pops up when starting a +program with main() (instead of WinMain). This is done by the second pragma. +We could also use the WinMain method, though losing platform independence then. +*/ +#ifdef _MSC_VER +#pragma comment(lib, "Irrlicht.lib") +#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") +#endif + +/* That's it. With your IDE set up like this, you will now be able to develop applications with the Irrlicht Engine. @@ -43,6 +48,11 @@ After we have set up the IDE, the compiler will know where to find the Irrlicht Engine header files so we can include it now in our code. */ #include + +/* +That header just adds the getExampleMediaPath tool-functions to help locating +the media we need. More about that later below. +*/ #include "exampleHelper.h" /* @@ -52,6 +62,9 @@ of the class. For example to use the IrrlichtDevice write: irr::IrrlichtDevice. To get rid of the irr:: in front of the name of every class, we tell the compiler that we use that namespace from now on, and we will not have to write irr:: anymore. +Note that you never should do that in headers - otherwise you will pollute the +namespace of every file including such a header. So in headers always write +out the full names including all namespaces. */ using namespace irr; @@ -70,20 +83,6 @@ using namespace video; using namespace io; using namespace gui; -/* -To be able to use the Irrlicht.DLL file, we need to link with the Irrlicht.lib. -We could set this option in the project settings, but to make it easy, we use a -pragma comment lib for VisualStudio. On Windows platforms, we have to get rid -of the console window, which pops up when starting a program with main(). This -is done by the second pragma. We could also use the WinMain method, though -losing platform independence then. -*/ -#ifdef _MSC_VER -#pragma comment(lib, "Irrlicht.lib") -#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") -#endif - - /* This is the main method. We can now use main() on every platform. */ @@ -92,25 +91,31 @@ int main() /* The most important function of the engine is the createDevice() function. The IrrlichtDevice is created by it, which is the root - object for doing anything with the engine. createDevice() has 7 - parameters: + object for doing anything with the engine. createDevice() has the + following parameters: - deviceType: Type of the device. This can currently be the Null-device, one of the two software renderers, D3D9, or OpenGL. In this - example we use EDT_SOFTWARE, but to try out, you might want to - change it to EDT_BURNINGSVIDEO, EDT_NULL, EDT_DIRECT3D9, or EDT_OPENGL. + example we use EDT_BURNINGSVIDEO, but to try out, you might want to + change it to EDT_SOFTWARE, EDT_NULL, EDT_DIRECT3D9, or EDT_OPENGL. + Generally you will want to use OpenGL or Direct3D as they are + using your graphic card for calculations instead of the CPU and + are way faster (and usually better looking). We just use one of the + software renderers here as it even works when your graphic card driver + isn't set up for 3d support. - windowSize: Size of the Window or screen in FullScreenMode to be created. In this example we use 640x480. - bits: Amount of color bits per pixel. This should be 16 or 32. The - parameter is often ignored when running in windowed mode. + parameter is often ignored when running in windowed mode. More + commonly you would chose 32 bit, again we're just playing it safe. - fullscreen: Specifies if we want the device to run in fullscreen mode - or not. + or windowed. - - stencilbuffer: Specifies if we want to use the stencil buffer (for - drawing shadows). + - stencilbuffer: Specifies if we want to use the stencil buffer (you + need it for drawing shadows). - vsync: Specifies if we want to have vsync enabled, this is only useful in fullscreen mode. @@ -150,25 +155,48 @@ int main() The text is placed at the position (10,10) as top left corner and (260,22) as lower right corner. */ - guienv->addStaticText(L"Hello World! This is the Irrlicht Software renderer!", + guienv->addStaticText(L"Hello World! This is Irrlicht with the burnings software renderer!", rect(10,10,260,22), true); /* - Get a media path dedicated for your platform. + Get a media path dedicated for your platform. Finding media files for your + applications can be tricky. First you have 2 options - working with relative + paths or working with absolute paths. + + On Windows a common solution is that your installer will write a key into + the registry with the absolute path of wherever the user installed the + media. And in your application you read out that key from the registry. + On Linux a common solution is to use config file which is placed in some + fixed location (for example in a . file/folder in the user home). + + But you can also work with relative paths - which is what we do here. There + is a slight complication with relative paths as they are relative to your + current working directory. And that depends on the way your application is + started and it might change inside your application. But mostly it will be + set to your executable on start so you can ignore that problem while + developing. + + When inside VisualStudio the current working directory is set to your + project files location unless you overwrite Project properties - Debugging + - Working Directory. In Irrlicht examples the media folder is on most + platforms ../../media which works for the examples as it's relative to our + project files as well as to the binary (.exe) files. + + Whatever you chose to find your base-folder for media - wrap it with some + function and then you can improve the code to locate the media later on. */ const io::path mediaPath = getExampleMediaPath(); /* To show something interesting, we load a Quake 2 model and display it. - We only have to get the Mesh from the Scene Manager with getMesh() and add - a SceneNode to display the mesh with addAnimatedMeshSceneNode(). We - check the return value of getMesh() to become aware of loading problems - and other errors. + We get the Mesh from the Scene Manager with getMesh() and add a SceneNode + to display the mesh with addAnimatedMeshSceneNode(). Check the return value + of getMesh() to become aware of loading problems and other errors. Instead of writing the filename sydney.md2, it would also be possible to load a Maya object file (.obj), a complete Quake3 map (.bsp) or any other supported file format. By the way, that cool Quake 2 model - called sydney was modelled by Brian Collins. + called sydney was modeled by Brian Collins. */ IAnimatedMesh* mesh = smgr->getMesh(mediaPath + "sydney.md2"); if (!mesh) @@ -201,10 +229,10 @@ int main() smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0)); /* - Ok, now we have set up the scene, lets draw everything: We run the + OK, now we have set up the scene, lets draw everything: We run the device in a while() loop, until the device does not want to run any more. This would be when the user closes the window or presses ALT+F4 - (or whatever keycode closes a window). + (or whatever keycode closes a window on your OS). */ while(device->run()) { diff --git a/examples/02.Quake3Map/main.cpp b/examples/02.Quake3Map/main.cpp index cd3f32fe..042b70fe 100644 --- a/examples/02.Quake3Map/main.cpp +++ b/examples/02.Quake3Map/main.cpp @@ -1,12 +1,12 @@ /** Example 002 Quake3Map -This Tutorial shows how to load a Quake 3 map into the engine, create a +This tutorial shows how to load a Quake 3 map into the engine, create a SceneNode for optimizing the speed of rendering, and how to create a user controlled camera. Please note that you should know the basics of the engine before starting this tutorial. Just take a short look at the first tutorial, if you haven't done -this yet: http://irrlicht.sourceforge.net/tut001.html +this yet: http://irrlicht.sourceforge.net/docu/example001.html Lets start like the HelloWorld example: We include the irrlicht header files and an additional file to be able to ask the user for a driver type using the @@ -38,7 +38,7 @@ easy, we use a pragma comment lib: #endif /* -Ok, lets start. Again, we use the main() method as start, not the WinMain(). +OK, lets start. Again, we use the main() method as start, not the WinMain(). */ int main() { @@ -51,7 +51,7 @@ int main() */ // ask user for driver - video::E_DRIVER_TYPE driverType=driverChoiceConsole(); + video::E_DRIVER_TYPE driverType=driverChoiceConsole(true); if (driverType==video::EDT_COUNT) return 1; @@ -75,16 +75,14 @@ int main() To display the Quake 3 map, we first need to load it. Quake 3 maps are packed into .pk3 files which are nothing else than .zip files. So we add the .pk3 file to our irr::io::IFileSystem. After it was added, - we are able to read from the files in that archive as if they are - directly stored on the disk. + we can read from the files in that archive as if they were stored on disk. */ device->getFileSystem()->addFileArchive(getExampleMediaPath() + "map-20kdm2.pk3"); /* - Now we can load the mesh by calling - irr::scene::ISceneManager::getMesh(). We get a pointer returned to an - irr::scene::IAnimatedMesh. As you might know, Quake 3 maps are not - really animated, they are only a huge chunk of static geometry with + Now we can load the mesh by calling irr::scene::ISceneManager::getMesh(). + We get a pointer returned to an irr::scene::IAnimatedMesh. Quake 3 maps are + not really animated, they are only a chunk of static geometry with some materials attached. Hence the IAnimatedMesh consists of only one frame, so we get the "first frame" of the "animation", which is our quake level and create an Octree scene node with it, using @@ -98,7 +96,8 @@ int main() driver. (There is a irr::video::IVideoDriver::getPrimitiveCountDrawn() method in the irr::video::IVideoDriver class). Note that this optimization with the Octree is only useful when drawing huge meshes - consisting of lots of geometry. + consisting of lots of geometry and if users can't see the whole scene at + once. */ scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp"); scene::ISceneNode* node = 0; @@ -108,7 +107,7 @@ int main() // node = smgr->addMeshSceneNode(mesh->getMesh(0)); /* - Because the level was not modelled around the origin (0,0,0), we + Because the level was not modeled around the origin (0,0,0), we translate the whole level a little bit. This is done on irr::scene::ISceneNode level using the methods irr::scene::ISceneNode::setPosition() (in this case), @@ -119,7 +118,7 @@ int main() node->setPosition(core::vector3df(-1300,-144,-1249)); /* - Now we only need a camera to look at the Quake 3 map. + Now we need a camera to look at the Quake 3 map. We want to create a user controlled camera. There are some cameras available in the Irrlicht engine. For example the MayaCamera which can be controlled like the camera in Maya: @@ -139,13 +138,13 @@ int main() device->getCursorControl()->setVisible(false); /* - We have done everything, so lets draw it. We also write the current + Everything is set up, so lets draw it. We also write the current frames per second and the primitives drawn into the caption of the window. The test for irr::IrrlichtDevice::isWindowActive() is optional, but prevents the engine to grab the mouse cursor after task switching - when other programs are active. The call to - irr::IrrlichtDevice::yield() will avoid the busy loop to eat up all CPU - cycles when the window is not active. + when other programs are active. The call to irr::IrrlichtDevice::yield() + will avoid the busy loop to eat up all CPU cycles when the window is not + active. */ int lastFPS = -1; diff --git a/examples/03.CustomSceneNode/main.cpp b/examples/03.CustomSceneNode/main.cpp index 4e842955..95529312 100644 --- a/examples/03.CustomSceneNode/main.cpp +++ b/examples/03.CustomSceneNode/main.cpp @@ -1,6 +1,6 @@ /** Example 003 Custom SceneNode -This Tutorial is more advanced than the previous ones. +This tutorial is more advanced than the previous ones. If you are currently just playing around with the Irrlicht engine, you may want to look at other examples first. This tutorials shows how to create a custom scene node and @@ -9,12 +9,11 @@ if you want to implement a render technique the Irrlicht Engine currently does not support. For example, you can write an indoor portal based renderer or an advanced terrain scene node with it. By creating custom scene nodes, you can -easily extend the Irrlicht Engine and adapt it to your own -needs. +easily extend the Irrlicht Engine and adapt it to your needs. -I will keep the tutorial simple: Keep everything very -short, everything in one .cpp file, and I'll use the engine -here as in all other tutorials. +I will keep the tutorial simple: Keep everything very short +and everything in one .cpp file. This is the style which +will also be used in most of the following tutorials. To start, I include the header files, use the irr namespace, and tell the linker to link with the .lib file. @@ -32,14 +31,14 @@ using namespace irr; Here comes the more sophisticated part of this tutorial: The class of our very own custom scene node. To keep it simple, our scene node will not be an indoor portal renderer nor a terrain -scene node, but a simple tetraeder, a 3d object consisting of 4 +scene node, but a simple tetrahedron, a 3D object consisting of 4 connected vertices, which only draws itself and does nothing more. Note that this scenario does not require a custom scene node in Irrlicht. Instead one would create a mesh from the geometry and pass it to a irr::scene::IMeshSceneNode. This example just illustrates creation of a custom -scene node in a very simple setting. +scene node in a simple setting. -To let our scene node be able to be inserted into the Irrlicht +To allow our scene node to be inserted into the Irrlicht Engine scene, the class we create needs to be derived from the irr::scene::ISceneNode class and has to override some methods. */ @@ -49,22 +48,22 @@ class CSampleSceneNode : public scene::ISceneNode /* First, we declare some member variables: - The bounding box, 4 vertices, and the material of the tetraeder. + The bounding box, 4 vertices, and the material of the tetrahedron. */ core::aabbox3d Box; video::S3DVertex Vertices[4]; video::SMaterial Material; +public: + /* The parameters of the constructor specify the parent of the scene node, a pointer to the scene manager, and an id of the scene node. In the constructor we call the parent class' constructor, - set some properties of the material, and - create the 4 vertices of the tetraeder we will draw later. + set some properties of the material, and create the 4 vertices of + the tetrahedron. */ -public: - CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id) : scene::ISceneNode(parent, mgr, id) { @@ -107,10 +106,9 @@ public: scene node to render normally. If we would like to let it be rendered like cameras or light, we would have to call SceneManager->registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA); - After this, we call the actual - irr::scene::ISceneNode::OnRegisterSceneNode() method of the base class, - which simply lets also all the child scene nodes of this node register - themselves. + After this, we call the actual irr::scene::ISceneNode::OnRegisterSceneNode() + method of the base class, which lets all the child scene nodes of this node + register themselves. */ virtual void OnRegisterSceneNode() { @@ -123,7 +121,7 @@ public: /* In the render() method most of the interesting stuff happens: The Scene node renders itself. We override this method and draw the - tetraeder. + tetrahedron. */ virtual void render() { @@ -142,11 +140,11 @@ public: And finally we create three small additional methods. irr::scene::ISceneNode::getBoundingBox() returns the bounding box of this scene node, irr::scene::ISceneNode::getMaterialCount() returns the - amount of materials in this scene node (our tetraeder only has one + amount of materials in this scene node (our tetrahedron only has one material), and irr::scene::ISceneNode::getMaterial() returns the - material at an index. Because we have only one material here, we can - return the only one material, assuming that no one ever calls - getMaterial() with an index greater than 0. + material at an index. Because we have only one material, we can + return that and assume that no one ever calls getMaterial() with an index + greater than 0. */ virtual const core::aabbox3d& getBoundingBox() const { @@ -165,8 +163,8 @@ public: }; /* -That's it. The Scene node is done. Now we simply have to start -the engine, create the scene node and a camera, and look at the result. +That's it. The Scene node is done. Now we start the engine, +create the scene node and a camera, and look at the result. */ int main() { @@ -176,14 +174,13 @@ int main() return 1; // create device - IrrlichtDevice *device = createDevice(driverType, core::dimension2d(640, 480), 16, false); if (device == 0) return 1; // could not create selected driver. - // create engine and camera + // set window caption, get some pointers, create a camera device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo"); @@ -206,7 +203,7 @@ int main() /* To animate something in this boring scene consisting only of one - tetraeder, and to show that you now can use your scene node like any + tetrahedron, and to show that you now can use your scene node like any other scene node in the engine, we add an animator to the scene node, which rotates the node a little bit. irr::scene::ISceneManager::createRotationAnimator() could return 0, so @@ -249,7 +246,7 @@ int main() smgr->drawAll(); driver->endScene(); - if (++frames==100) + if (++frames==100) // don't update more often, setWindowCaption can be expensive { core::stringw str = L"Irrlicht Engine ["; str += driver->getName(); diff --git a/examples/04.Movement/main.cpp b/examples/04.Movement/main.cpp index af890924..dcbcc30e 100644 --- a/examples/04.Movement/main.cpp +++ b/examples/04.Movement/main.cpp @@ -1,19 +1,17 @@ /** Example 004 Movement -This Tutorial shows how to move and animate SceneNodes. The +This tutorial shows how to move and animate SceneNodes. The basic concept of SceneNodeAnimators is shown as well as manual movement of nodes using the keyboard. We'll demonstrate framerate independent movement, which means moving by an amount dependent on the duration of the last run of the Irrlicht loop. -Example 19.MouseAndJoystick shows how to handle those kinds of input. +Example 19.MouseAndJoystick shows how to handle other input than keyboard. -As always, I include the header files, use the irr namespace, +As always, include the header files, use the irr namespace, and tell the linker to link with the .lib file. */ #ifdef _MSC_VER -// We'll also define this to stop MSVC complaining about sprintf(). -#define _CRT_SECURE_NO_WARNINGS #pragma comment(lib, "Irrlicht.lib") #endif @@ -24,8 +22,8 @@ and tell the linker to link with the .lib file. using namespace irr; /* -To receive events like mouse and keyboard input, or GUI events like "the OK -button has been clicked", we need an object which is derived from the +To receive events like mouse and keyboard input, or GUI events like +"button has been clicked", we need an object which is derived from the irr::IEventReceiver object. There is only one method to override: irr::IEventReceiver::OnEvent(). This method will be called by the engine once when an event happens. What we really want to know is whether a key is being @@ -41,6 +39,13 @@ public: if (event.EventType == irr::EET_KEY_INPUT_EVENT) KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown; + /* + Always return false by default. If you return true you tell the engine + that you handled this event completely and the Irrlicht should not + process it any further. So for example if you return true for all + EET_KEY_INPUT_EVENT events then Irrlicht would not pass on key-events + to it's GUI system. + */ return false; } @@ -65,9 +70,9 @@ private: /* The event receiver for keeping the pressed keys is ready, the actual responses will be made inside the render loop, right before drawing the scene. So lets -just create an irr::IrrlichtDevice and the scene node we want to move. We also -create some other additional scene nodes, to show that there are also some -different possibilities to move and animate scene nodes. +create an irr::IrrlichtDevice and the scene node we want to move. We also +create some additional scene nodes to show different possibilities to move and +animate scene nodes. */ int main() { @@ -76,9 +81,14 @@ int main() if (driverType==video::EDT_COUNT) return 1; - // create device + /* + Create the event receiver. Take care that the pointer to it has to + stay valid as long as the IrrlichtDevice uses it. Event receivers are not + reference counted. + */ MyEventReceiver receiver; + // create device IrrlichtDevice* device = createDevice(driverType, core::dimension2d(640, 480), 16, false, false, false, &receiver); @@ -97,12 +107,12 @@ int main() interesting. Because we have no dynamic lights in this scene we disable lighting for each model (otherwise the models would be black). */ - scene::ISceneNode * node = smgr->addSphereSceneNode(); - if (node) + scene::ISceneNode * sphereNode = smgr->addSphereSceneNode(); + if (sphereNode) { - node->setPosition(core::vector3df(0,0,30)); - node->setMaterialTexture(0, driver->getTexture(mediaPath + "wall.bmp")); - node->setMaterialFlag(video::EMF_LIGHTING, false); + sphereNode->setPosition(core::vector3df(0,0,30)); + sphereNode->setMaterialTexture(0, driver->getTexture(mediaPath + "wall.bmp")); + sphereNode->setMaterialFlag(video::EMF_LIGHTING, false); } /* @@ -114,36 +124,35 @@ int main() example. We create a cube scene node and attach a 'fly circle' scene node animator to it, letting this node fly around our sphere scene node. */ - scene::ISceneNode* n = smgr->addCubeSceneNode(); - - if (n) + scene::ISceneNode* cubeNode = smgr->addCubeSceneNode(); + if (cubeNode) { - n->setMaterialTexture(0, driver->getTexture(mediaPath + "t351sml.jpg")); - n->setMaterialFlag(video::EMF_LIGHTING, false); + cubeNode->setMaterialTexture(0, driver->getTexture(mediaPath + "t351sml.jpg")); + cubeNode->setMaterialFlag(video::EMF_LIGHTING, false); scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f); if (anim) { - n->addAnimator(anim); + cubeNode->addAnimator(anim); anim->drop(); } } /* - The last scene node we add to show possibilities of scene node animators is - a b3d model, which uses a 'fly straight' animator to run between to points. + The last scene node we add is a b3d model of a walking ninja. Is shows the + use of a 'fly straight' animator to move the node between two points. */ - scene::IAnimatedMeshSceneNode* anms = + scene::IAnimatedMeshSceneNode* ninjaNode = smgr->addAnimatedMeshSceneNode(smgr->getMesh(mediaPath + "ninja.b3d")); - if (anms) + if (ninjaNode) { scene::ISceneNodeAnimator* anim = smgr->createFlyStraightAnimator(core::vector3df(100,0,60), core::vector3df(-100,0,60), 3500, true); if (anim) { - anms->addAnimator(anim); + ninjaNode->addAnimator(anim); anim->drop(); } @@ -151,23 +160,23 @@ int main() To make the model look right we disable lighting, set the frames between which the animation should loop, rotate the model around 180 degrees, and adjust the animation speed and - the texture. To set the right animation (frames and speed), we + the texture. To set the correct animation (frames and speed), we would also be able to just call - "anms->setMD2Animation(scene::EMAT_RUN)" for the 'run' + "ninjaNode->setMD2Animation(scene::EMAT_RUN)" for the 'run' animation instead of "setFrameLoop" and "setAnimationSpeed", - but this only works with MD2 animations, and so you know how to - start other animations. But a good advice is to not use + But that only works with MD2 animations, while this can be used to + start other animations. For MD2 it's usually good advice not to use hardcoded frame-numbers... */ - anms->setMaterialFlag(video::EMF_LIGHTING, false); + ninjaNode->setMaterialFlag(video::EMF_LIGHTING, false); - anms->setFrameLoop(0, 13); - anms->setAnimationSpeed(15); -// anms->setMD2Animation(scene::EMAT_RUN); + ninjaNode->setFrameLoop(0, 13); + ninjaNode->setAnimationSpeed(15); +// ninjaNode->setMD2Animation(scene::EMAT_RUN); - anms->setScale(core::vector3df(2.f,2.f,2.f)); - anms->setRotation(core::vector3df(0,-90,0)); -// anms->setMaterialTexture(0, driver->getTexture(mediaPath + "sydney.bmp")); + ninjaNode->setScale(core::vector3df(2.f,2.f,2.f)); + ninjaNode->setRotation(core::vector3df(0,-90,0)); +// ninjaNode->setMaterialTexture(0, driver->getTexture(mediaPath + "sydney.bmp")); } @@ -186,14 +195,9 @@ int main() driver->getTexture(mediaPath + "irrlichtlogoalpha2.tga"), core::position2d(10,20)); - gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText( - L"", core::rect(10, 10, 400, 20)); - diagnostics->setOverrideColor(video::SColor(255, 255, 255, 0)); - /* - We have done everything, so lets draw it. We also write the current - frames per second and the name of the driver to the caption of the - window. + Lets draw the scene and also write the current frames per second and the + name of the driver to the caption of the window. */ int lastFPS = -1; @@ -201,7 +205,7 @@ int main() // how long it was since the last frame u32 then = device->getTimer()->getTime(); - // This is the movemen speed in units per second. + // This is the movement speed in units per second. const f32 MOVEMENT_SPEED = 5.f; while(device->run()) @@ -213,7 +217,7 @@ int main() /* Check if keys W, S, A or D are being held down, and move the sphere node around respectively. */ - core::vector3df nodePosition = node->getPosition(); + core::vector3df nodePosition = sphereNode->getPosition(); if(receiver.IsKeyDown(irr::KEY_KEY_W)) nodePosition.Y += MOVEMENT_SPEED * frameDeltaTime; @@ -225,7 +229,7 @@ int main() else if(receiver.IsKeyDown(irr::KEY_KEY_D)) nodePosition.X += MOVEMENT_SPEED * frameDeltaTime; - node->setPosition(nodePosition); + sphereNode->setPosition(nodePosition); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,113,113,133)); diff --git a/examples/05.UserInterface/main.cpp b/examples/05.UserInterface/main.cpp index 654b6ee2..501eed3d 100644 --- a/examples/05.UserInterface/main.cpp +++ b/examples/05.UserInterface/main.cpp @@ -60,8 +60,8 @@ void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin) /* The Event Receiver is not only capable of getting keyboard and mouse input events, but also events of the graphical user interface -(gui). There are events for almost everything: Button click, -Listbox selection change, events that say that a element was hovered +(gui). There are events for almost everything: button click, +listbox selection change, events that say that a element was hovered and so on. To be able to react to some of these events, we create an event receiver. We only react to gui events, and if it's such an event, we get the @@ -85,8 +85,8 @@ public: /* If a scrollbar changed its scroll position, and it is - 'our' scrollbar (the one with id GUI_ID_TRANSPARENCY_SCROLL_BAR), then we change - the transparency of all gui elements. This is a very + 'our' scrollbar (the one with id GUI_ID_TRANSPARENCY_SCROLL_BAR), + then we change the transparency of all gui elements. This is an easy task: There is a skin object, in which all color settings are stored. We simply go through all colors stored in the skin and change their alpha value. @@ -172,9 +172,9 @@ private: /* -Ok, now for the more interesting part. First, create the Irrlicht device. As in +OK, now for the more interesting part. First, create the Irrlicht device. As in some examples before, we ask the user which driver he wants to use for this -example: +example. */ int main() { @@ -184,7 +184,6 @@ int main() return 1; // create device and exit if creation failed - IrrlichtDevice * device = createDevice(driverType, core::dimension2d(640, 480)); if (device == 0) diff --git a/examples/06.2DGraphics/main.cpp b/examples/06.2DGraphics/main.cpp index 4338a9bf..930fbea5 100644 --- a/examples/06.2DGraphics/main.cpp +++ b/examples/06.2DGraphics/main.cpp @@ -1,6 +1,6 @@ /** Example 006 2D Graphics -This Tutorial shows how to do 2d graphics with the Irrlicht Engine. +This tutorial shows how to do 2d graphics with the Irrlicht Engine. It shows how to draw images, keycolor based sprites, transparent rectangles, and different fonts. You may consider this useful if you want to make a 2d game with the engine, or if @@ -31,7 +31,6 @@ int main() return 1; // create device - IrrlichtDevice *device = createDevice(driverType, core::dimension2d(512, 384)); @@ -62,7 +61,7 @@ int main() /* To be able to draw some text with two different fonts, we first load - them. Ok, we load just one. As the first font we just use the default + them. OK, we load just one. As the first font we just use the default font which is built into the engine. Also, we define two rectangles which specify the position of the images of the red imps (little flying creatures) in the texture. @@ -116,7 +115,7 @@ int main() (time/500 % 2) ? imp1 : imp2, 0, video::SColor(255,255,255,255), true); - // draw second flying imp with colorcylce + // draw second flying imp with color cycle driver->draw2DImage(images, core::position2d(270,105), (time/500 % 2) ? imp1 : imp2, 0, video::SColor(255,(time) % 255,255,255), true); diff --git a/examples/07.Collision/main.cpp b/examples/07.Collision/main.cpp index 8a705316..a52f493e 100644 --- a/examples/07.Collision/main.cpp +++ b/examples/07.Collision/main.cpp @@ -36,13 +36,6 @@ enum IDFlag_IsHighlightable = 1 << 1 }; -/* - Some triangle selectors allow to get collisions either per mesh or per meshbuffer. - Getting them per mesh can be faster. But if you need information about the hit - material you have to get the meshbuffer information as well. -*/ -const bool separateMeshBuffers = true; - int main() { // ask user for driver @@ -58,6 +51,14 @@ int main() if (device == 0) return 1; // could not create selected driver. + /* + If we want to receive information about the material of a hit triangle we have to get + collisions per meshbuffer. The only disadvantage of this is that getting them per + meshbuffer can be a little bit slower than per mesh, but usually that's not noticeable. + If you set this to false you will no longer get material names in the title bar. + */ + const bool separateMeshBuffers = true; + video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); @@ -95,8 +96,8 @@ int main() /* There is currently no way to split an octree by material. - So if we need that we have to create one octree per meshbuffer - and put them together in a MetaTriangleSelector. + So if we need material infos we have to create one octree per + meshbuffer and put them together in a MetaTriangleSelector. */ if ( separateMeshBuffers && q3node->getMesh()->getMeshBufferCount() > 1) { @@ -116,8 +117,8 @@ int main() } else { - // Just one octree for the whole mesh. - // Can't get information which material got hit, but for many situations that's enough. + // If you don't need material infos just create one octree for the + // whole mesh. selector = smgr->createOctreeTriangleSelector( q3node->getMesh(), q3node, 128); } @@ -129,13 +130,13 @@ int main() /* We add a first person shooter camera to the scene so that we can see and move in the quake 3 level like in tutorial 2. But this, time, we add a - special animator to the camera: A Collision Response animator. This - animator modifies the scene node to which it is attached to in order to - prevent it moving through walls, and to add gravity to it. The - only thing we have to tell the animator is how the world looks like, + special animator to the camera: A collision response animator. This + animator modifies the scene node to which it is attached in order to + prevent it from moving through walls and to add gravity to the node. The + only things we have to tell the animator is how the world looks like, how big the scene node is, how much gravity to apply and so on. After the collision response animator is attached to the camera, we do not have to do - anything more for collision detection, anything is done automatically. + anything else for collision detection, it's all done automatically. The rest of the collision detection code below is for picking. And please note another cool feature: The collision response animator can be attached also to all other scene nodes, not only to cameras. And it can @@ -144,26 +145,25 @@ int main() Now we'll take a closer look on the parameters of createCollisionResponseAnimator(). The first parameter is the - TriangleSelector, which specifies how the world, against collision - detection is done looks like. The second parameter is the scene node, - which is the object, which is affected by collision detection, in our + TriangleSelector, which specifies how the world, against which collision + detection is done, looks like. The second parameter is the scene node, + which is the object which is affected by collision detection - in our case it is the camera. The third defines how big the object is, it is the radius of an ellipsoid. Try it out and change the radius to smaller values, the camera will be able to move closer to walls after this. The next parameter is the direction and speed of gravity. We'll set it to - (0, -10, 0), which approximates to realistic gravity, assuming that our - units are meters. You could set it to (0,0,0) to disable gravity. And the - last value is just a translation: Without this, the ellipsoid with which - collision detection is done would be around the camera, and the camera would - be in the middle of the ellipsoid. But as human beings, we are used to have our - eyes on top of the body, with which we collide with our world, not in - the middle of it. So we place the scene node 50 units over the center - of the ellipsoid with this parameter. And that's it, collision - detection works now. + (0, -1000, 0), which approximates realistic gravity (depends on the units + which are used in the scene model). You could set it to (0,0,0) to disable + gravity. And the last value is just an offset: Without it the ellipsoid with + which collision detection is done would be around the camera and the camera + would be in the middle of the ellipsoid. But as human beings, we are used to + have our eyes on top of the body, not in the middle of it. So we place the + scene node 50 units over the center of the ellipsoid with this parameter. + And that's it, collision detection works now. */ - // Set a jump speed of 3 units per second, which gives a fairly realistic jump - // when used with the gravity of (0, -10, 0) in the collision response animator. + // Set a jump speed of 300 units per second, which gives a fairly realistic jump + // when used with the gravity of (0, -1000, 0) in the collision response animator. scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, ID_IsNotPickable, 0, 0, true, 300.f); camera->setPosition(core::vector3df(50,50,-60)); @@ -300,7 +300,7 @@ int main() // collision point/triangle, and returns the scene node containing that point. // Irrlicht provides other types of selection, including ray/triangle selector, // ray/box and ellipse/triangle selector, plus associated helpers. - // See the methods of ISceneCollisionManager + // You might also want to check the other methods of ISceneCollisionManager. irr::io::SNamedPath hitTextureName; scene::SCollisionHit hitResult; @@ -334,6 +334,7 @@ int main() highlightedSceneNode->setMaterialFlag(video::EMF_LIGHTING, false); } + // When separateMeshBuffers is set to true we can now find out which material was hit if ( hitResult.MeshBuffer && hitResult.Node && hitResult.Node->getMaterial(hitResult.MaterialIndex).TextureLayer[0].Texture ) { // Note we are interested in the node material and not in the meshbuffer material. @@ -347,6 +348,7 @@ int main() // Show some info in title-bar int fps = driver->getFPS(); + static core::stringw lastString; core::stringw str = L"Collision detection example - Irrlicht Engine ["; str += driver->getName(); str += "] FPS:"; @@ -357,7 +359,11 @@ int main() irr::io::path texName(hitTextureName.getInternalName()); str += core::deletePathFromFilename(texName); } - device->setWindowCaption(str.c_str()); + if ( str != lastString ) // changing caption is somewhat expensive, so don't when nothing changed + { + device->setWindowCaption(str.c_str()); + lastString = str; + } } device->drop(); @@ -367,4 +373,3 @@ int main() /* **/ - diff --git a/examples/08.SpecialFX/main.cpp b/examples/08.SpecialFX/main.cpp index 87a15163..ddac5d88 100644 --- a/examples/08.SpecialFX/main.cpp +++ b/examples/08.SpecialFX/main.cpp @@ -1,15 +1,14 @@ /** Example 008 SpecialFX -This tutorials describes how to do special effects. It shows how to use stencil +This tutorial describes how to do special effects. It shows how to use stencil buffer shadows, the particle system, billboards, dynamic light, and the water surface scene node. We start like in some tutorials before. Please note that this time, the 'shadows' flag in createDevice() is set to true, for we want to have a dynamic shadow cast from an animated character. If this example runs too slow, -set it to false. The Irrlicht Engine checks if your hardware doesn't support -the stencil buffer, and disables shadows by itself, but just in case the demo -runs slow on your hardware. +set it to false. The Irrlicht Engine also checks if your hardware doesn't +support the stencil buffer, and then disables shadows by itself. */ #include @@ -57,7 +56,7 @@ int main() const io::path mediaPath = getExampleMediaPath(); /* - For our environment, we load a .3ds file. It is a small room I modelled + For our environment, we load a .3ds file. It is a small room I modeled with Anim8or and exported into the 3ds format because the Irrlicht Engine does not support the .an8 format. I am a very bad 3d graphic artist, and so the texture mapping is not very nice in this model. diff --git a/examples/09.Meshviewer/main.cpp b/examples/09.Meshviewer/main.cpp index b06e0577..aa21c2bc 100644 --- a/examples/09.Meshviewer/main.cpp +++ b/examples/09.Meshviewer/main.cpp @@ -8,10 +8,10 @@ MessageBoxes, SkyBoxes, and how to parse XML files with the integrated XML reader of the engine. We start like in most other tutorials: Include all necessary header files, add -a comment to let the engine be linked with the right .lib file in Visual +a comment to let the engine be linked with the correct .lib file in Visual Studio, and declare some global variables. We also add two 'using namespace' statements, so we do not need to write the whole names of all classes. In this -tutorial, we use a lot stuff from the gui namespace. +tutorial, we use a lot of stuff from the gui namespace. */ #include #include "driverChoice.h" @@ -168,8 +168,6 @@ displays a short message box, if the model could not be loaded. */ void loadModel(const c8* fn) { - // modify the name if it a .pk3 file - io::path filename(fn); io::path extension; @@ -184,14 +182,15 @@ void loadModel(const c8* fn) extension == ".bmp" || extension == ".wal" || extension == ".rgb" || extension == ".rgba") { - video::ITexture * texture = - Device->getVideoDriver()->getTexture( filename ); + // Ensure reloading texture by clearing old one out of cache + video::ITexture * texture = Device->getVideoDriver()->findTexture( filename ); + if ( texture ) + Device->getVideoDriver()->removeTexture(texture); + + // Load the new one and put int on the model + texture = Device->getVideoDriver()->getTexture( filename ); if ( texture && Model ) { - // always reload texture - Device->getVideoDriver()->removeTexture(texture); - texture = Device->getVideoDriver()->getTexture( filename ); - Model->setMaterialTexture(0, texture); } return; @@ -203,12 +202,15 @@ void loadModel(const c8* fn) return; } - // load a model into the engine + // Remove old model if (Model) + { Model->remove(); + Model = 0; + } - Model = 0; + // .irr is a scene format, so load as scene and set Model pointer to first object in the scene if (extension==".irr") { @@ -220,11 +222,13 @@ void loadModel(const c8* fn) return; } + // load a model into the engine. Also log the time it takes to load it. + u32 then = Device->getTimer()->getRealTime(); - scene::IAnimatedMesh* m = Device->getSceneManager()->getMesh( filename.c_str() ); + scene::IAnimatedMesh* mesh = Device->getSceneManager()->getMesh( filename.c_str() ); Device->getLogger()->log("Loading time (ms): ", core::stringc(Device->getTimer()->getRealTime() - then).c_str()); - if (!m) + if (!mesh) { // model could not be loaded @@ -238,10 +242,10 @@ void loadModel(const c8* fn) // set default material properties if (Octree) - Model = Device->getSceneManager()->addOctreeSceneNode(m->getMesh(0)); + Model = Device->getSceneManager()->addOctreeSceneNode(mesh->getMesh(0)); else { - scene::IAnimatedMeshSceneNode* animModel = Device->getSceneManager()->addAnimatedMeshSceneNode(m); + scene::IAnimatedMeshSceneNode* animModel = Device->getSceneManager()->addAnimatedMeshSceneNode(mesh); Model = animModel; } Model->setMaterialFlag(video::EMF_LIGHTING, UseLight); @@ -261,8 +265,9 @@ void loadModel(const c8* fn) /* Function createToolBox() creates a toolbox window. In this simple mesh -viewer, this toolbox only contains a tab control with three edit boxes for -changing the scale of the displayed model. +viewer, this toolbox only contains a controls to change the scale +and animation speed of the model and a control to set the transparency +of the GUI-elements. */ void createToolBox() { @@ -409,7 +414,7 @@ class MyEventReceiver : public IEventReceiver public: virtual bool OnEvent(const SEvent& event) { - // Escape swaps Camera Input + // Key events if (event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == false) { @@ -417,6 +422,7 @@ public: return true; } + // GUI events if (event.EventType == EET_GUI_EVENT) { s32 id = event.GUIEvent.Caller->getID(); @@ -470,7 +476,7 @@ public: { case GUI_ID_BUTTON_SET_SCALE: { - // set scale + // set model scale gui::IGUIElement* root = env->getRootGUIElement(); core::vector3df scale; core::stringc s; @@ -531,6 +537,7 @@ public: if ( hasModalDialog() ) return false; + // Escape swaps Camera Input if (keyCode == irr::KEY_ESCAPE) { if (Device) @@ -546,6 +553,7 @@ public: } else if (keyCode == irr::KEY_F1) { + // Swap display of position information about the camera if (Device) { IGUIElement* elem = Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_POSITION_TEXT); @@ -581,7 +589,7 @@ public: switch(id) { - case GUI_ID_OPEN_MODEL: // FilOnButtonSetScalinge -> Open Model + case GUI_ID_OPEN_MODEL: // File -> Open Model File & Texture env->addFileOpenDialog(L"Please select a model file to open"); break; case GUI_ID_SET_MODEL_ARCHIVE: // File -> Set Model Archive @@ -809,11 +817,18 @@ int main(int argc, char* argv[]) if (xml) xml->drop(); // don't forget to delete the xml reader + // We can pass a model to load per command line parameter if (argc > 1) StartUpModelFile = argv[1]; + // set a nicer font + IGUISkin* skin = env->getSkin(); + IGUIFont* font = env->getFont("fonthaettenschweiler.bmp"); + if (font) + skin->setFont(font); + /* - That wasn't difficult. Now we'll set a nicer font and create the Menu. + Now create the Menu. It is possible to create submenus for every menu item. The call menu->addItem(L"File", -1, true, true); for example adds a new menu Item with the name "File" and the id -1. The following parameter says @@ -822,15 +837,6 @@ int main(int argc, char* argv[]) menu->getSubMenu(0), because the "File" entry is the menu item with index 0. */ - - // set a nicer font - - IGUISkin* skin = env->getSkin(); - IGUIFont* font = env->getFont("fonthaettenschweiler.bmp"); - if (font) - skin->setFont(font); - - // create menu gui::IGUIContextMenu* menu = env->addMenu(); menu->addItem(L"File", -1, true, true); menu->addItem(L"View", -1, true, true); @@ -932,18 +938,16 @@ int main(int argc, char* argv[]) postext->setVisible(false); // set window caption - Caption += " - ["; Caption += driver->getName(); Caption += "]"; Device->setWindowCaption(Caption.c_str()); /* - That's nearly the whole application. We simply show the about message - box at start up, and load the first model. To make everything look - better, a skybox is created and a user controlled camera, to make the - application a little bit more interactive. Finally, everything is drawn - in a standard drawing loop. + Now we show the about message box at start up, and load the first model. + To make everything look better a skybox is created. We also add a user + controlled camera, to make the application more interactive. + Finally, everything is drawn in a standard drawing loop. */ // show about message box and load default model @@ -952,7 +956,6 @@ int main(int argc, char* argv[]) loadModel(StartUpModelFile.c_str()); // add skybox - SkyBox = smgr->addSkyBoxSceneNode( driver->getTexture("irrlicht2_up.jpg"), driver->getTexture("irrlicht2_dn.jpg"), @@ -988,7 +991,6 @@ int main(int argc, char* argv[]) bool hasFocus = Device->isWindowFocused(); // draw everything - while(Device->run() && driver) { // Catch focus changes (workaround until Irrlicht has events for this) diff --git a/examples/10.Shaders/main.cpp b/examples/10.Shaders/main.cpp index 544ef3c6..70b9909f 100644 --- a/examples/10.Shaders/main.cpp +++ b/examples/10.Shaders/main.cpp @@ -298,7 +298,15 @@ int main() if (gpu) { - MyShaderCallBack* mc = new MyShaderCallBack(); + /* + Create one callback instance for each shader material you add. + Reason is that the getVertexShaderConstantID returns ID's which are + only valid per added material (The ID's tend to be identical + as long as the shader code is exactly identical, but it's not good + style to depend on that). + */ + MyShaderCallBack* mcSolid = new MyShaderCallBack(); + MyShaderCallBack* mcTransparentAdd = new MyShaderCallBack(); // create the shaders depending on if the user wanted high level // or low level shaders: @@ -314,25 +322,26 @@ int main() newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psFileName, "pixelMain", video::EPST_PS_1_1, - mc, video::EMT_SOLID, 0, shadingLanguage); + mcSolid, video::EMT_SOLID, 0, shadingLanguage); newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", video::EVST_VS_1_1, psFileName, "pixelMain", video::EPST_PS_1_1, - mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage); + mcTransparentAdd, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage); } else { // create material from low level shaders (asm or arb_asm) newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName, - psFileName, mc, video::EMT_SOLID); + psFileName, mcSolid, video::EMT_SOLID); newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName, - psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR); + psFileName, mcTransparentAdd, video::EMT_TRANSPARENT_ADD_COLOR); } - mc->drop(); + mcSolid->drop(); + mcTransparentAdd->drop(); } /* diff --git a/examples/16.Quake3MapShader/main.cpp b/examples/16.Quake3MapShader/main.cpp index 4a91b4e3..e8a318dc 100644 --- a/examples/16.Quake3MapShader/main.cpp +++ b/examples/16.Quake3MapShader/main.cpp @@ -1,6 +1,6 @@ /** Example 016 Quake3 Map Shader Support -This Tutorial shows how to load a Quake 3 map into the +This tutorial shows how to load a Quake 3 map into the engine, create a SceneNode for optimizing the speed of rendering and how to create a user controlled camera. diff --git a/examples/21.Quake3Explorer/main.cpp b/examples/21.Quake3Explorer/main.cpp index 8fd7d26b..7b14c92f 100644 --- a/examples/21.Quake3Explorer/main.cpp +++ b/examples/21.Quake3Explorer/main.cpp @@ -1,6 +1,6 @@ /** Example 021 Quake3 Explorer -This Tutorial shows how to load different Quake 3 maps. +This tutorial shows how to load different Quake 3 maps. Features: - Load BSP Archives at Runtime from the menu @@ -289,7 +289,8 @@ void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode * ICameraSceneNode* camera = 0; - SKeyMap keyMap[10]; + core::array keyMap; + keyMap.set_used(12); keyMap[0].Action = EKA_MOVE_FORWARD; keyMap[0].KeyCode = KEY_UP; keyMap[1].Action = EKA_MOVE_FORWARD; @@ -316,7 +317,13 @@ void Q3Player::create ( IrrlichtDevice *device, IQ3LevelMesh* mesh, ISceneNode * keyMap[9].Action = EKA_CROUCH; keyMap[9].KeyCode = KEY_KEY_C; - camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap, 10, false, 600.f); + keyMap[10].Action = EKA_ROTATE_LEFT; + keyMap[10].KeyCode = KEY_KEY_Q; + + keyMap[11].Action = EKA_ROTATE_RIGHT; + keyMap[11].KeyCode = KEY_KEY_E; + + camera = smgr->addCameraSceneNodeFPS(0, 100.0f, 0.6f, -1, keyMap.pointer(), keyMap.size(), false, 600.f); camera->setName ( "First Person Camera" ); //camera->setFOV ( 100.f * core::DEGTORAD ); camera->setFarValue( 20000.f ); diff --git a/examples/22.MaterialViewer/main.cpp b/examples/22.MaterialViewer/main.cpp index 08b7a21a..77181d79 100755 --- a/examples/22.MaterialViewer/main.cpp +++ b/examples/22.MaterialViewer/main.cpp @@ -10,7 +10,7 @@ You can move the camera while left-mouse button is clicked. // TODO: Should be possible to set all material values by the GUI. // For now just change the defaultMaterial in CApp::init for the rest. -// TODO: Allow users to switch between a sphere and a box meshĵ +// TODO: Allow users to switch between a sphere and a box mesh. #include #include "driverChoice.h" diff --git a/examples/26.OcclusionQuery/main.cpp b/examples/26.OcclusionQuery/main.cpp index d6de904c..6aea63cb 100644 --- a/examples/26.OcclusionQuery/main.cpp +++ b/examples/26.OcclusionQuery/main.cpp @@ -1,6 +1,6 @@ /** Example 026 OcclusionQuery -This Tutorial shows how to speed up rendering by use of the +This tutorial shows how to speed up rendering by use of the OcclusionQuery feature. The usual rendering tries to avoid rendering of scene nodes by culling those nodes which are outside the visible area, the view frustum. However, this technique does not cope with occluded objects diff --git a/examples/Demo/CDemo.cpp b/examples/Demo/CDemo.cpp index fe7a9d0d..43bbdf8e 100644 --- a/examples/Demo/CDemo.cpp +++ b/examples/Demo/CDemo.cpp @@ -304,31 +304,27 @@ void CDemo::switchToNextScene() campFire->setVisible(true); timeForThisScene = -1; - SKeyMap keyMap[9]; - keyMap[0].Action = EKA_MOVE_FORWARD; - keyMap[0].KeyCode = KEY_UP; - keyMap[1].Action = EKA_MOVE_FORWARD; - keyMap[1].KeyCode = KEY_KEY_W; + core::array keyMap(11); - keyMap[2].Action = EKA_MOVE_BACKWARD; - keyMap[2].KeyCode = KEY_DOWN; - keyMap[3].Action = EKA_MOVE_BACKWARD; - keyMap[3].KeyCode = KEY_KEY_S; + keyMap.push_back( SKeyMap(EKA_MOVE_FORWARD, KEY_UP) ); + keyMap.push_back( SKeyMap(EKA_MOVE_FORWARD, KEY_KEY_W) ); - keyMap[4].Action = EKA_STRAFE_LEFT; - keyMap[4].KeyCode = KEY_LEFT; - keyMap[5].Action = EKA_STRAFE_LEFT; - keyMap[5].KeyCode = KEY_KEY_A; + keyMap.push_back( SKeyMap(EKA_MOVE_BACKWARD, KEY_DOWN) ); + keyMap.push_back( SKeyMap(EKA_MOVE_BACKWARD, KEY_KEY_S) ); - keyMap[6].Action = EKA_STRAFE_RIGHT; - keyMap[6].KeyCode = KEY_RIGHT; - keyMap[7].Action = EKA_STRAFE_RIGHT; - keyMap[7].KeyCode = KEY_KEY_D; + keyMap.push_back( SKeyMap(EKA_STRAFE_LEFT, KEY_LEFT) ); + keyMap.push_back( SKeyMap(EKA_STRAFE_LEFT, KEY_KEY_A) ); - keyMap[8].Action = EKA_JUMP_UP; - keyMap[8].KeyCode = KEY_KEY_J; + keyMap.push_back( SKeyMap(EKA_STRAFE_RIGHT, KEY_RIGHT) ); + keyMap.push_back( SKeyMap(EKA_STRAFE_RIGHT, KEY_KEY_D) ); - camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap, 9, false, 300.f); + keyMap.push_back( SKeyMap(EKA_JUMP_UP, KEY_KEY_J) ); + + keyMap.push_back( SKeyMap(EKA_ROTATE_LEFT, KEY_KEY_Q) ); + + keyMap.push_back( SKeyMap(EKA_ROTATE_RIGHT, KEY_KEY_E) ); + + camera = sm->addCameraSceneNodeFPS(0, 100.0f, .4f, -1, keyMap.pointer(), keyMap.size(), false, 300.f); camera->setPosition(core::vector3df(108,140,-140)); camera->setFarValue(5000.0f); diff --git a/examples/Demo/CMainMenu.cpp b/examples/Demo/CMainMenu.cpp index 7ad85415..ebc9469e 100644 --- a/examples/Demo/CMainMenu.cpp +++ b/examples/Demo/CMainMenu.cpp @@ -2,27 +2,34 @@ // This file is not documented. #include "CMainMenu.h" +#include "CDemo.h" #include "exampleHelper.h" CMainMenu::CMainMenu() -: startButton(0), MenuDevice(0), selected(2), start(false), fullscreen(true), - music(true), shadows(false), additive(false), transparent(true), vsync(false), aa(false) +: startButton(0), MenuDevice(0), selected(0), start(false), fullscreen(false), +#if defined(USE_IRRKLANG) || defined(USE_SDL_MIXER) + music(true), +#else + music(false), +#endif + shadows(true), additive(false), transparent(true), vsync(true), aa(true), +#ifndef _IRR_WINDOWS_ + driverType(video::EDT_OPENGL) +#else + driverType(video::EDT_DIRECT3D9) +#endif + //driverType(video::EDT_BURNINGSVIDEO) { } -bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, - bool& outAdditive, bool& outVSync, bool& outAA, - video::E_DRIVER_TYPE& outDriver) +bool CMainMenu::run() { - video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO; - driverType = video::EDT_OPENGL; + video::E_DRIVER_TYPE driverType = EDT_OPENGL; if (!IrrlichtDevice::isDriverSupported(video::EDT_OPENGL)) - driverType = video::EDT_DIRECT3D9; - if (!IrrlichtDevice::isDriverSupported(video::EDT_DIRECT3D9)) - driverType = video::EDT_SOFTWARE; + driverType = video::video::EDT_BURNINGSVIDEO; MenuDevice = createDevice(driverType, core::dimension2d(512, 384), 16, false, false, false, this); @@ -76,6 +83,14 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, box->addItem(names[i-1]); } + switch (driverType ) + { + case video::EDT_OPENGL: selected = 0; break; + case video::EDT_DIRECT3D9: selected = 1; break; + case video::EDT_BURNINGSVIDEO: selected = 2; break; + case video::EDT_SOFTWARE: selected = 3; break; + default: break; + } box->setSelected(selected); // add button @@ -254,13 +269,6 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, MenuDevice->drop(); - outFullscreen = fullscreen; - outMusic = music; - outShadows = shadows; - outAdditive = additive; - outVSync = vsync; - outAA = aa; - for (u32 i=1; i& texture, ITexture* depthStencil) = 0; - + //! Set one texture. void setTexture(ITexture* texture, ITexture* depthStencil) { @@ -58,17 +58,22 @@ namespace video { return DriverType; } - + protected: - + //! Textures assigned to render target. core::array Texture; - + //! Depth or packed depth-stencil texture assigned to render target. ITexture* DepthStencil; //! Driver type of render target. E_DRIVER_TYPE DriverType; + + private: + // no copying (IReferenceCounted still allows that for reasons which take some time to work around) + IRenderTarget(const IRenderTarget&); + IRenderTarget& operator=(const IRenderTarget&); }; } diff --git a/include/driverChoice.h b/include/driverChoice.h index 4f20a6d9..accd4034 100644 --- a/include/driverChoice.h +++ b/include/driverChoice.h @@ -14,36 +14,38 @@ namespace irr { //! ask user for driver - static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=true) + static irr::video::E_DRIVER_TYPE driverChoiceConsole(bool allDrivers=false) { #if defined (_IRR_IPHONE_PLATFORM_) || defined (_IRR_ANDROID_PLATFORM_) return irr::video::EDT_OGLES2; #else printf("Please select the driver you want:\n"); irr::u32 i=0; - char c; + char c = 'a'; for (i=irr::video::EDT_COUNT; i>0; --i) { - if (allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1)))) + if ( allDrivers || irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1)) ) { - if (irr::video::E_DRIVER_TYPE(i-1) == irr::video::EDT_OPENGL) - c = 'a'+irr::video::EDT_COUNT-i; - - printf(" (%c) %s\n", 'a'+irr::video::EDT_COUNT-i, irr::video::DRIVER_TYPE_NAMES[i-1]); + printf(" (%c) %s\n", c, irr::video::DRIVER_TYPE_NAMES[i-1]); + ++c; } } - std::cin >> c; - c = irr::video::EDT_COUNT+'a'-c; + char userSelection; + std::cin >> userSelection; + c = 'a'; for (i=irr::video::EDT_COUNT; i>0; --i) { - if (!(allDrivers || (irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1))))) - --c; - if ((char)i==c) - return irr::video::E_DRIVER_TYPE(i-1); + if ( allDrivers || irr::IrrlichtDevice::isDriverSupported(irr::video::E_DRIVER_TYPE(i-1)) ) + { + if (userSelection == c) + return irr::video::E_DRIVER_TYPE(i-1); + ++c; + } } + return irr::video::EDT_COUNT; #endif } diff --git a/include/irrTypes.h b/include/irrTypes.h index d4254c27..9911b21e 100644 --- a/include/irrTypes.h +++ b/include/irrTypes.h @@ -7,8 +7,8 @@ #include "IrrCompileConfig.h" -#if __GNUC__ && __STDC_VERSION__ >= 199901L // Should at least be available since C99 - #include // needed by __WORDSIZE below +#if defined(__GNUC__) + #include // for __WORDSIZE #endif namespace irr @@ -76,8 +76,8 @@ typedef signed int s32; /** This is a typedef for 64bit uint, it ensures portability of the engine. */ #if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) typedef unsigned __int64 u64; -#elif __GNUC__ -#if __WORDSIZE == 64 +#elif defined(__GNUC__) +#if defined(__WORDSIZE) && __WORDSIZE == 64 typedef unsigned long int u64; #else __extension__ typedef unsigned long long u64; @@ -90,8 +90,8 @@ typedef unsigned long long u64; /** This is a typedef for 64bit int, it ensures portability of the engine. */ #if defined(_MSC_VER) || ((__BORLANDC__ >= 0x530) && !defined(__STRICT_ANSI__)) typedef __int64 s64; -#elif __GNUC__ -#if __WORDSIZE == 64 +#elif defined(__GNUC__) +#if defined(__WORDSIZE) && __WORDSIZE == 64 typedef long int s64; #else __extension__ typedef long long s64; diff --git a/source/Irrlicht/COpenGLCoreTexture.h b/source/Irrlicht/COpenGLCoreTexture.h index 7c71a28c..31e62bfb 100644 --- a/source/Irrlicht/COpenGLCoreTexture.h +++ b/source/Irrlicht/COpenGLCoreTexture.h @@ -131,6 +131,8 @@ public: Image.clear(); } + + Driver->testGLError(__LINE__); } COpenGLCoreTexture(const io::path& name, const core::dimension2d& size, ECOLOR_FORMAT format, TOpenGLDriver* driver) : ITexture(name, ETT_2D), Driver(driver), TextureType(GL_TEXTURE_2D), @@ -176,6 +178,7 @@ public: glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, Size.Width, Size.Height, 0, PixelFormat, PixelType, 0); Driver->getCacheHandler()->getTextureCache().set(0, prevTexture); + Driver->testGLError(__LINE__); } virtual ~COpenGLCoreTexture() diff --git a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp index d89fef0c..49453923 100644 --- a/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp +++ b/source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp @@ -40,13 +40,9 @@ CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cu // create default key map KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP)); KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN)); - KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_KEY_W)); - KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_KEY_S)); - KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_KEY_A)); - KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_KEY_D)); + KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT)); + KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT)); KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J)); - KeyMap.push_back(SKeyMap(EKA_ROTATE_LEFT, irr::KEY_LEFT)); - KeyMap.push_back(SKeyMap(EKA_ROTATE_RIGHT, irr::KEY_RIGHT)); } else {