EndScene() public method

Ends the scene
public EndScene ( ) : void
return void
コード例 #1
0
ファイル: ATMOSkytest.cs プロジェクト: Paulus/irrlichtnetcp
        public static void Main()
        {
            IrrlichtDevice device = new IrrlichtDevice(DriverType.OpenGL,
                                                    new Dimension2D(640, 480),
                                                    32, false, true, true, true);

            device.FileSystem.WorkingDirectory = "../../medias";
            device.OnEvent += new OnEventDelegate(device_OnEvent);

            string caption = "Irrlicht .NET CP ATMOSpere test";

            driver = device.VideoDriver;
            scene = device.SceneManager;

            terrain = scene.AddTerrainSceneNode(
                "terrain-heightmap.bmp", null, -1,
                new Vector3D(0,0,0), new Vector3D(1,1,1), new Vector3D(40, 4.4f, 40), new Color(255, 255, 255, 255),5,TerrainPatchSize.TPS17);

            terrain.SetMaterialFlag(MaterialFlag.Lighting, false);
            terrain.SetMaterialType(MaterialType.DetailMap);
            terrain.SetMaterialTexture(0, driver.GetTexture("terrain-texture.jpg"));
            terrain.SetMaterialTexture(1, driver.GetTexture("detail2.tga"));

            terrain.ScaleTexture(1.0f, 20.0f);

               	atmo = new ATMOSphere(device.Timer, null, scene, -1);
               	atmo.SkyTexture = driver.GetTexture("sky2.tga");
               	atmo.SunTexture = driver.GetTexture("sun.tga");
               	atmo.StarsTexture = driver.GetTexture("stars.bmp");
               	atmo.CreateSkyPalette();
            atmo.Speed = 600.0f;

                                KeyMap keyMap = new KeyMap();
                    keyMap.AssignAction(KeyAction.MoveForward,KeyCode.Key_W);
                    keyMap.AssignAction(KeyAction.MoveBackward,KeyCode.Key_S);
                    keyMap.AssignAction(KeyAction.StrafeLeft,KeyCode.Key_A);
                    keyMap.AssignAction(KeyAction.StrafeRight,KeyCode.Key_D);

            CameraSceneNode fpsCam = scene.AddCameraSceneNodeFPS(null, 50, 200, false, keyMap);
            fpsCam.Position = Vector3D.From(2200,440,2000);

            device.CursorControl.Visible = false;
            driver.SetTextureFlag(TextureCreationFlag.Always32Bit, true);
            Timer timer = device.Timer;

            new ATMOSkytest();

            while (device.Run() && !Exit)
            {
                driver.BeginScene(true, true, Color.Gray);
               			atmo.Update(device.Timer.RealTime);
                scene.DrawAll();
                driver.EndScene();

            }
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Paulus/irrlichtnetcp
        static void Main(string[] args)
        {
            //We choosed OpenGL because it is cross-platform and GUI does not need
            //Amazing performances...
            IrrlichtDevice device = new IrrlichtDevice(DriverType.OpenGL,
                                                    new Dimension2D(640, 480),
                                                    16, false, false, false, false);
            //Delegate that will catch our events
            device.OnEvent += new OnEventDelegate(device_OnEvent);

            //Does not seem to work on Linux but well...
            device.Resizeable = false;

            //We set a basic caption
            device.WindowCaption = "Irrlicht .NET CP General User Interface Example";

            //We set our handlers
            driver = device.VideoDriver;
            guienv = device.GUIEnvironment;

            //We set the skin as a metallic windows skin
            guienv.Skin = guienv.CreateSkin(GUISkinTypes.WindowsMetallic);
            guienv.Skin.SetColor(GuiDefaultColor.ButtonText, Color.White);

            TTFont font = new TTFont(device.VideoDriver);
            font.Antialias = true;
            TTFace face = new TTFace();
            face.Load("../../medias/FreeSans.ttf");
            font.Attach(face, 14);
            guienv.Skin.Font = font;

            //Our fader. We set it as first because we don't want him to hide our buttons.
            guienv.AddInOutFader(null, (int)GUIItems.Fader);
            //We add several buttons with the IDs we defined downwards
            guienv.AddButton(new Rect(new Position2D(250, 0), new Dimension2D(140, 100)),
                             null, (int)GUIItems.ClickMe, "Click me !");
            guienv.AddButton(new Rect(new Position2D(250, 380), new Dimension2D(140, 100)),
                             null, (int)GUIItems.DontClickMe, "Don't click me !");
            guienv.AddButton(new Rect(new Position2D(0, 190), new Dimension2D(140, 100)),
                             null, (int)GUIItems.FadeMe, "Fade me !");
            guienv.AddButton(new Rect(new Position2D(500, 190), new Dimension2D(140, 100)),
                             null, (int)GUIItems.FunnyEffect, "Funny effect !");

            guienv.AddStaticText ("Move this scrollbar and you'll see the miracle !", new Rect(new Position2D(220, 240), new Dimension2D(240, 30)),
                                  false, true, null, -1, false);

            guienv.AddSpinBox ("", new Rect(new Position2D (220, 270), new Dimension2D (120, 30)), null, -1);
            guienv.AddEditBox ("", new Rect(new Position2D (220, 300), new Dimension2D (120, 30)), true, null, -1);

            listbox = guienv.AddListBox(new Rect(new Position2D(400, 20), new Dimension2D(220, 150)), null, -1, true);
            //Our logo
            guienv.AddImage(driver.GetTexture("../../medias/NETCPlogo.png"), new Position2D(0, 0), true, null, -1, "");

            //And now the scrollbar
            GUIScrollBar scroll = guienv.AddScrollBar(true, new Rect(new Position2D(220, 220), new Dimension2D(240, 20)), null,
                                (int)GUIItems.ScrollBar);

            el = new CustomElement(guienv, null, -1, new Rect(new Position2D(220, 120), new Dimension2D(160, 100)));

            //Var for the funny effects
            int toAdd = 1;
            //While the device is running and we don't want him to exit
            while (device.Run() && !Exit)
            {
                //If our funny effect is enabled, we just scroll the scrollbar
                //It may seems strange but the "ScrollBarChanged" event is NOT fired
                //When we manually change the position... It's a gift and a cursed, depending on the situation.
                if (FunnyEffectEnabled)
                {
                    scroll.Pos += toAdd;
                    if(scroll.Pos >= 100 || scroll.Pos <= 0)
                        toAdd = -toAdd;
                    BackColor = Color.From(255, 255-scroll.Pos * 5 / 2, 255 - (scroll.Pos * 5 / 2), scroll.Pos * 5 / 2);
                }
                //Here we are, we begin the scene
                //Notice that we DO NOT use the ZBuffer because we have only two dimensions
                driver.BeginScene(true, false, BackColor);
                //We draw all the GUI
                guienv.DrawAll();
                //And we end
                driver.EndScene();
            }
            //As in the first example, we need to release main resources
            device.DumpElements();
            device.Close();
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: Paulus/irrlichtnetcp
        static void Main(string[] args)
        {
            //We choosed OpenGL because it is cross-platform and we only have the openGL shader
            //So please do not change this unless you change the shader !
            IrrlichtDevice device = new IrrlichtDevice(DriverType.Direct3D9,
                                                    new Dimension2D(640, 480),
                                                    32, false, true, true, false);
            //We set a new working directory
            device.FileSystem.WorkingDirectory = "../../medias";
            device.OnEvent += new OnEventDelegate(device_OnEvent);

            //We set a basic caption
            string caption = "Irrlicht .NET CP Shaders and Particles Example";

            //We set our handlers
            Driver = device.VideoDriver;
            Scene = device.SceneManager;

            //We have already seen that... The only special thing is the pointless emitter (what a funny name isn't it ?)
            //Which is detailed just down.
            Texture fire = Driver.GetTexture("fire.bmp");
            ParticleSystemSceneNode particles = Scene.AddParticleSystemSceneNode(false, null, -1);
            particles.SetEmitter(new PointlessEmitter());
            //particles.AddAffector(new PointlessAffector());
            particles.SetMaterialTexture(0, fire);
            particles.SetMaterialType(MaterialType.TransparentAddColor);
            particles.SetMaterialFlag(MaterialFlag.Lighting, false);
            particles.ParticleSize = new Dimension2Df(50, 50);
            particles.ParticlesAreGlobal = false;

            particles = Scene.AddParticleSystemSceneNode(false, null, -1);
            particles.SetEmitter(new PointlessEmitter());
            //particles.AddAffector(new PointlessAffector());
            particles.SetMaterialTexture(0, fire);
            particles.SetMaterialType(MaterialType.TransparentAddColor);
            particles.SetMaterialFlag(MaterialFlag.Lighting, false);
            particles.ParticleSize = new Dimension2Df(50, 50);
            particles.Position = new Vector3D(0, 400, 0);
            particles.ParticlesAreGlobal = false;

            particles = Scene.AddParticleSystemSceneNode(false, null, -1);
            particles.SetEmitter(new PointlessEmitter());
            //particles.AddAffector(new PointlessAffector());
            particles.SetMaterialTexture(0, fire);
            particles.SetMaterialType(MaterialType.TransparentAddColor);
            particles.SetMaterialFlag(MaterialFlag.Lighting, false);
            particles.ParticleSize = new Dimension2Df(50, 50);
            particles.Position = new Vector3D(0, -400, 0);
            particles.ParticlesAreGlobal = false;

            //Here we only create 3 cubes and add a texture... Nothing exciting
            SceneNode cube1, cube2, cube3;
            cube1 = Scene.AddCubeSceneNode(40f, null, -1);
            cube2 = Scene.AddCubeSceneNode(40f, null, -1);
            cube3 = Scene.AddCubeSceneNode(40f, null, -1);
            cube1.SetMaterialTexture(0, Driver.GetTexture("rockwall.bmp"));
            cube2.SetMaterialTexture(0, Driver.GetTexture("rockwall.bmp"));
            cube3.SetMaterialTexture(0, Driver.GetTexture("rockwall.bmp"));

            //Here comes the fun... We create two low level shaders (taken from Irrlich's shader Example) and we set the base material as
            //Solid for the first one and transparent for the second
            int mat = Driver.GPUProgrammingServices.AddShaderMaterialFromFiles("opengl.vsh", "opengl.psh", OnShaderSet, MaterialType.Solid, 0);
            int mat2 = Driver.GPUProgrammingServices.AddShaderMaterialFromFiles("opengl.vsh", "opengl.psh", OnShaderSet, MaterialType.TransparentAddColor, 0);
            //And now we add both materials... Notice that no cast is needed because SetMaterialType
            //Has an overload especially made for shaders !
            cube2.SetMaterialType(mat);
            cube3.SetMaterialType(mat2);

            cube2.Position = new Vector3D(0, -40, 0);
            cube3.Position = new Vector3D(0, 40, 0);

            //We create a fixed cam for our render target scene
            CameraSceneNode fixedcam = Scene.AddCameraSceneNode(null);
            fixedcam.Position = new Vector3D(50, 0, -1000);
            fixedcam.FarValue = 10000f;
            fixedcam.AddAnimator(Scene.CreateFlyCircleAnimator(fixedcam.Target, 5000f, 0.001f));

            //And a fps cam for our main scene
            CameraSceneNode fpscam = Scene.AddCameraSceneNodeFPS(null, 100f, 400f, false);
            Scene.ActiveCamera.Position = new Vector3D(50, 0, -1000);
            Scene.ActiveCamera.FarValue = 10000f;

            Texture mask = Driver.AddTexture(new Dimension2D(128, 128), "", ColorFormat.A8R8G8B8);

            //Here is another cool feature from .NET CP
            //Direct access to textures via Texture.Lock/Unlock and Texture.SetPixel/GetPixel
            //Uncomment these lines to see the effect :)
            /*int w = mask.OriginalSize.Width;
            int h = mask.OriginalSize.Height;
            double maxdistance = Math.Sqrt(Math.Pow(w, 2) + Math.Pow(h, 2));
            mask.Lock();
            for (int x = 0; x < w; x++)
                for (int y = 0; y < h; y++)
                {
                    double distance = Math.Sqrt(Math.Pow((w - x), 2) + Math.Pow((h - y), 2));
                    double coeff = distance / maxdistance;
                    int color = (int)(255 - (255 * coeff));
                    Color pixel = new Color((int)(color / 1.5), (int)(color / 1.5), (int)(color / 2), (int)(color / 2));
                    mask.SetPixel(x, y, pixel);
                }
            mask.Unlock();
            //Again a useful feature... Direct texture saving to common formats such as png,jpg,bmp or gif...
            //Without coding anything, your texture is directly saved in Irrlicht's working directory !
            mask.Save("image.png");*/

            //You may have noticed that GetPixel/SetPixel is very slow even if you lock the texture.
            //Another insecure but quite faster way to proceed is to convert our lock to a pointer.
            //It needs unsafe code but works very fast...
            //However it is very unsecure and you must know perfectly what you are doing...
            //That's why Modify/Retrieve exists (look down)
            /*int w = mask.OriginalSize.Width;
            int h = mask.OriginalSize.Height;
            double maxdistance = Math.Sqrt(Math.Pow(w, 2) + Math.Pow(h, 2));
            IntPtr lockresult = mask.Lock();
            unsafe
            {
                int* directacces = (int*)(void*)lockresult;
                int pitch = mask.Pitch / 4;
                for (int x = 0; x < w; ++x)
                    for (int y = 0; y < h; ++y)
                    {
                        double distance = Math.Sqrt(Math.Pow((w - x), 2) + Math.Pow((h - y), 2));
                        double coeff = distance / maxdistance;
                        int color = (int)(255 - (255 * coeff));
                        Color pixel = new Color((int)(color / 1.5), (int)(color / 1.5), (int)(color / 2), (int)(color / 2));
                        directacces[x + y * pitch] = pixel.NativeColor;
                    }
            }
            mask.Unlock();*/

            //Here is the SAFEST AND FASTEST way to modify our texture.
            //A simple delegate which takes the coords of the pixel and returns the color
            //It is called on each pixel and you can even return false if you don't want to change the pixel.
            //We can now create our mask without speed or compatibility issue !
            int w = mask.OriginalSize.Width / 2;
            int h = mask.OriginalSize.Height / 2;
            double maxdistance = Math.Sqrt(Math.Pow(w, 2) + Math.Pow(h, 2));
            //We create a delegate to modify each pixel
            ModifyPixel del = delegate(int x, int y, out Color col)
            {
                //Here is our formula... You can modify it as you wish, this is just an example !
                double distance = Math.Sqrt(Math.Pow((w - x), 2) + Math.Pow((h - y), 2));
                double coeff = distance / maxdistance;
                int color = (int)(255 - (255 * coeff));
                //We now set the out color
                col = new Color((int)(color / 1.5), (int)(color / 1.5), (int)(color / 2), (int)(color / 2));
                //And we return true since we created a color.
                //If you return false, the current pixel won't be modified !
                return true;
            };
            //And we modify our texture with our delegate
            mask.Modify(del);
            //Uncomment this line to save our mask on a portable network graphic file !
            //You do not need to know jpg, bmp, gif, png... formats since they are converted automatically
            //mask.Save("mask.png");

            Console.WriteLine();
            Console.WriteLine("============================================");
            Console.WriteLine("Features List :");
            Console.WriteLine();
            for (VideoDriverFeature feat = 0; feat < VideoDriverFeature.Count; feat++)
                Console.WriteLine(feat + " = " + Driver.QueryFeature(feat));
            Console.WriteLine("============================================");

            //Here is our logo
            Texture logo = Driver.GetTexture("NETCPlogo.png");

            //Here is another feature, RenderTarget
            Texture renderTarget = Driver.CreateRenderTargetTexture(new Dimension2D(320, 240));
            int lastfps = -1, fps = 0;
            while (device.Run() && !Exit)
            {
                Driver.BeginScene(true, true, Color.Gray);

                //Driver.SetRenderTarget(renderTarget, true, true, Color.TransparentBlue);
                //Scene.ActiveCamera = fixedcam;
                //Scene.DrawAll();
                //Driver.SetRenderTarget(null, true, true, Color.Gray);

                Scene.ActiveCamera = fpscam;
                Scene.DrawAll();
                //Ok, seems like Irrlicht 1.3.1 doesn't like drawing render target on OpenGL
                //I guess we will disable this for now...
                //Driver.Draw2DImage(renderTarget, new Position2D(0, 0), false);
                Driver.Draw2DImage(mask, new Rect(new Position2D(), Driver.ScreenSize), new Rect(new Position2D(), mask.OriginalSize), Color.White, true);

                //And finally our logo is painted
                Driver.Draw2DImage(logo, new Position2D(0, Driver.ScreenSize.Height - logo.OriginalSize.Height),
                                   new Rect(new Position2D(0, 0),
                                   logo.OriginalSize), Color.White, true);
                Driver.EndScene();

                fps = Driver.FPS;
                if(fps != lastfps)
                {
                    device.WindowCaption = caption + " - FPS : " + fps;
                    lastfps = fps;
                }
            }
            device.Close();
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: Paulus/irrlichtnetcp
        static void Main(string[] args)
        {
            IrrlichtDevice device = new IrrlichtDevice(DriverType.OpenGL, new Dimension2D(640, 480),
                                        32, false, false, false, false);

            string basecaption = "Irrlicht .NET CP Examples - Custom Scene Node feature";

            _scene = device.SceneManager;
            _driver = device.VideoDriver;

            CustomSceneNode myNode = new CustomSceneNode(null, _scene, 666);

            _scene.AddCameraSceneNode(null);
            _scene.ActiveCamera.Position = new Vector3D(0, -40, 0);
            _scene.ActiveCamera.Target = new Vector3D();

            myNode.AddAnimator(new CustomAnimator(new Vector3D(0.8f, 0, 0.8f)));
            int lastfps = -1, fps = 0;
            while (device.Run())
            {
                _driver.BeginScene(true, true, Color.Gray);
                _scene.DrawAll();
                _driver.EndScene();

                fps = _driver.FPS;
                if(fps != lastfps)
                {
                    device.WindowCaption = basecaption + " - FPS : " + fps;
                    lastfps = fps;
                }
            }
            device.DumpElements();
            device.Close();
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: Paulus/irrlichtnetcp
        public static void Main(string[] args)
        {
            //Shall we fullscreen ? (new verb I just invented)
            bool fullscreen = false;

            //We check the optimal video mode (resolution and screen depth)
            //As a default we choose 800x600x32
            VideoMode optimalmode;
            optimalmode.Resolution = new Dimension2D(800, 600);
            optimalmode.Depth = 32;

            //OpenGL is platform independent whereas DirectX isn't
            //As a default we choose OpenGL
            DriverType drivertype = DriverType.OpenGL;

            //We set a cool caption for our example
            string caption = "Irrlicht.NET CP Example on ";
            //Is the application started on a Windows platform ?
            //You may wonder why I did not wrote "Environment.OSVersion.Platform == PlatformID.Unix"
            //The reason is simple : We do not need to know if we are on an unix platform,
            //We need to know if we ARE NOT ON A WINDOWS platform, that's different indeed.
            if (Environment.OSVersion.Platform != PlatformID.Win32Windows &&
                Environment.OSVersion.Platform != PlatformID.Win32NT &&
                Environment.OSVersion.Platform != PlatformID.Win32S)
            {
                caption += "Linux/Unix System";
                //If the script is compiled on debug mode, we set 1024x768x32 with fullscreen.
                //I guess most of users will have at least a 15' screen...
            #if !DEBUG
                fullscreen = true;
                optimalmode.Resolution = new Dimension2D(1024, 768);
                optimalmode.Depth = 32;
            #endif
            }
            else //We ARE on a Windows Platform
            {
                caption += "Windows";

                //Uncomment this line and the engine will use DirectX 9 on a Windows system
                //I don't like Direct3D 9 but well the choice is yours ;)
                //drivertype = DriverType.Direct3D9;

                //Here we are, if the engine is compiled with release settings,
                //We can play with a funny toy : fakedevice.
                //It does not seem to work on Linux (perhaps one of those bugs that only appear on some cursed computers like mine)
                //With this device, we will determine the ideal video mode by forcing
                //The application to launch on the desktop video mode
                //If a bug occurs (meaning video mode is null for instance)
                //We set the same video mode as on Linux : 1024x768x32 which is the most common video mode.
            #if !DEBUG
                IrrlichtDevice fakedevice = new IrrlichtDevice(DriverType.Null, new Dimension2D(), 16, false, false, false, false);
                optimalmode = fakedevice.DesktopVideoMode;
                if(optimalmode.Resolution.Width == 0 || optimalmode.Resolution.Height == 0)
                {
                    optimalmode.Resolution = new Dimension2D(1024, 768);
                    optimalmode.Depth = 32;
                }
                fakedevice.Dispose();
                fullscreen = true;
            #endif
            }

            //We add a cool caption which says which renderer (OpenGL or Direct3D9 for instance) we use
            caption += " With " + drivertype + " - ";

            //Here we are, we create the device with settings we determined before
            IrrlichtDevice device = new IrrlichtDevice(drivertype,
                                                       optimalmode.Resolution,
                                                       optimalmode.Depth, fullscreen,
                                                       true, //Stencil Buffer (for shadow)
                                                       false, //Vertical Synchronisation (use it if you want your application not to go over 70 FPS)
                                                       false); //Anti Aliasing

            scene = device.SceneManager; //We get some object such as the scene manager
            driver = device.VideoDriver;
            guienv = device.GUIEnvironment;

            device.FileSystem.WorkingDirectory = "../../medias"; //We set Irrlicht's current directory to %application directory%/media
            device.CursorControl.Visible = false; //Let's hide the cursor

            device.OnEvent += new OnEventDelegate(device_OnEvent); //We had a simple delegate that will handle every event
            device.WindowCaption = caption; //And we set a basic caption

            //We create a floor mesh which is actually an hill plane mesh without height
            AnimatedMesh floormesh = scene.AddHillPlaneMesh("_MyHill_", new Dimension2Df(250, 250),
                                                            new Dimension2D(5, 5),
                                                            0f, new Dimension2Df(0, 0),
                                                            new Dimension2Df(10, 10));

            //We make the planar texture mapping to set the texture resolution
            scene.MeshManipulator.MakePlanarTextureMapping(floormesh.GetMesh(0), 0.006f);

            //We create a new mesh with tangents. It is needed for Parallax mapping
            Mesh tFloor = scene.MeshManipulator.CreateMeshWithTangents(floormesh.GetMesh(0));
            Texture heightmap = driver.GetTexture("rockwall_height.bmp"); //Our normal map
            driver.MakeNormalMapTexture(heightmap, 10f); //We make a quite exagerated normal map (just to show off)

            //And here we are, we finally create the scene node
            SceneNode floor = scene.AddMeshSceneNode(tFloor, null, -1);

            //We get the material
            Material mat = floor.GetMaterial(0);
            mat.Texture1 = driver.GetTexture("rockwall.bmp"); //Diffuse texture
            mat.Texture2 = heightmap; //Normal map
            mat.MaterialType = MaterialType.ParallaxMapSolid; //The beautiful Parallax Mapping
            mat.MaterialTypeParam = 0.035f; //Parameter for the height of parallax mapping

            //We create a FPS camera which is a basic camera controlled by
            //Arrow keys and mouse such as the camera in Quake or Doom
            CameraSceneNode cam = scene.AddCameraSceneNodeFPS(null, 50f, 100f, true);
            cam.Position = new Vector3D(0, 100, -100);
            cam.FarValue = 10000f; //We want to see all the scene

            //We add the sword (don't tell me that it is not a katana, I already know it !)
            SceneNode katana = scene.AddMeshSceneNode(scene.GetMesh("katana.x").GetMesh(0), cam, -1);
            Vector3D KInitialRotation = new Vector3D(0, 20, -90);
            Vector3D KInitialPosition = new Vector3D(23, -3, 40);
            //We set our materials (the n 1 is the sword and the 0 the stick)
            katana.Scale = new Vector3D(100f, 100f, 100f);
            mat = katana.GetMaterial(1);
            mat.DiffuseColor = new Color(255, 90, 90, 90);
            mat.AmbientColor = new Color(255, 90, 90, 90);
            mat.EmissiveColor = new Color(255, 90, 90, 90);
            mat.SpecularColor = new Color(255, 90, 90, 90);
            Material mat2 = katana.GetMaterial(0);
            mat2.DiffuseColor = new Color(255, 10, 10, 10);
            mat2.EmissiveColor = new Color(255, 120, 80, 0);

            //We add a little shining effect with particles on the sword
            ParticleSystemSceneNode particles = scene.AddParticleSystemSceneNode(false, katana, -1);
            particles.SetEmitter(particles.CreateBoxEmitter(scene.GetMesh("katana.x").GetMesh(0).GetMeshBuffer(1).BoundingBox,
                                                              new Vector3D(0, 0.002f, 0),
                                                              1000, 1000,
                                                              new Color(0, 255, 255, 255),
                                                              new Color(0, 255, 255, 255),
                                                              200, 200, 0));
            particles.ParticleSize = new Dimension2Df(1f, 3f); //A funny size for our funny effect
            particles.AddAffector(particles.CreateFadeOutParticleAffector(new Color(0, 0, 0, 0), 100));
            particles.SetMaterialTexture(0, driver.GetTexture("fire.bmp"));
            particles.SetMaterialType(MaterialType.TransparentAddColor);
            particles.SetMaterialFlag(MaterialFlag.Lighting, false);

            //We create three dwarves with shadows
            AnimatedMeshSceneNode dwarf = scene.AddAnimatedMeshSceneNode(scene.GetMesh("dwarf.x"));
            dwarf.AnimationSpeed = 15;
            dwarf.Position = new Vector3D(0, 0, 100);
            dwarf.AddShadowVolumeSceneNode(-1, true, 10000f); //Wow... It was really hard to create it !
            dwarf.Scale = new Vector3D(1.5f, 1.5f, 1.5f);

            //Here we have our light that will simply rotate around the dwarf
            LightSceneNode dwarflight = scene.AddLightSceneNode(dwarf, new Vector3D(0, 0, 0), Colorf.White, 10000f, -1);
            dwarflight.AddAnimator(scene.CreateFlyCircleAnimator(new Vector3D(0, 100, 0), 100f, 0.001f));

            dwarf = scene.AddAnimatedMeshSceneNode(scene.GetMesh("dwarf.x"));
            dwarf.AnimationSpeed = 10;
            dwarf.Position = new Vector3D(-100, 0, 100);
            dwarf.AddShadowVolumeSceneNode(-1, true, 10000f);
            dwarf.Scale = new Vector3D(1.5f, 1.5f, 1.5f);

            dwarf = scene.AddAnimatedMeshSceneNode(scene.GetMesh("dwarf.x"));
            dwarf.AnimationSpeed = 20;
            dwarf.Position = new Vector3D(100, 0, 100);
            dwarf.AddShadowVolumeSceneNode(-1, true, 10000f);
            dwarf.Scale = new Vector3D(1.5f, 1.5f, 1.5f);

            //We set the shadow color.
            //I reduced a lot the opacity since our light is not supposed to be the sun
            //And the scene is at night... Thus a shadow is not something very visible.
            scene.ShadowColor = new Color(100, 0, 0, 0);

            //We had a simple billboard to represent physically the light
            BillboardSceneNode lightbill = scene.AddBillboardSceneNode(dwarflight, new Dimension2Df(20, 20), -1);
            Texture fire = driver.GetTexture("fire.bmp");
            lightbill.SetMaterialTexture(0, fire);
            lightbill.SetMaterialType(MaterialType.TransparentAddColor);
            lightbill.SetMaterialFlag(MaterialFlag.Lighting, false);

            //We add a simple skybox
            scene.AddSkyBoxSceneNode(null, new Texture[] { driver.GetTexture("irrlicht2_up.jpg"),
                                                           driver.GetTexture("irrlicht2_dn.jpg"),
                                                           driver.GetTexture("irrlicht2_lf.jpg"),
                                                           driver.GetTexture("irrlicht2_rt.jpg"),
                                                           driver.GetTexture("irrlicht2_ft.jpg"),
                                                           driver.GetTexture("irrlicht2_bk.jpg") },
                                                           -1);

            //We had a simple texture that will be rendered each time
            Texture matthias = driver.GetTexture("matthias.png");

            //Here is our logo
            Texture logo = driver.GetTexture("NETCPlogo.png");

            //Just a simple demonstration of a feature which is not on Irrlicht .NET :
            //Listing children of the node as a simple Array.
            foreach (SceneNode node in cam.Children)
                Console.WriteLine("Child : " + node.ToString() + " Parent : " + node.Parent.ToString());

            //Another cool new feature :
            //FileSystem class with features like listing every file that Irrlicht can load
            //(including files on zip archives for instance)
            //foreach (FileListItem item in device.FileSystem.FileList)
            //    Console.WriteLine(item.ToString());

            double random = 0;
            Random chance = new Random();

            int lastfps = -1;
            while (device.Run() && !Exit)
            {
                //We get the FPS to synchronize all movements
                //Notice that I advice NOT TO USE THE FPS to synchronize
                //Because it is updated every second whereas it can change at every time
                //Use the time between each loop instead
                //(We use it here because it is not very important but be very careful)
                int FPS = driver.FPS;

                if(FPS != lastfps)
                {
                    //And here we are, we set the caption of the main window
                    device.WindowCaption = caption + "FPS : " + FPS;
                    lastfps = FPS;
                }

                if (FPS < 10)
                    FPS = 70;
                random += ((2000f / FPS) + chance.Next(-10, 10)) / 1000f;
                //If someone has played the demo about thirty years...
                if (random >= double.MaxValue)
                    random = 0;
                //Sinuses and Cosines are very useful because we all know that
                //they are between -1 and 1. Thus we don't need to add some "if"
                //And we can control the domain easilly
                //We had a realstic move of the sword because try to hold one during 10 minutes
                //You won't be static... Tested !
                //A nice thing would be to generate it using the camera movement speed or things like that...
                katana.Position = KInitialPosition +
                                    new Vector3D((float)(Math.Sin(random) / 6.0f),
                                                 (float)(Math.Sin(random) / 10f),
                                                 (float)(Math.Cos(random) / 6.0f));
                katana.Rotation = KInitialRotation +
                                    new Vector3D((float)(Math.Cos(random) / 2f),
                                                 (float)(Math.Cos(random)),
                                                 (float)(Math.Sin(random) / 2f));

                //We clear the back buffer and begin the scene
                driver.BeginScene(true, true, Color.From(255, 50, 50, 50));
                //First we draw all 3D Objects such as our sword or the dwarves
                //Notice that the order is very important... Try to move this line just before the
                //driver.EndScene and you will see the difference
                scene.DrawAll();

                //3 rectangles that could for instance represent Health, Mana and Endurance points...
                driver.Draw2DRectangle(new Rect(new Position2D(10, 5), new Dimension2D(300, 15)), Color.Red);
                driver.Draw2DRectangle(new Rect(new Position2D(10, 25), new Dimension2D(300, 15)), Color.Blue);
                driver.Draw2DRectangle(new Rect(new Position2D(10, 45), new Dimension2D(300, 15)), Color.Green);
                //A little image loaded before that could represent for instance our character
                driver.Draw2DImage(matthias, new Position2D(driver.ScreenSize.Width - matthias.OriginalSize.Width, 0),
                                   new Rect(new Position2D(0, 0),
                                   matthias.OriginalSize), Color.White, true);
                //And finally our logo is painted
                driver.Draw2DImage(logo, new Position2D(0, driver.ScreenSize.Height - logo.OriginalSize.Height),
                                   new Rect(new Position2D(0, 0),
                                   logo.OriginalSize), Color.White, true);

                //Finally we draw everything in the GUI Environment... CF the GUI example
                guienv.DrawAll();
                //End of the scene, the back buffer is displayed
                driver.EndScene();
            }
            //ALWAYS DISPOSE THE DEVICE AT THE END
            //It is REQUIRED on Linux because if you don't, XWindow will stay at the old video mode
            //And you can't imagine how ugly it is not to get back to the original video mode
            device.Close();
        }