using System;
using System.Collections.Generic;
using System.Text;
using IrrlichtNetSwig;

namespace RenderToTexture
{
    class Program
    {
        static void Main(string[] args)
        {
            	// let user select driver type

	E_DRIVER_TYPE driverType = E_DRIVER_TYPE.EDT_DIRECT3D9;

	Console.WriteLine(@"Please select the driver you want for this example:
(a) Direct3D 9.0c
(b) Direct3D 8.1
(c) OpenGL 1.5
(d) Software Renderer
(e) Burning's Software Renderer
(f) NullDevice
(otherKey) exit");

            var keyInfo = Console.ReadKey(true);

	switch(keyInfo.KeyChar)
	{
		case 'a': driverType = E_DRIVER_TYPE.EDT_DIRECT3D9;break;
		case 'b': driverType = E_DRIVER_TYPE.EDT_DIRECT3D8;break;
		case 'c': driverType = E_DRIVER_TYPE.EDT_OPENGL;   break;
		case 'd': driverType = E_DRIVER_TYPE.EDT_SOFTWARE; break;
		case 'e': driverType = E_DRIVER_TYPE.EDT_BURNINGSVIDEO;break;
		case 'f': driverType = E_DRIVER_TYPE.EDT_NULL;     break;
		default: return;
	}	

	// create device and exit if creation failed

	IrrlichtDevice device =
		IrrlichtNet.createDevice(driverType, new dimension2di(640, 480),
		16, false, false);

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

	IVideoDriver driver = device.getVideoDriver();
	ISceneManager smgr = device.getSceneManager();
	IGUIEnvironment env = device.getGUIEnvironment();
	
	/*
	Now, we load an animated mesh to be displayed. As in most examples,
	we'll take the fairy md2 model. The difference here: We set the
	shininess of the model to a value other than 0 which is the default
	value. This enables specular highlights on the model if dynamic
	lighting is on. The value influences the size of the highlights.
	*/

	// load and display animated fairy mesh

	IAnimatedMeshSceneNode fairy = smgr.addAnimatedMeshSceneNode(
		smgr.getMesh("../../media/faerie.md2"));

	if (fairy!=null)
	{
		fairy.setMaterialTexture(0,
				driver.getTexture("../../media/faerie2.bmp")); // set diffuse texture
		fairy.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, true); // enable dynamic lighting
		fairy.getMaterial(0).Shininess = 20.0f; // set size of specular highlights
		fairy.setPosition(new vector3df(-10,0,-100));
		fairy.setMD2Animation ( EMD2_ANIMATION_TYPE.EMAT_STAND );
	}
	
	/*
	To make specular highlights appear on the model, we need a dynamic
	light in the scene. We add one directly in vicinity of the model. In
	addition, to make the model not that dark, we set the ambient light to
	gray.
	*/

	// add white light
	smgr.addLightSceneNode(null, new vector3df(-15,5,-105),
			new SColorf(1.0f, 1.0f, 1.0f));

	// set ambient light
	smgr.setAmbientLight(new SColorf(0,60,60,60));
	
	/*
	The next is just some standard stuff: Add a user controlled camera to
	the scene, disable mouse cursor, and add a test cube and let it rotate
	to make the scene more interesting.
	*/

	// add fps camera
	ICameraSceneNode fpsCamera = smgr.addCameraSceneNodeFPS();
	fpsCamera.setPosition(new vector3df(-50,50,-150));

	// disable mouse cursor
	device.getCursorControl().setVisible(false);

	// create test cube
	ISceneNode test = smgr.addCubeSceneNode(60);

	// let the cube rotate and set some light settings
	ISceneNodeAnimator anim = smgr.createRotationAnimator(
		new vector3df(0.3f, 0.3f,0));

	test.setPosition(new vector3df(-100,0,-100));
	test.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, false); // disable dynamic lighting
	test.addAnimator(anim);
	//anim.drop();

	// set window caption
	device.setWindowCaption("Irrlicht Engine - Render to Texture and Specular Highlights example");
	
	/*
	To test out the render to texture feature, we need a render target
	texture. These are not like standard textures, but need to be created
	first. To create one, we call IVideoDriver::addRenderTargetTexture()
	and specify the size of the texture. Please don't use sizes bigger than
	the frame buffer for this, because the render target shares the zbuffer
	with the frame buffer.
	Because we want to render the scene not from the user camera into the
	texture, we add another fixed camera to the scene. But before we do all
	this, we check if the current running driver is able to render to
	textures. If it is not, we simply display a warning text.
	*/

	// create render target
	ITexture rt = null;
	ICameraSceneNode fixedCam = null;
	

	if (driver.queryFeature(E_VIDEO_DRIVER_FEATURE.EVDF_RENDER_TO_TARGET))
	{
		rt = driver.addRenderTargetTexture(new dimension2di(256,256), "RTT1");
		test.setMaterialTexture(0, rt); // set material of cube to render target

		// add fixed camera
		fixedCam = smgr.addCameraSceneNode(null, new vector3df(10,10,-80),
			new vector3df(-10,10,-100));
	}
	else
	{
		// create problem text
		IGUISkin skin = env.getSkin();
		IGUIFont font = env.getFont("../../media/fonthaettenschweiler.bmp");
		if (font!=null)
			skin.setFont(font);

		IGUIStaticText text = env.addStaticText(
			"Your hardware or this renderer is not able to use the render to texture feature. RTT Disabled.",
			new recti(150,20,470,60));

		text.setOverrideColor(new SColor(100,255,255,255));
	}
	
	/*
	Nearly finished. Now we need to draw everything. Every frame, we draw
	the scene twice. Once from the fixed camera into the render target
	texture and once as usual. When rendering into the render target, we
	need to disable the visibilty of the test cube, because it has the
	render target texture applied to it. That's it, wasn't too complicated
	I hope. :)
	*/

	int lastFPS = -1;

	while(device.run())
	if (device.isWindowActive())
	{
		driver.beginScene(true, true, new SColor());

		if (rt!=null)
		{
			// draw scene into render target
			
			// set render target texture
			driver.setRenderTarget(rt, true, true, new SColor(0,0,0,255));

			// make cube invisible and set fixed camera as active camera
			test.setVisible(false);
			smgr.setActiveCamera(fixedCam);

			// draw whole scene into render buffer
			smgr.drawAll();

			// set back old render target
			// The buffer might have been distorted, so clear it
			driver.setRenderTarget(null, true, true, new SColor());

			// make the cube visible and set the user controlled camera as active one
			test.setVisible(true);
			smgr.setActiveCamera(fpsCamera);
		}
		
		// draw scene normally
		smgr.drawAll();
		env.drawAll();

		driver.endScene();

		// display frames per second in window title
		int fps = driver.getFPS();
		if (lastFPS != fps)
		{
			string str = "Irrlicht Engine - Render to Texture and Specular Highlights example";
			str += " FPS:";
			str += fps;

			device.setWindowCaption(str);
			lastFPS = fps;
		}
	}

	//device.drop(); // drop device
	return;
        }
    }
}
