KODE / samples / KODEOgre / src / App.cpp

#include <stdexcept>
#include <thread>
#include <chrono>
#include <iostream>

#include <OgreWindowEventUtilities.h>

#include "App.hpp"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

using namespace Ogre;

namespace kode {
    namespace ogre {

        App* App::instance = nullptr;


        App::App(const std::string& title) :
            log{logMgr.createLog("OgreLogfile.log", true, true, false)},
            root{"plugins.cfg", "ogre.cfg"}
        {
            instance = this;


            if (!root.restoreConfig())
                if(!root.showConfigDialog())
                    throw std::runtime_error{"can't get a valid configuration"};

            renderWnd = root.initialise(true, title);


            ConfigFile cf;
            cf.load(SRC_DIR "/resources.cfg");

            ConfigFile::SectionIterator seci = cf.getSectionIterator();
            while (seci.hasMoreElements()) {
                String section = seci.peekNextKey();
                ConfigFile::SettingsMultiMap *settings = seci.getNext();
                ConfigFile::SettingsMultiMap::iterator i;
                for (i = settings->begin(); i != settings->end(); ++i) {
                    String type = i->first;
                    String path = i->second;
                    ResourceGroupManager::getSingleton().addResourceLocation(SRC_DIR"/" + path, type, section);
                }
            }
            //TextureManager::getSingleton().setDefaultNumMipmaps(5);
            ResourceGroupManager::getSingleton().initialiseAllResourceGroups();


            size_t hWnd = 0;
            OIS::ParamList paramList;
            renderWnd->getCustomAttribute("WINDOW", &hWnd);

            paramList.insert(OIS::ParamList::value_type("WINDOW", StringConverter::toString(hWnd)));

            if (true) {
                paramList.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
                paramList.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
                paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
                //paramList.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
            }

            inputMgr = OIS::InputManager::createInputSystem(paramList);

            keyboard = static_cast<OIS::Keyboard*>(inputMgr->createInputObject(OIS::OISKeyboard, true));
            mouse = static_cast<OIS::Mouse*>(inputMgr->createInputObject(OIS::OISMouse, true));

            mouse->getMouseState().height = renderWnd->getHeight();
            mouse->getMouseState().width  = renderWnd->getWidth();

            keyboard->setEventCallback(this);
            mouse->setEventCallback(this);



            sceneMgr = root.createSceneManager(ST_GENERIC);
            sceneMgr->setAmbientLight(ColourValue(0.4, 0.4, 0.4));

            camera = sceneMgr->createCamera("Camera");
            camera->setPosition(0, 5, 5);
            camera->lookAt(0, 0, 0);
            camera->setNearClipDistance(0.1);
            camera->setAutoAspectRatio(true);
            camera->setFixedYawAxis(true);

            viewport = renderWnd->addViewport(camera);
            viewport->setBackgroundColour(ColourValue(0.8f, 0.7f, 0.6f, 1.0f));
            viewport->setCamera(camera);


            timer.reset();

            renderWnd->setActive(true);

            windowResized(renderWnd);

            WindowEventUtilities::addWindowEventListener(renderWnd, this);

            sceneMgr->setSkyBox(true, "SkyBoxGradient");

            sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);

            Light* sun1 = sceneMgr->createLight("Sun1");
            sun1->setType(Light::LT_DIRECTIONAL);
            sun1->setDirection(0.5, -1, -0.5);
            sun1->setDiffuseColour (1.0, .9, .9);
            sun1->setSpecularColour(1.0, .9, .9);

            Light* sun2 = sceneMgr->createLight("Sun2");
            sun2->setType(Light::LT_DIRECTIONAL);
            sun2->setDirection(-0.5, -1, -0.5);
            sun2->setDiffuseColour (.9, 1.0, .9);
            sun2->setSpecularColour(.9, 1.0, .9);

            Light* sun3 = sceneMgr->createLight("Sun3");
            sun3->setType(Light::LT_DIRECTIONAL);
            sun3->setDirection(-0.1, -1, 0.5);
            sun3->setDiffuseColour (.9, .9, 1.0);
            sun3->setSpecularColour(.9, .9, 1.0);

            // physics
            world.setStepSize(0.01);
            world.setGravity(0, -1, 0);

        }



        App::~App()
        {
            if (inputMgr)
                OIS::InputManager::destroyInputSystem(inputMgr);
        }


        bool
        App::keyPressed(const OIS::KeyEvent &keyEvent)
        {
            if (keyEvent.key == OIS::KC_ESCAPE) {
                stop();
                return true;
            }
            return false;
        }


        bool
        App::keyReleased(const OIS::KeyEvent &)
        {
            return false;
        }


        bool
        App::mouseMoved(const OIS::MouseEvent &evt)
        {
            if (evt.state.buttonDown(OIS::MB_Left)) {
                float rX = evt.state.X.rel / 1000.;
                float rY = evt.state.Y.rel / 1000.;
                camera->yaw(::Ogre::Radian(-rX));
                camera->pitch(::Ogre::Radian(-rY));
                return true;
            }
            return false;
        }


        bool
        App::mousePressed(const OIS::MouseEvent &, OIS::MouseButtonID)
        {
            return false;
        }

        bool
        App::mouseReleased(const OIS::MouseEvent &, OIS::MouseButtonID)
        {
            return false;
        }


        void
        App::windowResized(RenderWindow*)
        {
            unsigned width, height, depth;
            int left, top;
            renderWnd->getMetrics(width, height, depth, left, top);

            const OIS::MouseState &ms = mouse->getMouseState();
            ms.width = width;
            ms.height = height;
        }


        void
        App::update(double timeSinceLastFrame)
        {
            keyboard->capture();
            mouse->capture();

            moveScale = moveSpeed   * timeSinceLastFrame;
            rotScale  = rotateSpeed * timeSinceLastFrame;

            translateVector = ::Ogre::Vector3::ZERO;

            getInput();
            moveCamera();

            frameEvent.timeSinceLastFrame = timeSinceLastFrame;
        }


        void
        App::moveCamera()
        {
            if(keyboard->isKeyDown(OIS::KC_LSHIFT))
                camera->moveRelative(translateVector*10);
            else
                camera->moveRelative(translateVector);
        }

        void
        App::getInput()
        {
            if (keyboard->isKeyDown(OIS::KC_A))
                translateVector.x = -moveScale;

            if (keyboard->isKeyDown(OIS::KC_D))
                translateVector.x = moveScale;

            if (keyboard->isKeyDown(OIS::KC_W))
                translateVector.z = -moveScale;

            if (keyboard->isKeyDown(OIS::KC_S))
                translateVector.z = moveScale;
        }


        void
        App::stop()
        {
            shutDownOgre = true;
        }


        void
        App::run()
        {
            log->logMessage("Start main loop...");


            double lastTime = 0;

            renderWnd->resetStatistics();

            lastTime = timer.getMilliseconds() * 1e-3;

            while (!shutDownOgre) {

                if (renderWnd->isClosed()) {
                    stop();
                    continue;
                }

                WindowEventUtilities::messagePump();

                if (renderWnd->isActive()) {
                    double now = timer.getMilliseconds() * 1e-3;

                    update(now - lastTime);
                    lastTime = now;

                    step();

                    root.renderOneFrame();
                } else {
                    std::this_thread::sleep_for(std::chrono::milliseconds(1));
                }

            }

            log->logMessage("Main loop quit");
        }


        void
        App::step()
        {}

    }
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.