<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Ogre中的多窗口渲染方法

    最近由于工作的關系,希望用一個3D圖形引擎實現棋牌類的2D游戲桌面。為了提供盡可能好的兼容性,選擇了Ogre作為后臺渲染引擎,因為它的評價在開源3D引擎中很不錯,而且同時支持Opengl和D3D,所以沒有多想就選擇了它。到后期才發現,Ogre雖然是號稱“Object Oriented Graphics Render Engine”,而且確實在場景,相機,窗口等等的三維對象的建模上做得相當不錯,但是其對于OCP等原則的遵循僅僅是大面上,Ogre中隨處可見一些巨大的對象類。所以要擴展它或者重用它的部分功能簡直是太困難了,不得已而拋棄了Ogre。這倒不一定是Ogre的錯,因為Ogre定位于游戲制作的,追求的是最新最酷的特效,這樣肯定很難從一開始就抽象好的。而且它要同時支持Opengl和D3D,這也是一個抽象的困難點。

    雖然沒有使用Ogre,但是對于Ogre中多窗口渲染方式的實現還是很下了一番功夫的,不想這些功夫白白浪費,還是把它寫出來與所有人共享吧。

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

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

    2. 多窗口渲染,每一個窗口使用不同的三維場景數據。

    先說說Ogre如何做到窗口渲染吧。Ogre中對應每一個渲染窗口有一個RenderWindow對象,該對象通過Root的CreateRenderWindow方法創建,為了與現有的GUI窗口兼容,我不希望Ogre為我產生新的HWND,而是把一個HWND作為參數傳遞給CreateRenderWindow方法,這是通過以下方法做到的:

    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);

    關于多窗口渲染,則需要先說說Ogre中的場景結構:

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

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

    說了這么多,還是來看看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();

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

    時間不早了,打算今晚去星美看通宵電影,關于Camera的詳細分析就留到明天繼續吧,哈哈。

    posted on 2007-06-16 22:27 雁過無痕 閱讀(8738) 評論(5)  編輯  收藏

    評論

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

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

    似乎那個Root->RenderWindow 屬于 1~n 關系。
    你沒表明。  回復  更多評論   

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

    操你媽,把這個頁面刪了吧  回復  更多評論   

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

    沒有多窗口渲染的內容 ,文不對題啊  回復  更多評論   

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

    啥也沒說  回復  更多評論   

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

    樓主你是白癡嗎?  回復  更多評論   


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2011年6月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    導航

    統計

    常用鏈接

    留言簿(7)

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国精无码欧精品亚洲一区| 亚洲国产成人久久综合一| 精品无码一级毛片免费视频观看 | 亚洲黄色在线播放| 成年丰满熟妇午夜免费视频| 免费手机在线看片| 国产亚洲无线码一区二区| 无人在线直播免费观看| 无码AV动漫精品一区二区免费| 亚洲av永久无码精品国产精品| 免费做爰猛烈吃奶摸视频在线观看| jzzijzzij在线观看亚洲熟妇| 亚洲国产精品无码久久久蜜芽| 国产高清免费视频| 一区二区三区视频免费观看| 亚洲无砖砖区免费| 亚洲男人av香蕉爽爽爽爽| 亚洲免费在线视频播放| 无码的免费不卡毛片视频| 亚洲欧洲日产v特级毛片| 2048亚洲精品国产| 国产麻豆视频免费观看| 成人片黄网站色大片免费观看APP| 亚洲av乱码一区二区三区| 国产亚洲精品成人a v小说| 曰曰鲁夜夜免费播放视频| www在线观看播放免费视频日本| 亚洲不卡1卡2卡三卡2021麻豆| 成人午夜亚洲精品无码网站| 99精品全国免费观看视频| 午夜无码A级毛片免费视频 | 一级黄色免费网站| 中文有码亚洲制服av片| 亚洲国产第一页www| 亚洲国产aⅴ综合网| 天天操夜夜操免费视频| 美丽姑娘免费观看在线观看中文版| 男男黄GAY片免费网站WWW| 亚洲а∨天堂久久精品9966| 亚洲视频在线不卡| 亚洲va久久久噜噜噜久久天堂|