Exemple #1
0
    void run(CSettings *pSettings) {
      CProgress *pProg=new CProgress(m_pDevice);

      ode::CIrrOdeEventProgress *p=new ode::CIrrOdeEventProgress(0,0);
      pProg->onEvent(p);
      delete p;

      //register the IrrOde scene node factory
      ode::CIrrOdeSceneNodeFactory cFactory(m_pSmgr);
      m_pSmgr->registerSceneNodeFactory(&cFactory);

      if (pSettings->isActive(4)) {
        CEventInstallRandomForestPlugin *p=new CEventInstallRandomForestPlugin();
        ode::CIrrOdeManager::getSharedInstance()->getOdeThread()->getOutputQueue()->postEvent(p);
        //delete p;
      }

#ifdef WITH_PARTICLES
      CAdvancedParticleSystemNodeFactory *cParticleFactory=new CAdvancedParticleSystemNodeFactory(m_pSmgr);
      m_pSmgr->registerSceneNodeFactory(cParticleFactory);
      cParticleFactory->drop();
#endif

      CRoadMeshLoader *pLoader=new CRoadMeshLoader(m_pDevice);
      m_pSmgr->addExternalMeshLoader(pLoader);

      //init the ODE
      ode::CIrrOdeManager::getSharedInstance()->initODE();

      //load the scene
      ode::CIrrOdeManager::getSharedInstance()->loadScene(DATADIR "/scenes/IrrOdeCar.xml",m_pSmgr);

      for (u32 i=0; i<m_pSmgr->getMeshCache()->getMeshCount(); i++) {
        scene::IAnimatedMesh *p=m_pSmgr->getMeshCache()->getMeshByIndex(i);
        for (u32 j=0; j<p->getMeshBufferCount(); j++) {
          p->getMeshBuffer(j)->setHardwareMappingHint(scene::EHM_STATIC);
        }
      }

      u32 iCars   = pSettings->getCountOf(0),
               iPlanes = pSettings->getCountOf(1),
               iTanks  = pSettings->getCountOf(2),
               iHelis  = pSettings->getCountOf(3);

      bool bRearCam=pSettings->isActive(6);

      core::dimension2du cScreenSize=m_pDevice->getVideoDriver()->getScreenSize();

      m_pCtrlReceiver = new CControlReceiver(m_pDevice, m_pSndEngine, cScreenSize.Width / (2.0f * cScreenSize.Height));

      if (!pSettings->isActive(0)) m_pCtrlReceiver->removeFromScene("roads"       ,m_pSmgr);
      if (!pSettings->isActive(2)) m_pCtrlReceiver->removeFromScene("targets"     ,m_pSmgr);
      if (!pSettings->isActive(3)) m_pCtrlReceiver->removeFromScene("plane_course",m_pSmgr);
      if (!pSettings->isActive(1)) {
        m_pCtrlReceiver->removeFromScene("ActiveSigns" ,m_pSmgr);
        m_pCtrlReceiver->removeFromScene("PassiveSigns",m_pSmgr);
      }
      if ( pSettings->isActive(4)) {
       const c8 sForests[][255]={ "RandomForest1", "RandomForest2", "Forest1", "Forest2" };

        for (u32 i=0; i<2; i++) {
          printf("merging \"%s\"...\n",sForests[i]);
          scene::ISceneNode *p=m_pSmgr->getSceneNodeFromName(sForests[i]);
          CRandomForest *pForest=(CRandomForest *)p;
          if (pForest!=NULL) {
            CMeshCombiner *pCombine=new CMeshCombiner(0.8f);
            core::array<scene::IMeshSceneNode *> aMeshSceneNodes;
            core::array<scene::ISceneNode *> aTrees=pForest->getGeneratedTrees();

            for (u32 j=0; j<aTrees.size(); j++) {
              scene::IMeshSceneNode *p=(scene::IMeshSceneNode *)aTrees[j];
              aMeshSceneNodes.push_back(p);
            }

            printf("%i trees\n",aMeshSceneNodes.size());

            if (aMeshSceneNodes.size()>0) {
              c8 s[0xFF];
              sprintf(s,"MyCombinedTrees_%i",i);
              scene::IMesh *pCombined=pCombine->combineMeshes(m_pSmgr,m_pDriver,aMeshSceneNodes,s);
              if (pCombined!=NULL) {
                scene::ISceneNode *pRoot=m_pSmgr->getSceneNodeFromName(sForests[i+2]);
                scene::IMeshSceneNode *pNode=m_pSmgr->addMeshSceneNode(pCombined,pRoot==NULL?m_pSmgr->getRootSceneNode():pRoot);
                for (u32 i=0; i<pNode->getMaterialCount(); i++) {
                  pNode->getMaterial(i).setFlag(video::EMF_LIGHTING,false);
                  pNode->getMaterial(i).MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                }
              }
            }
          }
        }
      }
      if (!pSettings->isActive(5)) {
        printf("removing terrain trimesh...\n");
        m_pCtrlReceiver->removeFromScene("terrain_trimesh",m_pSmgr);
      }
      else {
        printf("removing terrain heightfield...\n");
        m_pCtrlReceiver->removeFromScene("terrain_heightfield",m_pSmgr);
      }

      bool bUseShader=pSettings->getSelectedDriver()==video::EDT_OPENGL;

      if (bUseShader) {
        if (!m_pDriver->queryFeature(video::EVDF_PIXEL_SHADER_1_1)) {
          printf("Pixel shader disabled!\n");
          bUseShader=false;
        }

        if (!m_pDriver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) {
          printf("Vertex shader disabled!\n");
          bUseShader=false;
        }
      }

      //I can only add shaders for OpenGL
      if (bUseShader) {
        video::IGPUProgrammingServices *pGpu=m_pDriver->getGPUProgrammingServices();
        if (pGpu) {
          printf("\n**** compiling GLSL shader ... \n\n");
          CShaderCallBack *pCallback=new CShaderCallBack(m_pDevice);
          s32 iNewMaterial=pGpu->addHighLevelShaderMaterialFromFiles(
              DATADIR "/shaders/opengl.vert","vertexMain", video::EVST_VS_1_1,
              DATADIR "/shaders/opengl.frag", "pixelMain", video::EPST_PS_1_1,
              pCallback,video::EMT_SOLID);

          replaceMaterials(m_pSmgr->getRootSceneNode(),iNewMaterial);
          pCallback->drop();
          printf("Ready.\n\n");
        }
      }

      delete pSettings;

      //modify the textures of the car segment and the tank segment to
      scene::IAnimatedMeshSceneNode *pNode=(scene::IAnimatedMeshSceneNode *)m_pSmgr->getSceneNodeFromName("car_segment");
      if (pNode) pNode->getMaterial(0).getTextureMatrix(0).setTextureScale(50.0f,50.0f);
      pNode=(scene::IAnimatedMeshSceneNode *)m_pSmgr->getSceneNodeFromName("tank_segment");
      if (pNode) pNode->getMaterial(0).getTextureMatrix(0).setTextureScale(50.0f,50.0f);

      int lastFPS=-1;

      //create the necessary state objects
      core::array<CIrrOdeCarState *> aStates;

      m_pCtrlReceiver->createMenu(iCars, iPlanes, iHelis, iTanks, bRearCam);

      //phyiscs initialization
      ode::CIrrOdeManager::getSharedInstance()->initPhysics();

      delete pProg;

      m_pDriver->setFog(g_cFogColor,video::EFT_FOG_LINEAR,g_fMinFog,g_fMaxFog,0.00001f,true,false);
      enableFog(m_pSmgr->getRootSceneNode());

      u32 iFrames=0,iTotalFps=0;
      m_pCtrlReceiver->start();

      CCameraController *pCamCtrl = m_pCtrlReceiver->getCameraController();

      //let's run the loop
      while(m_pDevice->run()) {
        //step the simulation
        ode::CIrrOdeManager::getSharedInstance()->step();

        m_pCtrlReceiver->update();

        //now for the normal Irrlicht stuff ... begin, draw and end scene and update window caption
        m_pDriver->beginScene(true,true,video::SColor(0xFF,0xA0,0xA0,0xC0));
        pCamCtrl->render();
        m_pDriver->setMaterial(m_pDriver->getMaterial2D());   //Fix the flipped texture problem
        m_pGui->drawAll();
        m_pCtrlReceiver->drawSpecifics();

        m_pDriver->endScene();
        int fps = m_pDriver->getFPS();

        if (lastFPS != fps) {
          iFrames++;
          iTotalFps+=fps;

          core::stringw str = L"Irrlicht Engine - IrrODE Car Demo [";
          str += m_pDriver->getName();
          str += "] FPS:";
          str += fps;
          str += " (avg: ";
          str += (iTotalFps/iFrames);
          str += ")";

          m_pDevice->setWindowCaption(str.c_str());
          lastFPS = fps;

          pCamCtrl->setFps(str.c_str());
        }
      }

      ode::CIrrOdeWorldObserver::getSharedInstance()->destall();

      CConfigFileManager::getSharedInstance()->writeConfig(m_pDevice,DATADIR "/irrOdeCarControls.xml");

#ifndef NO_IRRKLANG
      //drop the world so it is destroyed
      m_pDevice->drop();

      if (m_pSndEngine) m_pSndEngine->drop();
#endif

      //and now some more cleanup...
      for (u32 i=0; i<aStates.size(); i++) {
        delete aStates[i];
      }
      aStates.clear();
    }