/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html
You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
//MaterialControls.h定义材质控制的头文件
//MaterialControls.cpp定义怎样导入材质等
//OceanDemo.h定义海洋Demo选择所用到的各种方法的头文件
//OceanDemo.cpp文件定义各种响应事件的处理以及各种mesh变换的处理
#ifndef __MaterialControls_H__
#define __MaterialControls_H__
#include "CEGUI/CEGUIForwardRefs.h"
#include "OgreString.h"
enum ShaderValType
{
GPU_VERTEX, GPU_FRAGMENT, MAT_SPECULAR, MAT_DIFFUSE, MAT_AMBIENT, MAT_SHININESS, MAT_EMISSIVE
};
//---------------------------------------------------------------------------
struct ShaderControl
{
Ogre::String Name;
Ogre::String ParamName;
ShaderValType ValType;
float MinVal;
float MaxVal;
size_t ElementIndex;
mutable size_t PhysicalIndex;
float getRange(void) const { return MaxVal - MinVal; }//声明范围变化方法
float convertParamToScrollPosition(const float val) const { return val - MinVal; }//声明滑动条与参数之间联系的方法
float convertScrollPositionToParam(const float val) const { return val + MinVal; }
};
typedef std::vector<ShaderControl> ShaderControlsContainer;
typedef ShaderControlsContainer::iterator ShaderControlIterator;
// used for materials that have user controls
//---------------------------------------------------------------------------
class MaterialControls
{//材质选择的处理
public:
MaterialControls(const Ogre::String& displayName, const Ogre::String& materialName)
: mDisplayName(displayName)
, mMaterialName(materialName)//构造函数
{
};
~MaterialControls(void){}//析构函数
const Ogre::String& getDisplayName(void) const { return mDisplayName; }
const Ogre::String& getMaterialName(void) const { return mMaterialName; }
size_t getShaderControlCount(void) const { return mShaderControlsContainer.size(); }
const ShaderControl& getShaderControl(const size_t idx) const
{
assert( idx < mShaderControlsContainer.size() );//声明索引数
return mShaderControlsContainer[idx];
}
/** add a new control by passing a string parameter
@param
params is a string using the following format:
"<Control Name>, <Shader parameter name>, <Parameter Type>, <Min Val>, <Max Val>, <Parameter Sub Index>"
<Control Name> is the string displayed for the control name on screen
<Shader parameter name> is the name of the variable in the shader
<Parameter Type> can be GPU_VERTEX, GPU_FRAGMENT
<Min Val> minimum value that parameter can be
<Max Val> maximum value that parameter can be
<Parameter Sub Index> index into the the float array of the parameter. All GPU parameters are assumed to be float[4].
*/
//声明获得用户所传递的参数来控制材质选择的方法
void addControl(const Ogre::String& params);
protected:
Ogre::String mDisplayName;
Ogre::String mMaterialName;
ShaderControlsContainer mShaderControlsContainer;
};
typedef std::vector<MaterialControls> MaterialControlsContainer;
typedef MaterialControlsContainer::iterator MaterialControlsIterator;
//---------------------------------------------------------------------------
struct ShaderControlGUIWidget//CEGUI免费开源GUI库中的一些参数
{
CEGUI::Window* TextWidget;
CEGUI::Window* NumberWidget;
CEGUI::Scrollbar* ScrollWidget;
ShaderControlGUIWidget() : TextWidget(NULL), NumberWidget(NULL), ScrollWidget(NULL) {}
};
//---------------------------------------------------------------------------
/** loads material shader controls from a configuration file
A .controls file is made up of the following:
[<material display name>]
material = <material name>
control = <Control Name>, <Shader parameter name>, <Parameter Type>, <Min Val>, <Max Val>, <Parameter Sub Index>
<material display name> is what is displayed in the material combo box.
<material name> is the name of the material in the material script.
control is the shader control associated with the material. The order
of the contol definions in the .controls file determins their order
when displayed in the controls window.
you can have multiple .controls files or put them all in one.
*/
void loadMaterialControlsFile(MaterialControlsContainer& controlsContainer, const Ogre::String& filename);//声明导入材质的方法
/** load all control files found in resource paths
*/
void loadAllMaterialControlFiles(MaterialControlsContainer& controlsContainer);//声明导入资源库所有材质的方法
#endif // __MaterialControls_H__
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html
You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
#include "MaterialControls.h"
#include "OgreLogManager.h"
#include "OgreStringVector.h"
#include "OgreStringConverter.h"
#include "OgreConfigFile.h"
#include "OgreResourceGroupManager.h"
#include "OgreException.h"
/********************************************************************************
MaterialControls Methods
*********************************************************************************/
void MaterialControls::addControl(const Ogre::String& params)
{
// params is a string containing using the following format:
// "<Control Name>, <Shader parameter name>, <Parameter Type>, <Min Val>, <Max Val>, <Parameter Sub Index>"
// break up long string into components
//传递由控制名称,阴影参数,类型,最小值,最大值,子索引组成的字符串,在这里进行分割提取
Ogre::StringVector vecparams = Ogre::StringUtil::split(params, ",");
// if there are not five elements then log error and move on
if (vecparams.size() != 6)//参数数目不对的处理
{
Ogre::LogManager::getSingleton().logMessage(
"Incorrect number of parameters passed in params string for MaterialControls::addControl()" );
return;
}
//头文件定义的结构体的对象,并对结构体中的所有参数赋值
ShaderControl newControl;
Ogre::StringUtil::trim(vecparams[0]);
newControl.Name = vecparams[0];
Ogre::StringUtil::trim(vecparams[1]);
newControl.ParamName = vecparams[1];
Ogre::StringUtil::trim(vecparams[2]);
if (vecparams[2] == "GPU_VERTEX")//判断阴影类型
newControl.ValType = GPU_VERTEX;
else if (vecparams[2] == "GPU_FRAGMENT")
newControl.ValType = GPU_FRAGMENT;
newControl.MinVal = Ogre::StringConverter::parseReal(vecparams[3]);
newControl.MaxVal = Ogre::StringConverter::parseReal(vecparams[4]);
newControl.ElementIndex = Ogre::StringConverter::parseInt(vecparams[5]);
mShaderControlsContainer.push_back(newControl);//放入到控制容器中
}
void loadMaterialControlsFile(MaterialControlsContainer& controlsContainer, const Ogre::String& filename)
{//保证容器中有实例,否则报异常
// Load material controls from config file
Ogre::ConfigFile cf;
try
{
cf.load(filename, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "/t;=", true);//从默认的资源管理器中导入资源文件
// Go through all sections & controls in the file
//
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
Ogre::String secName, typeName, materialName, dataString;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap* settings = seci.getNext();
if (!secName.empty() && settings)
{//获得不同材质的处理
materialName = cf.getSetting("material", secName);
MaterialControls newMaaterialControls(secName, materialName);
controlsContainer.push_back(newMaaterialControls);
size_t idx = controlsContainer.size() - 1;//这里表示控制容器存放进一个材质实例
Ogre::ConfigFile::SettingsMultiMap::iterator i;//声明多重映射的对象
for (i = settings->begin(); i != settings->end(); ++i)//使控制容器中的索引都对应着材质的数据
{
typeName = i->first;
dataString = i->second;
if (typeName == "control")
controlsContainer[idx].addControl(dataString);
}
}
}
Ogre::LogManager::getSingleton().logMessage( "Material Controls setup" );
}
catch (Ogre::Exception e)
{
// Guess the file didn't exist
}
}
void loadAllMaterialControlFiles(MaterialControlsContainer& controlsContainer)
{//导入资源组中与.controls想匹配的所有文件
Ogre::StringVectorPtr fileStringVector = Ogre::ResourceGroupManager::getSingleton().findResourceNames( Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "*.controls" );
std::vector<Ogre::String>::iterator controlsFileNameIterator = fileStringVector->begin();
while ( controlsFileNameIterator != fileStringVector->end() )
{
loadMaterialControlsFile(controlsContainer, *controlsFileNameIterator);
++controlsFileNameIterator;
}
}
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html
You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
#ifndef _OceanDemo_H_
#define _OceanDemo_H_
#include "CEGUI/CEGUI.h"
#include "OgreCEGUIRenderer.h"
#include "OgreConfigFile.h"
#include "OgreStringConverter.h"
#include "OgreException.h"
#include "OgreFrameListener.h"
#include "MaterialControls.h"
#include <OIS/OIS.h>
//---------------------------------------------------------------------------
enum MovementType//声明枚举类型
{
mv_CAMERA, mv_MODEL, mv_LIGHT
};
//---------------------------------------------------------------------------
class OceanDemo;
class OceanDemo_FrameListener : public Ogre::FrameListener, public OIS::KeyListener, OIS::MouseListener
{
#define MINSPEED .150f
#define MOVESPEED 30
#define MAXSPEED 1.800f
protected://声明CEGUI面板上的一些参数
OceanDemo* mMain;
Ogre::Vector3 mTranslateVector;
bool mStatsOn;
unsigned int mNumScreenShots;
bool mWriteToFile;
float mMoveScale;
float mRotScale;
float mSpeed;
float mAvgFrameTime;
int mSceneDetailIndex;
Ogre::Real mMoveSpeed;
Ogre::Real mRotateSpeed;
float mSkipCount;
float mUpdateFreq;
CEGUI::Point mLastMousePosition;//注意此处是CEGUI定义的二维向量,获得鼠标的位置
bool mLastMousePositionSet;
bool mSpinModel;
bool mSpinLight;
OIS::Mouse *mMouse;
OIS::Keyboard *mKeyboard;
OIS::InputManager* mInputManager;
// just to stop toggles flipping too fast
Ogre::Real mTimeUntilNextToggle ;
float mRotX, mRotY;
Ogre::TextureFilterOptions mFiltering;//声明材质过滤器
int mAniso;
bool mQuit;
bool mLMBDown;
bool mRMBDown;
bool mProcessMovement;
bool mUpdateMovement;
bool mMoveFwd;
bool mMoveBck;
bool mMoveLeft;
bool mMoveRight;
CEGUI::Renderer* mGuiRenderer;//声明CEGUI所用到的对象
CEGUI::Window* mGuiAvg;
CEGUI::Window* mGuiCurr;
CEGUI::Window* mGuiBest;
CEGUI::Window* mGuiWorst;
CEGUI::Window* mGuiTris;
CEGUI::Window* mGuiDbg;
CEGUI::Window* mRoot;
std::string mDebugText;
CEGUI::MouseButton convertOISButtonToCegui(int ois_button_id);
void CheckMovementKeys( CEGUI::Key::Scan keycode, bool state );
void updateStats(void);
public:
OceanDemo_FrameListener(OceanDemo* main);
virtual ~OceanDemo_FrameListener();
//声明抽象操作的方法
virtual bool mouseMoved ( const OIS::MouseEvent &arg );
virtual bool mousePressed ( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
virtual bool mouseReleased ( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
virtual bool keyPressed ( const OIS::KeyEvent &arg );
virtual bool keyReleased ( const OIS::KeyEvent &arg );
bool frameStarted(const Ogre::FrameEvent& evt);
bool handleMouseMove(const CEGUI::EventArgs& e);
bool handleMouseButtonUp(const CEGUI::EventArgs& e);
bool handleMouseButtonDown(const CEGUI::EventArgs& e);
bool handleMouseWheelEvent(const CEGUI::EventArgs& e);
bool handleKeyDownEvent(const CEGUI::EventArgs& e);
bool handleKeyUpEvent(const CEGUI::EventArgs& e);
bool handelModelSpinChange(const CEGUI::EventArgs& e);
bool handelLightSpinChange(const CEGUI::EventArgs& e);
};
//---------------------------------------------------------------------------
class OceanDemo//声明场景管理所用到的参数及方法
{
protected:
Ogre::Root* mRoot;
Ogre::Camera* mCamera;
Ogre::SceneManager* mSceneMgr;
// the scene node of the entity
Ogre::SceneNode* mMainNode;
OceanDemo_FrameListener* mFrameListener;
Ogre::RenderWindow* mWindow;
CEGUI::OgreCEGUIRenderer* mGUIRenderer;
CEGUI::System* mGUISystem;
Ogre::Entity* mCurrentEntity;
Ogre::Entity* mOceanSurfaceEnt;
size_t mCurrentMaterial;
Ogre::MaterialPtr mActiveMaterial;
Ogre::Pass* mActivePass;
Ogre::GpuProgramPtr mActiveFragmentProgram;
Ogre::GpuProgramPtr mActiveVertexProgram;
Ogre::GpuProgramParametersSharedPtr mActiveFragmentParameters;
Ogre::GpuProgramParametersSharedPtr mActiveVertexParameters;
typedef std::vector< ShaderControlGUIWidget > ShaderControlContainer;
typedef ShaderControlContainer::iterator ShaderControlIterator;
ShaderControlContainer mShaderControlContainer;
MaterialControlsContainer mMaterialControlsContainer;
CEGUI::Scrollbar* mVertScroll;
MovementType mMouseMovement;
// These internal methods package up the stages in the startup process
/** Sets up the application - returns false if the user chooses to abandon configuration. */
bool setup(void);
/** Configures the application - returns false if the user chooses to abandon configuration. */
bool configure(void);
void chooseSceneManager(void);
void createCamera(void);
void createViewports(void);
/// Method which will define the source of resources (other than current folder)
//声明资源来源的方法
void setupResources(void);
void loadResources(void);
bool setupGUI(void);
void createScene(void);
void createFrameListener(void);
void initComboBoxes(void);
void initDemoEventWiring(void);
void configureShaderControls(void);
void doErrorBox(const char* text);
bool handleQuit(const CEGUI::EventArgs& e);
bool handleShaderControl(const CEGUI::EventArgs& e);
bool handleModelComboChanged(const CEGUI::EventArgs& e);
bool handleShaderComboChanged(const CEGUI::EventArgs& e);
bool handleScrollControlsWindow(const CEGUI::EventArgs& e);
bool handleMovementTypeChange(const CEGUI::EventArgs& e);
bool handleErrorBox(const CEGUI::EventArgs& e);
void setShaderControlVal(const float val, const size_t index);
public:
OceanDemo() : mRoot(0), mFrameListener(0), mGUIRenderer(NULL), mGUISystem(0),
mCurrentEntity(0), mCurrentMaterial(0), mActivePass(0), mMouseMovement(mv_CAMERA)
{
}
~OceanDemo();
void go(void);
Ogre::Camera* getCamera(void) const { return mCamera; }
Ogre::SceneManager* getSceneManager(void) const { return mSceneMgr; }
Ogre::RenderWindow* getRenderWindow(void) const { return mWindow; }
MovementType getMouseMovement(void) const { return mMouseMovement; }
Ogre::SceneNode* getMainNode(void) const { return mMainNode; }
};
#endif // end _OceanDemo_H_
——————————————————————————————————————————————————————————
——————————————————————————————————————————————————————————
/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/
Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html
You may use this sample code for anything you like, it is not covered by the
LGPL like the rest of the engine.
-----------------------------------------------------------------------------
*/
#include "OceanDemo.h"
#include "Ogre.h"
#include <cstdlib>
/**********************************************************************
OS X Specific Resource Location Finding
**********************************************************************/
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE//非Window系统运行此段代码
Ogre::String bundlePath()
{
char path[1024];
CFBundleRef mainBundle = CFBundleGetMainBundle();
assert( mainBundle );
CFURLRef mainBundleURL = CFBundleCopyBundleURL( mainBundle);
assert( mainBundleURL);
CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
assert( cfStringRef);
CFStringGetCString( cfStringRef, path, 1024, kCFStringEncodingASCII);
CFRelease( mainBundleURL);
CFRelease( cfStringRef);
return Ogre::String( path);
}
#endif
/**********************************************************************
Static declarations
**********************************************************************/
// Lights
#define NUM_LIGHTS 1
// the light
Ogre::Light* mLights[NUM_LIGHTS];
// billboards for lights
//声明光源的包围盒
Ogre::BillboardSet* mLightFlareSets[NUM_LIGHTS];
Ogre::Billboard* mLightFlares[NUM_LIGHTS];
// Positions for lights
Ogre::Vector3 mLightPositions[NUM_LIGHTS] =
{
Ogre::Vector3(00, 400, 00)
};
// Base orientations of the lights
//光源在X轴35度的旋转
Ogre::Real mLightRotationAngles[NUM_LIGHTS] = { 35 };
Ogre::Vector3 mLightRotationAxes[NUM_LIGHTS] = {
Ogre::Vector3::UNIT_X
};
// Rotation speed for lights, degrees per second
//旋转速度
Ogre::Real mLightSpeeds[NUM_LIGHTS] = { 30};
// Colours for the lights
Ogre::ColourValue mDiffuseLightColours[NUM_LIGHTS] =//漫射光的颜色
{
Ogre::ColourValue(0.6, 0.6, 0.6)
};
Ogre::ColourValue mSpecularLightColours[NUM_LIGHTS] =//镜面光的颜色
{
Ogre::ColourValue(0.5, 0.5, 0.5)
};
// Which lights are enabled
bool mLightState[NUM_LIGHTS] =//光源的初始化状态
{
true
};
// the light nodes
Ogre::SceneNode* mLightNodes[NUM_LIGHTS];
// the light node pivots
Ogre::SceneNode* mLightPivots[NUM_LIGHTS];
//界面上GUI面板参数的初始化状态
#define UVECTOR2(x, y) UVector2(cegui_reldim(x), cegui_reldim(y))//UV方向的纹理贴图
#define TEXTWIDGET_SIZE UVECTOR2(0.19, 0.06)
#define NUMBERWIDGET_SIZE UVECTOR2(0.065, 0.06)
#define SCROLLWIDGET_SIZE UVECTOR2(0.21, 0.02)
#define TEXTWIDGET_XPOS 0.01
#define NUMBERWIDGET_XPOS 0.37
#define SCROLLWIDGET_XPOS 0.50
#define TEXTWIDGET_YADJUST (-0.05f)
#define WIDGET_YSTART 0.2f
#define WIDGET_YOFFSET 0.15f
/*************************************************************************
sub-class for ListboxTextItem that auto-sets the selection brush
image.
*************************************************************************/
class MyListItem : public CEGUI::ListboxTextItem
{//下拉框的设置
public:
MyListItem(const CEGUI::String& text, CEGUI::uint id) : CEGUI::ListboxTextItem(text, id)
{
setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");//TaharezLook在Media文件中gui文件夹中定义的图像集
}
};
/*********************************************************************
Main Program Entry Point
***********************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )//Window程序入口
#else
int main(int argc, char *argv[])
#endif
{
// Create application object
OceanDemo app;
try {
app.go();
} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == PLATFORM_WIN32
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr << "An exception has occured: " <<
e.getFullDescription().c_str() << std::endl;
#endif
}
return 0;
}
#ifdef __cplusplus
}
#endif
/*************************************************************************
OceanDemo Methods
*************************************************************************/
OceanDemo::~OceanDemo()
{//清除
delete mGUISystem;
delete mGUIRenderer;
delete mFrameListener;
// get rid of the shared pointers before shutting down ogre or exceptions occure
mActiveFragmentProgram.setNull();
mActiveFragmentParameters.setNull();
mActiveVertexProgram.setNull();
mActiveVertexParameters.setNull();
mActiveMaterial.setNull();
delete mRoot;
}
//--------------------------------------------------------------------------
void OceanDemo::go(void)
{//渲染的处理方法
if (!setup())
return;
mRoot->startRendering();
}
//--------------------------------------------------------------------------
bool OceanDemo::setup(void)
{
bool setupCompleted = false;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
Ogre::String mResourcePath;
mResourcePath = bundlePath() + "/Contents/Resources/";
mRoot = new Ogre::Root(mResourcePath + "plugins.cfg",
mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");
#else
mRoot = new Ogre::Root();
#endif
setupResources();//调用建立资源的方法(下面定义)
if (configure())
{
chooseSceneManager();//创建场景管理节点
createCamera();//构造摄像机
createViewports();//创建观察视口
// Set default mipmap level (NB some APIs ignore this)
Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
loadResources();//导入用户所选择的资源(如纹理,mesh等)
if (setupGUI())
{
// Create the scene
createScene();//创建场景
createFrameListener();//对窗体的监听
// load some GUI stuff for demo.
loadAllMaterialControlFiles(mMaterialControlsContainer);
initDemoEventWiring();//所有的Demo的处理
initComboBoxes();
setupCompleted = true;
}
}
return setupCompleted;
}
//--------------------------------------------------------------------------
bool OceanDemo::configure(void)
{
// Show the configuration dialog and initialise the system
// You can skip this and use root.restoreConfig() to load configuration
// settings if you were sure there are valid ones saved in ogre.cfg
//选择确认渲染窗体,返回布尔值
if(mRoot->showConfigDialog())
{
// If returned true, user clicked OK so initialise
// Here we choose to let the system create a default rendering window by passing 'true'
mWindow = mRoot->initialise(true);
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------
void OceanDemo::chooseSceneManager(void)
{
// Get the SceneManager, in this case a generic one
mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC, "ExampleSMInstance");
}
//--------------------------------------------------------------------------
void OceanDemo::createCamera(void)
{
// Create the camera
mCamera = mSceneMgr->createCamera("PlayerCam");//创建摄像机节点
// Position it at 500 in Z direction
mCamera->setPosition(Ogre::Vector3(0,0,0));//位置
// Look back along -Z
mCamera->lookAt(Ogre::Vector3(0,0,-300));//视角
mCamera->setNearClipDistance(1);//场景的近距离
}
//--------------------------------------------------------------------------
void OceanDemo::createViewports(void)
{
// Create one viewport, entire window
//创建对整个窗体的视口
Ogre::Viewport* vp = mWindow->addViewport(mCamera);
vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
// Alter the camera aspect ratio to match the viewport
//设置摄像机的长宽比以适应视口的大小
mCamera->setAspectRatio(
Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
}
//--------------------------------------------------------------------------
void OceanDemo::setupResources(void)
{
// Load resource paths from config file
Ogre::ConfigFile cf;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
Ogre::String mResourcePath;
mResourcePath = bundlePath() + "/Contents/Resources/";
cf.load(mResourcePath + "resources.cfg");
#else
cf.load("resources.cfg");//此处的.cfg文件是所有关于Ogre资源的配置文件
#endif
// Go through all sections & settings in the file
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();//遍历上述文件
Ogre::String secName, typeName, archName;
//所用到资源文件的建立
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();//获得资源管理器中的下一个的key(map映射的关系)
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();//获得资源管理器中的下一个的value
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
// OS X does not set the working directory relative to the app,
// In order to make things portable on OS X we need to provide
// the loading with it's own bundle path location
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
Ogre::String(bundlePath() + "/" + archName), typeName, secName);
#else
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(//资源定位
archName, typeName, secName);
#endif
}
}
Ogre::LogManager::getSingleton().logMessage( "Resource directories setup" );
}
//-----------------------------------------------------------------------------------
void OceanDemo::loadResources(void)
{
// Initialise, parse scripts etc
//初始化并分析所有的资源脚本
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
//--------------------------------------------------------------------------
bool OceanDemo::setupGUI(void)
{//建立GUI系统用于和Ogre进行交互
bool setupGUICompleted = false;
// setup GUI system
try
{
mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 0, mSceneMgr);
// load scheme and set up defaults
mGUISystem = new CEGUI::System(mGUIRenderer, 0, 0, 0, (CEGUI::utf8*)"OceanDemoCegui.config");
CEGUI::System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
setupGUICompleted = true;
}
catch(...)
{
}
return setupGUICompleted;
}
//--------------------------------------------------------------------------
void OceanDemo::createScene(void)
{
// Set ambient light
//设置环境光并设置颜色
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3));
mSceneMgr->setSkyBox(true, "SkyBox", 1000);//设置天空包围盒
mMainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
for (unsigned int i = 0; i < NUM_LIGHTS; ++i)
{//对2中光源的设置
mLightPivots[i] = mSceneMgr->getRootSceneNode()->createChildSceneNode();
mLightPivots[i]->rotate(mLightRotationAxes[i], Ogre::Angle(mLightRotationAngles[i]));
// Create a light, use default parameters
mLights[i] = mSceneMgr->createLight("Light" + Ogre::StringConverter::toString(i));
mLights[i]->setPosition(mLightPositions[i]);
mLights[i]->setDiffuseColour(mDiffuseLightColours[i]);
mLights[i]->setSpecularColour(mSpecularLightColours[i]);
mLights[i]->setVisible(mLightState[i]);
//mLights[i]->setAttenuation(400, 0.1 , 1 , 0);
// Attach light
mLightPivots[i]->attachObject(mLights[i]);
// Create billboard for light
mLightFlareSets[i] = mSceneMgr->createBillboardSet("Flare" + Ogre::StringConverter::toString(i));
mLightFlareSets[i]->setMaterialName("LightFlare");
mLightPivots[i]->attachObject(mLightFlareSets[i]);
mLightFlares[i] = mLightFlareSets[i]->createBillboard(mLightPositions[i]);
mLightFlares[i]->setColour(mDiffuseLightColours[i]);
mLightFlareSets[i]->setVisible(mLightState[i]);
}
// move the camera a bit right and make it look at the knot
//初始化摄像机的位置及视角
mCamera->moveRelative(Ogre::Vector3(50, 0, 100));
mCamera->lookAt(0, 0, 0);
// Define a plane mesh that will be used for the ocean surface
//初始化个平面用于作为海洋的表面
Ogre::Plane oceanSurface;
oceanSurface.normal = Ogre::Vector3::UNIT_Y;
oceanSurface.d = 20;
Ogre::MeshManager::getSingleton().createPlane("OceanSurface",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
oceanSurface,
1000, 1000, 50, 50, true, 1, 1, 1, Ogre::Vector3::UNIT_Z);
mOceanSurfaceEnt = mSceneMgr->createEntity( "OceanSurface", "OceanSurface" );
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(mOceanSurfaceEnt);
}
//--------------------------------------------------------------------------
void OceanDemo::initComboBoxes(void)//初始化组合框
{
using namespace CEGUI;
Combobox* cbobox = (Combobox*)WindowManager::getSingleton().getWindow("ShaderCombos");
for(size_t idx = 0; idx < mMaterialControlsContainer.size(); ++idx )
{
cbobox->addItem(new MyListItem( mMaterialControlsContainer[idx].getDisplayName().c_str(), static_cast<CEGUI::uint>(idx)));
}
// make first item visible
if (cbobox->getItemCount() > 0)
cbobox->setItemSelectState((size_t)0, true);
Editbox* eb;
// set text in combobox
if (!mMaterialControlsContainer.empty())
{
eb = (Editbox*)WindowManager::getSingleton().getWindow(cbobox->getName() + "__auto_editbox__");
eb->setText(mMaterialControlsContainer[0].getDisplayName().c_str());
handleShaderComboChanged(CEGUI::WindowEventArgs(cbobox));
}
cbobox = (Combobox*)WindowManager::getSingleton().getWindow("ModelCombos");
Ogre::StringVectorPtr meshStringVector = Ogre::ResourceGroupManager::getSingleton().findResourceNames( Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "*.mesh" );
std::vector<Ogre::String>::iterator meshFileNameIterator = meshStringVector->begin();
while ( meshFileNameIterator != meshStringVector->end() )
{
cbobox->addItem(new MyListItem( (*meshFileNameIterator).c_str(), 0 ));
++meshFileNameIterator;
}
// make first item visible
//cbobox->setItemSelectState((CEGUI::uint)0, true);
// eb = (Editbox*)WindowManager::getSingleton().getWindow(cbobox->getName() + "__auto_editbox__");
// if (meshStringVector->begin() != meshStringVector->end())
// {
// eb->setText((*meshStringVector->begin()).c_str());
// handleModelComboChanged(CEGUI::WindowEventArgs(cbobox));
// }
}
//--------------------------------------------------------------------------
void OceanDemo::initDemoEventWiring(void)//初始化所有的Demo
{
using namespace CEGUI;
//鼠标点击事件
WindowManager::getSingleton().getWindow("ExitDemoBtn")->
subscribeEvent(PushButton::EventClicked, CEGUI::Event::Subscriber(&OceanDemo::handleQuit, this));
//下拉框的选择
WindowManager::getSingleton().getWindow("ModelCombos")->
subscribeEvent(Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber(&OceanDemo::handleModelComboChanged, this));
WindowManager::getSingleton().getWindow("ShaderCombos")->
subscribeEvent(Combobox::EventListSelectionAccepted, CEGUI::Event::Subscriber(&OceanDemo::handleShaderComboChanged, this));
Window* wndw = WindowManager::getSingleton().getWindow("root");
// 对鼠标及键盘的各种控制(Subscriber用来定义对各种控制的侦听)
wndw->subscribeEvent(Window::EventMouseMove, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleMouseMove, mFrameListener));
wndw->subscribeEvent(Window::EventMouseButtonUp, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleMouseButtonUp, mFrameListener));
wndw->subscribeEvent(Window::EventMouseButtonDown, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleMouseButtonDown, mFrameListener));
wndw->subscribeEvent(Window::EventMouseWheel, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleMouseWheelEvent, mFrameListener));
wndw->subscribeEvent(Window::EventKeyDown, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleKeyDownEvent, mFrameListener ));
wndw->subscribeEvent(Window::EventKeyUp, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handleKeyUpEvent, mFrameListener ));
//复选框的设置
wndw = WindowManager::getSingleton().getWindow("ModelSpinCB");
wndw->subscribeEvent(Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handelModelSpinChange, mFrameListener ));
wndw = WindowManager::getSingleton().getWindow("LightSpinCB");
wndw->subscribeEvent(Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&OceanDemo_FrameListener::handelLightSpinChange, mFrameListener ));
//单选框的设置
wndw = WindowManager::getSingleton().getWindow("CameraRBtn");
wndw->subscribeEvent(RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&OceanDemo::handleMovementTypeChange, this ));
wndw = WindowManager::getSingleton().getWindow("ModelRBtn");
wndw->subscribeEvent(RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&OceanDemo::handleMovementTypeChange, this ));
//滑动条的控制
mVertScroll = (Scrollbar*)WindowManager::getSingleton().getWindow("VerticalScroll");
mVertScroll->subscribeEvent(Scrollbar::EventScrollPositionChanged, CEGUI::Event::Subscriber(&OceanDemo::handleScrollControlsWindow, this ));
}
//--------------------------------------------------------------------------
void OceanDemo::doErrorBox(const char* text)//异常的处理
{
using namespace CEGUI;
WindowManager& winMgr = WindowManager::getSingleton();
Window* root = winMgr.getWindow("root_wnd");
FrameWindow* errbox;
try
{
errbox = (FrameWindow*)winMgr.getWindow("ErrorBox");
}
catch(UnknownObjectException x)
{
// create frame window for box
FrameWindow* fwnd = (FrameWindow*)winMgr.createWindow("TaharezLook/FrameWindow", "ErrorBox");
root->addChildWindow(fwnd);
fwnd->setPosition(UVECTOR2(0.25, 0.25f));
fwnd->setMaxSize(UVECTOR2(1.0f, 1.0f));
fwnd->setSize(UVECTOR2(0.5f, 0.5f));
fwnd->setText("CEGUI Demo - Error!");
fwnd->setDragMovingEnabled(false);
fwnd->setSizingEnabled(false);
fwnd->setAlwaysOnTop(true);
fwnd->setCloseButtonEnabled(false);
// create error text message
Window* wnd = winMgr.createWindow("TaharezLook/StaticText", "ErrorBox/Message");
fwnd->addChildWindow(wnd);
wnd->setPosition(UVECTOR2(0.1f, 0.1f));
wnd->setSize(UVECTOR2(0.8f, 0.5f));
wnd->setProperty("VertFormatting", "VertCentred");
wnd->setProperty("HorzFormatting", "HorzCentred");
wnd->setProperty("BackgroundEnabled", "false");
wnd->setProperty("FrameEnabled", "false");
// create ok button
wnd = (PushButton*)winMgr.createWindow("TaharezLook/Button", "ErrorBox/OkButton");
fwnd->addChildWindow(wnd);
wnd->setPosition(UVECTOR2(0.3f, 0.80f));
wnd->setSize(UVECTOR2(0.4f, 0.1f));
wnd->setText("Okay!");
// subscribe event
wnd->subscribeEvent(PushButton::EventClicked, CEGUI::Event::Subscriber(&OceanDemo::handleErrorBox, this ));
errbox = fwnd;
}
errbox->getChild("ErrorBox/Message")->setText(text);
errbox->show();
errbox->activate();
}
//--------------------------------------------------------------------------
bool OceanDemo::handleQuit(const CEGUI::EventArgs& e)
{//结束处理
mRoot->queueEndRendering();
return true;
}
//--------------------------------------------------------------------------
void OceanDemo::setShaderControlVal(const float val, const size_t index)
{
char valTxtBuf[20];
// set the text of the value
sprintf(valTxtBuf, "%3.3f", val );
mShaderControlContainer[index].NumberWidget->setText(valTxtBuf);
}
//--------------------------------------------------------------------------
bool OceanDemo::handleShaderControl(const CEGUI::EventArgs& e)//对阴影控制的处理
{
using namespace CEGUI;
using namespace Ogre;
size_t index = ((Scrollbar*)((const WindowEventArgs&)e).window)->getID();
const ShaderControl& ActiveShaderDef = mMaterialControlsContainer[mCurrentMaterial].getShaderControl(index);
float val = ((Scrollbar*)((const WindowEventArgs&)e).window)->getScrollPosition();
val = ActiveShaderDef.convertScrollPositionToParam(val);
setShaderControlVal( val, index );
if(mActivePass)
{
switch(ActiveShaderDef.ValType)
{//不同的类型处理
case GPU_VERTEX:
case GPU_FRAGMENT:
{
GpuProgramParametersSharedPtr activeParameters =
(ActiveShaderDef.ValType == GPU_VERTEX) ?
mActiveVertexParameters : mActiveFragmentParameters;
if(!activeParameters.isNull())
{
activeParameters->_writeRawConstant(
ActiveShaderDef.PhysicalIndex + ActiveShaderDef.ElementIndex, val);
}
}
break;
case MAT_SPECULAR:
{
// get the specular values from the material pass
ColourValue OldSpec(mActivePass->getSpecular());
OldSpec[ActiveShaderDef.ElementIndex] = val;
mActivePass->setSpecular( OldSpec );
}
break;
case MAT_DIFFUSE:
{
// get the specular values from the material pass
ColourValue OldSpec(mActivePass->getDiffuse());
OldSpec[ActiveShaderDef.ElementIndex] = val;
mActivePass->setDiffuse( OldSpec );
}
break;
case MAT_AMBIENT:
{
// get the specular values from the material pass
ColourValue OldSpec(mActivePass->getAmbient());
OldSpec[ActiveShaderDef.ElementIndex] = val;
mActivePass->setAmbient( OldSpec );
}
break;
case MAT_SHININESS:
// get the specular values from the material pass
mActivePass->setShininess( val );
break;
}
}
return true;
}
//--------------------------------------------------------------------------
void OceanDemo::configureShaderControls(void)//.cfg文件的资源的获取并设置
{
using namespace CEGUI;
if (mMaterialControlsContainer.empty()) return;
mActiveMaterial = Ogre::MaterialManager::getSingleton().getByName( mMaterialControlsContainer[mCurrentMaterial].getMaterialName() );
if(!mActiveMaterial.isNull() && mActiveMaterial->getNumSupportedTechniques())
{
Ogre::Technique* currentTechnique = mActiveMaterial->getSupportedTechnique(0);
if(currentTechnique)
{
mActivePass = currentTechnique->getPass(0);
if(mActivePass)
{
if (mActivePass->hasFragmentProgram())
{
mActiveFragmentProgram = mActivePass->getFragmentProgram();
mActiveFragmentParameters = mActivePass->getFragmentProgramParameters();
}
if (mActivePass->hasVertexProgram())
{
mActiveVertexProgram = mActivePass->getVertexProgram();
mActiveVertexParameters = mActivePass->getVertexProgramParameters();
}
size_t activeControlCount = mMaterialControlsContainer[mCurrentMaterial].getShaderControlCount();
mVertScroll->setDocumentSize( activeControlCount / 5.0f );
mVertScroll->setScrollPosition(0.0f);
// init the GUI controls
// check the material entry for Params GUI list
if(mMaterialControlsContainer[mCurrentMaterial].getShaderControlCount() > 0)
{
// if mShaderControlContainer size < Params list
if( activeControlCount > mShaderControlContainer.size())
{
// resize container
mShaderControlContainer.resize( activeControlCount );
}
Window* controlWindow = WindowManager::getSingleton().getWindow("ShaderControlsWin");
// initialize each widget based on control data
// iterate through the params GUI list
for( size_t i=0; i < activeControlCount; ++i )
{
const ShaderControl& ActiveShaderDef = mMaterialControlsContainer[mCurrentMaterial].getShaderControl(i);
// if TextWidget is NULL
Window* activeTextWidget = mShaderControlContainer[i].TextWidget;
if(activeTextWidget == NULL)
{
// create TextWidget
mShaderControlContainer[i].TextWidget = activeTextWidget =
WindowManager::getSingleton().createWindow("TaharezLook/StaticText",
( ("UniformTxt" + Ogre::StringConverter::toString(i)).c_str() ));
// add to Shader control window
controlWindow->addChildWindow( activeTextWidget );
// set position based on its index
activeTextWidget->setPosition(UVECTOR2(TEXTWIDGET_XPOS, WIDGET_YSTART + TEXTWIDGET_YADJUST + WIDGET_YOFFSET * float(i)));
activeTextWidget->setProperty("VertFormatting", "TopAligned");
activeTextWidget->setProperty("HorzFormatting", "RightAligned");
activeTextWidget->setProperty("FrameEnabled", "false");
activeTextWidget->setInheritsAlpha(false);
activeTextWidget->setProperty("BackgroundEnabled", "false");
activeTextWidget->setMaxSize( TEXTWIDGET_SIZE );
activeTextWidget->setMinSize( TEXTWIDGET_SIZE );
activeTextWidget->setSize( TEXTWIDGET_SIZE );
}
// set TextWidget text to control name
activeTextWidget->setText( ActiveShaderDef.Name.c_str() );
// make TextWidget visible
activeTextWidget->show();
// if NumberWidget is NULL
Window* activeNumberWidget = mShaderControlContainer[i].NumberWidget;
if(activeNumberWidget == NULL)
{
// create NumberWidget
mShaderControlContainer[i].NumberWidget = activeNumberWidget =
WindowManager::getSingleton().createWindow("TaharezLook/StaticText",
( ("UniformNumTxt" + Ogre::StringConverter::toString(i)).c_str() ));
// add to Shader control window
controlWindow->addChildWindow( activeNumberWidget );
// set position based on its index
activeNumberWidget->setPosition(UVECTOR2(NUMBERWIDGET_XPOS, WIDGET_YSTART + TEXTWIDGET_YADJUST + WIDGET_YOFFSET * float(i)));
activeNumberWidget->setProperty("HorzFormatting", "RightAligned");
activeNumberWidget->setProperty("VertFormatting", "TopAligned");
activeNumberWidget->setProperty("FrameEnabled", "false");
activeNumberWidget->setInheritsAlpha(false);
activeNumberWidget->setProperty("BackgroundEnabled", "false");
activeNumberWidget->setMaxSize( NUMBERWIDGET_SIZE );
activeNumberWidget->setMinSize( NUMBERWIDGET_SIZE );
activeNumberWidget->setSize( NUMBERWIDGET_SIZE );
}
// make TextWidget visible
activeNumberWidget->show();
Scrollbar* activeScrollWidget = mShaderControlContainer[i].ScrollWidget;
// if ScrollWidget is NULL
if( activeScrollWidget == NULL )
{
// create ScrollWidget
mShaderControlContainer[i].ScrollWidget = activeScrollWidget =
(Scrollbar*)WindowManager::getSingleton().createWindow("TaharezLook/HorizontalScrollbar",
( ("UniformSB" + Ogre::StringConverter::toString(i)).c_str() ));
// add to Shader control window
controlWindow->addChildWindow( activeScrollWidget );
// set position based on its index
activeScrollWidget->setPosition(UVECTOR2(SCROLLWIDGET_XPOS, WIDGET_YSTART + WIDGET_YOFFSET * float(i)));
activeScrollWidget->setInheritsAlpha(false);
activeScrollWidget->setMaxSize( SCROLLWIDGET_SIZE );
activeScrollWidget->setMinSize( SCROLLWIDGET_SIZE );
activeScrollWidget->setSize( SCROLLWIDGET_SIZE );
activeScrollWidget->setID( static_cast<CEGUI::uint>(i) );
activeScrollWidget->setOverlapSize(0);
// wire up ScrollWidget position changed event to handleShaderControl
activeScrollWidget->subscribeEvent(Scrollbar::EventScrollPositionChanged, CEGUI::Event::Subscriber(&OceanDemo::handleShaderControl, this )); }
// set max value of ScrollWidget
float maxval = ActiveShaderDef.getRange();
activeScrollWidget->setDocumentSize(maxval);
activeScrollWidget->setPageSize(0.000);
activeScrollWidget->setStepSize(maxval/20);
// get current value of param
float uniformVal = 0.0;
switch(ActiveShaderDef.ValType)
{
case GPU_VERTEX:
case GPU_FRAGMENT:
{
Ogre::GpuProgramParametersSharedPtr activeParameters =
(ActiveShaderDef.ValType == Ogre::GPT_VERTEX_PROGRAM) ?
mActiveVertexParameters : mActiveFragmentParameters;
if(!activeParameters.isNull())
{
// use param name to get index : use appropiate paramters ptr
const Ogre::GpuConstantDefinition& def =
activeParameters->getConstantDefinition(ActiveShaderDef.ParamName);
ActiveShaderDef.PhysicalIndex = def.physicalIndex;
// use index to get RealConstantEntry
const float* pFloat = activeParameters->getFloatPointer(ActiveShaderDef.PhysicalIndex);
// set position of ScrollWidget as param value
uniformVal = pFloat[ActiveShaderDef.ElementIndex];
activeScrollWidget->setScrollPosition( ActiveShaderDef.convertParamToScrollPosition(uniformVal) );
}
}
break;
case MAT_SPECULAR:
{
// get the specular values from the material pass
Ogre::ColourValue OldSpec(mActivePass->getSpecular());
uniformVal = OldSpec[ActiveShaderDef.ElementIndex];
activeScrollWidget->setScrollPosition( ActiveShaderDef.convertParamToScrollPosition(uniformVal) );
}
break;
case MAT_DIFFUSE:
{
// get the diffuse values from the material pass
Ogre::ColourValue OldSpec(mActivePass->getDiffuse());
uniformVal = OldSpec[ActiveShaderDef.ElementIndex];
activeScrollWidget->setScrollPosition( ActiveShaderDef.convertParamToScrollPosition(uniformVal) );
}
break;
case MAT_AMBIENT:
{
// get the ambient values from the material pass
Ogre::ColourValue OldSpec(mActivePass->getAmbient());
uniformVal = OldSpec[ActiveShaderDef.ElementIndex];
activeScrollWidget->setScrollPosition( ActiveShaderDef.convertParamToScrollPosition(uniformVal) );
}
break;
case MAT_SHININESS:
{
// get the ambient values from the material pass
uniformVal = mActivePass->getShininess();
activeScrollWidget->setScrollPosition( ActiveShaderDef.convertParamToScrollPosition(uniformVal) );
}
break;
case MAT_EMISSIVE:
{
// get the ambient values from the material pass
//ColourValue OldSpec(mActivePass->gete());
//activeScrollWidget->setScrollPosition( OldSpec.val[ActiveShaderDef->ElementIndex] );
}
break;
}
setShaderControlVal( uniformVal, i );
activeScrollWidget->show();
} // end of iterate
}
// turn off extra GUI widgets
// iterate from 1 + active widgets to end
for( size_t i = activeControlCount; i < mShaderControlContainer.size(); i++ )
{
// hide widget
if( mShaderControlContainer[i].TextWidget != NULL )
{
mShaderControlContainer[i].TextWidget->hide();
}
if( mShaderControlContainer[i].NumberWidget != NULL )
{
mShaderControlContainer[i].NumberWidget->hide();
}
{
mShaderControlContainer[i].ScrollWidget->hide();
}
}// end of iterate
}
}
}
}
//--------------------------------------------------------------------------
bool OceanDemo::handleModelComboChanged(const CEGUI::EventArgs& e)//对选择mesh的处理
{
using namespace CEGUI;
// get the selected mesh filename from the combo box
CEGUI::ListboxItem* item = ((Combobox*)((const WindowEventArgs&)e).window)->getSelectedItem();//从下拉框中选择mesh名称
// convert from CEGUI::String to Ogre::String
Ogre::String meshName(item->getText().c_str());//字符串转换
// hide the current entity
if (mCurrentEntity)
{
mCurrentEntity->setVisible(false);
// disconnect the entity from the scenenode
mMainNode->detachObject(mCurrentEntity->getName());
}
// find the entity selected in combo box
// an exception is raised by getEntity if it doesn't exist
// so trap the exception if entity not found and load it
try
{
mCurrentEntity = mSceneMgr->getEntity( meshName );
}
catch (Ogre::Exception e)
// if not found create it
{
Ogre::MeshPtr pMesh = Ogre::MeshManager::getSingleton().load(meshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
//Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY,
//Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY,
//true, true
); //so we can still read it
// Build tangent vectors, all our meshes use only 1 texture coordset
//pMesh->buildTangentVectors(0, 1);
// Create entity
mCurrentEntity = mSceneMgr->createEntity(meshName, meshName);
}
// make the entity visible and attach it to our main scenenode
mCurrentEntity->setVisible(true);
mMainNode->attachObject(mCurrentEntity);
// set the the entity's material to the current material
//mCurrentEntity->setMaterialName(mMaterialControlsContainer[mCurrentMaterial].getMaterialName());
configureShaderControls();
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo::handleShaderComboChanged(const CEGUI::EventArgs& e)//阴影选择的处理
{
using namespace CEGUI;
CEGUI::ListboxItem* item = ((Combobox*)((const WindowEventArgs&)e).window)->getSelectedItem();
mCurrentMaterial = item->getID();
if (mOceanSurfaceEnt)
mOceanSurfaceEnt->setMaterialName(mMaterialControlsContainer[mCurrentMaterial].getMaterialName());
configureShaderControls();
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo::handleScrollControlsWindow(const CEGUI::EventArgs& e)//对各种滑动条的处理
{
using namespace CEGUI;
size_t controlCount = mShaderControlContainer.size();
float scrollval = ((Scrollbar*)((const WindowEventArgs&)e).window)->getScrollPosition();
for (size_t i = 0; i < controlCount; i++)
{
float ypos = WIDGET_YSTART + WIDGET_YOFFSET * float(i) - scrollval;
mShaderControlContainer[i].TextWidget->setPosition(UVECTOR2( TEXTWIDGET_XPOS, ypos + TEXTWIDGET_YADJUST));
mShaderControlContainer[i].NumberWidget->setPosition(UVECTOR2( NUMBERWIDGET_XPOS, ypos + TEXTWIDGET_YADJUST));
mShaderControlContainer[i].ScrollWidget->setPosition(UVECTOR2( SCROLLWIDGET_XPOS, ypos ));
}
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo::handleMovementTypeChange(const CEGUI::EventArgs& e)//单选按钮响应事件的处理
{
using namespace CEGUI;
CEGUI::uint id = ((RadioButton*)((const WindowEventArgs&)e).window)->getSelectedButtonInGroup()->getID();
if (id == 0)
{
mMouseMovement = mv_CAMERA;
}
else
{
mMouseMovement = mv_MODEL;
}
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo::handleErrorBox(const CEGUI::EventArgs& e)
{
CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"ErrorBox")->hide();
return true;
}
//--------------------------------------------------------------------------
void OceanDemo::createFrameListener(void)
{
mFrameListener= new OceanDemo_FrameListener(this);
mRoot->addFrameListener(mFrameListener);
}
/*************************************************************************
OceanDemo_FrameListener methods that handle all input for this GLSL demo.
*************************************************************************/
//处理所有的输入输出
OceanDemo_FrameListener::OceanDemo_FrameListener(OceanDemo* main)
: mMain(main)
, mStatsOn(true)
, mWriteToFile(false)
, mLastMousePositionSet(false)
, mSpinModel(true)
, mSpinLight(false)
, mMouse(0)
, mKeyboard(0)
, mLMBDown(false)
, mRMBDown(false)
, mProcessMovement(false)
, mUpdateMovement(false)
, mMoveFwd(false)
, mMoveBck(false)
, mMoveLeft(false)
, mMoveRight(false)
{
mRotateSpeed = 0;
mMoveSpeed = 100;
mNumScreenShots = 0;
mTimeUntilNextToggle = 0;
mSceneDetailIndex = 0;
mMoveScale = 0.0f;
mSpeed = MINSPEED;
mRotX = 0;
mRotY = 0;
mRotScale = 0.0f;
mTranslateVector = Ogre::Vector3::ZERO;
mAniso = 1;
mFiltering = Ogre::TFO_BILINEAR;
mAvgFrameTime = 0.1;
// using buffered input
OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;
mMain->getRenderWindow()->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
mInputManager = OIS::InputManager::createInputSystem( pl );
//Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
unsigned int width, height, depth;
int left, top;
mMain->getRenderWindow()->getMetrics(width, height, depth, left, top);
//Set Mouse Region.. if window resizes, we should alter this to reflect as well
const OIS::MouseState &ms = mMouse->getMouseState();
ms.width = width;
ms.height = height;
mMouse->setEventCallback(this);//对鼠标的监听
mKeyboard->setEventCallback(this);//对键盘的监听
mQuit = false;
mSkipCount = 0;
mUpdateFreq = 50;
mGuiRenderer = CEGUI::System::getSingleton().getRenderer();
mGuiAvg = CEGUI::WindowManager::getSingleton().getWindow("OPAverageFPS");
mGuiCurr = CEGUI::WindowManager::getSingleton().getWindow("OPCurrentFPS");
mGuiBest = CEGUI::WindowManager::getSingleton().getWindow("OPBestFPS");
mGuiWorst = CEGUI::WindowManager::getSingleton().getWindow("OPWorstFPS");
mGuiTris = CEGUI::WindowManager::getSingleton().getWindow("OPTriCount");
mGuiDbg = CEGUI::WindowManager::getSingleton().getWindow("OPDebugMsg");
mRoot = CEGUI::WindowManager::getSingleton().getWindow("root");
}
//--------------------------------------------------------------------------
OceanDemo_FrameListener::~OceanDemo_FrameListener()
{
if(mInputManager)
{
mInputManager->destroyInputObject(mMouse);
mInputManager->destroyInputObject(mKeyboard);
OIS::InputManager::destroyInputSystem(mInputManager);
mInputManager = 0;
}
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::frameStarted(const Ogre::FrameEvent& evt)
{
mMouse->capture();
mKeyboard->capture();
if (mQuit)
return false;
else
{
mSkipCount++;
if (mSkipCount >= mUpdateFreq)
{
mSkipCount = 0;
updateStats();
}
// update movement process
if(mProcessMovement || mUpdateMovement)
{
mTranslateVector.x += mMoveLeft ? mAvgFrameTime * -MOVESPEED : 0;
mTranslateVector.x += mMoveRight ? mAvgFrameTime * MOVESPEED : 0;
mTranslateVector.z += mMoveFwd ? mAvgFrameTime * -MOVESPEED : 0;
mTranslateVector.z += mMoveBck ? mAvgFrameTime * MOVESPEED : 0;
switch(mMain->getMouseMovement())
{
case mv_CAMERA:
mMain->getCamera()->yaw(Ogre::Angle(mRotX));
mMain->getCamera()->pitch(Ogre::Angle(mRotY));
mMain->getCamera()->moveRelative(mTranslateVector);
break;
case mv_MODEL:
mMain->getMainNode()->yaw(Ogre::Angle(mRotX));
//mMain->getMainNode()->pitch(mRotY);
mMain->getMainNode()->translate(mTranslateVector);
break;
default:
break;
}
mUpdateMovement = false;
mRotX = 0;
mRotY = 0;
mTranslateVector = Ogre::Vector3::ZERO;
}
if(mSpinModel)
{
mRotateSpeed = mAvgFrameTime * 20;
mMain->getMainNode()->yaw( Ogre::Angle(mRotateSpeed) );
}
if(mSpinLight)
{
mLightPivots[0]->rotate(mLightRotationAxes[0], Ogre::Angle(mRotateSpeed * 2.0f));
}
if(mWriteToFile)
{
char tmp[20];
sprintf(tmp, "frame_%d.png", ++mNumScreenShots);
mMain->getRenderWindow()->writeContentsToFile(tmp);
}
return true;
}
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::mouseMoved (const OIS::MouseEvent &e)
{
CEGUI::System::getSingleton().injectMouseMove( e.state.X.rel, e.state.Y.rel );
CEGUI::System::getSingleton().injectMouseWheelChange(e.state.Z.rel);
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::keyPressed (const OIS::KeyEvent &e)
{
// give 'quitting' priority
if (e.key == OIS::KC_ESCAPE)
{
mQuit = true;
return false;
}
if (e.key == OIS::KC_SYSRQ )
{
std::ostringstream ss;
ss << "screenshot_" << ++mNumScreenShots << ".png";
mMain->getRenderWindow()->writeContentsToFile(ss.str());
//mTimeUntilNextToggle = 0.5;
mDebugText = "Saved: " + ss.str();
}
// do event injection
CEGUI::System& cegui = CEGUI::System::getSingleton();
cegui.injectKeyDown(e.key);
cegui.injectChar(e.text);
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::keyReleased (const OIS::KeyEvent &e)
{
CEGUI::System::getSingleton().injectKeyUp(e.key);
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
CEGUI::System::getSingleton().injectMouseButtonDown(convertOISButtonToCegui(id));
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::mouseReleased (const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
CEGUI::System::getSingleton().injectMouseButtonUp(convertOISButtonToCegui(id));
return true;
}
//--------------------------------------------------------------------------
CEGUI::MouseButton OceanDemo_FrameListener::convertOISButtonToCegui(int ois_button_id)
{
switch (ois_button_id)
{
case 0: return CEGUI::LeftButton;
case 1: return CEGUI::RightButton;
case 2: return CEGUI::MiddleButton;
case 3: return CEGUI::X1Button;
default: return CEGUI::LeftButton;
}
}
//--------------------------------------------------------------------------
void OceanDemo_FrameListener::updateStats(void)
{
static CEGUI::String currFps = "Current FPS: ";
static CEGUI::String avgFps = "Average FPS: ";
static CEGUI::String bestFps = "Best FPS: ";
static CEGUI::String worstFps = "Worst FPS: ";
static CEGUI::String tris = "Triangle Count: ";
const Ogre::RenderTarget::FrameStats& stats = mMain->getRenderWindow()->getStatistics();
mGuiAvg->setText(avgFps + Ogre::StringConverter::toString(stats.avgFPS));
mGuiCurr->setText(currFps + Ogre::StringConverter::toString(stats.lastFPS));
mGuiBest->setText(bestFps + Ogre::StringConverter::toString(stats.bestFPS)
+ " " + Ogre::StringConverter::toString(stats.bestFrameTime)+" ms");
mGuiWorst->setText(worstFps + Ogre::StringConverter::toString(stats.worstFPS)
+ " " + Ogre::StringConverter::toString(stats.worstFrameTime)+" ms");
mGuiTris->setText(tris + Ogre::StringConverter::toString(stats.triangleCount));
mGuiDbg->setText(mDebugText);
mAvgFrameTime = 1.0f/(stats.avgFPS + 1.0f);
if (mAvgFrameTime > 0.1f) mAvgFrameTime = 0.1f;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleMouseMove(const CEGUI::EventArgs& e)//对鼠标移动的处理
{
using namespace CEGUI;
if( mLMBDown && !mRMBDown)//单击鼠标左键
{
// rotate camera
//摄像机旋转的处理
mRotX += -((const MouseEventArgs&)e).moveDelta.d_x * mAvgFrameTime * 10.0;
mRotY += -((const MouseEventArgs&)e).moveDelta.d_y * mAvgFrameTime * 10.0;
MouseCursor::getSingleton().setPosition( mLastMousePosition );
mUpdateMovement = true;
}
else
{
if( mRMBDown && !mLMBDown)//单击鼠标右键
{
// translate camera
//摄像机移动的处理
mTranslateVector.x += ((const MouseEventArgs&)e).moveDelta.d_x * mAvgFrameTime * MOVESPEED;
mTranslateVector.y += -((const MouseEventArgs&)e).moveDelta.d_y * mAvgFrameTime * MOVESPEED;
//mTranslateVector.z = 0;
MouseCursor::getSingleton().setPosition( mLastMousePosition );
mUpdateMovement = true;
}
else
{
if( mRMBDown && mLMBDown)//双键同时按下的处理
{
mTranslateVector.z += (((const MouseEventArgs&)e).moveDelta.d_x + ((const MouseEventArgs&)e).moveDelta.d_y) * mAvgFrameTime * MOVESPEED;
MouseCursor::getSingleton().setPosition( mLastMousePosition );
mUpdateMovement = true;
}
}
}
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleMouseButtonUp(const CEGUI::EventArgs& e)//左右键响应的处理
{
using namespace CEGUI;
//Window* wndw = ((const WindowEventArgs&)e).window;
if( ((const MouseEventArgs&)e).button == LeftButton )
{
mLMBDown = false;
}
if( ((const MouseEventArgs&)e).button == RightButton )
{
mRMBDown = false;
}
if( !mLMBDown && !mRMBDown )
{
MouseCursor::getSingleton().show();
if(mLastMousePositionSet)
{
MouseCursor::getSingleton().setPosition( mLastMousePosition );
mLastMousePositionSet = false;
}
mRoot->releaseInput();
}
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleMouseButtonDown(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
//Window* wndw = ((const WindowEventArgs&)e).window;
if( ((const MouseEventArgs&)e).button == LeftButton )
{
mLMBDown = true;
}
if( ((const MouseEventArgs&)e).button == RightButton )
{
mRMBDown = true;
}
if( mLMBDown || mRMBDown )
{
MouseCursor::getSingleton().hide();
if (!mLastMousePositionSet)
{
mLastMousePosition = MouseCursor::getSingleton().getPosition();
mLastMousePositionSet = true;
}
mRoot->captureInput();
}
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleMouseWheelEvent(const CEGUI::EventArgs& e)//鼠标滑轮的处理
{
using namespace CEGUI;
mTranslateVector.z += ((const MouseEventArgs&)e).wheelChange * -5.0;
mUpdateMovement = true;
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleKeyDownEvent(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
CheckMovementKeys( ((const KeyEventArgs&)e).scancode , true);
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handleKeyUpEvent(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
CheckMovementKeys( ((const KeyEventArgs&)e).scancode, false );
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handelModelSpinChange(const CEGUI::EventArgs& e)
{
using namespace CEGUI;
mSpinModel = ((Checkbox*)((const WindowEventArgs&)e).window)->isSelected();
return true;
}
//--------------------------------------------------------------------------
bool OceanDemo_FrameListener::handelLightSpinChange(const CEGUI::EventArgs& e)//灯光选择的处理
{
using namespace CEGUI;
mSpinLight = ((Checkbox*)((const WindowEventArgs&)e).window)->isSelected();
return true;
}
//--------------------------------------------------------------------------
void OceanDemo_FrameListener::CheckMovementKeys( CEGUI::Key::Scan scancode, bool state )//按键响应的处理
{
using namespace CEGUI;
switch ( scancode )
{
case Key::A:
mMoveLeft = state;
break;
case Key::D:
mMoveRight = state;
break;
case Key::S:
mMoveBck = state;
break;
case Key::W:
mMoveFwd = state;
break;
default:
break;
}
mProcessMovement = mMoveLeft || mMoveRight || mMoveFwd || mMoveBck;
}