ogre 学习笔记 - Day 5

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没有加入工程的吐槽。要想学好,还是得花点精力去捋一捋的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值