• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            的筆記

            隨時隨地編輯

            CEGUI筆記

            開發環境:
            CEGUI 0.74,OGRE 1.72

            教程:
            CEGUI and Ogre
            http://www.ogre3d.org/tikiwiki/tiki-print.php?page_ref_id=262&page=Basic%20Tutorial%207#Initializing_CEGUI

            The Beginners Guide to Getting CEGUI Rendering
            http://www.cegui.org.uk/api_reference/rendering_tutorial.html

            CEGUI使用的基本三步驟

            1. 創建CEGUI::Renderer對象.
            2. 創建CEGUI::System 對象(passing in the renderer created above).
            3. 在幀循環中調用CEGUI::System::renderGUI function to perform the rendering.

             

            創建CEGUI::Renderer對象

            為了創建CEGUI::Renderer對象,有兩條路可以走:簡單的和難的。

            A.簡單:bootstrapSystem快速創建。這種方式同時創建了renderer和system

            CEGUI::OgreRenderer& myRenderer = CEGUI::OgreRenderer::bootstrapSystem();

                booststrapSystem代碼

            OgreRenderer& OgreRenderer::bootstrapSystem()
            {
                
            if (System::getSingletonPtr())
                    CEGUI_THROW(InvalidRequestException(
            "OgreRenderer::bootstrapSystem: "
                        
            "CEGUI::System object is already initialised."));

                OgreRenderer
            & renderer = create();
                OgreResourceProvider
            & rp = createOgreResourceProvider();
                OgreImageCodec
            & ic = createOgreImageCodec();
                System::create(renderer, 
            &rp, static_cast<XMLParser*>(0), &ic);

                
            return renderer;
            }


            B.復雜:手動創建
            如果不想使用bootstrapSystem創建對象,你可以手動創建。注意:如果已經使用了bootstrapSystem,則不能再手動創建。手動創建需要創建renderer和system。
            1.創建CEGUI::Renderer對象

            // Create an OgreRenderer object that uses the default Ogre rendering
            // window as the default output surface.
            CEGUI::OgreRenderer& myRenderer = CEGUI::OgreRenderer::create();

            2.創建CEGUI::System

            CEGUI::System::create( myRenderer );

                system源碼:

            System& System::create(Renderer& renderer, ResourceProvider* resourceProvider,
                                   XMLParser
            * xmlParser, ImageCodec* imageCodec,
                                   ScriptModule
            * scriptModule, const String& configFile,
                                   
            const String& logFile)
            {
                
            return *new System(renderer, resourceProvider, xmlParser, imageCodec,
                                   scriptModule, configFile, logFile);
            }

                可以發現system的創建函數就是完成system的構造。構造函數的第2個參數開始都帶默認參數。

              - 刪除Renderer

            CEGUI::OgreRenderer::destroySystem();


             - 取回Renderer
            CEGUI::Renderer中竟然沒有取回renderer的方法!跟蹤代碼后發現只有system唯一一處保存了renderer。那么當然的就可以這樣取回renderer了:

            CEGUI::System &sys = CEGUI::System::getSingleton();
            CEGUI::Renderer
            * ceguiRenderer = sys.getRenderer(void);


             

            渲染CEGUIUI

            不同的渲染引擎方式都不一樣,一般就是在幀渲染中調用渲染方法:

            System::getSingleton().renderGUI();

            但是在Ogre中,CEGUI很巧妙的避免在幀渲染中手動添加代碼,使用了監聽者處理CEGUI渲染:

             1//! call stack
             2CEGUIOgreRenderer_d.dll!CEGUI::OgreGUIFrameListener::frameRenderingQueued
             3OgreMain_d.dll!Ogre::Root::_fireFrameRenderingQueued
             4OgreMain_d.dll!Ogre::Root::_fireFrameRenderingQueued
             5OgreMain_d.dll!Ogre::Root::_updateAllRenderTargets
             6OgreMain_d.dll!Ogre::Root::renderOneFrame
             7OgreMain_d.dll!Ogre::Root::startRendering
             8
             9//!source code
            10bool OgreGUIFrameListener::frameRenderingQueued(const Ogre::FrameEvent&)
            11{
            12    if (d_enabled)
            13        System::getSingleton().renderGUI();
            14
            15    return true;
            16}


            那么cegui的幀監聽者是如何創建的呢?
            首先這個監聽者是個靜態對象,并且是用了全局唯一的方式聲明。好像和單間模式的作用差不多。也許是作者的個人習慣吧。

            // Internal Ogre::FrameListener based class.  This is how we noew hook into the
            // rendering process (as opposed to render queues previously)
            static class OgreGUIFrameListener : public Ogre::FrameListener
            {
            public:
                OgreGUIFrameListener();

                
            void setCEGUIRenderEnabled(bool enabled);
                
            bool isCEGUIRenderEnabled() const;

                
            bool frameRenderingQueued(const Ogre::FrameEvent& evt);

            private:
                
            bool d_enabled;

            }
             S_frameListener;


            其次這個監聽者是在bootstrapSystem中創建的,正好是在OgreRenderer創建的同時創建

            //! call stack
            CEGUIOgreRenderer_d.dll!CEGUI::OgreRenderer::constructor_impl
            CEGUIOgreRenderer_d.dll
            !CEGUI::OgreRenderer::OgreRenderer
            CEGUIOgreRenderer_d.dll
            !CEGUI::OgreRenderer::create
            CEGUIOgreRenderer_d.dll
            !CEGUI::OgreRenderer::bootstrapSystem

            //! source code
            void OgreRenderer::constructor_impl(Ogre::RenderTarget& target)
            {
                d_renderSystem 
            = d_ogreRoot->getRenderSystem();

                d_displaySize.d_width  
            = target.getWidth();
                d_displaySize.d_height 
            = target.getHeight();

                
            // create default target & rendering root (surface) that uses it
                d_defaultTarget = new OgreWindowTarget(*this*d_renderSystem, target);
                d_defaultRoot 
            = new RenderingRoot(*d_defaultTarget);

                
            // hook into the rendering process
                d_ogreRoot->addFrameListener(&S_frameListener);
            }

                至此cegui的幀渲染水落石出。



            注入按鍵事件

            CEGUI::System &sys = CEGUI::System::getSingleton();

             
            //!按下 ,同事需要注入字符,以便于處理非英語國家的utf8字符
            sys.injectK;
            sys.injectChar(arg.text);

            //! 按鍵彈起
            CEGUI::System::getSingleton().injectKeyUp(arg.key);

             


            注入鼠標事件

             code:

            CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));

            CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));

            CEGUI::System 
            &sys = CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);

            CEGUI::MouseButton convertButton(OIS::MouseButtonID buttonID)
            {
                
            switch (buttonID)
                
            {
                
            case OIS::MB_Left:
                    
            return CEGUI::LeftButton;
                
            case OIS::MB_Right:
                    
            return CEGUI::RightButto  case OIS::MB_Middle:
                    
            return CEGUI::MiddleButton;
                
            default:
                    
            return CEGUI::LeftButton;
                }

            }

             

             

            加載CEGUI編輯器產生的窗口

            code:
            CEGUI::Window *guiRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout("TextDemo.layout"); 
            CEGUI::System::getSingleton().setGUISheet(guiRoot);

             

            手動創建CEGUI窗口對象

            code:
            //! 必須使用框架提供的管理器,窗口必須作為sheet的子窗口出現
            CEGUI::WindowManager &wmgr = CEGUI::WindowManager::getSingleton();
            CEGUI::Window 
            *sheet = wmgr.createWindow("DefaultWindow""CEGUIDemo/Sheet");

            //! 創建一個窗口,此時并未接入sheet作為子窗口,所以并未展現
            CEGUI::Window *quit = wmgr.createWindow("TaharezLook/Button""CEGUIDemo/QuitButton");
            quit
            ->setText("Quit");
            quit
            ->setSize(CEGUI::UVector2(CEGUI::UDim(0.150), CEGUI::UDim(0.050)));


            //! 窗口加入sheet以便展現
            sheet->addChildWindow(quit);
            CEGUI::System::getSingleton().setGUISheet(sheet);

            //! 以上創建的是一個按鈕,名字為“Quit”,為了響應按鈕按下消息,需要在框架中注冊監聽消息,鏈接監聽回調
            quit->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&BasicTutorial7::quit, this));

             

            渲染到紋理、畫中畫效果

            code:
            //! 創建自定義紋理對象
            Ogre::TexturePtr tex = mRoot->getTextureManager()->createManual(
                
            "RTT",
                Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                Ogre::TEX_TYPE_2D,
                
            512,
                
            512,
                
            0,
                Ogre::PF_R8G8B8,
                Ogre::TU_RENDERTARGET);
            Ogre::RenderTexture 
            *rtex = tex->getBuffer()->getRenderTarget();

            //! 創建一個新的照相機和視口,記得關閉視口的一些特性例如Overlays,否則我們創建的CEGUI窗口和OGRE會出現重疊
            Ogre::Camera *cam = mSceneMgr->createCamera("RTTCam");
            cam
            ->setPosition(100-100-400);
            cam
            ->lookAt(00-300);
            Ogre::Viewport 
            *= rtex->addViewport(cam);
            v
            ->setOverlaysEnabled(false);
            v
            ->setClearEveryFrame(true);
            v
            ->setBackgroundColour(Ogre::ColourValue::Black);

            //! 從CEGUI引導對象創建CEGUI紋理
            //! mRenderer(類型為CEGUI::OgreRenderer*)正是第一部創建的CEGUI引導對象,
            CEGUI::Texture &guiTex = mRenderer->createTexture(tex);

            //! 創建CEGUI圖像對象集。注意:與CEGUI窗口對象需要在窗口對象集(sheet)的管理下使用類似,圖像對象也需要在圖像對象集的管理下使用
            CEGUI::Imageset &imageSet =
              CEGUI::ImagesetManager::getSingleton().create(
            "RTTImageset", guiTex);
            imageSet.defineImage(
            "RTTImage",
                                 CEGUI::Point(
            0.0f0.0f),
                                 CEGUI::Size(guiTex.getSize().d_width,
                                             guiTex.getSize().d_height),
                                 CEGUI::Point(
            0.0f0.0f));

            //! 創建CEGUI窗口,之前已經介紹過,這里和它沒有區別
            CEGUI::Window *si = CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/StaticImage""RTTWindow");
            si
            ->setSize(CEGUI::UVector2(CEGUI::UDim(0.5f0),
                                        CEGUI::UDim(
            0.4f0)));
            si
            ->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5f0),
                                            CEGUI::UDim(
            0.0f0)));

            //! 指定窗口中展現的圖片,取得圖像對象依然必須經過圖像集對象
            si->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet.getImage("RTTImage")));

            //! 將窗口加入窗口集(sheet),前面已經介紹過
            sheet->addChildWindow(si);


            加載CEGUI資源

            考察一個這樣加載資源的過程:
                CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");

            加載之前先設置schememanager的資源分組
                CEGUI::Scheme::setDefaultResourceGroup("Schemes");

            在資源配置里這樣設置:
            [Schemes]
            FileSystem
            =../media/cegui/datafiles/schemes

            則創建"taharezlook.scheme"的時候會在"...datafiles/schemes"中查找對應的文件。

            代碼分析:

            call stack
            CEGUIOgreRenderer_d.dll!CEGUI::OgreResourceProvider::loadRawDataContainer
            CEGUIExpatParser_d.dll
            !CEGUI::ExpatParser::parseXMLFile
            CEGUIBase_d.dll
            !CEGUI::Scheme_xmlHandler::Scheme_xmlHandler
            CEGUIBase_d.dll
            !CEGUI::NamedXMLResourceManager<CEGUI::Scheme,CEGUI::Scheme_xmlHandler>::create
            Tutorial7.exe
            !Tutorial7::createScene

            加載資源
             1void OgreResourceProvider::loadRawDataContainer(const String& filename,
             2                                                RawDataContainer& output,
             3                                                const String& resourceGroup)
             4{
             5    String orpGroup;
             6    if (resourceGroup.empty())
             7        orpGroup = d_defaultResourceGroup.empty() ?
             8            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME.c_str() :
             9            d_defaultResourceGroup;
            10    else
            11        orpGroup = resourceGroup;
            12
            13    Ogre::DataStreamPtr input = Ogre::ResourceGroupManager::getSingleton().
            14        openResource(filename.c_str(), orpGroup.c_str());
            15
            16    if (input.isNull())
            17        CEGUI_THROW(InvalidRequestException(
            18            "OgreCEGUIResourceProvider::loadRawDataContainer: Unable to open "
            19            "resource file '" + filename + "' in resource group '" + orpGroup +
            20            "'."));
            21
            22    Ogre::String buf = input->getAsString();
            23    const size_t memBuffSize = buf.length();
            24
            25    unsigned char* mem = new unsigned char[memBuffSize];
            26    memcpy(mem, buf.c_str(), memBuffSize);
            27
            28    output.setData(mem);
            29    output.setSize(memBuffSize);
            30}

            由此可見ceguiogrerenderer將cegui的資源加載與ogre鏈接起來了。

            用std::string替換CEGUI::String

            幸運的是cegui開發小組已經完成了這個小工作,不幸的是這項工作在cegui 0.8才會有。不過也可以自己手動修改。這個修改作為cegui 的一個issue發布了:
            Description I have created a patch that allows CEGUI to use both the inbuilt utf32 String as well as std::string (with 8bit characters). std::string has lower memory requirements and can be (in very special circumstances) faster (easier pass by const reference, etc...).

            This is intended for library users not needing Unicode support (which I imagine is a large percentage).
            Additional Information This patch adds a configuration switch CEGUI_STRING_CLASS, three options are available:

            Unicode - utf32 inbuilt string - utf8 and utf32 support
            std::string - no unicode support
            std::string allocated with allocators - same but pass by reference can be harder but is allocated according to the allocator config

            This has not been committed yet! The only macro preprocessor if/ifdefs are in CEGUIString.h and CEGUIDefaultResourceProvider.h (in the Windows-only utf16 to utf8/char conversion functions).

            詳情:0000421: Configuration option to use std::string as CEGUI::String

            若干不勝其煩的小失誤

          1. 大小寫敏感---這個小錯誤讓偶跟蹤了一個多小時cegui源碼,誰會想到是拼寫錯誤呢
          2. posted on 2011-06-13 16:07 的筆記 閱讀(5960) 評論(4)  編輯 收藏 引用

            評論

            # re: CEGUI筆記 2011-08-01 11:09 玉清

            Hi~夸父,你知道OgreRenderer里面的紋理資源是如何加載的嗎?  回復  更多評論   

            # re: CEGUI筆記 2011-08-01 11:13 玉清

            在OgreRenderer里面有一個成員為OgreRenderer_impl結構體,這個結構體里面保存了OgreTexture的指針列表,想問一下這些紋理指針是什么時候在哪里創建和載入紋理的呢?MyGUI也是類似的情況,謝謝~~~~  回復  更多評論   

            # re: CEGUI筆記 2011-08-06 12:42 夸父的筆記

            玉清哥哥,OgreRenderer內部我還沒跟過,不是很了解:)  回復  更多評論   

            # re: CEGUI筆記 2013-09-18 15:45 song

            我創建render和system時老是失敗?求解釋啊  回復  更多評論   

            久久影院综合精品| 99久久综合国产精品免费| 久久综合狠狠综合久久综合88| 亚洲精品乱码久久久久久中文字幕| 久久夜色精品国产噜噜亚洲AV| 激情伊人五月天久久综合| 亚洲国产精品久久久久婷婷老年| 久久精品中文字幕有码| 亚洲人成网亚洲欧洲无码久久| 香蕉久久一区二区不卡无毒影院 | 久久精品人人做人人爽97| 色综合久久久久久久久五月| 久久99国内精品自在现线| 久久久久国产精品麻豆AR影院| 日韩av无码久久精品免费| 精品久久久久久国产免费了| 久久无码人妻一区二区三区 | 久久久久久久久久久久中文字幕 | 一级做a爰片久久毛片人呢| 久久亚洲国产精品成人AV秋霞| 天天爽天天爽天天片a久久网| 久久精品aⅴ无码中文字字幕不卡| 99精品久久久久久久婷婷| 亚洲精品乱码久久久久久| 亚洲精品乱码久久久久久蜜桃 | 国产一区二区三区久久精品| 国内精品久久久久久久久电影网| 久久久久久A亚洲欧洲AV冫| 伊人久久综在合线亚洲2019| 久久精品中文闷骚内射| 久久亚洲AV成人无码| 亚洲国产精品成人久久蜜臀| 国内精品久久久久影院网站| 国产精品久久久久久| 99久久精品国产高清一区二区 | 欧美久久精品一级c片片| 国产精品久久久久aaaa| 久久精品国产91久久麻豆自制| 国产精品毛片久久久久久久 | 国产精品久久久久a影院| 香港aa三级久久三级老师2021国产三级精品三级在 |