ogre 学习笔记 - Day 5
通过前几天的学习,已经可以对sample进行分析了。
class SdkSample : public Sample
class Sample : public InputListener, public TrayListener, public Ogre::GeneralAllocatedObject
// GeneralAllocatedObject 内存分配对象,用来指定内存分配器
-
class sample
/*----------------------------------------------------------------------------- | Tests to see if target machine meets any special requirements of | this sample. Signal a failure by throwing an exception. -----------------------------------------------------------------------------*/ virtual void testCapabilities(const Ogre::RenderSystemCapabilities* caps) {}
测试是否支持特性,测试失败时抛出异常。
void requireMaterial(const Ogre::String& name) { Ogre::StringStream err; err << "Material: " << name << " "; auto mat = Ogre::MaterialManager::getSingleton().getByName(name); if(!mat) { err << "not found"; OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, err.str()); } mat->load(); if (mat->getSupportedTechniques().empty()) { err << mat->getUnsupportedTechniquesExplanation(); OGRE_EXCEPT(Ogre::Exception::ERR_NOT_IMPLEMENTED, err.str()); } }
加载需要的材质,失败时抛出异常
virtual Ogre::StringVector getRequiredPlugins() { return Ogre::StringVector(); }
获取需要的插件
void _setupTrays(Ogre::RenderWindow* window) { mTrayMgr.reset(new TrayManager("SampleControls", window, this)); // create a tray interface // show stats and logo and hide the cursor mTrayMgr->showFrameStats(TL_BOTTOMLEFT); mTrayMgr->showLogo(TL_BOTTOMRIGHT); mTrayMgr->hideCursor(); }
启用UI
virtual void _setup(Ogre::RenderWindow* window, Ogre::FileSystemLayer* fsLayer, Ogre::OverlaySystem* overlaySys) { // ... }
设置sample
virtual void _shutdown() { // ... }
关闭 sample
-----------------------------------------------------------------------------*/ virtual void createSceneManager() { mSceneMgr = Ogre::Root::getSingleton().createSceneManager(); #ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM mShaderGenerator->addSceneManager(mSceneMgr); auto mainRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME); // reset global light state mainRenderState->setLightCount(Ogre::Vector3i(0)); mainRenderState->setLightCountAutoUpdate(true); #endif if(mOverlaySystem) mSceneMgr->addRenderQueueListener(mOverlaySystem); }
创建默认场景
突然冒出个 mShaderGenerator,找找哪里设置的void setShaderGenerator(Ogre::RTShader::ShaderGenerator* shaderGenerator) { mShaderGenerator = shaderGenerator; }
setShaderGenerator 函数在 class sample里并没有调用?
createSceneManager 在 _setup 函数里 调用,所以在子类中需要主动在 _setup之前调用!
这个操作设定有点迷。而且mShaderGenerator并没有判断null值,必须调用。作为一个sample就不深究了。出现一个新的东西
auto mainRenderState = mShaderGenerator->getRenderState(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
RenderState 场景中渲染状态,灯光信息等
SubRenderState 渲染管线的渲染状态
-
class SdkSample
virtual void saveState(Ogre::NameValuePairList& state)
{
if (mCameraMan->getStyle() == CS_FREELOOK)
{
state["CameraPosition"] = Ogre::StringConverter::toString(mCameraNode->getPosition());
state["CameraOrientation"] = Ogre::StringConverter::toString(mCameraNode->getOrientation());
}
}
保存状态
virtual void restoreState(Ogre::NameValuePairList& state)
{
if (state.find("CameraPosition") != state.end() && state.find("CameraOrientation") != state.end())
{
mCameraMan->setStyle(CS_FREELOOK);
mCameraNode->setPosition(Ogre::StringConverter::parseVector3(state["CameraPosition"]));
mCameraNode->setOrientation(Ogre::StringConverter::parseQuaternion(state["CameraOrientation"]));
}
}
恢复状态
mCameraMan->setStyle(CS_FREELOOK);
用来控制 camera如何移动
enum CameraStyle /// enumerator values for different styles of camera movement
{
CS_FREELOOK,
CS_ORBIT,
CS_MANUAL
};
bool CameraMan::keyPressed(const KeyboardEvent &evt)
{
if (mStyle == CS_FREELOOK)
{
Keycode key = evt.keysym.sym;
if (key == 'w' || key == SDLK_UP) mGoingForward = true;
else if (key == 's' || key == SDLK_DOWN) mGoingBack = true;
else if (key == 'a' || key == SDLK_LEFT) mGoingLeft = true;
else if (key == 'd' || key == SDLK_RIGHT) mGoingRight = true;
else if (key == SDLK_PAGEUP) mGoingUp = true;
else if (key == SDLK_PAGEDOWN) mGoingDown = true;
else if (key == SDLK_LSHIFT) mFastMove = true;
}
return InputListener::keyPressed(evt);
}
bool CameraMan::keyReleased(const KeyboardEvent &evt)
{
if (mStyle == CS_FREELOOK)
{
Keycode key = evt.keysym.sym;
if (key == 'w' || key == SDLK_UP) mGoingForward = false;
else if (key == 's' || key == SDLK_DOWN) mGoingBack = false;
else if (key == 'a' || key == SDLK_LEFT) mGoingLeft = false;
else if (key == 'd' || key == SDLK_RIGHT) mGoingRight = false;
else if (key == SDLK_PAGEUP) mGoingUp = false;
else if (key == SDLK_PAGEDOWN) mGoingDown = false;
else if (key == SDLK_LSHIFT) mFastMove = false;
}
return InputListener::keyReleased(evt);
}
特定的相机移动功能,不深究
virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt)
{
if(!mTrayMgr) return true;
mTrayMgr->frameRendered(evt);
mControls->frameRendered(evt);
if (!mTrayMgr->isDialogVisible())
{
mCameraMan->frameRendered(evt); // if dialog isn't up, then update the camera
}
return true;
}
virtual bool mouseReleased(const MouseButtonEvent& evt)
{
}
事件响应
virtual void _shutdown()
{
// ...
// restore settings we may have changed, so as not to affect other samples
Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_BILINEAR);
Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(1);
}
MaterialManager::setDefaultXXX 设置默认属性
void addTextureDebugOverlay(TrayLocation loc, const Ogre::TexturePtr& tex, size_t i)
{
using namespace Ogre;
// Create material
String matName = "Ogre/DebugTexture" + StringConverter::toString(i);
MaterialPtr debugMat = MaterialManager::getSingleton().getByName(
matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (!debugMat)
{
debugMat = MaterialManager::getSingleton().create(matName,
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
}
Pass* p = debugMat->getTechnique(0)->getPass(0);
p->removeAllTextureUnitStates();
p->setLightingEnabled(false);
TextureUnitState *t = p->createTextureUnitState(tex->getName());
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
// create template
if (!OverlayManager::getSingleton().hasOverlayElement("Ogre/DebugTexOverlay", true))
{
OverlayElement* e = OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexOverlay", true);
e->setMetricsMode(GMM_PIXELS);
e->setWidth(128);
e->setHeight(128);
}
// add widget
String widgetName = "DebugTex"+ StringConverter::toString(i);
Widget* w = mTrayMgr->getWidget(widgetName);
if (!w)
{
w = mTrayMgr->createDecorWidget(loc, widgetName, "Ogre/DebugTexOverlay");
}
w->getOverlayElement()->setMaterial(debugMat);
}
添加纹理debug层,想看看效果,下断点,全局搜索,发现竟然没有调用过。
这里面提到了
MaterialManager::getSingleton().create
debugMat->getTechnique(0)->getPass(0);
既然没有调用,看看就好。
到这里,sample的基类大致看过了一遍。好像没有什么需要特别关注的。
然后,可以具体看每一个sample了。
SampleBrowser
运行sample Brower,看看每个sample的介绍。看完好像也不能得到哪个简单,不知道应该从哪个开始看起。
包括之前没有HelloWorld,Tutoral没有加入工程的吐槽。要想学好,还是得花点精力去捋一捋的。