/**
     * Application main function:
     *   Initializes Ogre, creates a window, creates scenes, starts the rendering loop
     */
    void run() {
        // ----------------------- Create root object & window --------------------- //
        // Initialize (~ glutInit)
        mRoot = new Ogre::Root();
        mRoot->restoreConfig();                  // Read config from ogre.cfg
        //if(!mRoot->showConfigDialog()) return; // Alternatively, you can show a dialog window here

        // Create window (~ glutCreateWindow)
        mWindow = mRoot->initialise(true, "Basic OGRE example");

        // Register per-frame callbacks (~ glutIdleFunc)
        mRoot->addFrameListener(this);

        // Register keyboard and mouse callbacks (~ glutMouseFunc, glutKeyboardFunc, glutWindowFunc)
        // This class already implements some logic, such as "quit on Escape".
        // It is described in input_util.h, feel free to play with that implementation.
        mEventListener = new SimpleMouseAndKeyboardListener(mWindow, mRoot, this);

        // ----------- Create scene ----------------- //
        // Each scene is represented by a "SceneManager" object, which
        // combines a SceneGraph (set of objects with their model transforms)
        // with a Camera (view-projection transform)
        mScene = createTriangleScene();      // Very basic colored triangle

        // This is like (~ glViewport), in that you could specify the region of the window to draw to.
        // You can have several scenes rendered to different parts in the window.
        Ogre::Viewport* vp = mWindow->addViewport(mScene->getCamera("MainCamera"));

        // ~ glClearColor
        vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

        // Enable control of a camera with mouse & keyboard using the utility class.
        mEventListener->controlCamera(mScene->getCamera("MainCamera"));

        // ------------------------ Configuration complete ----------------- //
        // Enter the infinite rendering & event processing loop.
        // ~ glutMainLoop()
        mRoot->startRendering();
    }
	 void createScene(){
		_sceneManager->setAmbientLight(Ogre::ColourValue(1.0f,1.0f,1.0f));
		_sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

		_sceneManager->setSkyBox(true, "OMV/SkyBoxUnderwater1");

		Ogre::Plane plane(Ogre::Vector3::UNIT_Y , -5000.0);

		Ogre::MeshManager::getSingleton().createPlane("plane", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
						plane, 60000,100000,200,200,true, 1,10,10, Ogre::Vector3::UNIT_Z);
		Ogre::SceneNode* nodePlano;
		Ogre::Entity* entPlano = _sceneManager->createEntity("PlanoEntity","plane");
		nodePlano = _sceneManager->createSceneNode("NodePlano");
		nodePlano->attachObject(entPlano);
		_sceneManager->getRootSceneNode()->addChild(nodePlano);
		entPlano->setMaterialName("plano");
		nodePlano->translate(Ogre::Vector3(0.0f,0.0f,45000.0f));
		
		
		Ogre::SceneNode* nodeEsfera02;
		Ogre::Light* light02;
		Ogre::Entity* entEsfera02 = _sceneManager->createEntity("EntEsfera02","sphere.mesh");
		//Ogre::SceneNode* nodeEsfera02 = mSceneMgr->createSceneNode("NodeEsfera02");
		nodeEsfera02 = _sceneManager->createSceneNode("NodeEsfera02");
		_sceneManager->getRootSceneNode()->addChild(nodeEsfera02);
		nodeEsfera02->attachObject(entEsfera02);
		
		 //NODO LUZ
		float lightScale = 0.9f;
		Ogre::SceneNode* nodeLuz02 = _sceneManager->createSceneNode("NodeLuz02");		
		light02 = _sceneManager->createLight("LuzPoint01");
		light02->setType(Ogre::Light::LT_POINT);		
		light02->setDiffuseColour(lightScale*Ogre::ColourValue(2.0f,2.0f,2.0f));	
		nodeLuz02->attachObject(light02);


		nodeEsfera02->addChild(nodeLuz02);
		nodeEsfera02->setScale(0.05f,0.05f,0.05f);
		nodeEsfera02->setPosition(0.0f,5000.0f,0.0f);

		banderin[0] = new Banderin("Inicio",_sceneManager, 5105.0, -2000.0, 0.0);
		_sceneManager->getRootSceneNode()->addChild(banderin[0]->nodoBanderin);
		banderin[1] = new Banderin("Fin",_sceneManager, 5105.0, -2000.0, 90000.0);
		_sceneManager->getRootSceneNode()->addChild(banderin[1]->nodoBanderin);

		
		

		nave = new Nave(_sceneManager, _sceneManager->getCamera("Camera"));

		for (int i = 0; i < num_monedas; i++)
		{
			crearMoneda(i,4000,5000,90000);
		}

		for (int i = 0; i < num_aros; i++)
		{
			crearAro(i,4000,5000,90000);
		}

		for (int i = 0; i < num_obstaculo; i++)
		{
			crearObstaculo(i,4000,5000,90000);
		}
		
	 }
//=============================================================================
void UpdateStats(Widget* _widget)
{
    ParamsPanel* _panel = dynamic_cast<ParamsPanel*>(_widget);
    assert(_panel);

    // param names
    const Ogre::StringVector& params = _panel->getAllParamNames();
    if (params.empty())
    {
        Ogre::String ParamNames[] = {"Camera Pos","Last FPS","Average FPS","Best FPS","Worst FPS","Triangles","Batches","ProcessMemory"};
        //stat
	    Ogre::StringVector stats(ParamNames, ParamNames + sizeof(ParamNames)/sizeof(Ogre::String));

        _panel->setPanelWidth(250);
        _panel->setAllParamNames(stats);
        _panel->setPanelAlignment(Ogre::GHA_RIGHT, Ogre::GVA_BOTTOM);
    } // End if
    
    // param values
    if (_panel->getOverlayElement()->isVisible())    
	{		
        Ogre::StringVector values;

        Ogre::SceneManager* pSceneMgr = Ogre::Root::getSingletonPtr()->getSceneManager("DefaultSceneManager");
        assert(pSceneMgr);
        Ogre::Camera* pCamera = pSceneMgr->getCamera("DefaultCamera");
        assert(pCamera);
        const Ogre::Vector3& vPosition = pCamera->getPosition();

        char buf[64];
        sprintf_s(buf, sizeof(buf), "%.2f, %.2f, %.2f", vPosition.x, vPosition.y, vPosition.z);
        values.push_back(buf);

        Ogre::RenderWindow* _pRenderWindow = (Ogre::RenderWindow*)Ogre::Root::getSingletonPtr()->getRenderTarget("Ogre Render Window");
        assert(_pRenderWindow);    
        const Ogre::RenderTarget::FrameStats& stats = _pRenderWindow->getStatistics();

        // fps info
		std::ostringstream oss;
        Ogre::String str;

        float fps[] = {stats.lastFPS, stats.avgFPS, stats.bestFPS, stats.worstFPS};
        int size = sizeof(fps)/sizeof(float);
        for (int j = 0 ; j < size ; ++j)
        {
            oss.str("");
            oss << std::fixed << std::setprecision(1) << fps[j];
            str = oss.str();
		    for (int i = str.length() - 5; i > 0; i -= 3) { str.insert(i, 1, ','); }
		    values.push_back(str);
        } // End for
        
        // triangle info
		str = Ogre::StringConverter::toString(stats.triangleCount);
		for (int i = str.length() - 3; i > 0; i -= 3) { str.insert(i, 1, ','); }
		values.push_back(str);

		str = Ogre::StringConverter::toString(stats.batchCount);
		for (int i = str.length() - 3; i > 0; i -= 3) { str.insert(i, 1, ','); }
		values.push_back(str);

/*
 * calculate total triangle count for all render targets
 *
        size_t uiTotalTriangleCount = 0, uiTotalBatchCount = 0;
        Ogre::RenderSystem* _pRenderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
        assert(_pRenderSystem);
        Ogre::RenderSystem::RenderTargetIterator it = _pRenderSystem->getRenderTargetIterator();
	    while(it.hasMoreElements())
	    {
            uiTotalTriangleCount += it.current()->second->getTriangleCount();
		    uiTotalBatchCount += it.current()->second->getBatchCount();

            it.getNext();
	    } // End while
*/
        // memory info
        oss.str("");
		oss << std::fixed << std::setprecision(3) << CalculateProcessMemory()/(1024.0f*1024.0f);
        str = oss.str();
 		values.push_back(str);

		_panel->setAllParamValues(values);
	}
}