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