2012年7月20日 星期五

NeoOgreApplication

NeoOgreApplicaion.h


#ifndef _NEO_OGRE_APPLICATION_H_
#define _NEO_OGRE_APPLICATION_H_
#include "Ogre\Ogre.h"
#include "OIS\OIS.h"
class NeoFrameListener : public Ogre::FrameListener
{
public:
    NeoFrameListener(): _listener(NULL){}
    NeoFrameListener(Ogre::RenderWindow* win, Ogre::Camera* camera, Ogre::SceneNode* node, Ogre::Entity* ent)
    {
        _camMovementSpeed = 50.0f;
        _walkingSpeed = 10.0f;
        _walkingRotation = 0;
        _cam = camera;
        _node = node;
        _ent = ent;
        OIS::ParamList pl;
        unsigned int windowHandle = 0;
        std::ostringstream windowHandleString;
        win->getCustomAttribute("WINDOW",  &windowHandle);
        windowHandleString << windowHandle;
        pl.insert(std::make_pair("WINDOW",  windowHandleString.str()));
        _im = OIS::InputManager::createInputSystem(pl);
        _key = static_cast(_im->createInputObject(OIS::OISKeyboard,false ));
        _mouse = static_cast(_im->createInputObject( OIS::OISMouse, false ));

        _aniState = _ent->getAnimationState("RunBase");
        _aniState->setLoop(false);
        _aniStateTop = _ent->getAnimationState("RunTop");
        _aniStateTop->setLoop(false);
    }
    ~NeoFrameListener()
    {
        delete _listener;
        _im->destroyInputObject(_key);
        _im->destroyInputObject(_mouse);
        OIS::InputManager::destroyInputSystem(_im);
    }
    bool frameStarted(const Ogre::FrameEvent& evt)
    {
        bool walked = false;
        Ogre::Vector3 camTranslate(0,0,0);
        Ogre::Vector3 nodeTranslate(0,0,0);
        _key->capture();
        if(_key->isKeyDown(OIS::KC_ESCAPE))
        {
            return false;
        }
        if(_key->isKeyDown(OIS::KC_1) && !_downKey1)
        {
            _downKey1 = true;
            _comp1 = !_comp1;
            Ogre::CompositorManager::getSingleton().setCompositorEnabled(_cam->getViewport(),"Compositor1",_comp1);
            return true;
        }
         if(!_key->isKeyDown(OIS::KC_1))
        {
            _downKey1 = false;
        }
         if(_key->isKeyDown(OIS::KC_SPACE))
        {

          _isActionKeyPress = true;
          _aniStateTop = _ent->getAnimationState("SliceHorizontal");
          _aniStateTop->setLoop(false);
          _aniStateTop->setTimePosition(0.0f);

        }
        if(_key->isKeyDown(OIS::KC_UP))
        {
            nodeTranslate += Ogre::Vector3(0,0,-1);
            _walkingRotation = 3.14f;
            walked = true;
        }
        if(_key->isKeyDown(OIS::KC_DOWN))
        {
            nodeTranslate += Ogre::Vector3(0,0,1);
            _walkingRotation = 0.0f;
            walked = true;
        }
        if(_key->isKeyDown(OIS::KC_LEFT))
        {
            nodeTranslate += Ogre::Vector3(-1,0,0);
            _walkingRotation = -1.57f;
            walked = true;
        }
        if(_key->isKeyDown(OIS::KC_RIGHT))
        {
            nodeTranslate += Ogre::Vector3(1,0,0);
            _walkingRotation = 1.57f;
            walked = true;
        }
        if(_key->isKeyDown(OIS::KC_W))
        {
            camTranslate += Ogre::Vector3(0,0,-1);
        }
        if(_key->isKeyDown(OIS::KC_S))
        {
            camTranslate += Ogre::Vector3(0,0,1);
        }
        if(_key->isKeyDown(OIS::KC_A))
        {
            camTranslate += Ogre::Vector3(-1,0,0);
        }
        if(_key->isKeyDown(OIS::KC_D))
        {
            camTranslate += Ogre::Vector3(1,0,0);
        }

        if(walked){
             _aniStateTop->setEnabled(true);
             _aniState->setEnabled(true);
             if(_aniState->hasEnded())
            {
                _aniState->setTimePosition(0.0f);
            }
            if(_aniStateTop->hasEnded())
            {
                _aniStateTop->setTimePosition(0.0f);
            }
             _aniState->addTime(evt.timeSinceLastFrame*1);
             _aniStateTop->addTime(evt.timeSinceLastFrame*1);
        }
        else
        {
            if(_isActionKeyPress)
            {
                _aniStateTop->setEnabled(true);
                _aniStateTop->addTime(evt.timeSinceLastFrame*1);
                if(_aniStateTop->hasEnded())
                {
                    _isActionKeyPress = false;
                    _aniStateTop = _ent->getAnimationState("RunTop");
                    _aniStateTop->setLoop(false);
                    _aniStateTop->setTimePosition(0.0f);
                }
            }
            else
            {
                if(!_aniStateTop->hasEnded())
                {
                    _aniStateTop->addTime(evt.timeSinceLastFrame*1);
                }
                 if(!_aniState->hasEnded())
                {
                    _aniState->addTime(evt.timeSinceLastFrame*1);
                }
            }
        }
        _node->translate(nodeTranslate * evt.timeSinceLastFrame * _walkingSpeed);
        _node->resetOrientation();
        _node->yaw(Ogre::Radian(_walkingRotation));

        _cam->moveRelative(camTranslate*evt.timeSinceLastFrame * _camMovementSpeed);
        _mouse->capture();
        float mouseRotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame* -1;
        float mouseRotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;
        _cam->yaw(Ogre::Radian(mouseRotX));
        _cam->pitch(Ogre::Radian(mouseRotY));
        return true;
    }
    bool frameEnded(const Ogre::FrameEvent& evt)
    {
        return true;
    }
    bool frameRenderingQueued(const Ogre::FrameEvent& evt)
    {
        return true;
    }
    float _camMovementSpeed;
    float _walkingSpeed;
    float _walkingRotation;
    Ogre::AnimationState* _aniState;
    Ogre::AnimationState* _aniStateTop;
    NeoFrameListener* _listener;
    OIS::InputManager* _im;
    OIS::Keyboard* _key;
    OIS::Mouse* _mouse;
    Ogre::Camera* _cam;
    Ogre::SceneNode* _node;
    Ogre::Entity* _ent;
    bool _downKey1;
    bool _comp1;
    bool _isActionKeyPress;

};

class NeoOgreApplication
{
public:
     NeoOgreApplication(): mSceneMgr(NULL),mRoot(NULL),mCamera(NULL),mWindow(NULL){}
    ~NeoOgreApplication(){if (mRoot) delete mRoot;}
    void runFirstFrame()
    {
        if(!initinalize())
        {
            exit(-1);
        }
        createCamera();
        loadResources();
        createScene();
        createCompositor();
        createFrameListener();
        runOneFrame();
    }
    void runOneFrame()
    {
          Ogre::WindowEventUtilities::messagePump();
          _keepRunning = mRoot->renderOneFrame();
    }
    bool keepRunning()
    {
        return _keepRunning;
    }
    void run()
    {
        if(!initinalize())
        {
            exit(-1);
        }
        createCamera();
        createCompositor();
        loadResources();
        createScene();
        createFrameListener();
        mRoot->startRendering();
    }
protected:
    void loadGroupResources(void)
    {
        Ogre::ConfigFile cf;
        cf.load("resources.cfg");
        Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator();
        Ogre::String sectionName, typeName,  dataName;
        while (sectionIter.hasMoreElements())
        {
            sectionName = sectionIter.peekNextKey();
            Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();
            Ogre::ConfigFile::SettingsMultiMap::iterator i;
            for (i = settings->begin(); i != settings->end(); ++i)
            {
                typeName = i->first;
                dataName = i->second;
                Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataName,typeName, sectionName);
            }
        }
        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    }
    virtual void loadResources(void)
    {
        //Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./Media/packs/Sinbad.zip","Zip");
        //Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
        loadGroupResources();
    }
    bool initinalize(void)
    {
        //Load Pluging
        /*
        mRoot = new Ogre::Root("plugins.cfg","ogre.cfg","Ogre.log");
        if(!mRoot->showConfigDialog())
            return -1;
        */
        mRoot = new Ogre::Root("","");
        //mRoot->loadPlugin( "RenderSystem_Direct3D9" );
        mRoot->loadPlugin("RenderSystem_GL");
        mRoot->loadPlugin("Plugin_ParticleFX");
        mRoot->loadPlugin("Plugin_CgProgramManager");
       // mRoot->loadPlugin("Plugin_OctreeSceneManager");

        const Ogre::RenderSystemList &render_sys_list = mRoot->getAvailableRenderers();//for 1.7
        Ogre::RenderSystemList::const_iterator it_render_sys( render_sys_list.begin() );//for 1.7
        while ( it_render_sys != render_sys_list.end() )                                //for 1.7
        {
            Ogre::RenderSystem* render_sys = *(it_render_sys++);
            //if(render_sys->getName().find("Direct3D9") != Ogre::String::npos)
            if(render_sys->getName().find("OpenGL") != Ogre::String::npos)
            {
                mRoot->setRenderSystem(render_sys);
                break;
            }
        }
        if(mRoot == NULL)
        {
            delete mRoot;
            return false;
        }

        Ogre::NameValuePairList opts;
        opts["resolution"] = "1024x768";
        opts["Full Screen"] = "Yes";
        opts["vsync"] = "false";
        opts["Colour Depth"] = "2";

        mRoot->initialise(false);//false表示不自動產生視窗,手動產生
        mWindow = mRoot->createRenderWindow("Neo Ogre", 800, 600, false,&opts); //false表非全螢幕模式
        Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("Neo Ogre");

        //mWindow = mRoot->initialise(true,"Neo Ogre");
        mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
        //設定camera和vierport----------------------------------------------------------------------
        mCamera = mSceneMgr->createCamera("MyCamera");
        return true;
    }
    virtual void createCompositor()
    {
        Ogre::CompositorManager::getSingleton().addCompositor(mCamera->getViewport(),"Compositor1");
    }
     virtual void createCamera()
    {
        mCamera->setPosition(Ogre::Vector3(0,0,50));
        mCamera->lookAt(Ogre::Vector3(0,0,0));
        mCamera->setNearClipDistance(5);
        mCamera->setFarClipDistance(10000);
        mCamera->setFOVy(Ogre::Degree(45));
        Ogre::Viewport* vp = mWindow->addViewport(mCamera);
        vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
        mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth())/Ogre::Real(vp->getActualHeight()));
    }
     virtual void createScene()
    {
       mEnt = mSceneMgr->createEntity("NeoEntity","Sinbad.mesh");
       mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("NeoNode");
       mNode->attachObject(mEnt);
    }
    virtual void createFrameListener()
    {
        NeoFrameListener* _listener = new NeoFrameListener(mWindow,mCamera,mNode, mEnt);
        mRoot->addFrameListener(_listener);
    }
protected:
    bool _keepRunning;
    Ogre::Root* mRoot;
    Ogre::SceneManager* mSceneMgr;
    Ogre::Camera* mCamera;
    Ogre::RenderWindow* mWindow;
    Ogre::SceneNode* mNode;
    Ogre::Entity* mEnt;
};
#endif

main.cpp
#include "NeoOgreApplication.h"
class MyOgre : public NeoOgreApplication
{
    void loadResources()
    {
        Ogre::ResourceGroupManager::getSingleton().createResourceGroup( "test" );
        Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./neoResource/packs/Sinbad.zip","Zip","test");
        Ogre::ResourceGroupManager::getSingleton().addResourceLocation("./neoResource/resource","FileSystem","test");
        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    }

    void createScene()
    {
       mEnt = mSceneMgr->createEntity("NeoEntity","Sinbad.mesh");
       mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("NeoNode");
       mNode->attachObject(mEnt);
       Ogre::Entity* sword1 = mSceneMgr->createEntity("Sword1","Sword.mesh");
       Ogre::Entity* sword2 = mSceneMgr->createEntity("Sword2","Sword.mesh");
       mEnt->attachObjectToBone("Handle.L",sword1);
       mEnt->attachObjectToBone("Handle.R", sword2);
       Ogre::Plane plane(Ogre::Vector3::UNIT_Y,-5);
       Ogre::MeshManager::getSingleton().createPlane("plane",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,1500,1500,20,20,true,1,5,5,Ogre::Vector3::UNIT_Z);
       Ogre::Entity* ground = mSceneMgr->createEntity("LightPlaneEntity", "plane");
       mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ground);
       ground->setMaterialName("Examples/BeachStones");
       Ogre::Light* light = mSceneMgr->createLight("Light1");
       light->setType(Ogre::Light::LT_DIRECTIONAL);
       light->setDirection(Ogre::Vector3(1,-1,0));
       mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
    }

};
int main (void)
{
MyOgre a;
//a.run();
a.runFirstFrame();
while(a.keepRunning())
{
    a.runOneFrame();
}
return 0;
}

沒有留言:

張貼留言