/* ========================================================================== * (C) 2006 Universitat Jaume I * ========================================================================== * PROYECT: GAME TOOLS * ==========================================================================*/ /** CONTENT: * * * @file main.cpp /** COMMENTS: * Model must be in "media/models" folder. * Lod file must be in "media/GT" folder. /*===========================================================================*/ #include "ExampleApplication.h" #include "GeoLodTreeLibrary.h" #include "GeoMeshLoader.h" // Distance values #define dist_min 300 #define dist_max 700 // Model name #define model_name "arbol" //Global variables Entity* entity; Geometry::LodTreeLibrary* myTrees; Ogre::Mesh *ogreMesh=NULL; Geometry::GeoMeshLoader *meshloader=NULL; bool force_maxLODfactor = false; Ogre::Vector3 forest_center; ColourValue color=ColourValue::Red; Camera* theCam; Entity* pPlaneEnt; OverlayElement* mInfo; OverlayElement* mInfo2; void DumpDataToOgreBuffers(Ogre::Mesh *original_mesh, Geometry::LodTreeLibrary *lodTreesLib) { // Copy to Ogre buffers including the degenerated triangles Ogre::HardwareIndexBufferSharedPtr ibuf; Ogre::IndexData *indexes; Ogre::RenderOperation mRenderOp; for (int submesh=0; submesh < original_mesh->getNumSubMeshes(); submesh++) { bool istrunk = lodTreesLib->GetLeavesSubMesh()!=submesh; original_mesh->getSubMesh(submesh)->_getRenderOperation(mRenderOp,0); // we will suppose this submesh is the foliage int indices_to_render = lodTreesLib->CurrentLOD_Foliage_IndexCount(); int offset = 0; if (istrunk) { // this submesh is the trunk offset = lodTreesLib->GetValidTrunkOffset(submesh); indices_to_render = lodTreesLib->GetValidTrunkIndexCount(submesh); } ibuf = mRenderOp.indexData->indexBuffer; mRenderOp.indexData->indexStart = 0; mRenderOp.indexData->indexCount = indices_to_render; unsigned long* pIdx = static_cast(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); for (int k=0; kCurrentLOD_Trunk_Indices()->GetIndex(k+offset); else pIdx[k] = lodTreesLib->CurrentLOD_Foliage_Indices()->GetIndex(k); ibuf->unlock(); } } class FresnelFrameListener : public ExampleFrameListener { int manage; public: FresnelFrameListener(RenderWindow* win, Camera* cam) : ExampleFrameListener(win, cam, false, false) { manage=1; } bool frameStarted(const FrameEvent& evt) { Vector3 dist; int distance=0,inc2=0,d; unsigned int nlod,diflods; // Move upto 80 units/second Real MoveFactor = 180.0 * evt.timeSinceLastFrame; // Copy the current state of the input devices mInputDevice->capture(); // If this is the first frame, pick a speed if (evt.timeSinceLastFrame == 0) { mMoveScale = 1; mRotScale = 0.1; } // Otherwise scale movement units by time passed since last frame else { // Move about 100 units per second, mMoveScale = mMoveSpeed * evt.timeSinceLastFrame; // Take about 10 seconds for full rotation mRotScale = mRotateSpeed * evt.timeSinceLastFrame; } mRotX = 0; mRotY = 0; mTranslateVector = Vector3::ZERO; //LOD selection int difdist = dist_max - dist_min; int i=0; dist = forest_center - mCamera->getPosition(); distance =dist.length(); float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min); lodfactor = 1.0f - lodfactor; if (lodfactor<0.0f) lodfactor=0.0f; if (lodfactor>1.0f) lodfactor=1.0f; if (force_maxLODfactor) lodfactor=1.0f; static float lodfactorBefore = -1.0f; if (fabsf(lodfactorBefore-lodfactor)>0.05f) { myTrees->GoToLod(lodfactor); DumpDataToOgreBuffers(ogreMesh,myTrees); lodfactorBefore=lodfactor; } // Move the node if(mInputDevice->isKeyDown(Ogre::KC_UP)) mTranslateVector.z = -mMoveScale; if(mInputDevice->isKeyDown(Ogre::KC_DOWN)) mTranslateVector.z = mMoveScale; // Instead of moving the ship left and right, rotate it using yaw() if(mInputDevice->isKeyDown(Ogre::KC_LEFT)) mCamera->yaw(mRotScale); force_maxLODfactor=mInputDevice->isKeyDown(Ogre::KC_F2); if(mInputDevice->isKeyDown(Ogre::KC_RIGHT)) mCamera->yaw(-mRotScale); if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE)) { //delete myTrees; return false; } if( mInputDevice->getMouseButton( 1 ) ) { mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13; mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13; } else { mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13); mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13); } char cadena[256]; sprintf(cadena,"Distance: %d",distance); mInfo->setCaption(cadena); sprintf(cadena,"LOD factor: %f",lodfactor); mInfo2->setCaption(cadena); mCamera->yaw(mRotX); mCamera->pitch(mRotY); mCamera->moveRelative(mTranslateVector); return true; } }; class FresnelApplication : public ExampleApplication { protected: public: FresnelApplication() { } ~FresnelApplication() { } protected: // Just override the mandatory create scene method void createScene(void) { // mat = new MaterialPtr[1]; theCam = mCamera; theCam->setPosition(0,20,dist_min-40); // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.4, 0.4, 0.4)); // Create a directional light Light* l = mSceneMgr->createLight("MainLight"); l->setType(Light::LT_DIRECTIONAL); l->setDirection(0.0,-1.0,0.0); // Define a floor plane mesh Plane plane( Vector3::UNIT_Y, 0 ); MeshManager::getSingleton().createPlane("ground", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z); Entity* suelo = mSceneMgr->createEntity( "GroundEntity", "ground" ); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(suelo); suelo->setMaterialName("Examples/GrassFloor"); suelo->setCastShadows(false); mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); // My node to which all objects will be attached SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); std::string model_file=model_name; model_file.append(".mesh"); //Models entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ML12m.mesh"); ogreMesh = entity->getMesh().getPointer(); // load LOD info from the object meshloader=new Geometry::GeoMeshLoader; Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ML12m.mesh"); if (!meshloader->GetLodStripsData()) OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the trunk","LOD Demo"); if (!meshloader->GetTreeSimpSeq()) OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the foliage","LOD Demo"); myTrees = new Geometry::LodTreeLibrary(meshloader->GetLodStripsData(),meshloader->GetTreeSimpSeq(),themesh); entity->setNormaliseNormals(true); for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++) { bool istrunk = myTrees->GetLeavesSubMesh()!=submesh; int indices_to_render = 0; if (istrunk) { entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/trunk"); indices_to_render = myTrees->GetValidTrunkIndexCount(submesh); } else { entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/leaf"); indices_to_render = myTrees->CurrentLOD_Foliage_IndexCount(); } Ogre::RenderOperation mRenderOp; ogreMesh->getSubMesh(submesh)->_getRenderOperation(mRenderOp,0); mRenderOp.indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( Ogre::HardwareIndexBuffer::IT_32BIT, // type of index indices_to_render, // number of indexes Ogre::HardwareBuffer::HBU_DISCARDABLE , // usage false); // no shadow buffer } forest_center=Ogre::Vector3(150.0f,0.0f,0.0f); for (int i=1; i<8; i++) // 20 for (int j=1; j<8; j++) // 20 { char newTreeName[16]=""; sprintf(newTreeName,"arbol_%d_%d",i,j); Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); Ogre::Entity *auxent = entity->clone(newTreeName); auxnode->attachObject( auxent ); auxnode->scale(4.0f,4.0f,4.0f); auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360)); auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD); float randomsepx = (float)((rand()%18)-9); float randomsepy = (float)((rand()%12)-6); auxnode->translate(i*30.0f+randomsepx,0.0f,-j*30.0f-randomsepx); auxent->setNormaliseNormals(true); } if (!meshloader->GetLodStripsData() || !meshloader->GetTreeSimpSeq()) OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo"); // show overlay Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay"); mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1"); mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2"); pOver->show(); } void createFrameListener(void) { mFrameListener= new FresnelFrameListener(mWindow, mCamera); mFrameListener->showDebugOverlay(true); mRoot->addFrameListener(mFrameListener); } }; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif { // Create application object FresnelApplication app; try { app.go(); } catch( Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription(); #endif } return 0; } #ifdef __cplusplus } #endif