三个Entity的material所在文件
ogrenew\Samples\Media\materials\scripts\Example.material
// 铁效果的
material Examples/TextureEffect1
{
    technique
    {
        pass
        {
            ambient 0.75 0.75 0.75
            cull_hardware none
            cull_software none
            texture_unit
            {
                texture BumpyMetal.jpg
                rotate_anim 0.2
                wave_xform scale_x sine 1 0.1 0 5
                wave_xform scale_y sine 0.5 0.2 0.5 3
            }
        }
    }
}
// 绳结
material Examples/TextureEffect2
{
    technique
    {
        pass
        {
            texture_unit
            {
                texture Water02.jpg
                scroll_anim 0.5 0
            }
        }
    }
}
// 水平面
material Examples/TextureEffect3
{
    technique
    {
        pass
        {
            ambient 0.7 0.7 0.7
            cull_hardware none
            cull_software none
            texture_unit
            {
                texture Water01.jpg
                scroll_anim -0.25 0.1
            }
            texture_unit
            {
                texture Water01.jpg
                colour_op_ex add src_texture src_current
                colour_op_multipass_fallback one one
                scroll_anim -0.1 0.25
            }
        }
    }
}
截图:
 ogrenew\Samples\Media\materials\textures\BumpyMetal.jpg
ogrenew\Samples\Media\materials\textures\BumpyMetal.jpg 如下:
 
/**
    \file 
        TextureFX.h
    \brief
        Shows OGRE's ability to handle different types of texture effects.
*/
#include "ExampleApplication.h"
class TextureEffectsApplication : public ExampleApplication
{
public:
    TextureEffectsApplication() {}
protected:
    void createScalingPlane()
    {
        // Set up a material for the plane
        // Create a prefab plane
        Entity *planeEnt = mSceneMgr->createEntity("Plane", SceneManager::PT_PLANE);
        // Give the plane a texture
        planeEnt->setMaterialName("Examples/TextureEffect1");
        SceneNode* node = 
            mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-250,-40,-100));
        node->attachObject(planeEnt);
    }
    void createScrollingKnot()
    {
        Entity *ent = mSceneMgr->createEntity("knot", "knot.mesh");
        ent->setMaterialName("Examples/TextureEffect2");
        // Add entity to the root scene node
        SceneNode* node = 
            mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(200,50,150));
        node->attachObject(ent);
    }
    void createWateryPlane()
    {
        // Create a prefab plane
        Entity *planeEnt = mSceneMgr->createEntity("WaterPlane", SceneManager::PT_PLANE);
        // Give the plane a texture
        planeEnt->setMaterialName("Examples/TextureEffect3");
        mSceneMgr->getRootSceneNode()->attachObject(planeEnt);
    }
    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Set ambient light
        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
        // Create a point light
        Light* l = mSceneMgr->createLight("MainLight");
        // Accept default settings: point light, white diffuse, just set position
        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
        //  other objects, but I don't
        l->setPosition(20,80,50);
        createScalingPlane();
        createScrollingKnot();
        createWateryPlane();
        // Set up a material for the skydome
        MaterialPtr skyMat = MaterialManager::getSingleton().create("SkyMat",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        // Perform no dynamic lighting on the sky
        skyMat->setLightingEnabled(false);
        // Use a cloudy sky
        TextureUnitState* t = skyMat->getTechnique(0)->getPass(0)->createTextureUnitState("clouds.jpg");
        // Scroll the clouds
        t->setScrollAnimation(0.15, 0);
        // System will automatically set no depth write
        // Create a skydome
        mSceneMgr->setSkyDome(true, "SkyMat", -5, 2);
    }
};
提出问题,然后解决问题!解决的问题多了看OGRE就很通透了!吼吼!Q:
渲染流程是怎样?A:一图解千言!看图吧!    

Q:
ViewPort到底是什么?有些地图编辑器里面有几个渲染小窗口,比如像3D Max那种四个视图,这四个视图是什么?四个ViewPort?A:
   /** An abstraction of a viewport, i.e. a rendering region on a render
        target.
        @remarks
            A viewport is the meeting of a camera and a rendering surface -
            the camera renders the scene from a viewpoint, and places its
            results into some subset of a rendering target, which may be the
            whole surface or just a part of the surface. Each viewport has a
            single camera as source and a single target as destination. A
            camera only has 1 viewport, but a render target may have several.
            A viewport also has a Z-order, i.e. if there is more than one
            viewport on a single render target and they overlap, one must
            obscure the other in some predetermined way.
    */
    class _OgreExport Viewport
    说得再明白也不如改改代码看效果来得直接易懂,看效果    

    爽吧!哈哈!
    改动的代码(红色的部分):
    ExampleApplicaton.h里面的话就是所有的Demo都变成4个ViewPort,所以最好在自己的Demo里面override这个成员函数,这样子就只有这一个demo是4个ViewPort。
    virtual void createViewports(void)
    {
        // Create one viewport, entire window
        Viewport* vp = mWindow->addViewport(mCamera, 0, 0.5f, 0.0f, 0.5f, 0.5f);
        vp->setBackgroundColour(ColourValue(0,0,0));
        
        mWindow->addViewport(mCamera, 2, 0.0f, 0.0f, 0.5f, 0.5f);
        mWindow->addViewport(mCamera, 3, 0.0f, 0.5f, 0.5f, 0.5f);
        mWindow->addViewport(mCamera, 4, 0.5f, 0.5f, 0.5f, 0.5f);
        // Alter the camera aspect ratio to match the viewport
        mCamera->setAspectRatio(
            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
    }
    我们继续YY!让每个ViewPort的Camera都不一样!也就是每个ViewPort里面看到的是不一样的(不同的观察方向等)!直观点说,就是放了多个摄像机在拍冠希柏芝,不同的角度而已!    

    改动的代码:
    virtual void createViewports(void)
    {
        // Create the first viewport
        Viewport* vp = mWindow->addViewport(mCamera, 0, 0.5f, 0.0f, 0.5f, 0.5f);
        vp->setBackgroundColour(ColourValue(0,0,0));
        // Alter the camera aspect ratio to match the viewport
        mCamera->setAspectRatio(
            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
        // Create the second viewport
        vp = mWindow->addViewport(mCamera1, 1, 0.0f, 0.0f, 0.5f, 0.5f);
        mCamera1->setAspectRatio(
            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
        // Create the third viewport
        vp = mWindow->addViewport(mCamera2, 2, 0.0f, 0.5f, 0.5f, 0.5f);
        mCamera2->setAspectRatio(
            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
        // Create the fourth viewport
        vp = mWindow->addViewport(mCamera3, 3, 0.5f, 0.5f, 0.5f, 0.5f);
        mCamera2->setAspectRatio(
            Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
    }
    virtual void createCamera(void)
    {
        // Create the first camera
        mCamera = mSceneMgr->createCamera("PlayerCam");
        // Position it at 500 in Z direction
        mCamera->setPosition(Vector3(0,0,500));
        // Look back along -Z
        mCamera->lookAt(Vector3(0,0,-300));
        mCamera->setNearClipDistance(5);
        // Create the second camera
        mCamera1 = mSceneMgr->createCamera("PlayerCam1");
        // Position it at 500 in Z direction
        mCamera1->setPosition(Vector3(0,100,500));
        // Look back along -Z
        mCamera1->lookAt(Vector3(0,100,-300));
        mCamera1->setNearClipDistance(5);
        // Create the third camera
        mCamera2 = mSceneMgr->createCamera("PlayerCam2");
        // Position it at 500 in Z direction
        mCamera2->setPosition(Vector3(0,-100,500));
        // Look back along -Z
        mCamera2->lookAt(Vector3(0,-100,-300));
        mCamera2->setNearClipDistance(5);
        // Create the fouth camera
        mCamera3 = mSceneMgr->createCamera("PlayerCam3");
        // Position it at 500 in Z direction
        mCamera3->setPosition(Vector3(100,0,500));
        // Look back along -Z
        mCamera3->lookAt(Vector3(100,0,-300));
        mCamera3->setNearClipDistance(5);
    }
       自己定义三个camera:   
private:
    Camera* mCamera1;
    Camera* mCamera2;
    Camera* mCamera3;
    上面的改动之后,只有第一象限的ViewPort里的摄像机能随鼠标动,我们来让其他三个ViewPort的摄像机也能随鼠标动。同时动,不是每个ViewPort单独动!
    virtual void createFrameListener(void)
    {
        mFrameListener  = new ExampleFrameListener(mWindow, mCamera);
        mFrameListener1 = new ExampleFrameListener(mWindow, mCamera1);
        mFrameListener2 = new ExampleFrameListener(mWindow, mCamera2);
        mFrameListener3 = new ExampleFrameListener(mWindow, mCamera3);
        mFrameListener->showDebugOverlay(true);
        mFrameListener1->showDebugOverlay(true);
        mFrameListener2->showDebugOverlay(true);
        mFrameListener3->showDebugOverlay(true);
        mRoot->addFrameListener(mFrameListener);
        mRoot->addFrameListener(mFrameListener1);
        mRoot->addFrameListener(mFrameListener2);
        mRoot->addFrameListener(mFrameListener3);
    }
    新加三个成员变量:
    ExampleFrameListener* mFrameListener1;
    ExampleFrameListener* mFrameListener2;
    ExampleFrameListener* mFrameListener3;
构造和析构:
    TextureEffectsApplication() 
        : mFrameListener1(0)
        , mFrameListener2(0)
        , mFrameListener3(0)
    {
        
    }
    ~TextureEffectsApplication()
    {
        if (mFrameListener1)
        {
            delete mFrameListener1;
        }
        if (mFrameListener2)
        {
            delete mFrameListener2;
        }
        if (mFrameListener3)
        {
            delete mFrameListener3;
        }
    }
    
    每个ViewPort里面不同的render mode可不可以不同呢?当然可以!
    
    这儿还用到CEGUI了,改动还挺多!
    添加了一个按钮RenderMode,点击时切换渲染模式。不过只能切换第一象限的,不能区分点击的是哪个象限的按钮!放四个按钮吧,分别控制四个象限。    

    界面配置文件
ogrenew\Samples\Media\gui\ogregui.lyl.layout:   
<?xml version="1.0" ?>
<GUILayout>
<Window Type="DefaultGUISheet" Name="root">
    <Window Type="DefaultGUISheet" Name="OgreGuiDemo">
        <Property Name="UnifiedSize" Value="{{0.25,0},{1,0}}" />
        <Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton0">
            <Property Name="UnifiedPosition" Value="{{0.0,0},{0.0,0}}" />
            <Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
            <Property Name="Text" Value="RenderMode0" />
        </Window>
        <Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton1">
            <Property Name="UnifiedPosition" Value="{{0.0,0},{0.05,0}}" />
            <Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
            <Property Name="Text" Value="RenderMode1" />
        </Window>
        <Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton2">
            <Property Name="UnifiedPosition" Value="{{0.0,0},{0.1,0}}" />
            <Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
            <Property Name="Text" Value="RenderMode2" />
        </Window>
        <Window Type="TaharezLook/Button" Name="OgreGuiDemo/RenderModeButton3">
            <Property Name="UnifiedPosition" Value="{{0.0,0},{0.15,0}}" />
            <Property Name="UnifiedSize" Value="{{0.8,0},{0.05,0}}" />
            <Property Name="Text" Value="RenderMode3" />
        </Window>
    </Window>
</Window>
</GUILayout>
        如何使用CEGUI?
       1.声明两个成员变量:      
    CEGUI::OgreCEGUIRenderer* mGUIRenderer;
    CEGUI::System* mGUISystem;
            2.创建实例,载入配置文件
        // setup GUI system
        mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, 
            Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
        mGUISystem = new CEGUI::System(mGUIRenderer);
        CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);
        // load scheme and set up defaults
        CEGUI::SchemeManager::getSingleton().loadScheme(
            (CEGUI::utf8*)"TaharezLookSkin.scheme");
        mGUISystem->setDefaultMouseCursor(
            (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
        mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");
        CEGUI::Window* sheet = 
            CEGUI::WindowManager::getSingleton().loadWindowLayout(
            (CEGUI::utf8*)"ogregui.lyl.layout"); 
        mGUISystem->setGUISheet(sheet);
             3.配置事件处理器
    void setupEventHandlers(void)
    {
        CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
        wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton0")
            ->subscribeEvent(
            CEGUI::PushButton::EventClicked, 
            CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode0, this));
        wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton1")
            ->subscribeEvent(
            CEGUI::PushButton::EventClicked, 
            CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode1, this));
        wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton2")
            ->subscribeEvent(
            CEGUI::PushButton::EventClicked, 
            CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode2, this));
        wmgr.getWindow((CEGUI::utf8*)"OgreGuiDemo/RenderModeButton3")
            ->subscribeEvent(
            CEGUI::PushButton::EventClicked, 
            CEGUI::Event::Subscriber(&TextureEffectsApplication::handleRenderMode3, this));
    }
        4.listener中把OIS的事件转成CEGUI的
    //----------------------------------------------------------------//
    bool mouseMoved( const OIS::MouseEvent &arg )
    {
        CEGUI::System::getSingleton().injectMouseMove( arg.state.X.rel, arg.state.Y.rel );
        return true;
    }
    //----------------------------------------------------------------//
    bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
    {
        CEGUI::System::getSingleton().injectMouseButtonDown(convertOISMouseButtonToCegui(id));
        return true;
    }
    //----------------------------------------------------------------//
    bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
    {
        CEGUI::System::getSingleton().injectMouseButtonUp(convertOISMouseButtonToCegui(id));
        return true;
    }
    //----------------------------------------------------------------//
    bool keyPressed( const OIS::KeyEvent &arg )
    {
        if( arg.key == OIS::KC_ESCAPE )
            mShutdownRequested = true;
        CEGUI::System::getSingleton().injectKeyDown( arg.key );
        CEGUI::System::getSingleton().injectChar( arg.text );
        return true;
    }
    //----------------------------------------------------------------//
    bool keyReleased( const OIS::KeyEvent &arg )
    {
        CEGUI::System::getSingleton().injectKeyUp( arg.key );
        return true;
    }
Q:
material文件是如何解析的?A:还是看调用堆栈好了   

Q:
material文件中各个参数都是他妈的干什么鸟用的,为什么这么简单的几个参数一调就搞出这么牛B的效果?A: 嗯,这个就要查下 
 每天花30分钟看OGRE--(8) 《Pro OGRE 3D Programming》 Appendix B : Script Attribute Reference
   material technique pass都有一堆参数,这个要慢慢领会!                       
	
posted on 2008-04-22 22:12 
七星重剑 阅读(4157) 
评论(5)  编辑 收藏 引用  所属分类: 
Game Graphics 、
OGRE