/* ========================================================================== * (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; SceneNode* node; MaterialPtr *mat; 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 = 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 mRenderOp.indexData->indexBuffer = ibuf; 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 = node->getPosition() - mCamera->getPosition(); distance =dist.length(); DumpDataToOgreBuffers(ogreMesh,myTrees); float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min); lodfactor = 1.0f - lodfactor; if (lodfactor >= 0.0f && lodfactor <= 1.0f) { myTrees->GoToLod(lodfactor); if (lodfactor < 0.333f) { color.r=0.0; color.g=(lodfactor)*3.0f;//nlod*1.0/(diflods/3); color.b=(1.0-lodfactor)*3.0f;//(nlod*1.0/(diflods/3)); } else { if (lodfactor<0.666f) { color.r=(lodfactor-0.333f)*3.0f;//(nlod-diflods/3)*1.0/(diflods/3); color.g=1.0; color.b=0.0; } else { color.r=1.0; color.g=(1.0-lodfactor)*3.0f;//(nlod-(2*diflods/3))*1.0/(diflods/3); color.b=0.0; } } mat[0]->setDiffuse(color); } /* else { if ((distance > dist_max)) { // myStrips->GoToLod(1.0f); color.r=0.0; color.g=0.0; color.b=1.0; mat[0]->setDiffuse(color); } else { if ((distance < dist_min)) { // myStrips->GoToLod(0.0f); color.r=1.0; color.g=0.0; color.b=0.0; mat[0]->setDiffuse(color); } } }*/ // 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); if(mInputDevice->isKeyDown(Ogre::KC_RIGHT)) mCamera->yaw(-mRotScale); // Move the node if(mInputDevice->isKeyDown(Ogre::KC_W)) node->translate(0,mMoveScale,0); if(mInputDevice->isKeyDown(Ogre::KC_S)) node->translate(0,-mMoveScale,0); if(mInputDevice->isKeyDown(Ogre::KC_Z)) node->scale(1.01,1.01,1.01); if(mInputDevice->isKeyDown(Ogre::KC_X)) node->scale(0.99,0.99,0.99); // Rotate if(mInputDevice->isKeyDown(Ogre::KC_A)) node->yaw(mRotScale); if(mInputDevice->isKeyDown(Ogre::KC_D)) node->yaw(-mRotScale); if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE)) { delete myTrees; delete [] mat; 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); if (lodfactor<0.0f) lodfactor=0.0f; if (lodfactor>1.0f) lodfactor=1.0f; 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_max+50); // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3)); // Create a point light Light* l = mSceneMgr->createLight("MainLight"); l->setType(Light::LT_DIRECTIONAL); l->setDirection(0.0,0.0,-1.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/betulalod.mesh"); ogreMesh = entity->getMesh().getPointer(); // load LOD info from the object meshloader=new Geometry::GeoMeshLoader; Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/betulalod.mesh"); node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); node->attachObject( entity ); node->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-90.0f)); // myStrips = new LodStripsLibrary(lod_file,entity->getMesh().getPointer()); if (!meshloader->GetLodStripsData() || !meshloader->GetTreeSimpSeq()) exit(1); // myStrips = new Geometry::LodStripsLibrary(meshloader->GetLodStripsData(),themesh); myTrees = new Geometry::LodTreeLibrary(meshloader->GetLodStripsData(),meshloader->GetTreeSimpSeq(),themesh); entity->setNormaliseNormals(true); /* // Colour-coded material mat[0] = MaterialManager::getSingleton().create("test_mat", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat[0]->setCullingMode(CULL_ANTICLOCKWISE); mat[0]->setAmbient(ColourValue::Black); mat[0]->setDiffuse(color); mat[0]->setLightingEnabled(true); entity->setMaterialName("test_mat");*/ // Colour-coded material mat[0] = MaterialManager::getSingleton().create("test_mat", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat[0]->setCullingMode(CULL_NONE); mat[0]->setAmbient(ColourValue::Black); mat[0]->setDiffuse(color); mat[0]->setLightingEnabled(true); mat[0]->createTechnique()->createPass()->createTextureUnitState("nm_rt.png"); //entity->setMaterialName("test_mat"); entity->setMaterialName("Examples/GrassFloor"); // 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