void runIrrlichtInWindowsFormTest() { // testing irrlicht running embedded in a windows form System.Windows.Forms.Form f = new System.Windows.Forms.Form(); f.Text = "Irrlicht running embedded in Windows.Form"; device = new IrrlichtDevice(SelectedDriverType, new Dimension2D(800, 600), 16, false, false, false, true, f.Handle); f.Show(); // set up a simple scene ICameraSceneNode cam = device.SceneManager.AddCameraSceneNode(null, new Vector3D(), new Vector3D(), -1); ISceneNodeAnimator anim = device.SceneManager.CreateFlyCircleAnimator( new Vector3D(0, 10, 0), 30.0f, 0.003f); cam.AddAnimator(anim); ISceneNode cube = device.SceneManager.AddCubeSceneNode(25, null, -1, new Vector3D()); cube.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/rockwall.bmp")); cube.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false); // draw everything device.Run(); // fix for a temporary bug where quit messages are not be removed in the queue while (device.Run() && f.Visible) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(255, 0, 0, 50)); device.SceneManager.DrawAll(); device.GUIEnvironment.DrawAll(); device.VideoDriver.EndScene(); } } }
void runIrrlichtInWindowsFormTest(Control c) { device = new IrrlichtDevice(Irrlicht.Video.DriverType.DIRECT3D9, new Dimension2D(c.Width, c.Height), 32, false, false, false, true, c.Handle); ICameraSceneNode cam = device.SceneManager.AddCameraSceneNode(null, new Vector3D(), new Vector3D(), -1); ISceneNodeAnimator anim = device.SceneManager.CreateFlyCircleAnimator(new Vector3D(0, 10, 0), 30.0f, 0.003f); cam.AddAnimator(anim); ISceneNode cube = device.SceneManager.AddTestSceneNode(25, null, -1, new Vector3D()); cube.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../../media/rockwall.bmp")); cube.SetMaterialFlag(MaterialFlag.LIGHTING, false); // draw everything // Note, using device.WindowActive will not work on a control, since we don't // really activate controls.. while (device.Run() && c.Enabled) { device.VideoDriver.BeginScene(true, true, new Irrlicht.Video.Color(255, 0, 0, 50)); device.SceneManager.DrawAll(); device.GUIEnvironment.DrawAll(); device.VideoDriver.EndScene(); } }
public void run() { /* The next few lines start up the engine. Just like in most other tutorials * before. But in addition, we ask the user if he wants this example to use * high level shaders if he selected a driver which is capable of doing so. */ // ask user for driver DriverType driverType; // Ask user to select driver: StringBuilder sb = new StringBuilder(); sb.Append("Please select the driver you want for this example:\n"); sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5"); sb.Append("\n(d) Software Renderer\n(e) Apfelbaum Software Renderer"); sb.Append("\n(f) Null Device\n(otherKey) exit\n\n"); // Get the user's input: TextReader tIn = Console.In; TextWriter tOut = Console.Out; tOut.Write(sb.ToString()); string input = tIn.ReadLine(); // Select device based on user's input: switch (input) { case "a": driverType = DriverType.DIRECT3D9; break; case "b": driverType = DriverType.DIRECT3D8; break; case "c": driverType = DriverType.OPENGL; break; case "d": driverType = DriverType.SOFTWARE; break; case "e": driverType = DriverType.SOFTWARE2; break; case "f": driverType = DriverType.NULL_DRIVER; break; default: return; } // ask the user if we should use high level shaders for this example if (driverType == DriverType.DIRECT3D9 || driverType == DriverType.OPENGL) { tOut.Write("Please press 'y' if you want to use high level shaders.\n"); input = tIn.ReadLine(); if (input.ToLower() == "y") { UseHighLevelShaders = true; } } // create device device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, false, true, true); if (device == null) { tOut.Write("Device creation failed."); return; } ISceneManager smgr = device.SceneManager; IVideoDriver driver = device.VideoDriver; IGUIEnvironment gui = device.GUIEnvironment; /*Now for the more interesting parts. If we are using Direct3D, we want to * load vertex and pixel shader programs, if we have OpenGL, we want to use ARB * fragment and vertex programs. I wrote the corresponding programs down into the * files d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, opengl.ps and opengl.vs. We only * need the right filenames now. This is done in the following switch. Note, * that it is not necessary to write the shaders into text files, like in this * example. You can even write the shaders directly as strings into the cpp source * file, and use later addShaderMaterial() instead of addShaderMaterialFromFiles().*/ string vsFileName = ""; string psFileName = ""; switch (driverType) { case DriverType.DIRECT3D8: psFileName = path + "d3d8.psh"; vsFileName = path + "d3d8.vsh"; break; case DriverType.DIRECT3D9: if (UseHighLevelShaders) { psFileName = path + "d3d9.hlsl"; vsFileName = psFileName; // both shaders are in the same file } else { psFileName = path + "d3d9.psh"; vsFileName = path + "d3d9.vsh"; } break; case DriverType.OPENGL: if (UseHighLevelShaders) { psFileName = path + "opengl.frag"; vsFileName = path + "opengl.vert"; } else { psFileName = path + "opengl.psh"; vsFileName = path + "opengl.vsh"; } break; } /*In addition, we check if the hardware and the selected renderer is capable * of executing the shaders we want. If not, we simply set the filename string * to 0. This is not necessary, but useful in this example: For example, if the * hardware is able to execute vertex shaders but not pixel shaders, we create a * new material which only uses the vertex shader, and no pixel shader. Otherwise, * if we would tell the engine to create this material and the engine sees that * the hardware wouldn't be able to fullfill the request completely, it would not * create any new material at all. So in this example you would see at least the * vertex shader in action, without the pixel shader.*/ if (!driver.QueryFeature(VideoDriverFeature.PIXEL_SHADER_1_1) && !driver.QueryFeature(VideoDriverFeature.ARB_FRAGMENT_PROGRAM_1)) { // still unimplemented //device.Logger.log("WARNING: Pixel shaders disabled \n"+ // "because of missing driver/hardware support."); psFileName = null; } if (!driver.QueryFeature(VideoDriverFeature.VERTEX_SHADER_1_1) && !driver.QueryFeature(VideoDriverFeature.ARB_FRAGMENT_PROGRAM_1)) { // still unimplemented //device.Logger.log("WARNING: Vertex shaders disabled \n"+ // "because of missing driver/hardware support."); vsFileName = null; } /*Now lets create the new materials. As you maybe know from previous examples, * a material type in the Irrlicht engine is set by simply changing the * MaterialType value in the SMaterial struct. And this value is just a simple * 32 bit value, like video::EMT_SOLID. So we only need the engine to create a * new value for us which we can set there. To do this, we get a pointer to the * IGPUProgrammingServices and call addShaderMaterialFromFiles(), which returns * such a new 32 bit value. That's all. The parameters to this method are the * following: First, the names of the files containing the code of the vertex * and the pixel shader. If you would use addShaderMaterial() instead, you would * not need file names, then you could write the code of the shader directly as * string. The following parameter is a pointer to the IShaderConstantSetCallBack * class we wrote at the beginning of this tutorial. If you don't want to set * constants, set this to 0. The last paramter tells the engine which material * it should use as base material. To demonstrate this, we create two materials * with a different base material, one with EMT_SOLID and one with * EMT_TRANSPARENT_ADD_COLOR.*/ // create materials IGPUProgrammingServices gpu = driver.GPUProgrammingServices; int newMaterialType1 = 0; int newMaterialType2 = 0; if (gpu != null) { IShaderConstantSetCallBack callBack = this; // create the shaders depending on if the user wanted high level // or low level shaders: if (UseHighLevelShaders) { // create material from high level shaders (hlsl or glsl) newMaterialType1 = gpu.AddHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", VertexShaderType.VST_VS_1_1, psFileName, "pixelMain", PixelShaderType.PST_PS_1_1, callBack, MaterialType.SOLID); newMaterialType2 = gpu.AddHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", VertexShaderType.VST_VS_1_1, psFileName, "pixelMain", PixelShaderType.PST_PS_1_1, callBack, MaterialType.TRANSPARENT_ADD_COLOR); } else { newMaterialType1 = gpu.AddShaderMaterialFromFiles(vsFileName, psFileName, callBack, MaterialType.SOLID); newMaterialType2 = gpu.AddShaderMaterialFromFiles(vsFileName, psFileName, callBack, MaterialType.TRANSPARENT_ADD_COLOR); } } /*Now its time for testing out the materials. We create a test cube and set the * material we created. In addition, we add a text scene node to the cube and a * rotatation animator, to make it look more interesting and important.*/ // create test scene node 1, with the new created material type 1 ISceneNode node = smgr.AddTestSceneNode(50, null, 0, new Vector3D(0, 0, 0)); node.SetMaterialTexture(0, driver.GetTexture(path + "wall.bmp")); node.SetMaterialType((MaterialType)newMaterialType1); smgr.AddTextSceneNode(gui.BuiltInFont, "PS & VS & EMT_SOLID", new Color(255, 255, 255, 255), node, new Vector3D(), 0); ISceneNodeAnimator anim = smgr.CreateRotationAnimator( new Vector3D(0, 0.3f, 0)); node.AddAnimator(anim); //Same for the second cube, but with the second material we created. node = smgr.AddTestSceneNode(50, null, 0, new Vector3D(0, -10, 50)); node.SetMaterialTexture(0, driver.GetTexture(path + "wall.bmp")); node.SetMaterialType((MaterialType)newMaterialType2); smgr.AddTextSceneNode(gui.BuiltInFont, "PS & VS & EMT_TRANSPARENT", new Color(255, 255, 255, 255), node, new Vector3D(), 0); anim = smgr.CreateRotationAnimator( new Vector3D(0, 0.3f, 0)); node.AddAnimator(anim); // Then we add a third cube without a shader on it, to be able to compare the cubes. node = smgr.AddTestSceneNode(50, null, 0, new Vector3D(0, 50, 25)); node.SetMaterialTexture(0, driver.GetTexture(path + "wall.bmp")); smgr.AddTextSceneNode(gui.BuiltInFont, "NO SHADER", new Color(255, 255, 255, 255), node, new Vector3D(), 0); //And last, we add a skybox and a user controlled camera to the scene. For the //skybox textures, we disable mipmap generation, because we don't need mipmaps on it. // add a nice skybox driver.SetTextureCreationFlag(TextureCreationFlag.CREATE_MIP_MAPS, false); smgr.AddSkyBoxSceneNode( driver.GetTexture(path + "irrlicht2_up.jpg"), driver.GetTexture(path + "irrlicht2_dn.jpg"), driver.GetTexture(path + "irrlicht2_lf.jpg"), driver.GetTexture(path + "irrlicht2_rt.jpg"), driver.GetTexture(path + "irrlicht2_ft.jpg"), driver.GetTexture(path + "irrlicht2_bk.jpg"), null, 0); driver.SetTextureCreationFlag(TextureCreationFlag.CREATE_MIP_MAPS, true); // add a camera and disable the mouse cursor ICameraSceneNode cam = smgr.AddCameraSceneNodeFPS(null, 100, 100, 0); cam.Position = new Vector3D(-100, 50, 100); cam.Target = new Vector3D(); device.CursorControl.Visible = false; /*Finally we simply have to draw everything, that's all.*/ int lastFPS = -1; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200)); device.SceneManager.DrawAll(); device.VideoDriver.EndScene(); int fps = device.VideoDriver.FPS; if (lastFPS != fps) { device.WindowCaption = "Irrlicht Engine - Quake 3 Map example [" + device.VideoDriver.Name + "] FPS:" + fps.ToString(); lastFPS = fps; } } } /* * In the end, delete the Irrlicht device. */ // Instead of device->drop, we'll use: GC.Collect(); }
public void run() { /* Like in the HelloWorld example, we create an IrrlichtDevice with * new(). The difference now is that we ask the user to select * which hardware accelerated driver to use. The Software device would be * too slow to draw a huge Quake 3 map, but just for the fun of it, we make * this decision possible too. */ // ask user for driver DriverType driverType; // Ask user to select driver: StringBuilder sb = new StringBuilder(); sb.Append("Please select the driver you want for this example:\n"); sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5"); sb.Append("\n(d) Software Renderer\n(e)Apfelbaum Software Renderer"); sb.Append("\n(f) Null Device\n(otherKey) exit\n\n"); // Get the user's input: TextReader tIn = Console.In; TextWriter tOut = Console.Out; tOut.Write(sb.ToString()); string input = tIn.ReadLine(); // Select device based on user's input: switch (input) { case "a": driverType = DriverType.DIRECT3D9; break; case "b": driverType = DriverType.DIRECT3D8; break; case "c": driverType = DriverType.OPENGL; break; case "d": driverType = DriverType.SOFTWARE; break; case "e": driverType = DriverType.SOFTWARE2; break; case "f": driverType = DriverType.NULL_DRIVER; break; default: return; } // Create device and exit if creation fails: device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, true, true, true); // Bob changed this. if (device == null) { tOut.Write("Device creation failed."); return; } /* set this as event receiver*/ device.EventReceiver = this; /* * Get a reference to the video driver and the SceneManager so that * we do not always have to write device.VideoDriver and * device.SceneManager. */ ISceneManager smgr = device.SceneManager; IVideoDriver driver = device.VideoDriver; /*Create the node for moving it with the 'W' and 'S' key. We create a * 'test node', which is a cube built in into the engine for testing purposes. * We place the node a (0,0,30) and we assign a texture to it to let it look a * little bit more interesting.*/ node = smgr.AddCubeSceneNode(10, null, 0, new Vector3D(0, 0, 30), new Vector3D(), new Vector3D(1, 1, 1)); node.SetMaterialTexture(0, driver.GetTexture(path + "wall.bmp")); node.SetMaterialFlag(MaterialFlag.LIGHTING, false); /* Now we create another node, moving using a scene node animator. Scene * node animators modify scene nodes and can be attached to any scene node * like mesh scene nodes, billboards, lights and even camera scene nodes. * Scene node animators are not only able to modify the position of a scene * node, they can also animate the textures of an object for example. We create * a test scene node again an attach a 'fly circle' scene node to it, letting * this node fly around our first test scene node.*/ ISceneNode n = smgr.AddTestSceneNode(10, null, 0, new Vector3D(), new Vector3D(), new Vector3D(1, 1, 1)); n.SetMaterialTexture(0, driver.GetTexture(path + "t351sml.jpg")); ISceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3D(0, 0, 30), 20, 0.001f); n.AddAnimator(anim); //is this really necessary? anim.__dtor(); /*The last scene node we add to show possibilities of scene node animators * is a md2 model, which uses a 'fly straight' animator to run between two * points.*/ IAnimatedMeshSceneNode anms = smgr.AddAnimatedMeshSceneNode( smgr.GetMesh(path + "sydney.md2"), null, 0); if (anms != null) { anim = smgr.CreateFlyStraightAnimator(new Vector3D(100, 0, 60), new Vector3D(-100, 0, 60), 10000, true); anms.AddAnimator(anim); anim.__dtor(); /*To make to model look better, we disable lighting (we have created no lights, * and so the model would be black), 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 would also be able to just * call "anms->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.*/ anms.Position = new Vector3D(0, 0, 40); anms.SetMaterialFlag(MaterialFlag.LIGHTING, false); anms.SetFrameLoop(320, 360); anms.AnimationSpeed = 30; anms.Rotation = new Vector3D(0, 180, 0); anms.SetMaterialTexture(0, driver.GetTexture(path + "sydney.BMP")); } /*To be able to look at and move around in this scene, we create a first person * shooter style camera and make the mouse cursor invisible.*/ ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100, 100, 0); camera.Position = new Vector3D(0, 0, 0); device.CursorControl.Visible = false; /* * We have done everything, so lets draw it. We also write the current * frames per second and the drawn primitives to the caption of the * window. */ int lastFPS = -1; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200)); device.SceneManager.DrawAll(); device.VideoDriver.EndScene(); int fps = device.VideoDriver.FPS; if (lastFPS != fps) { device.WindowCaption = "Irrlicht Engine - Movement example [" + device.VideoDriver.Name + "] FPS:" + fps.ToString(); lastFPS = fps; } } } /* * In the end, delete the Irrlicht device. */ // Instead of device->drop, we'll use: GC.Collect(); }
public void run() { /* At first, we let the user select the driver type, * then start up the engine, set a caption, and get a * pointer to the video driver. */ // ask user for driver DriverType driverType; // Ask user to select driver: StringBuilder sb = new StringBuilder(); sb.Append("Please select the driver you want for this example:\n"); sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5"); sb.Append("\n(d) Software Renderer\n(e) Apfelbaum Software Renderer"); sb.Append("\n(f) Null Device\n(otherKey) exit\n\n"); // Get the user's input: TextReader tIn = Console.In; TextWriter tOut = Console.Out; tOut.Write(sb.ToString()); string input = tIn.ReadLine(); // Select device based on user's input: switch (input) { case "a": driverType = DriverType.DIRECT3D9; break; case "b": driverType = DriverType.DIRECT3D8; break; case "c": driverType = DriverType.OPENGL; break; case "d": driverType = DriverType.SOFTWARE; break; case "e": driverType = DriverType.SOFTWARE2; break; case "f": driverType = DriverType.NULL_DRIVER; break; default: return; } // Create device and exit if creation fails: device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, false, true, true); if (device == null) { tOut.Write("Device creation failed."); return; } /* * Get a pointer to the video driver and the SceneManager so that * we do not always have to write device->getVideoDriver() and * device->getSceneManager(). */ ISceneManager smgr = device.SceneManager; IVideoDriver driver = device.VideoDriver; device.FileSystem.AddZipFileArchive(path + "map-20kdm2.pk3"); IAnimatedMesh q3levelmesh = smgr.GetMesh("20kdm2.bsp"); ISceneNode q3node = null; if (q3levelmesh != null) { q3node = smgr.AddOctTreeSceneNode(q3levelmesh.GetMesh(0), null, 0); } /*So far so good, we've loaded the quake 3 level like in tutorial 2. * Now, here comes something different: We create a triangle selector. A * triangle selector is a class which can fetch the triangles from scene * nodes for doing different things with them, for example collision * detection. There are different triangle selectors, and all can be * created with the ISceneManager. In this example, we create an * OctTreeTriangleSelector, which optimizes the triangle output a little * bit by reducing it like an octree. This is very useful for huge meshes * like quake 3 levels. * After we created the triangle selector, we attach it to the q3node. * This is not necessary, but in this way, we do not need to care for the * selector, for example dropping it after we do not need it anymore.*/ ITriangleSelector selector = null; if (q3node != null) { q3node.Position = new Vector3D(-1370, -130, -1400); selector = smgr.CreateOctTreeTriangleSelector( q3levelmesh.GetMesh(0), q3node, 128); // not implemented but not necessary //q3node.TriangleSelector=selector; } /*We add a first person shooter camera to the scene for being able to 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 thing modifies * the scene node to which it is attached to in that way, that it may no * more move through walls and is affected by gravity. The only thing we have * to tell the animator is how the world looks like, how big the scene node is, * how gravity 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 automaticly, all other collision detection code below is * for picking. And please note another cool feature: The collsion response * animator can be attached also to all other scene nodes, not only to cameras. * And it can be mixed with other scene node animators. In this way, collision * detection and response in the Irrlicht engine is really, really easy. * 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 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. 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. */ ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100, 300, 0); camera.Position = new Vector3D(-100, 50, -150); ISceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator( selector, camera, new Vector3D(30, 50, 30), new Vector3D(0, -3, 0), new Vector3D(0, 50, 0), 0); camera.AddAnimator(anim); /*Because collision detection is no big deal in irrlicht, I'll describe how * to do two different types of picking in the next section. But before this, * I'll prepare the scene a little. I need three animated characters which we * could pick later, a dynamic light for lighting them, a billboard for drawing * where we found an intersection, and, yes, I need to get rid of this mouse * cursor. :)*/ //disable mouse cursor device.CursorControl.Visible = false; // add billboard IBillboardSceneNode bill = smgr.AddBillboardSceneNode( null, new Dimension2Df(20, 20), new Vector3D(), 0); bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR); bill.SetMaterialTexture(0, driver.GetTexture( path + "particle.bmp")); bill.SetMaterialFlag(MaterialFlag.LIGHTING, false); bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false); Material material = new Material(); material.Texture1 = driver.GetTexture( path + "faerie2.bmp"); material.Lighting = true; IAnimatedMeshSceneNode node = null; IAnimatedMesh faerie = smgr.GetMesh( path + "faerie.md2"); if (faerie != null) { node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0); node.Position = new Vector3D(-70, 0, -90); node.SetMD2Animation(MD2AnimationType.RUN); node.SetMaterial(0, material); node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0); node.Position = new Vector3D(-70, 0, -30); node.SetMD2Animation(MD2AnimationType.SALUTE); node.SetMaterial(0, material); node = smgr.AddAnimatedMeshSceneNode(faerie, null, 0); node.Position = new Vector3D(-70, 0, -60); node.SetMD2Animation(MD2AnimationType.JUMP); node.SetMaterial(0, material); } material.Texture1 = null; material.Lighting = false; //Add a light smgr.AddLightSceneNode(null, new Vector3D(-60, 100, 400), new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 600, 0); /*For not making it too complicated, I'm doing picking inside the drawing * loop. We take two pointers for storing the current and the last selected * scene node and start the loop.*/ ISceneNode selectedSceneNode = null; ISceneNode lastSelectedSceneNode = null; int lastFPS = -1; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200)); device.SceneManager.DrawAll(); /*After we've drawn the whole scene whit smgr->drawAll(), we'll do the * first picking: We want to know which triangle of the world we are * looking at. In addition, we want the exact point of the quake 3 * level we are looking at. For this, we create a 3d line starting at * the position of the camera and going through the lookAt-target of it. * Then we ask the collision manager if this line collides with a * triangle of the world stored in the triangle selector. If yes, we draw * the 3d triangle and set the position of the billboard to the intersection * point.*/ Line3D line = new Line3D(); line.start = camera.Position; line.end = line.start + (camera.Target - line.start).Normalize() * 1000; Vector3D intersection; Triangle3D tri; if (smgr.SceneCollisionManager.GetCollisionPoint( line, selector, out intersection, out tri)) { bill.Position = intersection; driver.SetTransform(TransformationState.WORLD, new Matrix4()); driver.SetMaterial(material); driver.Draw3DTriangle(tri, new Color(0, 255, 0, 0)); } /*Another type of picking supported by the Irrlicht Engine is scene node * picking based on bouding boxes. Every scene node has got a bounding box, * and because of that, it's very fast for example to get the scene node * which the camera looks at. Again, we ask the collision manager for this, * and if we've got a scene node, we highlight it by disabling Lighting in * its material, if it is not the billboard or the quake 3 level.*/ selectedSceneNode = smgr.SceneCollisionManager. GetSceneNodeFromCameraBB(camera, 0); if (lastSelectedSceneNode != null) { lastSelectedSceneNode.SetMaterialFlag( MaterialFlag.LIGHTING, true); } if (selectedSceneNode == q3node || selectedSceneNode == bill) { selectedSceneNode = null; } if (selectedSceneNode != null) { selectedSceneNode.SetMaterialFlag( MaterialFlag.LIGHTING, false); } lastSelectedSceneNode = selectedSceneNode; /*That's it, we just have to finish drawing.*/ driver.EndScene(); int fps = device.VideoDriver.FPS; if (lastFPS != fps) { device.WindowCaption = "Irrlicht Engine - Quake 3 Map example [" + device.VideoDriver.Name + "] FPS:" + fps.ToString(); lastFPS = fps; } } } /* * In the end, delete the Irrlicht device. */ // Instead of device->drop, we'll use: GC.Collect(); }
public void runShaderTest() { // testing irrlicht with shaders device = new IrrlichtDevice(SelectedDriverType, new Dimension2D(800, 600), 16, false, true, false); device.EventReceiver = this; device.ResizeAble = true; device.WindowCaption = "Irrlicht.NET shader test"; String vsFileName = ""; String psFileName = ""; UseHighLevelShaders = false; switch (SelectedDriverType) { case DriverType.DIRECT3D8: psFileName = "../../media/d3d8.psh"; vsFileName = "../../media/d3d8.vsh"; break; case DriverType.DIRECT3D9: if (UseHighLevelShaders) { psFileName = "../../media/d3d9.hlsl"; vsFileName = psFileName; // both shaders are in the same file } else { psFileName = "../../media/d3d9.psh"; vsFileName = "../../media/d3d9.vsh"; } break; case DriverType.OPENGL: if (UseHighLevelShaders) { psFileName = "../../media/opengl.frag"; vsFileName = "../../media/opengl.vert"; } else { psFileName = "../../media/opengl.psh"; vsFileName = "../../media/opengl.vsh"; } break; } // create materials int newMaterialType1 = 0; int newMaterialType2 = 0; if (device.VideoDriver.GPUProgrammingServices != null) { IShaderConstantSetCallBack callBack = this; if (UseHighLevelShaders) { newMaterialType1 = device.VideoDriver.GPUProgrammingServices.AddHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", VertexShaderType.VST_VS_1_1, psFileName, "pixelMain", PixelShaderType.PST_PS_1_1, callBack, MaterialType.SOLID); newMaterialType2 = device.VideoDriver.GPUProgrammingServices.AddHighLevelShaderMaterialFromFiles( vsFileName, "vertexMain", VertexShaderType.VST_VS_1_1, psFileName, "pixelMain", PixelShaderType.PST_PS_1_1, callBack, MaterialType.TRANSPARENT_ADD_COLOR); } else { newMaterialType1 = device.VideoDriver.GPUProgrammingServices.AddShaderMaterialFromFiles( vsFileName, psFileName, callBack, MaterialType.SOLID); newMaterialType2 = device.VideoDriver.GPUProgrammingServices.AddShaderMaterialFromFiles( vsFileName, psFileName, callBack, MaterialType.TRANSPARENT_ADD_COLOR); } } // create test scene node 1, with the new created material type 1 ISceneNode node = device.SceneManager.AddCubeSceneNode(50, null, -1, new Vector3D(0, 0, 0)); node.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/wall.bmp")); node.SetMaterialType((MaterialType)newMaterialType1); node.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false); //device.SceneManager.AddTextSceneNode( device.GUIEnvironment.BuiltInFont, // "PS & VS & EMT_SOLID", new Color(255,255,255,255), node, new Vector3D(0,0,0), -1); ISceneNodeAnimator anim = device.SceneManager.CreateRotationAnimator( new Vector3D(0, 0.3f, 0)); node.AddAnimator(anim); // create test scene node 1, with the new created material type 1 node = device.SceneManager.AddCubeSceneNode(50, null, -1, new Vector3D(0, -10, 50)); node.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/wall.bmp")); node.SetMaterialType((MaterialType)newMaterialType2); node.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false); //device.SceneManager.AddTextSceneNode( device.GUIEnvironment.BuiltInFont, // "PS & VS & EMT_TRANSPARENT", new Color(255,255,255,255), node, new Vector3D(0,0,0), -1); anim = device.SceneManager.CreateRotationAnimator( new Vector3D(0, 0.3f, 0)); node.AddAnimator(anim); //Then we add a third cube without a shader on it, to be able to compare the //cubes. node = device.SceneManager.AddCubeSceneNode(50, null, -1, new Vector3D(0, 50, 25)); node.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/wall.bmp")); node.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false); //device.SceneManager.AddTextSceneNode( device.GUIEnvironment.BuiltInFont, // "NO SHADER", new Color(255,255,255,255), node, new Vector3D(0,0,0), -1); // And last, we add a skybox and a user controlled camera to the scene. device.SceneManager.AddSkyBoxSceneNode( device.VideoDriver.GetTexture("../../media/irrlicht2_up.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_dn.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_lf.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_rt.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_ft.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_bk.jpg"), null, -1); ICameraSceneNode cam = device.SceneManager.AddCameraSceneNodeFPS(); cam.Target = new Vector3D(0, 0, 0); cam.Position = new Vector3D(-100, 50, 100); device.CursorControl.Visible = false; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(255, 0, 0, 50)); device.SceneManager.DrawAll(); device.GUIEnvironment.DrawAll(); device.VideoDriver.EndScene(); } } }
public void runIndoorTest() { device = new IrrlichtDevice(SelectedDriverType, new Dimension2D(800, 600), 16, false, true, false); device.EventReceiver = this; device.ResizeAble = true; device.WindowCaption = "Irrlicht.NET indoor test"; // load some textures and meshes ITexture texSydney = device.VideoDriver.GetTexture(@"..\..\media\sydney.bmp"); ITexture texWall = device.VideoDriver.GetTexture(@"..\..\media\wall.jpg"); ITexture texLogo = device.VideoDriver.GetTexture(@"..\..\media\irrlichtlogoaligned.jpg"); Irrlicht.Scene.IAnimatedMesh mesh = device.SceneManager.GetMesh(@"..\..\media\sydney.md2"); if (mesh == null) { System.Windows.Forms.MessageBox.Show( @"Could not load mesh ..\..\media\sydney.md2, exiting.", "Problem starting program"); return; } // add a cube to the scene ISceneNode node = device.SceneManager.AddCubeSceneNode(15, null, -1, new Vector3D(30, -15, 0)); node.SetMaterialTexture(0, texWall); node.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING, false); // add an animator to the cube to make it rotate ISceneNodeAnimator anim = device.SceneManager.CreateRotationAnimator(new Vector3D(0.2f, 0.2f, 0)); node.AddAnimator(anim); // add animated mesh IAnimatedMeshSceneNode anode = device.SceneManager.AddAnimatedMeshSceneNode(mesh, null, -1); anode.SetMaterialTexture(0, texSydney); anode.SetMaterialFlag(MaterialFlag.LIGHTING, false); anode.Scale = new Vector3D(2, 2, 2); anode.Position = new Vector3D(0, -20, 0); // add a shadow Shadow = anode.AddShadowVolumeSceneNode(); if (Shadow != null) { Shadow.Visible = false; } // where no light there no shadow device.SceneManager.AddLightSceneNode(null, new Vector3D(20, 100, -50), new Colorf(255, 0, 0), 200, -1); // add quake 3 level device.FileSystem.AddZipFileArchive("../../media/map-20kdm2.pk3"); IAnimatedMesh q3levelmesh = device.SceneManager.GetMesh("20kdm2.bsp"); ISceneNode q3node = device.SceneManager.AddOctTreeSceneNode(q3levelmesh, null, -1); q3node.Position = new Vector3D(-1370, -130, -1400); // create octtree triangle selector for q3 mesh ITriangleSelector selector = device.SceneManager.CreateOctTreeTriangleSelector( q3levelmesh.GetMesh(0), q3node, 128); // add billboard IBillboardSceneNode bill = device.SceneManager.AddBillboardSceneNode(null, new Dimension2Df(20, 20), new Vector3D(0, 0, 0), -1); bill.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR); bill.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/particle.bmp")); bill.SetMaterialFlag(MaterialFlag.LIGHTING, false); bill.SetMaterialFlag(MaterialFlag.ZBUFFER, false); // create camera ICameraSceneNode cam = device.SceneManager.AddCameraSceneNodeFPS(null, 100, 300, -1); cam.Position = new Vector3D(20, 300, -50); // make cursor invisible device.CursorControl.Visible = false; // create collision animator and add it to the camera ISceneNodeAnimator collAnim = device.SceneManager.CreateCollisionResponseAnimator( selector, cam, new Vector3D(30, 50, 30), // size of ellipsoid around camera new Vector3D(0, -3, 0), // gravity new Vector3D(0, 50, 0), // translation 0.0005f); // sliding value cam.AddAnimator(collAnim); // load some font and set it into the skin IGUIFont font = device.GUIEnvironment.GetFont("../../media/fonthaettenschweiler.bmp"); device.GUIEnvironment.Skin.Font = font; // add some gui stuff device.GUIEnvironment.AddMessageBox("Hello World", "I'm a Irrlicht.NET MessageBox. Please press SPACE to close me.", true, MessageBoxFlag.OK | MessageBoxFlag.CANCEL, null, -1); // start drawing loop int fps = 0; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(255, 0, 0, 50)); // draw scene device.SceneManager.DrawAll(); device.GUIEnvironment.DrawAll(); // do some collision testing Line3D line = new Line3D(); line.start = cam.Position; line.end = ((cam.Target - line.start).Normalize() * 1000.0f) + line.start; Vector3D intersection = new Vector3D(); Triangle3D tri = new Triangle3D(); if (device.SceneManager.SceneCollisionManager.GetCollisionPoint( line, selector, out intersection, out tri)) { bill.Position = intersection; Material mat = new Material(); mat.Lighting = false; device.VideoDriver.SetTransform(TransformationState.WORLD, new Matrix4()); device.VideoDriver.SetMaterial(mat); device.VideoDriver.Draw3DTriangle(tri, new Color(0, 255, 0, 0)); } // draw 2d logo device.VideoDriver.Draw2DImage( texLogo, new Position2D(10, 10), new Rect(0, 0, 88, 31), new Rect(new Position2D(0, 0), device.VideoDriver.ScreenSize), new Color(0xffffff), false); // draw some text font.Draw("Press 'S' to toggle the visibility of the realtime shadow.", new Position2D(120, 20), new Color(100, 150, 200, 200)); device.VideoDriver.EndScene(); if (fps != device.VideoDriver.FPS) { fps = device.VideoDriver.FPS; device.WindowCaption = "Irrlicht.NET test (primitives:" + device.VideoDriver.PrimitiveCountDrawn + ") fps:" + fps; } } } }
public void runTerrainTest() { device = new IrrlichtDevice(SelectedDriverType, new Dimension2D(800, 600), 16, false, false, false); device.EventReceiver = this; device.ResizeAble = true; device.WindowCaption = "Irrlicht.NET terrain test"; // create a camera ICameraSceneNode cam = device.SceneManager.AddCameraSceneNodeFPS(null, 100, 1200, -1); cam.Position = new Vector3D(1900 * 2, 255 * 2, 3700 * 2); cam.Target = new Vector3D(2397 * 2, 343 * 2, 2700 * 2); cam.FarValue = 12000.0f; // create the terrain ITerrainSceneNode terrain = device.SceneManager.AddTerrainSceneNode( "../../media/terrain-heightmap.bmp", null, -1, new Vector3D(), new Vector3D(40, 4.4f, 40), new Color(255, 255, 255, 255)); terrain.SetMaterialFlag(MaterialFlag.LIGHTING, false); terrain.SetMaterialType(MaterialType.DETAIL_MAP); terrain.SetMaterialTexture(0, device.VideoDriver.GetTexture("../../media/terrain-texture.jpg")); terrain.SetMaterialTexture(1, device.VideoDriver.GetTexture("../../media/detailmap3.jpg")); terrain.ScaleTexture(1.0f, 20.0f); // create terrain triangle selector for collision ITriangleSelector selector = device.SceneManager.CreateTerrainTriangleSelector(terrain, 0); // create collision animator and add it to the camera ISceneNodeAnimator collAnim = device.SceneManager.CreateCollisionResponseAnimator( selector, cam, new Vector3D(30, 50, 30), // size of ellipsoid around camera new Vector3D(0, 0, 0), // gravity new Vector3D(0, 50, 0), // translation 0.0005f); // sliding value cam.AddAnimator(collAnim); // add sky box device.SceneManager.AddSkyBoxSceneNode( device.VideoDriver.GetTexture("../../media/irrlicht2_up.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_dn.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_lf.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_rt.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_ft.jpg"), device.VideoDriver.GetTexture("../../media/irrlicht2_bk.jpg"), null, -1); // make cursor invisible device.CursorControl.Visible = false; // draw everything while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(255, 0, 0, 50)); device.SceneManager.DrawAll(); device.GUIEnvironment.DrawAll(); device.VideoDriver.EndScene(); } } }
public void run() { /* At first, we let the user select the driver type, * then start up the engine, set a caption, and get a * pointer to the video driver. */ // ask user for driver DriverType driverType; // Ask user to select driver: StringBuilder sb = new StringBuilder(); sb.Append("Please select the driver you want for this example:\n"); sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5"); sb.Append("\n(d) Software Renderer\n(e) Apfelbaum Software Renderer"); sb.Append("\n(f) Null Device\n(otherKey) exit\n\n"); // Get the user's input: TextReader tIn = Console.In; TextWriter tOut = Console.Out; string input = string.Empty; bool shadows = false; tOut.Write("Do you want to use realtime shadows? (y/n)"); input = tIn.ReadLine(); if (input == "y") { shadows = true; } tOut.Write(sb.ToString()); input = tIn.ReadLine(); // Select device based on user's input: switch (input) { case "a": driverType = DriverType.DIRECT3D9; break; case "b": driverType = DriverType.DIRECT3D8; break; case "c": driverType = DriverType.OPENGL; break; case "d": driverType = DriverType.SOFTWARE; break; case "e": driverType = DriverType.SOFTWARE2; break; case "f": driverType = DriverType.NULL_DRIVER; break; default: return; } /* 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 casted from an animated character. If your this example * runs to 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.*/ /* * From the unmanaged API documentation: * stencilbuffer: * Specifies if the stencil buffer should be enabled. * Set this to true, if you want the engine be able to draw stencil buffer shadows. * Note that not all devices are able to use the stencil buffer. * If they don't no shadows will be drawn. */ device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, false, shadows, true); if (device == null) { tOut.Write("Device creation failed."); return; } ISceneManager smgr = device.SceneManager; IVideoDriver driver = device.VideoDriver; /* For our environment, we load a .3ds file. It is a small room I modelled with * Anim8or and exported it into the 3ds format because the Irrlicht Engine did * not support the .an8 format when I wrote this tutorial. I am a very bad 3d * graphic artist, and so the texture mapping is not very nice in this model. * Luckily I am a better programmer than artist, and so the Irrlicht Engine is * able to create a cool texture mapping for me: Just use the mesh manipulator * and create a planar texture mapping for the mesh. If you want to see the * mapping I made with Anim8or, uncomment this line. I also did not figure out * how to set the material right in Anim8or, it has an emissive light color * which I don't really like. I'll switch it off too with this code.*/ IAnimatedMesh mesh = smgr.GetMesh( path + "room.3ds"); smgr.MeshManipulator.MakePlanarTextureMapping( mesh.GetMesh(0), 0.008f); ISceneNode node = smgr.AddAnimatedMeshSceneNode(mesh, null, 0); node.SetMaterialTexture( 0, driver.GetTexture(path + "wall.jpg")); node.GetMaterial(0).EmissiveColor.Set(0, 0, 0, 0); // Add a shadow to the room if it is not dark enough /* The result is interesting but not exactly what I was expecting! * Try for yourself... I think this could be a little problem in the * Irrlicht.NET wrapper but I promise I will investigate further to see * if I can make it work as intended * Forum Article (http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=10584) */ // IAnimatedMeshSceneNode xnode = (IAnimatedMeshSceneNode)node; // xnode.AddShadowVolumeSceneNode(); // /*Now, for the first special effect: Animated water. It works like this: The * WaterSurfaceSceneNode takes a mesh as input and makes it wave like a water * surface. And if we let this scene node use a nice material like the * MT_REFLECTION_2_LAYER, it looks really cool. We are doing this with the * next few lines of code. As input mesh, we create a hill plane mesh, without * hills. But any other mesh could be used for this, you could even use the * room.3ds (which would look really strange) if you wanted to.*/ mesh = smgr.AddHillPlaneMesh("myHill", new Dimension2Df(20, 20), new Dimension2D(40, 40), new Material(), 0, new Dimension2Df(0, 0), new Dimension2Df(10, 10)); node = smgr.AddWaterSurfaceSceneNode(mesh.GetMesh(0), 3.0f, 300.0f, 30.0f, null, 0); node.Position = new Vector3D(0, 7, 0); node.SetMaterialTexture(0, driver.GetTexture(path + "water.jpg")); node.SetMaterialTexture(1, driver.GetTexture(path + "stones.jpg")); node.SetMaterialType(MaterialType.REFLECTION_2_LAYER); /*The second special effect is very basic, I bet you saw it already in some * Irrlicht Engine demos: A transparent billboard combined with a dynamic light. * We simply create a light scene node, let it fly around, an to make it look * more cool, we attach a billboard scene node to it.*/ // create light node = smgr.AddLightSceneNode(null, new Vector3D(0, 0, 0), new Colorf(1.0f, 0.6f, 0.7f, 1.0f), 600.0f, 0); ISceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3D(0, 150, 0), 250.0f, 0.0005f); node.AddAnimator(anim); // attach billboard to light node = smgr.AddBillboardSceneNode(node, new Dimension2Df(50, 50), new Vector3D(), 0); node.SetMaterialFlag(MaterialFlag.LIGHTING, false); node.SetMaterialType(MaterialType.TRANSPARENT_ADD_COLOR); node.SetMaterialTexture(0, driver.GetTexture(path + "particlewhite.bmp")); /* The next special effect is a lot more interesting: A particle system. The * particle system in the Irrlicht Engine is quit modular and extensible and * yet easy to use. There is a particle system scene node into which you can * put particle emitters, which make particles come out of nothing. These * emitters are quite flexible and usually have lots of parameters like * direction, amount and color of the particles they should create. * There are different emitters, for example a point emitter which lets * particles pop out at a fixed point. If the particle emitters available * in the engine are not enough for you, you can easily create your own ones, * you'll simply have to create a class derived from the IParticleEmitter * interface and attach it to the particle system using setEmitter(). * In this example we create a box particle emitter, which creates particles * randomly inside a box. The parameters define the box, direction of the * articles, minimal and maximal new particles per second, color and minimal * and maximal livetime of the particles. Because only with emitters particle * system would be a little bit boring, there are particle affectors, which * modify particles during they fly around. They can be added to the particle * system, simulating additional effects like gravity or wind. The particle * affector we use in this example is an affector, which modifies the color * of the particles: It lets them fade out. Like the particle emitters, * additional particle affectors can also be implemented by you, simply derive * a class from IParticleAffector and add it with addAffector(). After we set * a nice material to the particle system, we have a cool looking camp fire. * By adjusting material, texture, particle emitter and affector parameters, * it is also easily possible to create smoke, rain, explosions, snow, and * so on.*/ IParticleSystemSceneNode ps = smgr.AddParticleSystemSceneNode( false, null, 0, new Vector3D(-70, 60, 40), new Vector3D(), new Vector3D(2, 2, 2)); ps.ParticleSize = new Dimension2Df(20, 10); IParticleEmitter em = ps.CreateBoxEmitter( new Box3D(-7, 0, -7, 7, 1, 7), new Vector3D(0.0f, 0.03f, 0.0f), 80, 100, new Color(0, 255, 255, 255), new Color(0, 255, 255, 255), 800, 2000, 0); ps.SetEmitter(em); IParticleAffector paf = ps.CreateFadeOutParticleAffector(new Color(), 1500); ps.AddAffector(paf); ps.SetMaterialFlag(MaterialFlag.LIGHTING, false); ps.SetMaterialTexture(0, driver.GetTexture(path + "particle.bmp")); ps.SetMaterialType(MaterialType.TRANSPARENT_VERTEX_ALPHA); /*As our last special effect, we want a dynamic shadow be casted from an animated * character. For this we load a quake 2 .md2 model and place it into our world. * For creating the shadow, we simply need to call addShadowVolumeSceneNode(). The * color of shadows is only adjustable globally for all shadows, by calling * ISceneManager::setShadowColor(). Voila, here is our dynamic shadow. Because * the character is a little bit too small for this scene, we make it bigger * using setScale(). And because the character is lighted by a dynamic light, * we need to normalize the normals to make the lighting on it correct. This * is always necessary if the scale of a dynamic lighted model is not (1,1,1). * Otherwise it would get too dark or too bright because the normals will be * scaled too.*/ mesh = smgr.GetMesh(path + "faerie.md2"); IAnimatedMeshSceneNode anode = smgr.AddAnimatedMeshSceneNode(mesh, null, 0); anode.Position = new Vector3D(-50, 45, -60); anode.SetMD2Animation(MD2AnimationType.STAND); anode.SetMaterialTexture(0, driver.GetTexture(path + "Faerie5.BMP")); // add shadow anode.AddShadowVolumeSceneNode(); smgr.ShadowColor = new Color(220, 0, 0, 0); // make the model a little bit bigger and normalize its normals // because of this for correct lighting anode.Scale = new Vector3D(2, 2, 2); anode.SetMaterialFlag(MaterialFlag.NORMALIZE_NORMALS, true); /*Finally we simply have to draw everything, that's all.*/ ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(); camera.Position = new Vector3D(-50, 50, -150); // Remove the mouse cursor: device.CursorControl.Visible = false; int lastFPS = -1; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200)); device.SceneManager.DrawAll(); device.VideoDriver.EndScene(); int fps = device.VideoDriver.FPS; if (lastFPS != fps) { device.WindowCaption = "Irrlicht Engine - SpecialFX tutorial [" + device.VideoDriver.Name + "] FPS:" + fps.ToString(); lastFPS = fps; } } } /* * In the end, delete the Irrlicht device. */ // Instead of device->drop, we'll use: GC.Collect(); }
public void run() { /* The start of the main function starts like in most other example. * We ask the user for the desired renderer and start it up. */ // ask user for driver DriverType driverType; // Ask user to select driver: StringBuilder sb = new StringBuilder(); sb.Append("Please select the driver you want for this example:\n"); sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5"); sb.Append("\n(d) Software Renderer\n(e)Apfelbaum Software Renderer"); sb.Append("\n(f) Null Device\n(otherKey) exit\n\n"); // Get the user's input: TextReader tIn = Console.In; TextWriter tOut = Console.Out; tOut.Write(sb.ToString()); string input = tIn.ReadLine(); // Select device based on user's input: switch (input) { case "a": driverType = DriverType.DIRECT3D9; break; case "b": driverType = DriverType.DIRECT3D8; break; case "c": driverType = DriverType.OPENGL; break; case "d": driverType = DriverType.SOFTWARE; break; case "e": driverType = DriverType.SOFTWARE2; break; case "f": driverType = DriverType.NULL_DRIVER; break; default: return; } // Create device and exit if creation fails: IrrlichtDevice device = new IrrlichtDevice( driverType, new Dimension2D(640, 480), 32, false, true, true); if (device == null) { tOut.Write("Device creation failed."); return; } /* set this as event receiver*/ device.EventReceiver = this; /*************************************************/ /* First, we add standard stuff to the scene: A nice irrlicht engine logo, * a small help text, a user controlled camera, and we disable the mouse * cursor.*/ ISceneManager smgr = device.SceneManager; IVideoDriver driver = device.VideoDriver; IGUIEnvironment env = device.GUIEnvironment; driver.SetTextureCreationFlag(TextureCreationFlag.ALWAYS_32_BIT, true); // add irrlicht logo env.AddImage(driver.GetTexture(path + "irrlichtlogoalpha.tga"), new Position2D(10, 10), true, null, 0, ""); // add some help text IGUIStaticText text = env.AddStaticText( "Press 'W' to change wireframe mode\nPress 'D' to toggle detail map", new Rect(10, 453, 200, 475), true, true, null, -1); // add camera ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100.0f, 1200.0f, -1); camera.Position = new Vector3D(1900 * 2, 255 * 2, 3700 * 2); camera.Target = new Vector3D(2397 * 2, 343 * 2, 2700 * 2); camera.FarValue = 12000.0f; // disable mouse cursor device.CursorControl.Visible = false; /* Here comes the terrain renderer scene node: We add it just like any other scene * node to the scene using ISceneManager::addTerrainSceneNode(). The only parameter * we use is a file name to the heightmap we use. A heightmap is simply a gray * scale texture. The terrain renderer loads it and creates the 3D terrain * from it. * To make the terrain look more big, we change the scale factor of it to * (40, 4.4, 40). Because we don't have any dynamic lights in the scene, we * switch off the lighting, and we set the file terrain-texture.jpg as texture * for the terrain and detailmap3.jpg as second texture, called detail map. * At last, we set the scale values for the texture: The first texture will be * repeated only one time over the whole terrain, and the second one (detail map) * 20 times. */ // add terrain scene node terrain = smgr.AddTerrainSceneNode( path + "terrain-heightmap.bmp", null, -1, new Vector3D(), new Vector3D(40, 4.4f, 40), new Color(255, 255, 255, 255)); terrain.SetMaterialFlag(MaterialFlag.LIGHTING, false); terrain.SetMaterialType(MaterialType.DETAIL_MAP); terrain.SetMaterialTexture(0, driver.GetTexture(path + "terrain-texture.jpg")); terrain.SetMaterialTexture(1, driver.GetTexture(path + "detailmap3.jpg")); terrain.ScaleTexture(1.0f, 20.0f); /* To be able to do collision with the terrain, we create a triangle selector. * If you want to know what triangle selectors do, just take a look into the * collision tutorial. The terrain triangle selector works together with the * terrain. To demonstrate this, we create a collision response animator and * attach it to the camera, so that the camera will not be able to fly through * the terrain.*/ // create triangle selector for the terrain ITriangleSelector selector = smgr.CreateTerrainTriangleSelector(terrain, 0); // create collision response animator and attach it to the camera ISceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator( selector, camera, new Vector3D(60, 100, 60), new Vector3D(0, 0, 0), new Vector3D(0, 50, 0), 0.0005f); camera.AddAnimator(anim); //we add the skybox which we already used in lots of Irrlicht examples. driver.SetTextureCreationFlag(TextureCreationFlag.CREATE_MIP_MAPS, false); smgr.AddSkyBoxSceneNode( driver.GetTexture(path + "irrlicht2_up.jpg"), driver.GetTexture(path + "irrlicht2_dn.jpg"), driver.GetTexture(path + "irrlicht2_lf.jpg"), driver.GetTexture(path + "irrlicht2_rt.jpg"), driver.GetTexture(path + "irrlicht2_ft.jpg"), driver.GetTexture(path + "irrlicht2_bk.jpg"), null, 0); driver.SetTextureCreationFlag(TextureCreationFlag.CREATE_MIP_MAPS, true); /* That's it, draw everything. Now you know how to use terrain * in Irrlicht. */ int lastFPS = -1; while (device.Run()) { if (device.WindowActive) { device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200)); device.SceneManager.DrawAll(); device.VideoDriver.EndScene(); int fps = device.VideoDriver.FPS; if (lastFPS != fps) { device.WindowCaption = "Irrlicht Engine - Terrain example [" + device.VideoDriver.Name + "] FPS:" + fps.ToString(); lastFPS = fps; } } } /* * In the end, delete the Irrlicht device. */ // Instead of device.drop, we'll use: GC.Collect(); }