Ogre中的多窗口渲染方法

          最近由于工作的關(guān)系,希望用一個(gè)3D圖形引擎實(shí)現(xiàn)棋牌類的2D游戲桌面。為了提供盡可能好的兼容性,選擇了Ogre作為后臺(tái)渲染引擎,因?yàn)樗脑u(píng)價(jià)在開(kāi)源3D引擎中很不錯(cuò),而且同時(shí)支持Opengl和D3D,所以沒(méi)有多想就選擇了它。到后期才發(fā)現(xiàn),Ogre雖然是號(hào)稱“Object Oriented Graphics Render Engine”,而且確實(shí)在場(chǎng)景,相機(jī),窗口等等的三維對(duì)象的建模上做得相當(dāng)不錯(cuò),但是其對(duì)于OCP等原則的遵循僅僅是大面上,Ogre中隨處可見(jiàn)一些巨大的對(duì)象類。所以要擴(kuò)展它或者重用它的部分功能簡(jiǎn)直是太困難了,不得已而拋棄了Ogre。這倒不一定是Ogre的錯(cuò),因?yàn)镺gre定位于游戲制作的,追求的是最新最酷的特效,這樣肯定很難從一開(kāi)始就抽象好的。而且它要同時(shí)支持Opengl和D3D,這也是一個(gè)抽象的困難點(diǎn)。

          雖然沒(méi)有使用Ogre,但是對(duì)于Ogre中多窗口渲染方式的實(shí)現(xiàn)還是很下了一番功夫的,不想這些功夫白白浪費(fèi),還是把它寫出來(lái)與所有人共享吧。

          為了提供同一個(gè)用戶同時(shí)打多局游戲的可能,所以采用Ogre的話必須支持多桌面渲染,這里有兩點(diǎn)需要考慮:

          1. 窗口渲染而不是全屏幕渲染

          2. 多窗口渲染,每一個(gè)窗口使用不同的三維場(chǎng)景數(shù)據(jù)。

          先說(shuō)說(shuō)Ogre如何做到窗口渲染吧。Ogre中對(duì)應(yīng)每一個(gè)渲染窗口有一個(gè)RenderWindow對(duì)象,該對(duì)象通過(guò)Root的CreateRenderWindow方法創(chuàng)建,為了與現(xiàn)有的GUI窗口兼容,我不希望Ogre為我產(chǎn)生新的HWND,而是把一個(gè)HWND作為參數(shù)傳遞給CreateRenderWindow方法,這是通過(guò)以下方法做到的:

          Ogre::NameValuePairList parms;
          parms["externalWindowHandle"] = Ogre::StringConverter::toStrin((long)hwnd);
          bool bFullScreen = false; RECT rect; ::GetWindowRect(hwnd, &rect);
          int windowWidth = rect.right - rect.left;
          int windowHeight = rect.bottom - rect.top;
          Ogre::RenderWindow* window = m_OgreRoot->createRenderWindow(windowName, windowWidth, windowHeight, bFullScreen, &parms);

          關(guān)于多窗口渲染,則需要先說(shuō)說(shuō)Ogre中的場(chǎng)景結(jié)構(gòu):

          如圖所示,Ogre中一切起源于Root對(duì)象,它負(fù)責(zé)產(chǎn)生和銷毀所有Manager。SceneManager負(fù)責(zé)管理場(chǎng)景數(shù)據(jù),所以為了實(shí)現(xiàn)多窗口,必須要有多個(gè)SceneManager實(shí)例,SceneManager中包含MovableObject,顧名思義,MovableObject是場(chǎng)景中可以運(yùn)動(dòng)的物體,SceneManager中還有一些靜止不變的數(shù)據(jù),比如Terrain等等,圖中并未列出。MovableObject如果不掛在SceneNode上在場(chǎng)景中是無(wú)法顯示出來(lái)的,一個(gè)SceneNode上可以掛多個(gè)MovableObject,這樣組織成一棵場(chǎng)景樹的結(jié)構(gòu),值得一提的是MovableObject是無(wú)法共享的,也就是說(shuō)它只能掛在一個(gè)SceneNode下,想共享的話,只有使用Mesh了。Mesh由MeshManager產(chǎn)生,它定義了基本幾何形狀。一輛汽車可以同時(shí)在場(chǎng)景多個(gè)部分出現(xiàn),顯然不需要每一輛汽車創(chuàng)建一個(gè)幾何形狀,公用一個(gè)Mesh即可,這正是Entity的工作方式。Entity還提供了位置,動(dòng)畫等信息的封裝。

          有了多個(gè)SceneManager之后如何讓這些場(chǎng)景渲染到指定的多個(gè)窗口上呢。這要通過(guò)Camera和Viewport實(shí)現(xiàn)。這里也正是Ogre設(shè)計(jì)得比較精巧的地方。Camera定義了觀察者從哪個(gè)位置以及角度觀察場(chǎng)景,以及可以觀察的范圍(視角,最遠(yuǎn)與最近位置等等),而RenderWindow通過(guò)Camera創(chuàng)建一個(gè)自身的Viewport,使得場(chǎng)景可以渲染到RenderWindow上。具體的渲染機(jī)制我并沒(méi)有深入研究,在Root中應(yīng)該有相關(guān)代碼。

          說(shuō)了這么多,還是來(lái)看看Ogre中多窗口渲染的代碼吧

          Ogre::NameValuePairList parms;
          parms["externalWindowHandle"] = Ogre::StringConverter::toString((long)hwnd);

          RECT rect;
          ::GetWindowRect(hwnd, &rect);
          int windowWidth = rect.right - rect.left;
          int windowHeight = rect.bottom - rect.top;
          Ogre::RenderWindow* window = m_OgreRoot->createRenderWindow(ogreNameFactory::applyWindowName(), windowWidth, windowHeight, false, &parms);

          // Create SceneManager
          m_SceneManager = m_OgreRoot->createSceneManager(Ogre::ST_GENERIC, ogreNameFactory::applySceneManagerName());
          // Set ambient light
          m_SceneManager->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));

          //Create Camera
          m_Camera = m_SceneManager->createCamera(ogreNameFactory::applyCameraName());
          m_Camera->setProjectionType(Ogre::PT_ORTHOGRAPHIC);

          m_Camera->setFixedYawAxis( true, Ogre::Vector3(0, -1, 0) );
          //// Position it at 500 in Z direction
          m_Camera->setPosition(Ogre::Vector3(Ogre::Real(windowWidth)/2.0, Ogre::Real(windowHeight)/2.0, -260));
          //// Look back along -Z
          m_Camera->lookAt(Ogre::Vector3(Ogre::Real(windowWidth)/2.0, Ogre::Real(windowHeight)/2.0, 0));

          m_Camera->setFOVy(Ogre::Degree(180.0 - 1.6416));
          m_Camera->setNearClipDistance(5);
          m_Camera->setFarClipDistance(271);

          // Create one viewport, entire window
          Ogre::Viewport* vp = window->addViewport(m_Camera);
          vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

          //// Alter the camera aspect ratio to match the viewport
          m_Camera->setAspectRatio(Ogre::Real(windowWidth) / Ogre::Real(windowHeight));

          ////Used for Hittest

          Ogre::Ray aimRay = m_Camera->getCameraToViewportRay( 0, 0 );
          m_RaySceneQuery = m_SceneManager->createRayQuery(aimRay);

          // Make window active and post an update
          window->setActive(true);
          window->update();

          代碼中與相機(jī)設(shè)置相關(guān)的部分看不懂美關(guān)系,關(guān)于相機(jī)的設(shè)置,我會(huì)在另一篇文章中詳細(xì)分析之。以上的代碼將成功的在hwnd上初始化渲染環(huán)境,現(xiàn)在要做得就是在SceneManager中添加Entity了,需要重繪的時(shí)候調(diào)用RenderWindow的update()即可。

          時(shí)間不早了,打算今晚去星美看通宵電影,關(guān)于Camera的詳細(xì)分析就留到明天繼續(xù)吧,哈哈。

          posted on 2007-06-16 22:27 雁過(guò)無(wú)痕 閱讀(8741) 評(píng)論(5)  編輯  收藏

          評(píng)論

          # re: Ogre中的多窗口渲染方法[未登錄](méi) 2008-10-17 10:59 1

          明顯是要多次createRenderWindow。
          每個(gè)Window包含所有一個(gè)正常Ogre Window的東西。
          包括SceneManger , MeshManger等.

          似乎那個(gè)Root->RenderWindow 屬于 1~n 關(guān)系。
          你沒(méi)表明。  回復(fù)  更多評(píng)論   

          # re: Ogre中的多窗口渲染方法 2009-05-15 17:21 操你媽

          操你媽,把這個(gè)頁(yè)面刪了吧  回復(fù)  更多評(píng)論   

          # re: Ogre中的多窗口渲染方法 2010-01-14 14:32 23

          沒(méi)有多窗口渲染的內(nèi)容 ,文不對(duì)題啊  回復(fù)  更多評(píng)論   

          # re: Ogre中的多窗口渲染方法 2011-06-05 11:37 ff

          啥也沒(méi)說(shuō)  回復(fù)  更多評(píng)論   

          # re: Ogre中的多窗口渲染方法 2012-09-28 19:09 樓主是個(gè)傻逼

          樓主你是白癡嗎?  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2010年1月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(7)

          隨筆檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 招远市| 定兴县| 阿荣旗| 阿巴嘎旗| 张家界市| 万荣县| 台山市| 萨迦县| 顺昌县| 永福县| 钟山县| 万安县| 宁波市| 临漳县| 广宁县| 禄劝| 电白县| 上蔡县| 和平区| 中江县| 藁城市| 聊城市| 石阡县| 肃宁县| 东阳市| 中牟县| 伊川县| 乐山市| 新津县| 彩票| 大理市| 万全县| 紫云| 女性| 新竹县| 内江市| 万载县| 陈巴尔虎旗| 界首市| 临汾市| 弥勒县|