2012年5月20日星期日

Port SkyX and Hydrax to Ogrekit

Sorry for my bad english. Maybe there're lots of wrong messages.I hope anybody can point those out and give me the right results.

My email is oneminute3b@gmail.com.
Welcome emails.

(Tomorrow I'll write the section 2 -- AppOgreKit(the plugin of blender))


list:
1. Port skyx and hydrax to AppCppDemo
    1.1 Create directory tree
    1.2 Copy and create source code
    1.3 Create cmakelists.txt for the new projects
    1.4 Edit cmakelists.txt of AppCppDemo project
    1.5 Generate Visual Studio Solution
    1.6 Edit source code of AppCppDemo
    1.7 Solve some exceptions
2. Port skyx and hydrax to AppOgreKit (plugin for blender)
    2.1 Edit the gkCoreApplication class
    2.2 Edit the GameKit class
    2.3 Modify gkUserDefs.cpp
    2.4 Modify CMakeLists.txt of project AppOgreKit
    2.5 Setup plugin for blender
    2.6 Edit ui.py of the plugin
    2.7 Edit operators.py of the plugin


Please follow me step by step. We begin with editing cmakelists.txt.

1. Port skyx and hydrax to AppCppDemo
We should create skyx and hydrax projects. Users can choose whether to create the wrapper projects for skyx and hydrax.

1.1 Create directory tree
How to get the clean source code of ogrekit is not of my work. So first, I imagine you have got an source code from svn or by other ways.
Figure 1-1 is the clean root directory of ogrekit
Figure 1-1

We create five directories: skyx, hydrax, gkskyx, gkhydrax and resources. Like the shown of Figure 1-2.
Figure 1-2
In each of the four folders(gkhydrax, gkskyx, hydrax, skyx) we should create subfolders with the names of "include" and "src". So the result is looked like the shown of Figure 1-3.

Figure 1-3


1.2 Copy and create source code
I use skyx of version v0.3 and hydrx of version v0.5.1. This section we copy the source code of skyx and hydrax to the folders we just created. Then create source code of wrapper projects.

Copy all .cpp files from <your hydrax root path>\Hydrax-v0.5.1\Hydrax\src\Hydrax to <your ogrekit root path>\hydrax\src. Note that keeping the source directory tree. Like Figure 1-4 and 1-5.
 Figure 1-4 cpp files of hydrax in folder "src"
Figure 1-5 header files of hydrax in folder "include"
Do the same thing of skyx. The result is like Figure 1-6 and 1-7.
 Figure 1-6 cpp files of skyx in folder "src"
Figure 1-7 header files of skyx in folder "include"

Next, we should create source files for wrapper projects.
In gkskyx we create gkWheather.h in folder gkskyx\include. The content is:

#ifndef __GK_WHEATHER_H__
#define __GK_WHEATHER_H__

#include "utSingleton.h"

class gkWheatherListener
    : public Ogre::FrameListener
{
public:
    virtual bool frameStarted( const Ogre::FrameEvent& evt );
};

class gkWheather :
    public utSingleton<gkWheather>
{
public:
    /** SkyX settings struct
    @remarks These just are the most important SkyX parameters, not all SkyX parameters.
    */
    typedef struct SkyXSettings
    {
        /** Constructor
        @remarks Skydome + vol. clouds + lightning settings
        */
        SkyXSettings(const Ogre::Vector3 t, const Ogre::Real& tm, const Ogre::Real& mp, const SkyX::AtmosphereManager::Options& atmOpt,
            const bool& lc, const bool& vc, const Ogre::Real& vcws, const bool& vcauto, const Ogre::Radian& vcwd,
            const Ogre::Vector3& vcac, const Ogre::Vector4& vclr,  const Ogre::Vector4& vcaf, const Ogre::Vector2& vcw,
            const bool& vcl, const Ogre::Real& vclat, const Ogre::Vector3& vclc, const Ogre::Real& vcltm)
            : time(t), timeMultiplier(tm), moonPhase(mp), atmosphereOpt(atmOpt), layeredClouds(lc), volumetricClouds(vc), vcWindSpeed(vcws)
            , vcAutoupdate(vcauto), vcWindDir(vcwd), vcAmbientColor(vcac), vcLightResponse(vclr), vcAmbientFactors(vcaf), vcWheater(vcw)
            , vcLightnings(vcl), vcLightningsAT(vclat), vcLightningsColor(vclc), vcLightningsTM(vcltm)
        {}

        /** Constructor
        @remarks Skydome + vol. clouds
        */
        SkyXSettings(const Ogre::Vector3 t, const Ogre::Real& tm, const Ogre::Real& mp, const SkyX::AtmosphereManager::Options& atmOpt,
            const bool& lc, const bool& vc, const Ogre::Real& vcws, const bool& vcauto, const Ogre::Radian& vcwd,
            const Ogre::Vector3& vcac, const Ogre::Vector4& vclr,  const Ogre::Vector4& vcaf, const Ogre::Vector2& vcw)
            : time(t), timeMultiplier(tm), moonPhase(mp), atmosphereOpt(atmOpt), layeredClouds(lc), volumetricClouds(vc), vcWindSpeed(vcws)
            , vcAutoupdate(vcauto), vcWindDir(vcwd), vcAmbientColor(vcac), vcLightResponse(vclr), vcAmbientFactors(vcaf), vcWheater(vcw), vcLightnings(false)
        {}

        /** Constructor
        @remarks Skydome settings
        */
        SkyXSettings(const Ogre::Vector3 t, const Ogre::Real& tm, const Ogre::Real& mp, const SkyX::AtmosphereManager::Options& atmOpt, const bool& lc)
            : time(t), timeMultiplier(tm), moonPhase(mp), atmosphereOpt(atmOpt), layeredClouds(lc), volumetricClouds(false), vcLightnings(false)
        {}

        /// Time
        Ogre::Vector3 time;
        /// Time multiplier
        Ogre::Real timeMultiplier;
        /// Moon phase
        Ogre::Real moonPhase;
        /// Atmosphere options
        SkyX::AtmosphereManager::Options atmosphereOpt;
        /// Layered clouds?
        bool layeredClouds;
        /// Volumetric clouds?
        bool volumetricClouds;
        /// VClouds wind speed
        Ogre::Real vcWindSpeed;
        /// VClouds autoupdate
        bool vcAutoupdate;
        /// VClouds wind direction
        Ogre::Radian vcWindDir;
        /// VClouds ambient color
        Ogre::Vector3 vcAmbientColor;
        /// VClouds light response
        Ogre::Vector4 vcLightResponse;
        /// VClouds ambient factors
        Ogre::Vector4 vcAmbientFactors;
        /// VClouds wheater
        Ogre::Vector2 vcWheater;
        /// VClouds lightnings?
        bool vcLightnings;
        /// VClouds lightnings average aparition time
        Ogre::Real vcLightningsAT;
        /// VClouds lightnings color
        Ogre::Vector3 vcLightningsColor;
        /// VClouds lightnings time multiplier
        Ogre::Real vcLightningsTM;
    }SkyXSettings;

public:
    /** Demo presets
    @remarks The best way of determinate each parameter value is by using a real-time editor.
    These presets have been quickly designed using the Paradise Editor, which is a commercial solution.
    At the time I'm writting these lines, SkyX 0.1 is supported by Ogitor. Hope that the Ogitor team will
    support soon SkyX 0.2, this way you all are going to be able to quickly create cool SkyX configurations.
    */
    static const SkyXSettings mPresets[];

    static const Ogre::uint32 mCurrentPreset = 1;

private:
    gkWheatherListener* mWheatherListener;
    SkyX::SkyX* mSkyX;               
    SkyX::BasicController* mBasicController;   
    Ogre::Light* mSunLight;
    Ogre::Light* mMoonLight;

    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;
    Ogre::Camera* mCamera;

public:
    Ogre::Light* getSunLight() const { return mSunLight; }
    Ogre::Light* getMoonLight() const { return mMoonLight; }
    SkyX::SkyX* getSkyX() const
    {
        return mSkyX;
    }

    UT_DECLARE_SINGLETON(gkWheather);

public:
    gkWheather(void);
    virtual ~gkWheather(void);
    virtual bool initialize(Ogre::SceneManager* _sceneMgr, Ogre::RenderWindow* _window, Ogre::Camera* _camera);
    virtual void destroy();
    virtual bool initSky();
    virtual void setPreset(const SkyXSettings& preset);
};

#endif // __GK_WHEATHER_H__

As you see, it's the sample code of skyx. I have got little modifications. And we create the gkWheather.cpp in folder gkskyx\src. The content is:

#include <assert.h>
#include <SkyX.h>
#include "gkWheather.h"


gkWheather::gkWheather(void)
    : mWheatherListener(NULL),
    mBasicController(NULL),
    mSkyX(NULL),
    mSceneMgr(NULL),
    mWindow(NULL),
    mCamera(NULL)
{
}

gkWheather::~gkWheather(void)
{

}

bool gkWheather::initialize(Ogre::SceneManager* _sceneMgr, Ogre::RenderWindow* _window, Ogre::Camera* _camera)
{
    assert(_sceneMgr);
    assert(_window);
    assert(_camera);

    mSceneMgr = _sceneMgr;
    mWindow = _window;
    mCamera = _camera;

    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.8f, 0.8f, 0.8f));

    Ogre::Vector3 lightdir(0.55f, -0.3f, 0.75f);
    lightdir.normalise();

    mSunLight = mSceneMgr->createLight("mSunLight");
    mSunLight->setType(Ogre::Light::LT_DIRECTIONAL);
    mSunLight->setDirection(lightdir);
    mSunLight->setDiffuseColour(Ogre::ColourValue::White);
    mSunLight->setSpecularColour(Ogre::ColourValue(0.6f, 0.4f, 0.4f));

    mMoonLight = mSceneMgr->createLight("mMoonLight");
    mMoonLight->setType(Ogre::Light::LT_DIRECTIONAL);
    mMoonLight->setDirection(lightdir);
    mMoonLight->setDiffuseColour(Ogre::ColourValue(0.01f, 0.01f, 0.01f));
    mMoonLight->setSpecularColour(Ogre::ColourValue(0.02f, 0.02f, 0.02f));

    if (!initSky()) return false;

    mWheatherListener = new gkWheatherListener();
    Ogre::Root::getSingleton().addFrameListener(mWheatherListener);

    return true;
}

bool gkWheather::initSky()
{
    // Create SkyX
    mBasicController = new SkyX::BasicController();
    mSkyX = new SkyX::SkyX(mSceneMgr, mBasicController);
    mSkyX->create();

    mSkyX->getVCloudsManager()->getVClouds()->setDistanceFallingParams(Ogre::Vector2(2,-1));

    // Register SkyX listeners
    Ogre::Root::getSingleton().addFrameListener(mSkyX);
    mWindow->addListener(mSkyX);

    //mPresets[mCurrentPreset].vcWheater.x = 0.10253;
    //mPresets[mCurrentPreset].vcWheater.y = 0.10210;
    setPreset(mPresets[mCurrentPreset]);
    //mSkyX->getCloudsManager()->add(SkyX::CloudLayer::Options(/* Default options */));

    return true;
}

void gkWheather::setPreset( const SkyXSettings& preset )
{
    mSkyX->setTimeMultiplier(preset.timeMultiplier);
    mBasicController->setTime(preset.time);
    mBasicController->setMoonPhase(preset.moonPhase);
    mSkyX->getAtmosphereManager()->setOptions(preset.atmosphereOpt);

    // Layered clouds
    if (preset.layeredClouds)
    {
        // Create layer cloud
        if (mSkyX->getCloudsManager()->getCloudLayers().empty())
        {
            mSkyX->getCloudsManager()->add(SkyX::CloudLayer::Options(/* Default options */));
        }
    }
    else
    {
        // Remove layer cloud
        if (!mSkyX->getCloudsManager()->getCloudLayers().empty())
        {
            mSkyX->getCloudsManager()->removeAll();
        }
    }

    mSkyX->getVCloudsManager()->setWindSpeed(preset.vcWindSpeed);
    mSkyX->getVCloudsManager()->setAutoupdate(preset.vcAutoupdate);

    SkyX::VClouds::VClouds* vclouds = mSkyX->getVCloudsManager()->getVClouds();

    vclouds->setWindDirection(preset.vcWindDir);
    vclouds->setAmbientColor(preset.vcAmbientColor);
    vclouds->setLightResponse(preset.vcLightResponse);
    vclouds->setAmbientFactors(preset.vcAmbientFactors);
    vclouds->setWheater(preset.vcWheater.x, preset.vcWheater.y, false);

    if (preset.volumetricClouds)
    {
        // Create VClouds
        if (!mSkyX->getVCloudsManager()->isCreated())
        {
            // SkyX::MeshManager::getSkydomeRadius(...) works for both finite and infinite(=0) camera far clip distances
            mSkyX->getVCloudsManager()->create(mSkyX->getMeshManager()->getSkydomeRadius(mCamera));
        }
    }
    else
    {
        // Remove VClouds
        if (mSkyX->getVCloudsManager()->isCreated())
        {
            mSkyX->getVCloudsManager()->remove();
        }
    }

    vclouds->getLightningManager()->setEnabled(preset.vcLightnings);
    vclouds->getLightningManager()->setAverageLightningApparitionTime(preset.vcLightningsAT);
    vclouds->getLightningManager()->setLightningColor(preset.vcLightningsColor);
    vclouds->getLightningManager()->setLightningTimeMultiplier(preset.vcLightningsTM);

    mSkyX->update(0);
}

void gkWheather::destroy()
{
    if (mWheatherListener)
    {
        Ogre::Root::getSingleton().removeFrameListener(mWheatherListener);
        delete mWheatherListener;
        mWheatherListener = NULL;
    }

    if (mSkyX)
    {
        Ogre::Root::getSingleton().removeFrameListener(mSkyX);
        mWindow->removeListener(mSkyX);
        delete mSkyX;
        mSkyX = NULL;
    }
}

/** Demo presets
    @remarks The best way of determinate each parameter value is by using a real-time editor.
             These presets have been quickly designed using the Paradise Editor, which is a commercial solution.
             At the time I'm writting these lines, SkyX 0.1 is supported by Ogitor. Hope that the Ogitor team will
             support soon SkyX 0.3, this way you all are going to be able to quickly create cool SkyX configurations.
 */
const gkWheather::SkyXSettings gkWheather::mPresets[] = {
    // Sunset
    gkWheather::SkyXSettings(Ogre::Vector3(8.85f, 7.5f, 20.5f),  -0.8f, 0, SkyX::AtmosphereManager::Options(9.77501f, 10.2963f, 0.01f, 0.0022f, 0.000675f, 30, Ogre::Vector3(0.57f, 0.52f, 0.44f), -0.991f, 3, 4), false, true, 300, false, Ogre::Radian(270), Ogre::Vector3(0.63f,0.63f,0.7f), Ogre::Vector4(0.35, 0.2, 0.92, 0.1), Ogre::Vector4(0.4, 0.7, 0, 0), Ogre::Vector2(0.8,1)),
    // Clear
    gkWheather::SkyXSettings(Ogre::Vector3(17.16f, 7.5f, 20.5f), 0.8, 0, SkyX::AtmosphereManager::Options(9.77501f, 10.2963f, 0.01f, 0.0017f, 0.000675f, 30, Ogre::Vector3(0.57f, 0.54f, 0.44f), -0.991f, 2.5f, 4), false),
    // Thunderstorm 1
    gkWheather::SkyXSettings(Ogre::Vector3(12.23, 7.5f, 20.5f),  0.8, 0, SkyX::AtmosphereManager::Options(9.77501f, 10.2963f, 0.01f, 0.00545f, 0.000375f, 30, Ogre::Vector3(0.55f, 0.54f, 0.52f), -0.991f, 1, 4), false, true, 300, false, Ogre::Radian(0), Ogre::Vector3(0.63f,0.63f,0.7f), Ogre::Vector4(0.25, 0.4, 0.5, 0.1), Ogre::Vector4(0.45, 0.3, 0.6, 0.1), Ogre::Vector2(1,1), true, 0.5, Ogre::Vector3(1,0.976,0.92), 2),
    // Thunderstorm 2
    gkWheather::SkyXSettings(Ogre::Vector3(10.23, 7.5f, 20.5f),  0.8, 0, SkyX::AtmosphereManager::Options(9.77501f, 10.2963f, 0.01f, 0.00545f, 0.000375f, 30, Ogre::Vector3(0.55f, 0.54f, 0.52f), -0.991f, 0.5, 4), false, true, 300, false, Ogre::Radian(0), Ogre::Vector3(0.63f,0.63f,0.7f), Ogre::Vector4(0, 0.02, 0.34, 0.24), Ogre::Vector4(0.29, 0.3, 0.6, 1), Ogre::Vector2(1,1), true, 0.5, Ogre::Vector3(0.95,1,1), 2),
    // Desert
    gkWheather::SkyXSettings(Ogre::Vector3(7.59f, 7.5f, 20.5f), 0.8, -0.8f, SkyX::AtmosphereManager::Options(9.77501f, 10.2963f, 0.01f, 0.0072f, 0.000925f, 30, Ogre::Vector3(0.71f, 0.59f, 0.53f), -0.997f, 2.5f, 1), true),
    // Night
    gkWheather::SkyXSettings(Ogre::Vector3(21.5f, 7.5, 20.5), 0.8, -0.25, SkyX::AtmosphereManager::Options(), true)
};


bool gkWheatherListener::frameStarted( const Ogre::FrameEvent& evt )
{
    SkyX::SkyX* skyX = gkWheather::getSingleton().getSkyX();
    //skyX->update(evt.timeSinceLastFrame);
    gkWheather::getSingleton().getMoonLight()->setDirection(
        -skyX->getController()->getMoonDirection());
    gkWheather::getSingleton().getSunLight()->setDirection(
        -skyX->getController()->getSunDirection());
    return true;
}

UT_IMPLEMENT_SINGLETON(gkWheather);


Next we create gkWaterManager.h in folder gkhydrax\include. The content is:

#ifndef _GK_WATER_MANAGER_H__
#define _GK_WATER_MANAGER_H__

#include "utSingleton.h"

class gkWaterListener
    : public Ogre::FrameListener
{
public:
    gkWaterListener(Ogre::RenderWindow* win, Ogre::Camera* cam, Ogre::SceneManager *sm);
    virtual bool frameStarted( const Ogre::FrameEvent& evt );

private:
    Ogre::RenderWindow* mWindow;
    Ogre::Camera* mCamera;
    Ogre::SceneManager* mSceneMgr;
};

class gkWaterManager
    : public utSingleton<gkWaterManager>
{
public:
    gkWaterManager();
    virtual ~gkWaterManager();

    virtual bool initialize(Ogre::SceneManager* _sceneMgr, Ogre::RenderWindow* _window, Ogre::Camera* _camera);
    void destroy();
    Hydrax::Hydrax * getHydrax() const { return mHydrax; }

    UT_DECLARE_SINGLETON(gkWaterManager);

private:
    Hydrax::Hydrax *mHydrax;
    gkWaterListener* mListener;

    Ogre::SceneManager* mSceneMgr;
    Ogre::RenderWindow* mWindow;
    Ogre::Camera* mCamera;
};

#endif //_GK_WATER_MANAGER_H__


Create gkWaterManager.h in folder gkhydrax\src. The content is:

#include <assert.h>
#include <SkyX.h>
#include <Hydrax.h>
#include <Noise/Perlin/Perlin.h>
#include <Modules/ProjectedGrid/ProjectedGrid.h>
#include <OgreCompositorManager.h>
#include "gkWheather.h"
#include "gkWaterManager.h"


gkWaterManager::gkWaterManager()
    : mHydrax(NULL),
    mListener(NULL),
    mSceneMgr(NULL),
    mWindow(NULL),
    mCamera(NULL)
{

}

gkWaterManager::~gkWaterManager()
{
   
}

bool gkWaterManager::initialize(Ogre::SceneManager* _sceneMgr, Ogre::RenderWindow* _window, Ogre::Camera* _camera)
{
    assert(_sceneMgr);
    assert(_window);
    assert(_camera);

    mSceneMgr = _sceneMgr;
    mWindow = _window;
    mCamera = _camera;

    mHydrax = new Hydrax::Hydrax(mSceneMgr, mCamera, mWindow->getViewport(0));
    // Create our projected grid module 
    Hydrax::Module::ProjectedGrid *mModule
        = new Hydrax::Module::ProjectedGrid(// Hydrax parent pointer
        mHydrax,
        // Noise module
        new Hydrax::Noise::Perlin(/*Generic one*/),
        // Base plane
        Ogre::Plane(Ogre::Vector3(0, 1, 0), Ogre::Vector3(0, 0, 0)),
        // Normal mode
        Hydrax::MaterialManager::NM_VERTEX,
        // Projected grid options
        Hydrax::Module::ProjectedGrid::Options(/*264 /*Generic one*/));

    // Set our module
    mHydrax->setModule(static_cast<Hydrax::Module::Module*>(mModule));

    // Load all parameters from config file
    // Remarks: The config file must be in Hydrax resource group.
    // All parameters can be set/updated directly by code(Like previous versions),
    // but due to the high number of customizable parameters, since 0.4 version, Hydrax allows save/load config files.
     mHydrax->loadCfg("HydraxDemo.hdx");

    // Create water
    mHydrax->create();

    mListener = new gkWaterListener(mWindow, mCamera, mSceneMgr);
    Ogre::Root::getSingletonPtr()->addFrameListener(mListener);

    return true;
}

void gkWaterManager::destroy()
{
    if(mListener)
    {
        Ogre::Root::getSingleton().removeFrameListener(mListener);
        delete mListener;
        mListener = NULL;
    }
   
    if(mHydrax)
    {
        /*Ogre::CompositorChain* chain =
            Ogre::CompositorManager::getSingleton().getCompositorChain(mCamera->getViewport());
        assert(chain);*/
        delete mHydrax;
        mHydrax = NULL;
       
    }
}

bool gkWaterListener::frameStarted( const Ogre::FrameEvent& e )
{
    // Check camera height
    Ogre::RaySceneQuery *raySceneQuery =
        mSceneMgr->
        createRayQuery(Ogre::Ray(mCamera->getPosition() + Ogre::Vector3(0,1000000,0),
        Ogre::Vector3::NEGATIVE_UNIT_Y));
    Ogre::RaySceneQueryResult& qryResult = raySceneQuery->execute();
    Ogre::RaySceneQueryResult::iterator i = qryResult.begin();
    if (i != qryResult.end() && i->worldFragment)
    {
        if (mCamera->getPosition().y < i->worldFragment->singleIntersection.y + 30)
        {
            mCamera->
                setPosition(mCamera->getPosition().x,
                i->worldFragment->singleIntersection.y + 30,
                mCamera->getPosition().z);
        }
    }

    delete raySceneQuery;

    // Update Hydrax
    Hydrax::Hydrax* hydrax = gkWaterManager::getSingletonPtr()->getHydrax();
    SkyX::SkyX* skyx = gkWheather::getSingletonPtr()->getSkyX();
    hydrax->update(e.timeSinceLastFrame);
    hydrax->setSunPosition(skyx->getController()->getSunDirection() * 10000);

    return true;
}

gkWaterListener::gkWaterListener( Ogre::RenderWindow* win, Ogre::Camera* cam, Ogre::SceneManager *sm )
    : mWindow(win),
    mCamera(cam),
    mSceneMgr(sm)
{

}

UT_IMPLEMENT_SINGLETON(gkWaterManager);


At last of this section. We should copy all resources of hydrax and skyx to folder "ogrekit\resources" we just created.
In folder "ogrekit\resources" we create a subdirectory named "Media".
Then copy directory of "<your skyx root path>\SkyXCommon\Bin\Media\SkyX" to "Media".
Copy directory of "<your hydrax root path>\Hydrax\media\Hydrax" to "Media" we just created above.
You can also create the resource config file with the name "resource.cfg" as you like. The content is:

[SkyX]
#Zip=E:/dependencies/ogre/Samples/Media/packs/SdkTrays.zip
FileSystem=./Media/SkyX

[Hydrax]
FileSystem=./Media/Hydrax


The directory tree is like Figure 1-8.
Figure 1-8

1.3 Create cmakelists.txt for the new projects
In ogrekit\CMakeLists.txt, we should add the folders we just created above to the solution. So open the ogrekit\CMakeLists.txt. At about line 30, add the follow code:

subdirs(Hydrax)
subdirs(Skyx)
subdirs(gkSkyx)
subdirs(gkHydrax)


The result is like Figure 1-9.
Figure 1-9

In folder gkhydrax we create file CMakeLists.txt. The content is:

PROJECT(gkHydrax)

SET(GKHYDRAX_SRCS
    src/gkWaterManager.cpp)
   
SET(GKHYDRAX_HDRS
    include/gkWaterManager.h)
   
include_directories(${OGREKIT_OGRE_INCLUDE})
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${OGREKIT_INCLUDE})
include_directories(${skyx_SOURCE_DIR}/include)
include_directories(${gkSkyx_SOURCE_DIR}/include)
include_directories(${gkHydrax_SOURCE_DIR}/include)
include_directories(${Hydrax_SOURCE_DIR}/include)
ADD_LIBRARY(gkhydrax ${GKHYDRAX_SRCS} ${GKHYDRAX_HDRS})

In folder gkskyx we create file CMakeList.txt. The content is:

PROJECT(gkSkyx)

SET(GKSKYX_SRCS
    src/gkWheather.cpp)
   
SET(GKSKYX_HDRS
    include/gkWheather.h)
   
include_directories(${OGREKIT_OGRE_INCLUDE})
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${OGREKIT_INCLUDE})
include_directories(${gkSkyx_SOURCE_DIR}/include)
include_directories(${skyx_SOURCE_DIR}/include)
ADD_LIBRARY(gkskyx ${GKSKYX_SRCS} ${GKSKYX_HDRS})


In folder hydrax we create file CMakeLists.txt. The content is:

PROJECT(Hydrax)

SET(HYDRAX_HRDS
    include/CfgFileManager.h
    include/DecalsManager.h
    include/Enums.h
    include/GodRaysManager.h
    include/GPUNormalMapManager.h
    include/Help.h
    include/Hydrax.h
    include/Image.h
    include/MaterialManager.h
    include/Mesh.h
    include/Prerequisites.h
    include/RttManager.h
    include/TextureManager.h
    include/Modules/Module.h
    include/Modules/ProjectedGrid/ProjectedGrid.h
    include/Modules/RadialGrid/RadialGrid.h
    include/Modules/SimpleGrid/SimpleGrid.h
    include/Noise/Noise.h
    include/Noise/FFT/FFT.h
    include/Noise/Perlin/Perlin.h)

SET(HYDRAX_SRCS
    src/CfgFileManager.cpp
    src/DecalsManager.cpp
    src/Enums.cpp
    src/GodRaysManager.cpp
    src/GPUNormalMapManager.cpp

    src/Help.cpp
    src/Hydrax.cpp
    src/Image.cpp
    src/MaterialManager.cpp
    src/Mesh.cpp
    src/Prerequisites.cpp
    src/RttManager.cpp
    src/TextureManager.cpp
    src/Modules/Module.cpp
    src/Modules/ProjectedGrid/ProjectedGrid.cpp
    src/Modules/RadialGrid/RadialGrid.cpp
    src/Modules/SimpleGrid/SimpleGrid.cpp
    src/Noise/Noise.cpp
    src/Noise/FFT/FFT.cpp
    src/Noise/Perlin/Perlin.cpp)


include_directories(
    ${OGREKIT_OGRE_INCLUDE}
    ${Boost_INCLUDE_DIRS}
    ${Hydrax_SOURCE_DIR}/include
    ${Hydrax_SOURCE_DIR}/include/Modules
    ${Hydrax_SOURCE_DIR}/include/Modules/ProjectedGrid

    ${Hydrax_SOURCE_DIR}/include/Modules/RadialGrid
    ${Hydrax_SOURCE_DIR}/include/Modules/SimpleGrid
    ${Hydrax_SOURCE_DIR}/include/Noise
    ${Hydrax_SOURCE_DIR}/include/Noise/FFT
    ${Hydrax_SOURCE_DIR}/include/Noise/Perlin
)


ADD_LIBRARY(hydrax ${HYDRAX_SRCS} ${HYDRAX_HRDS})


In folder skyx we create file CMakeLists.txt. The content is:

PROJECT(skyx)   

SET(SKYX_HRDS
    include/AtmosphereManager.h
    include/BasicController.h
    include/CloudsManager.h
    include/ColorGradient.h
    include/Controller.h
    include/GPUManager.h
    include/MeshManager.h
    include/MoonManager.h
    include/Prerequisites.h
    include/SkyX.h
    include/VCloudsManager.h
    include/VClouds/DataManager.h
    include/VClouds/Ellipsoid.h
    include/VClouds/FastFakeRandom.h
    include/VClouds/GeometryBlock.h
    include/VClouds/GeometryManager.h
    include/VClouds/Lightning.h
    include/VClouds/LightningManager.h
    include/VClouds/VClouds.h  )

SET(SKYX_SRCS
    src/AtmosphereManager.cpp
    src/BasicController.cpp
    src/CloudsManager.cpp
    src/ColorGradient.cpp
    src/GPUManager.cpp
    src/MeshManager.cpp
    src/MoonManager.cpp
    src/Prerequisites.cpp
    src/SkyX.cpp
    src/VCloudsManager.cpp
    src/VClouds/DataManager.cpp
    src/VClouds/Ellipsoid.cpp
    src/VClouds/FastFakeRandom.cpp
    src/VClouds/GeometryBlock.cpp
    src/VClouds/GeometryManager.cpp
    src/VClouds/Lightning.cpp
    src/VClouds/LightningManager.cpp
    src/VClouds/VClouds.cpp)
   
include_directories(
    ${OGREKIT_OGRE_INCLUDE}
    ${skyx_SOURCE_DIR}/include
    ${Boost_INCLUDE_DIRS}
)
ADD_LIBRARY(skyx ${SKYX_SRCS} ${SKYX_HRDS})



1.4 Edit cmakelists.txt of AppCppDemo project
After created the CMakeLists for the new Projects. We should modify CMakeLists.txt of the target demo project. So we modify the CMakeLists.txt of CppDemo at "ogrekit\Samples\CppDemo\CMakeLists.txt".
The modified code is follow. The red code is added.# ---------------------------------------------------------
cmake_minimum_required(VERSION 2.6)

set(CONTENT
    Maps.blend
    Momo.blend
    Rat.blend
    ${OGREKIT_SOURCE_DIR}/resources/resources.cfg
)
set(TargetName AppCppDemo)


if (APPLE)
    include_directories(${OGRELITE_SOURCE_DIR}/OgreMain/include/OSX)
    SET(EXETYPE MACOSX_BUNDLE)
    SET_SOURCE_FILES_PROPERTIES( MainMenu.nib  PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
    SET_SOURCE_FILES_PROPERTIES(${CONTENT} PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
    SET (NibFile MainMenu.nib)
endif()


set(CPP_CONT_SRC
    Controllers/gkJoystickController.cpp
    Controllers/gkDefaultController.cpp
)

set(CPP_CONT_HDR
    gkGameController.h
    Controllers/gkJoystickController.h
    Controllers/gkDefaultController.h
)


set(CPP_MAIN_SRC
    gkApplication.cpp
    gkCollisionCameraConstraint.cpp
    gkGamePlayer.cpp
    gkGameLevel.cpp
    # gkGameNPC.cpp
)

set(CPP_MAIN_HDR
    gkApplication.h
    gkCollisionCameraConstraint.h
    gkGamePlayer.h
    gkGameLevel.h
    # gkGameNPC.h
)


set(SRC
    ${CONTENT}
    ${CPP_MAIN_SRC}  ${CPP_MAIN_HDR}
    ${CPP_CONT_SRC}  ${CPP_CONT_HDR}
    ${CPP_GRAPH_SRC} ${CPP_GRAPH_HDR}
    )



if(WIN32)

    source_group(Main\\Source FILES ${CPP_MAIN_SRC})
    source_group(Main\\Header FILES ${CPP_MAIN_HDR})

    source_group(Controllers\\Source FILES ${CPP_CONT_SRC})
    source_group(Controllers\\Header FILES ${CPP_CONT_HDR})

    source_group(Datafiles FILES ${CONTENT})
endif()


include_directories(
    ${OGREKIT_INCLUDE}
    .
    ${skyx_SOURCE_DIR}/include
    ${Hydrax_SOURCE_DIR}/include
    ${gkHydrax_SOURCE_DIR}/include
    ${gkSkyx_SOURCE_DIR}/include
)

link_libraries(
    ${OGREKIT_LIB}
    hydrax
    skyx
    gkhydrax
    gkskyx
)


if (APPLE)

    ogrekit_add_executable(
        ${TargetName}
        MACOSX_BUNDLE
        MainMenu.nib
        ${SRC}
    )

else ()

    ogrekit_add_executable(${TargetName} ${SRC})
   
   
    IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
        ADD_CUSTOM_COMMAND(
            TARGET ${TargetName}
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Maps.blend ${CMAKE_CURRENT_BINARY_DIR}/Maps.blend
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Momo.blend ${CMAKE_CURRENT_BINARY_DIR}/Momo.blend
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/Rat.blend ${CMAKE_CURRENT_BINARY_DIR}/Rat.blend
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${OGREKIT_SOURCE_DIR}/resources/resources.cfg ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${OGREKIT_SOURCE_DIR}/resources/Media ${CMAKE_CURRENT_BINARY_DIR}/Media
        )
    ENDIF ()

endif()


1.5 Generate Visual Studio Solution
Then we should generate the solution using cmake.
I use visual studio 2010. So I generate the vs2010 solution. Like Figure 1-10.
Figure 1-10

In ogrekit branch I select the following options(Highlight blue). Shown in Figure 1-11.
Figure 1-11
Then generate the solution. I choose the path "E:\thirdparty\ogrekit_vc10".
Goto the path. And double click the OGREKIT.sln and open the solution.

1.6 Edit source code of AppCppDemo
Open file gkApplication.cpp in project AppCppDemo. Modify the content as following(The modifications are hightlight with red):

/*
-------------------------------------------------------------------------------
    This file is part of OgreKit.
    http://gamekit.googlecode.com/

    Copyright (c) 2006-2010 Charlie C.

    Contributor(s): none yet.
-------------------------------------------------------------------------------
  This software is provided 'as-is', without any express or implied
  warranty. In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
-------------------------------------------------------------------------------
*/
#include <Ogre.h>
#include "gkApplication.h"
#include "gkGameLevel.h"
#include "gkLogger.h"
#include "gkUserDefs.h"
#include "Graphics/gkHUDManager.h"
#include "gkMemoryTest.h"

int main(int argc, char** argv)
{
    TestMemory;


    gkLogger::enable("AppCppDemo.log", GK_CPP_VERBOSE_LOG);


    gkUserDefs prefs;
    prefs.rendersystem = OGRE_RS_D3D9;
    //prefs.winsize.x = 1360.f;
    //prefs.winsize.y = 768.f;
    //prefs.fullscreen = true;
    prefs.wintitle = "OgreKit C++ Testbed";
    prefs.verbose = GK_CPP_VERBOSE_LOG;
    //prefs.fsaa = true;
    //prefs.debugPhysics = true;
    prefs.debugFps = true;
    prefs.enableshadows = false;
    //prefs.grabInput = false;


    gkEngine eng(&prefs);

    //Setup everything. Ogre, gk etc.
    eng.initialize();
    eng.loadResources("resources.cfg");

    if (!eng.isInitialized())
    {
        gkPrintf("CppDemo: failed to initialize engine.\n");
        system("pause");
        return 1;
    }

    {
        gkGameLevel game;
        game.loadLevel(GK_LEVEL_PICKUP);

        //Connect game tick callbacks
        eng.addListener(&game);


        if (!eng.initializeStepLoop())
        {
            gkPrintf("CppDemo: failed to initialize main loop.\n");
            system("pause");
            return 1;
        }


        gkPrintf("CppDemo: enter main loop.\n");

        for (;;)
        {
            if (!eng.stepOneFrame())
            {
                gkPrintf("CppDemo: exit main loop.\n");
                break;
            }
        }
    }

    eng.finalize();

    return 0;
}


Open file gkGameLevel.h in project AppCppDemo. Modify the content as following(The modifications are hightlight with red):


/*
-------------------------------------------------------------------------------
    This file is part of OgreKit.
    http://gamekit.googlecode.com/

    Copyright (c) 2006-2010 Charlie C.

    Contributor(s): none yet.
-------------------------------------------------------------------------------
  This software is provided 'as-is', without any express or implied
  warranty. In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
-------------------------------------------------------------------------------
*/
#ifndef _gkGameLevel_h_
#define _gkGameLevel_h_


#include "gkEngine.h"
#include "gkApplication.h"
#include "gkInput.h"
#include "gkInstancedManager.h"
#include "gkResourceManager.h"

class gkWheather;
class gkWaterManager;

class gkGameLevel : public gkEngine::Listener,
    public gkInstancedManager::InstancedListener,
    public gkResourceManager::ResourceListener
{
public:

    gkGameLevel();
    virtual ~gkGameLevel();


    void loadLevel(const gkLevel& level);

    gkScene* getLevel(void);

    gkJoystick* getJoystick(void) {return m_joy;}

protected:

    void notifyInstanceCreated(gkInstancedObject* inst);
    void notifyResourceCreated(gkResource* res);

    void loadPickup(void);

    gkScene* m_pickup;
    gkScene* m_killThemAll;
    gkLevel m_level;

    gkGamePlayer* m_player;
    utArray<gkGamePlayer*> m_enemies;

    gkKeyboard* m_keyboard;
    gkMouse* m_mouse;
    gkJoystick* m_joy;
    void tick(gkScalar delta);

    gkWheather* m_wheather;
    gkWaterManager* m_waterManager;
};


#endif//_gkGameLevel_h_


Open file gkGameLevel.cpp in project AppCppDemo. Modify the content as following(The modifications are hightlight with red):

/*
-------------------------------------------------------------------------------
    This file is part of OgreKit.
    http://gamekit.googlecode.com/

    Copyright (c) 2006-2010 Charlie C.

    Contributor(s): none yet.
-------------------------------------------------------------------------------
  This software is provided 'as-is', without any express or implied
  warranty. In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
-------------------------------------------------------------------------------
*/
#include <Ogre.h>
#include <SkyX.h>
#include <Hydrax.h>
#include <Noise/Perlin/Perlin.h>
#include <Modules/ProjectedGrid/ProjectedGrid.h>
#include "gkGameLevel.h"
#include "gkGamePlayer.h"
#include "gkGameObjectManager.h"
#include "gkFontManager.h"
#include "OgreKit.h"
#include "gkWheather.h"
#include "gkWaterManager.h"

#define LEVEL_GROUP_NAME "CppDemo"


gkGameLevel::gkGameLevel()
    :    m_pickup(0),
         m_killThemAll(0),
         m_level(GK_LEVEL_EXIT),
         m_keyboard(0),
         m_mouse(0),
         m_player(0),
         m_wheather(NULL),
         m_waterManager(NULL)
{
    m_keyboard = gkWindowSystem::getSingleton().getKeyboard();
    m_mouse    = gkWindowSystem::getSingleton().getMouse();
    m_joy      = gkWindowSystem::getSingleton().getJoystick(0);

    gkGameObjectManager::getSingleton().addInstanceListener(this);
    gkGameObjectManager::getSingleton().addResourceListener(this);
    gkSceneManager::getSingleton().addInstanceListener(this);
    gkSceneManager::getSingleton().addResourceListener(this);
    gkGroupManager::getSingleton().addResourceListener(this);
    gkTextManager::getSingleton().addResourceListener(this);
    gkFontManager::getSingleton().addResourceListener(this);

}


gkGameLevel::~gkGameLevel()
{
    delete m_player;
    m_player = 0;

    for (UTsize i = 0; i < m_enemies.size(); i++)
        delete m_enemies[i];
    m_enemies.clear();

    if (m_waterManager)
    {
        m_waterManager->destroy();
        delete m_waterManager;
        m_waterManager = NULL;
    }

    gkGameObjectManager::getSingleton().removeResourceListener(this);
    gkGameObjectManager::getSingleton().removeInstanceListener(this);
    gkSceneManager::getSingleton().removeInstanceListener(this);
    gkSceneManager::getSingleton().removeResourceListener(this);
    gkGroupManager::getSingleton().removeResourceListener(this);
    gkTextManager::getSingleton().removeResourceListener(this);
    gkFontManager::getSingleton().removeResourceListener(this);

    if (m_wheather)
    {
        m_wheather->destroy();
        delete m_wheather;
        m_wheather = NULL;
    }

    if (m_pickup)
        gkSceneManager::getSingleton().destroy(m_pickup->getResourceHandle());

}


void gkGameLevel::loadLevel(const gkLevel& level)
{
    m_level = level;

    if (m_level == GK_LEVEL_PICKUP)
        loadPickup();
    else if (m_level == GK_LEVEL_KILL_THEM_ALL)
    {
    }
}



void gkGameLevel::loadPickup(void)
{
    if (m_pickup)
    {
        m_pickup->reinstance();
        return;
    }


    gkBlendFile* playerData = gkBlendLoader::getSingleton().loadFile(gkUtils::getFile(GK_RESOURCE_PLAYER), "", LEVEL_GROUP_NAME);
    if (!playerData || !playerData->getMainScene())
    {
        gkPrintf("GameLevel: Blend '%s' loading failed", GK_RESOURCE_PLAYER);
        return;
    }


    // log status
    gkPrintf("GameLevel: Blend '%s' loaded", GK_RESOURCE_PLAYER);

   
    gkBlendFile* mapData = gkBlendLoader::getSingleton().loadFile(gkUtils::getFile(GK_RESOURCE_MAPS), "Pickup", LEVEL_GROUP_NAME);
    if (!mapData || !mapData->getMainScene())
    {
        gkPrintf("GameLevel: Blend '%s'->Pickup loading failed", GK_RESOURCE_MAPS);
        return;
    }

    // log status
    gkPrintf("GameLevel: Blend '%s'->Pickup loaded", GK_RESOURCE_MAPS);

    gkScene* sc = mapData->getMainScene();


    m_pickup = (gkScene*)gkSceneManager::getSingleton().create("PickupLevel");
    m_pickup->setHorizonColor(gkColor(0.2f, 0.2f, 0.2f));
    m_pickup->setAmbientColor(gkColor(0.5f, 0.5f, 0.5f));

    gkSceneManager::getSingleton().copyObjects(sc, m_pickup);

    m_player = new gkGamePlayer(this);
    m_player->load(playerData);

    m_pickup->getProperties().m_fog.m_mode = gkFogParams::FM_NONE;
    m_pickup->createInstance();
   

    gkGamePlayer* enemy = m_player->clone();
    enemy->setPosition(gkVector3(0,1,1));
    m_enemies.push_back(enemy);

    enemy = enemy->clone();
    enemy->setPosition(gkVector3(1,1,1));
    m_enemies.push_back(enemy);

    Ogre::SceneManager* sceneMgr = m_pickup->getManager();
    Ogre::RenderWindow* window = m_pickup->getDisplayWindow()->getRenderWindow();
    Ogre::Camera* camera = m_pickup->getMainCamera()->getCamera();

    camera->setFarClipDistance(30000);
   
    m_wheather = new gkWheather;
    m_waterManager = new gkWaterManager;
    m_wheather->initialize(sceneMgr, window, camera);
    m_waterManager->initialize(sceneMgr, window, camera);
}



void gkGameLevel::notifyInstanceCreated(gkInstancedObject* inst)
{
    gkLogMessage("GameLevel: Instanced -> " << inst->getResourceName().getName());
}

void gkGameLevel::notifyResourceCreated(gkResource* res)
{

    gkLogMessage(res->getManagerType() << ", " << res->getResourceType() <<
                 ":handle " <<  res->getResourceHandle() << ", created " << res->getResourceName().getName());
}

void gkGameLevel::tick(gkScalar delta)
{
    // update game states
    if (m_player)
        m_player->update(delta);

    for (UTsize i = 0; i < m_enemies.size(); i++)
        m_enemies[i]->update(delta);

    if (m_keyboard->key_count > 0)
    {
        if (m_keyboard->isKeyDown(KC_ESCKEY))
            gkEngine::getSingleton().requestExit();
    }
}




gkScene* gkGameLevel::getLevel(void)
{
    if (m_level == GK_LEVEL_PICKUP)
        return m_pickup;
    else if (m_level == GK_LEVEL_KILL_THEM_ALL)
        return m_killThemAll;
    return 0;
}

Open file gkGameLevel.cpp in project AppCppDemo. Modify the content as following(The modifications are hightlight with red):

/*
-------------------------------------------------------------------------------
    This file is part of OgreKit.
    http://gamekit.googlecode.com/

    Copyright (c) 2006-2010 Charlie C.

    Contributor(s): none yet.
-------------------------------------------------------------------------------
  This software is provided 'as-is', without any express or implied
  warranty. In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
-------------------------------------------------------------------------------
*/
#include "gkGameController.h"
#include "gkDefaultController.h"
#include "gkWindowSystem.h"
#include "gkGamePlayer.h"
#include "gkGameObject.h"
#include "gkEntity.h"

gkDefaultController::gkDefaultController(gkGamePlayer* player)
{
    m_player = player;
    m_keyboard = gkWindowSystem::getSingleton().getKeyboard();
    m_mouse = gkWindowSystem::getSingleton().getMouse();


    bindScanCode(IC_RUN,      KC_WKEY);
    bindScanCode(IC_WALK,     KC_NONE);
    bindScanCode(IC_BUTTON_0, gkMouse::Left);
    bindScanCode(IC_BUTTON_1, KC_SPACEKEY);
    bindScanCode(IC_BUTTON_2, gkMouse::Right);
    bindScanCode(IC_STOP,     KC_NONE);
    bindScanCode(IC_CAM_MODE, KC_RKEY);
}



gkDefaultController::~gkDefaultController()
{
}

bool gkDefaultController::hasInput(const gkGameController::InputCode& ic)
{
    switch (ic)
    {
    case IC_WALK:
        return false;
    case IC_BUTTON_1:
    case IC_RUN:
        return m_keyboard->isKeyDown((gkScanCode)m_bindings[ic]);
    case IC_BUTTON_0:
    case IC_BUTTON_2:
        return m_mouse->isButtonDown(m_bindings[ic]);
    case IC_STOP:
        return !m_keyboard->isKeyDown((gkScanCode)m_bindings[IC_RUN]);
    case IC_CAM_MODE:
        return m_keyboard->isKeyDown((gkScanCode)18);
    }
    return false;
}

void gkDefaultController::moveCamera(void)
{
    gkGamePlayer::Data& data = m_player->getData();


    if (m_mouse->mouseMoved())
    {
        const gkScalar tick = gkAppData::gkFixedTickDelta * .25f;

        if (m_mouse->relative.x!= 0.f)
            data.m_zRot->yaw(-gkRadian(m_mouse->relative.x * tick));
        if (m_mouse->relative.y!= 0.f)
            data.m_xRot->pitch(-gkRadian(m_mouse->relative.y * tick));
    }
    else
    {
        // Auto rebound pitch.
        gkScalar cPitch = data.m_xRot->getRotation().x.valueRadians();

        cPitch = -gkAppData::gkJoyReboundFac * cPitch;
        data.m_xRot->pitch(gkDegree(cPitch));

    }

    data.m_zRot->translate(
        (data.m_physics->getPosition() - (data.m_zRot->getPosition() +
                                          gkVector3(0, -gkAppData::gkPlayerHeadZ, 0))
        ) * gkAppData::gkCameraTol
    );

}
void gkDefaultController::movePlayer(void)
{
    gkGamePlayer::Data& data = m_player->getData();


    gkScalar speed = 3.f;
  
    if(data.m_zRot)
    {
        gkVector3 movement = data.m_zRot->getOrientation()  * gkVector3(0, speed, 0);
        
        Ogre::Vector3 cameDir = data.m_camera->getCamera()->getDerivedDirection();
        if (cameDir.z >= 0)
        {
            data.m_entity->setOrientation(gkEuler(0, 0, 180.0f - data.m_zRot->getRotation().y.valueDegrees()));
        }
        else
        {
            data.m_entity->setOrientation(gkEuler(0, 0, data.m_zRot->getRotation().y.valueDegrees()));
        }

        movement.y = data.m_physics->getLinearVelocity().y;
        data.m_physics->setLinearVelocity(movement);
    }
}

void gkDefaultController::bindScanCode(const InputCode& ic, const int &code)
{
    int iic = (int)ic;
    if (iic >= 0 && iic < IC_MAX)
        m_bindings[ic] = code;
}
At file gkGamePlayer.cpp find the code following:

    if (m_physics)
    {
        // 限制活动区域
        gkLimitLocConstraint* ll = new gkLimitLocConstraint();
        ll->setMinX(-30.f);
        ll->setMaxX(30.f);
        ll->setMinY(0.f);
        ll->setMaxY(30.f);
        ll->setMinZ(-30.f);
        ll->setMaxZ(30.f);
        dest->addConstraint(m_physics, ll);
    }


Modify the code as the red above.

You should modify the gravity of bullet.
At line 587 of file ogrekit\Engine\gkSerialize.h, change "m_gravity(0.f, 0.f, -9.81f)" to "m_gravity(0.f, -9.81f, 0.f)"
At line 63 of file ogrekit\Engine\Particles\Ogre\gkOgreParticleAffector.cpp, change "gkVector3(0,0,-9.81f)" to "gkVector3(0,-9.81f,0)".
At line 140 of file ogrekit\engine\loaders\blender2\gkblendersceneconverter.cpp, change "gkVector3(0.f, 0.f, -world->gravity);" to "gkVector3(0.f, -world->gravity, 0.f);"

The last thing is to modify the blend files "Maps.blend" and "Momo.blend". Because of blend use z-aixs up, but ogre use y-axis up. So users can use my modified file here. You can also rotate your whole scene("Maps.blend" and "Momo.blend") -90 degrees by X-axis.

The shown is in Figure 1-12
Figure 1-12

1.7 Solve some exceptions
If you get compile error C2039 when compiling the hydrax. Then please look here:
http://www.ogre3d.org/addonforums/viewtopic.php?f=20&t=10124

if you get link error LNK2019 when compiling the AppCppDemo. Then comment all "DllExport" macro in project hydrax. Because the default link type is dll. But we use the static lib.

if you get assertion failure as "The minimum corner of the box must be less than or equal to maximum corner" at line 251 in file OgreAxisAlignedBox.h, maybe there is a bug in skyx. You can change the following code at line 146 in Lighting.cpp of skyx:


Lightning* lightning = new Lightning(mSceneManager, mSceneNode, mSegments.at(k).b, dir, lengthMult*mLength, 2+mDivisions*lengthMult, mRecursivity-1, mTimeMultiplier, mWidthMultiplier, bounds);
lightning->create();
mChildren.push_back(lightning);

to:


if (mRecursivity > 1)
{
    Lightning* lightning = new Lightning(mSceneManager, mSceneNode, mSegments.at(k).b, dir, lengthMult*mLength, 2+mDivisions*lengthMult, mRecursivity-1, mTimeMultiplier, mWidthMultiplier, bounds);
    lightning->create();
    mChildren.push_back(lightning);
}

2. Port skyx and hydrax to AppOgreKit (plugin for blender)
OK, let's modify the AppOgreKit project to support the skyx and hydrax.

2.1 Edit the gkCoreApplication class
Find the gkCoreApplication.h in project OgreKitCore. Shown in Figure 2-1.
Figure 2-1
At line 58, change "bool initialize(void);" to "virtual bool initialize(void);". Shown in Figure 2-2.
Figure 2-2
Of course you don't need to hack the source code. You can inherit the gkCoreApplication and create your own initialize and run functions instead of the original ones. But this is the easy way to use.


2.2 Edit the GameKit class
Next, find main.cpp in project AppOgreKit. Modify the code as following. Be attention of the red block.

#include <SkyX.h>
#include <Hydrax.h>
#include <Noise/Perlin/Perlin.h>
#include <gkWheather.h>
#include <gkWaterManager.h>
#include "tclap/CmdLine.h"
#include "OgreKit.h"



const gkString gkDefaultBlend   = "momo_ogre.blend";
const gkString gkDefaultConfig  = "OgreKitStartup.cfg";


class OgreKit : public gkCoreApplication, public gkWindowSystem::Listener
{
public:
    gkString    m_blend;
    gkScene*    m_scene;
public:
    OgreKit();
    virtual ~OgreKit()
    {
        if (m_waterManager)
        {
            m_waterManager->destroy();
            delete m_waterManager;
            m_waterManager = NULL;
        }

        if (m_wheather)
        {
            m_wheather->destroy();
            delete m_wheather;
            m_wheather = NULL;
        }
    }

    int setup(int argc, char** argv);

    void keyReleased(const gkKeyboard& key, const gkScanCode& sc);
    virtual bool initialize(void);

private:
    gkWheather* m_wheather;
    gkWaterManager* m_waterManager;
    bool setup(void);
};



OgreKit::OgreKit()
    :   m_blend(gkDefaultBlend),
    m_scene(0),
    m_wheather(NULL),
    m_waterManager(NULL)
{
}


int OgreKit::setup(int argc, char** argv)
{
    int winsize_x        = 800;
    int winsize_y        = 600;
    m_prefs.wintitle    = gkString("OgreKit Demo (Press Escape to exit)[") + m_blend + gkString("]");


    gkString cfgfname;

    // Parse command line
    try
    {
        TCLAP::CmdLine cmdl("Ogrekit", ' ', "n/a");
        cmdl.setExceptionHandling(false);

        //cfg arguments

        TCLAP::ValueArg<std::string>    rendersystem_arg        ("r", "rendersystem",            "Set rendering system. (gl, d3d9, d3d10, d3d11)", false, "", "string"); //default GL
        TCLAP::ValueArg<std::string>    viewportOrientation_arg    ("",  "viewportorientation",    "Set viewport orientation.", false, m_prefs.viewportOrientation, "string");
        TCLAP::ValueArg<std::string>    log_arg                    ("",  "log",                    "Set log file name.", false, m_prefs.log, "string");
        TCLAP::ValueArg<bool>            verbose_arg                ("v", "verbose",                "Enable verbose log.", false, m_prefs.verbose, "bool");
        TCLAP::ValueArg<int>            winsize_x_arg            ("",  "width",                    "Set window width.", false, winsize_x, "int");
        TCLAP::ValueArg<int>            winsize_y_arg            ("",  "height",                    "Set window height.", false, winsize_y, "int");
        TCLAP::ValueArg<std::string>    wintitle_arg            ("",  "wintitle",                "Set window title.", false, m_prefs.wintitle, "string");
        TCLAP::ValueArg<bool>            fullscreen_arg            ("f", "fullscreen",                "Enable fullscreen mode.", false, m_prefs.fullscreen, "bool");
        TCLAP::ValueArg<std::string>    framingType_arg            ("",  "framingtype",            "Set viewport framing type. (extend, crop, letterbox)", false, "", "string");
        TCLAP::ValueArg<std::string>    resources_arg            ("",  "resources",                "Set resouces.", false, m_prefs.resources, "string");
        TCLAP::ValueArg<bool>            blendermat_arg            ("",  "blendmat",                "Convert meshes using blender materials.", false, m_prefs.blendermat, "bool");
        TCLAP::ValueArg<bool>            matblending_arg            ("",  "matblending",            "Enable material pass blending mode.", false, m_prefs.matblending, "bool");       
        TCLAP::ValueArg<bool>            grapInput_arg            ("g", "grabinput",                "Grap mouse input.", false, m_prefs.grabInput, "bool");
        TCLAP::ValueArg<bool>            debugFps_arg            ("d", "debugfps",                "Display debug fps.", false, m_prefs.debugFps, "bool");
        TCLAP::ValueArg<bool>            debugPhysics_arg        ("p", "debugphysics",            "Display debug physics.", false, m_prefs.debugPhysics, "bool");
        TCLAP::ValueArg<bool>            debugPhysicsAabb_arg    ("a", "debugphysicsaabb",        "Display debug physics aabb.", false, m_prefs.debugPhysicsAabb, "bool");
        TCLAP::ValueArg<bool>            buildStaticGeometry_arg    ("",  "buildinstances",            "Build Static Geometry.", false, m_prefs.buildStaticGeometry, "bool");
        TCLAP::ValueArg<bool>            useBulletDbvt_arg        ("",  "frustumculling",            "Enable view frustum culling by dbvt.", false, m_prefs.useBulletDbvt, "bool");
        TCLAP::ValueArg<bool>            showDebugProps_arg        ("t", "showdebugprops",            "Show debug props.", false, m_prefs.showDebugProps, "bool");
        TCLAP::ValueArg<bool>            debugSounds_arg            ("",  "debugsounds",            "Debug sounds.", false, m_prefs.debugSounds, "bool");
        TCLAP::ValueArg<bool>            disableSound_arg        ("s", "disablesound",            "Disable sounds.", false, m_prefs.disableSound, "bool");
        TCLAP::ValueArg<bool>            fsaa_arg                ("",  "fsaa",                    "Enable fsaa.", false, m_prefs.fsaa, "bool");
        TCLAP::ValueArg<int>            fsaaSamples_arg            ("",  "fsaasSamples",            "Set fsaa samples.", false, m_prefs.fsaaSamples, "int");
        TCLAP::ValueArg<bool>            enableshadows_arg        ("w",  "enableshadows",            "Enable Shadows.", false, m_prefs.enableshadows, "bool");
        TCLAP::ValueArg<int>            defaultMipMap_arg        ("",  "defaultmipmap",            "Set default mipMap.", false, m_prefs.defaultMipMap, "int");
        TCLAP::ValueArg<std::string>    shadowtechnique_arg        ("",  "shadowtechnique",        "Set shadow technique.", false, m_prefs.shadowtechnique, "string");
        TCLAP::ValueArg<std::string>    colourshadow_arg        ("",  "colourshadow",            "Set shadow colour.", false, "", "string");
        TCLAP::ValueArg<float>            fardistanceshadow_arg    ("",  "fardistanceshadow",        "Set far distance shadow.", false, m_prefs.fardistanceshadow, "float");
        TCLAP::ValueArg<std::string>    shaderCachePath_arg        ("",  "shadercachepath",        "RTShaderSystem cache file path.", false, m_prefs.shaderCachePath, "string");
        TCLAP::ValueArg<bool>            enableSkyX_arg            ("",  "enableskyx",                "Enable Skyx.", false, m_prefs.enableSkyX, "bool");

        cmdl.add(rendersystem_arg);
        cmdl.add(viewportOrientation_arg);
        cmdl.add(log_arg);
        cmdl.add(verbose_arg);
        cmdl.add(winsize_x_arg);
        cmdl.add(winsize_y_arg);
        cmdl.add(wintitle_arg);
        cmdl.add(fullscreen_arg);
        cmdl.add(framingType_arg);
        cmdl.add(resources_arg);
        cmdl.add(blendermat_arg);
        cmdl.add(matblending_arg);
        cmdl.add(grapInput_arg);
        cmdl.add(debugFps_arg);
        cmdl.add(debugPhysics_arg);   
        cmdl.add(debugPhysicsAabb_arg);   
        cmdl.add(buildStaticGeometry_arg);
        cmdl.add(useBulletDbvt_arg);
        cmdl.add(showDebugProps_arg);
        cmdl.add(debugSounds_arg);
        cmdl.add(disableSound_arg);
        cmdl.add(fsaa_arg);
        cmdl.add(fsaaSamples_arg);
        cmdl.add(enableshadows_arg);
        cmdl.add(defaultMipMap_arg);
        cmdl.add(shadowtechnique_arg);
        cmdl.add(colourshadow_arg);
        cmdl.add(fardistanceshadow_arg);
        cmdl.add(shaderCachePath_arg);
        cmdl.add(enableSkyX_arg);

        //input file arguments
       
        TCLAP::ValueArg<std::string>            cfgfname_arg("c", "config-file", "Startup configuration file (.cfg) to use.", false, gkDefaultConfig, "string");
        TCLAP::UnlabeledValueArg<std::string>    bfname_arg("blender-file", "Blender file to launch as game.", false, gkDefaultBlend, "string");

        cmdl.add(cfgfname_arg);
        cmdl.add(bfname_arg);

        cmdl.parse( argc, argv );

        cfgfname                        = cfgfname_arg.getValue();
        m_blend                            = bfname_arg.getValue();

        m_prefs.rendersystem            = gkUserDefs::getOgreRenderSystem(rendersystem_arg.getValue());
        m_prefs.viewportOrientation        = viewportOrientation_arg.getValue();
        //m_prefs.sceneManager            = sceneManager_arg.getValue();
        m_prefs.log                        = log_arg.getValue();
        m_prefs.verbose                    = verbose_arg.getValue();

        m_prefs.winsize                    = gkVector2(winsize_x_arg.getValue(), winsize_y_arg.getValue());
        m_prefs.wintitle                = wintitle_arg.getValue();

        m_prefs.fullscreen                = fullscreen_arg.getValue();
        m_prefs.framingType                = gkUserDefs::getViewportFramingType(framingType_arg.getValue());
        m_prefs.resources                = resources_arg.getValue();
        m_prefs.blendermat                = blendermat_arg.getValue();
        m_prefs.matblending                = matblending_arg.getValue();
        m_prefs.grabInput                = grapInput_arg.getValue();
        m_prefs.debugFps                = debugFps_arg.getValue();
        m_prefs.debugPhysics            = debugPhysics_arg.getValue();
        m_prefs.debugPhysicsAabb        = debugPhysicsAabb_arg.getValue();
        m_prefs.buildStaticGeometry        = buildStaticGeometry_arg.getValue();
        m_prefs.useBulletDbvt            = useBulletDbvt_arg.getValue();
        m_prefs.showDebugProps            = showDebugProps_arg.getValue();
        m_prefs.debugSounds                = debugSounds_arg.getValue();
        m_prefs.disableSound            = disableSound_arg.getValue();

        m_prefs.fsaa                    = fsaa_arg.getValue();
        m_prefs.fsaaSamples                = fsaaSamples_arg.getValue();
        m_prefs.enableshadows            = enableshadows_arg.getValue();
        m_prefs.defaultMipMap            = defaultMipMap_arg.getValue();
        m_prefs.shadowtechnique            = shadowtechnique_arg.getValue();
        m_prefs.fardistanceshadow        = fardistanceshadow_arg.getValue();   
        m_prefs.shaderCachePath            = shaderCachePath_arg.getValue();
        m_prefs.enableSkyX                = enableSkyX_arg.getValue();

        if (colourshadow_arg.isSet())
            m_prefs.colourshadow        = Ogre::StringConverter::parseColourValue(colourshadow_arg.getValue());

#ifdef __APPLE__
        if (m_blend.find("-psn") != gkString::npos)
            m_blend = gkDefaultBlend;
#endif

    }
    catch (TCLAP::ArgException& e)
    {
        std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl;
        return -1;
    }
    catch (TCLAP::ExitException&)
    {
        // just return and exit app
        return -1;
    }
    catch (...)
    {
        std::cerr << "Unknown exception." << std::endl;
        return -1;
    }



    gkPath path = cfgfname;

    // overide settings if found
    if (path.isFile())
        m_prefs.load(path.getPath());

    return 0;
}


bool OgreKit::setup(void)
{
    gkBlendFile* blend = gkBlendLoader::getSingleton().loadFile(gkUtils::getFile(m_blend), gkBlendLoader::LO_ALL_SCENES);
    if (!blend)
    {
        gkPrintf("File loading failed.\n");
        return false;
    }

    m_scene = blend->getMainScene();
    if (!m_scene)
    {
        gkPrintf("No usable scenes found in blend.\n");
        return false;
    }


    m_scene->createInstance();

    // add input hooks
    gkWindowSystem::getSingleton().addListener(this);

#ifdef OGREKIT_USE_COMPOSITOR
    //gkCompositorManager::getSingleton().setCompositorChain(GK_COMPOSITOR_OP_ADD, GK_COMPOSITOR_BLOOM);
#endif

    return true;
}

void OgreKit::keyReleased(const gkKeyboard& key, const gkScanCode& sc)
{
    if (sc == KC_ESCKEY)
        m_engine->requestExit();
}

bool OgreKit::initialize()
{
    if (!gkCoreApplication::initialize())
        return false;

    m_engine->loadResources("resources.cfg");

    Ogre::SceneManager* sceneMgr = m_scene->getManager();
    Ogre::RenderWindow* window = m_scene->getDisplayWindow()->getRenderWindow();
    Ogre::Camera* camera = m_scene->getMainCamera()->getCamera();
    camera->setFarClipDistance(30000);

    if (m_prefs.enableSkyX)
    {
        m_wheather = new gkWheather;
        m_wheather->initialize(sceneMgr, window, camera);
        m_waterManager = new gkWaterManager;
        m_waterManager->initialize(sceneMgr, window, camera);
    }

    return true;
}

int main(int argc, char** argv)
{

    TestMemory;

    OgreKit okit;
    if (okit.setup(argc, argv) != 0)
    {
        for (int i = 0; i < argc; i++)
            printf("arg[%d]: %s\n", i, argv[i]);
        system("pause");
        // error
        return -1;
    }

    // Launch runtime
    okit.run();
    return 0;
}

2.3 Modify gkUserDefs.cpp
At line 315 in file gkUserDefs.cpp add the following code.

    if (KeyEq("enableskyx"))
    {
        enableSkyX = Ogre::StringConverter::parseBool(val);
        return;
    }


Shown as Figure 2-3.
Figure 2-3

2.4 Modify CMakeLists.txt of project AppOgreKit
Open the file ogrekit\Samples\Runtime\CMakeLists.txt. Modify the code as following.

# ---------------------------------------------------------
cmake_minimum_required(VERSION 2.6)



if (APPLE)
    include_directories(${OGRELITE_SOURCE_DIR}/OgreMain/include/OSX)
    SET(EXETYPE MACOSX_BUNDLE)
    SET_SOURCE_FILES_PROPERTIES( MainMenu.nib  PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
    SET_SOURCE_FILES_PROPERTIES(momo_ogre.blend PROPERTIES MACOSX_PACKAGE_LOCATION Resources )
    SET (NibFile MainMenu.nib)
endif()

set(SRC
    momo_ogre.blend
    Main.cpp
)

include_directories(
    ${OGREKIT_INCLUDE}
    ../../Dependencies/Source/tclap/include
    ${skyx_SOURCE_DIR}/include
    ${hydrax_SOURCE_DIR}/src
    ${gkhydrax_SOURCE_DIR}/include
    ${gkskyx_SOURCE_DIR}/include
)

link_libraries(
    ${OGREKIT_LIB}
    hydrax
    skyx
    gkhydrax
    gkskyx
)


set(HiddenCMakeLists ../CMakeLists.txt)
source_group(ParentCMakeLists FILES ${HiddenCMakeLists})

if (WIN32)
    set(PLAT_RESOURCE Win32/app.rc)
    set(RESOURCE )   
    set_source_files_properties(${RESOURCE} PROPERTIES HEADER_FILE_ONLY 1)
    source_group(Content\\Resources FILES ${PLAT_RESOURCE} ${RESOURCE})

    list(APPEND SRC ${PLAT_RESOURCE})
endif()

if (APPLE)

    add_executable(
        AppOgreKit
        MACOSX_BUNDLE
        MainMenu.nib
        ${SRC}
        ${HiddenCMakeLists}
    )

else ()

    add_executable(AppOgreKit ${SRC} ${HiddenCMakeLists})
   
    IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
        ADD_CUSTOM_COMMAND(
            TARGET AppOgreKit
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/momo_ogre.blend ${CMAKE_CURRENT_BINARY_DIR}/momo_ogre.blend
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${OGREKIT_SOURCE_DIR}/resources/resources.cfg ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg
            COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${OGREKIT_SOURCE_DIR}/resources/Media ${CMAKE_CURRENT_BINARY_DIR}/Media
        )
    ENDIF ()

endif()


Then use the cmake gui edition to regenerate the solution. And compile the AppOgreKit project in release mode.

2.5 Setup plugin for blender
Copy all from folder ogrekit\BlenderAddon to <your blender install path>\2.63\scripts\addons. I use blender with the version 2.63. You can choose the right folder to change "2.63".
Rename the data.py to game_gamekit.py. Shown as Figure 2-4
Figure 2-4

Copy all from folder ogrekit\resources to <your blender install path>. Do you still remember the folder resources we created to store resources of skyx and hydrax.
Copy AppOgreKit.exe from your release folder just compiled to <your blender install path>.
Shown as Figure 2-5.
Figure 2-5


2.6 Edit ui.py of the plugin
Open file <your blender install path>\2.63\scripts\addons\game_gamekit\ui.py. At about line 305 add the following codes.

        col.label(text="SkyX")
        col.prop(gks, "gk_enable_skyx", text="SkyX")


Note that the indents must be space characters. If you use "tab" instead, you will get exception as runtime. Shown as Figure 2-6
Figure 2-6

At the end of the file, add the following code.

    GamekitSettings.gk_enable_skyx = bpy.props.BoolProperty(
                    name="Enable SkyX",
                    default=True
                    )


Also use the space characters as the indents. Shown as Figure 2-7.
Figure 2-7


2.7 Edit operators.py of the plugin
Open file <your blender install path>\2.63\scripts\addons\game_gamekit\operators.py. At about line 110 add "cfg.set('enableskyx', str(gks.gk_enable_skyx))". Shown as Figure 2-8.

Figure 2-8

Then you can open a blend file. Be sure to unchecked the "Enable shadows". And press the button "Start Game". You will see the plugin window. Shown as following Figures.



 What a long blog. Please remember my email address: oneminute3b@gmail.com

没有评论:

发表评论