Minor updates &f fixes to examples and their documentation.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5499 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
0c8a5f8700
commit
c0e17f7329
|
@ -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<u32>(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<s32>(10,20));
|
||||
|
||||
gui::IGUIStaticText* diagnostics = device->getGUIEnvironment()->addStaticText(
|
||||
L"", core::rect<s32>(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));
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
@ -183,9 +183,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()
|
||||
{
|
||||
|
@ -195,7 +195,6 @@ int main()
|
|||
return 1;
|
||||
|
||||
// create device and exit if creation failed
|
||||
|
||||
IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
|
||||
|
||||
if (device == 0)
|
||||
|
|
|
@ -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<u32>(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<s32>(270,105),
|
||||
(time/500 % 2) ? imp1 : imp2, 0,
|
||||
video::SColor(255,(time) % 255,255,255), true);
|
||||
|
|
|
@ -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()
|
|||
|
||||
/*
|
||||
**/
|
||||
|
||||
|
|
|
@ -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 <irrlicht.h>
|
||||
|
@ -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.
|
||||
|
|
|
@ -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 <irrlicht.h>
|
||||
#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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <irrlicht.h>
|
||||
#include "driverChoice.h"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue