亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于IoC模式的D3D渲染工作流引擎設(shè)計(jì)

        2010-01-16 01:58:00
        關(guān)鍵詞:管理器引擎實(shí)例

        熊 偉

        (武漢大學(xué)計(jì)算機(jī)學(xué)院,湖北武漢430079)

        隨著DirectX的發(fā)展和成熟,DirectX已經(jīng)成為當(dāng)今游戲和多媒體開發(fā)的首選技術(shù)。然而,DirectX的功能都是以COM組件的形式提供的,應(yīng)用程序更多地采用了面向過程的設(shè)計(jì)思想,這種方式使得應(yīng)用程序的業(yè)務(wù)邏輯和DirectX的API混合在一起,破壞了系統(tǒng)的模塊化,增大了模塊間的耦合度,系統(tǒng)也不易于維護(hù)和擴(kuò)展。

        本文提出一個(gè)基于IoC模式的D3D(DirectX中的Direct3D)渲染工作流引擎的設(shè)計(jì)方案,該方案將剝離應(yīng)用程序邏輯和D3D實(shí)現(xiàn)之間的關(guān)系,采用工作流的設(shè)計(jì)思想來封裝D3D的API,并使用IoC容器來創(chuàng)建構(gòu)件和組裝其依賴關(guān)系,最后通過實(shí)例來驗(yàn)證本引擎的可行性和實(shí)現(xiàn)效果。

        1 3D渲染過程簡(jiǎn)介

        3D渲染過程就是三維物體的成像過程。三維物體通過建模的微分方法,根據(jù)不同的精確程度,將表面切分為多個(gè)三角形面,從而將表面的繪制轉(zhuǎn)化為三角形面的繪制。渲染由眾多三角形面組成的三維場(chǎng)景,需要引入多個(gè)坐標(biāo)系,經(jīng)過這些坐標(biāo)系的轉(zhuǎn)化后,三維場(chǎng)景最終會(huì)作為一個(gè)二維的場(chǎng)景被繪制出來。[1]

        在三維場(chǎng)景中,每個(gè)物體最初都擁有自己的局部坐標(biāo)系,局部坐標(biāo)系為物體進(jìn)行三角形頂點(diǎn)的坐標(biāo)量化。然后每個(gè)場(chǎng)景都有一個(gè)世界坐標(biāo)系,該坐標(biāo)系描述了各個(gè)物體之間的位置關(guān)系(如果有光照,還需要對(duì)頂點(diǎn)的顏色值進(jìn)行計(jì)算)。這時(shí),一個(gè)攝影坐標(biāo)系將會(huì)描述該場(chǎng)景的取景范圍,不可見的三角形面將被裁剪。對(duì)攝影坐標(biāo)系的頂點(diǎn)進(jìn)行剪裁和透視投影處理后,將可以得到輸出于視覺區(qū)域中的投影坐標(biāo)系的頂點(diǎn)信息。最后,將平面投影的點(diǎn)變換到計(jì)算機(jī)屏幕的視口中,如果采用了紋理貼圖,還需要對(duì)像素顏色值進(jìn)行混色計(jì)算。固化渲染代碼以管道流水線的形式來實(shí)現(xiàn)三維物體的渲染,D3D提供了API來簡(jiǎn)化這個(gè)渲染過程,它通過設(shè)置該管道流水線的各種過程參數(shù),最終啟動(dòng)該管道流水線的執(zhí)行代碼來實(shí)現(xiàn)三維的圖形顯示。[2-5]

        傳統(tǒng)的D3D應(yīng)用程序設(shè)計(jì)是基于面向過程思想的,應(yīng)用程序在開啟渲染模式后,根據(jù)程序邏輯來設(shè)置管道流水線的過程參數(shù),并最終將結(jié)果繪制在顯示器上。這種面向過程的設(shè)計(jì)思想導(dǎo)致了程序邏輯和D3D的具體實(shí)現(xiàn)混合在一起,使得程序設(shè)計(jì)復(fù)雜、模塊化差、耦合性低和易讀性差。本引擎將以面向?qū)ο蟮脑O(shè)計(jì)思想來封裝D3D的API,并將管道流水線的渲染過程抽象為工作流,最終基于IoC容器來配置該工作流,使D3D渲染過程更為靈活和方便,從而徹底剝離了應(yīng)用程序和D3D的具體實(shí)現(xiàn)之間的關(guān)系。

        2 引擎設(shè)計(jì)

        引擎的主要任務(wù)是將應(yīng)用程序與D3D具體實(shí)現(xiàn)分離,使得應(yīng)用程序充當(dāng)生產(chǎn)工人的角色,而D3D具體實(shí)現(xiàn)充當(dāng)工作流的角色。引擎將按照工作流的設(shè)計(jì)思想將D3D對(duì)象和API封裝成工作流構(gòu)件,并提供相應(yīng)的接口給應(yīng)用程序,從而保證兩者的分離和通信。另外,為了進(jìn)一步降低構(gòu)件間的耦合,引擎將引入 IoC容器來托管引擎的主要構(gòu)件對(duì)象。引擎設(shè)計(jì)將包括工作流設(shè)計(jì)和IoC容器設(shè)計(jì)兩個(gè)部分,其中,工作流設(shè)計(jì)主要是依照管道流水線的渲染過程來設(shè)計(jì)各個(gè)構(gòu)件等,并按照抽象工廠的設(shè)計(jì)模式來抽象C++對(duì)象;IoC容器主要是現(xiàn)實(shí)對(duì)象的動(dòng)態(tài)創(chuàng)建和采用XML來配置三維場(chǎng)景。

        2.1 工作流設(shè)計(jì)

        工作流中的對(duì)象按照角色分為基本構(gòu)件、過程構(gòu)件、管理器和處理器[6]。其關(guān)系如圖1所示。

        圖1 工作流構(gòu)件的關(guān)系

        2.1.1 基本構(gòu)件

        基本構(gòu)件是工作流中的基本單位,其作用是實(shí)現(xiàn)工作流分配給自己的任務(wù),而無需知道自己在整個(gè)工作流中的作用。它主要包括4個(gè)接口:創(chuàng)建、設(shè)置參數(shù)、獲取參數(shù)和釋放,記為M={C,S,G,R},當(dāng)一個(gè)基本構(gòu)件被創(chuàng)建后,外界將需要對(duì)其進(jìn)行一些設(shè)置,然后在被釋放之前,外界都可以在它身上獲取到需要的信息和接口。

        在引擎中,基本構(gòu)件包括了頂點(diǎn)、索引、紋理、材質(zhì)、燈光等D3D基本元素,比如,類 GLight描述了D3D中的燈光的信息和行為,它封裝了D3DLIGHT9對(duì)象,并提供了相應(yīng)接口(C,S,G,R),其子類 GPointLight、GDirectionalLight和GSpotLight分別實(shí)現(xiàn)了點(diǎn)光源、平行光和聚光源的具體設(shè)置和行為(重載了父類的C,S,G,R)。

        2.1.2 過程構(gòu)件

        過程構(gòu)件描述了基本構(gòu)件之間的關(guān)系和工作流的邏輯流程,其作用是按照工作流設(shè)計(jì)出流程路線和邏輯關(guān)系。主要包括4個(gè)接口:創(chuàng)建、裝配、運(yùn)行和釋放,記為L(zhǎng)={C,A,P,R},過程構(gòu)件一般只有一個(gè)實(shí)例,當(dāng)它被創(chuàng)建后,外界將其需要的所有基本構(gòu)件都裝配在其實(shí)例上,然后運(yùn)行該實(shí)例,直至它被釋放。在引擎中,類 GScene實(shí)現(xiàn)了D3D管道渲染的過程,它首先啟動(dòng)渲染,然后分別獲取裝配在它身上的頂點(diǎn)、索引、紋理、材質(zhì)、燈光等信息,通過預(yù)定的渲染方式來渲染場(chǎng)景,直至渲染過程結(jié)束。

        2.1.3 管理器

        管理器負(fù)責(zé)管理所有基本構(gòu)件和過程構(gòu)件實(shí)例,其主要接口包括創(chuàng)建、新建新構(gòu)件、查找構(gòu)件、刪除構(gòu)件和釋放,記為 G={C,N,F,D,R}。管理器分為基本構(gòu)件管理器和過程構(gòu)件管理器,基本構(gòu)件管理器來創(chuàng)建和釋放基本構(gòu)件實(shí)例,過程構(gòu)件管理器則負(fù)責(zé)創(chuàng)建和釋放過程構(gòu)件。管理器的主要作用是對(duì)所有散亂的基本和過程構(gòu)件集中管理,增強(qiáng)工作流的靈活性,實(shí)現(xiàn)高內(nèi)聚、低耦合的目的。在引擎中,每個(gè)基本構(gòu)件和過程構(gòu)件都有其對(duì)應(yīng)的管理器,如類GTextureHolder為紋理對(duì)象的管理器,而 GMaterialHolder為材質(zhì)對(duì)象的管理器。

        2.1.4 處理器

        處理器負(fù)責(zé)執(zhí)行工作流,其主要接口包括創(chuàng)建、輸入、處理、輸出和釋放,記為 P={C,I,P,O,R}。處理器首先從管理構(gòu)件中獲取到過程構(gòu)件實(shí)例,然后根據(jù)初始化信息獲取到所有過程構(gòu)件實(shí)例所需的基本構(gòu)件實(shí)例,然后將這些基本構(gòu)件實(shí)例組裝到過程構(gòu)件實(shí)例中,運(yùn)行過程構(gòu)件實(shí)例,在運(yùn)行過程中,處理器會(huì)根據(jù)用戶輸入或其他消息來創(chuàng)建新的基本構(gòu)件實(shí)例或釋放那些不再需要的基本構(gòu)件實(shí)例,還會(huì)通過實(shí)例的設(shè)置接口來初始化和更新所有的實(shí)例,直至程序結(jié)束。

        在引擎中,類 GGraphics實(shí)現(xiàn)了處理器的功能,它封裝了 IDirect3DDevice9對(duì)象,完成了 d3d的渲染過程,并對(duì)邏輯程序提供了相應(yīng)接口,使邏輯程序可以更新最終的輸出結(jié)果。

        2.1.5 抽象工廠模式設(shè)計(jì)

        工作流的運(yùn)行原理是首先由處理器來做一些初始化的工作,然后根據(jù)輸入信息從管理器中獲取到所需對(duì)象(管理器會(huì)根據(jù)處理器的要求來創(chuàng)建對(duì)象),并將那些基本構(gòu)件裝配到過程構(gòu)件上。然后處理器啟動(dòng)過程構(gòu)件,由于過程構(gòu)件中已定義好所需基本構(gòu)件的接口,它將按照自己定義的流程來運(yùn)行,運(yùn)行結(jié)束后,處理器結(jié)束過程構(gòu)件。

        可見,工作流是基于不同構(gòu)件之間的接口來設(shè)計(jì)的,它并不依賴于具體的對(duì)象實(shí)例,這種使用抽象接口來創(chuàng)建一組相關(guān)或依賴的產(chǎn)品組的模式,可以通過抽象工廠來實(shí)現(xiàn)。這樣,工作流就從具體的產(chǎn)品中被解耦,圖2是本引擎采用抽象工廠所實(shí)現(xiàn)的構(gòu)件間的關(guān)系及其渲染過程。

        圖2 引擎渲染時(shí)序圖

        在圖2中,所有構(gòu)件都是通過接口來實(shí)現(xiàn)的,引擎并不知道所需要渲染的對(duì)象有哪些,它只需要從一個(gè)XML的文檔中動(dòng)態(tài)去解析各種所需對(duì)象的信息,然后裝配到 GScene對(duì)象中,一切渲染的過程都由 GScene對(duì)象來完成,這樣就徹底分離了應(yīng)用程序與引擎間的關(guān)系。

        2.2 IOC容器設(shè)計(jì)

        在工作流中,不同類型的構(gòu)件之間存在著各種依賴關(guān)系,導(dǎo)致了構(gòu)件間耦合度低,裝配靈活性低等缺點(diǎn),為了協(xié)調(diào)各構(gòu)件的依賴關(guān)系,提高構(gòu)件的重用性和移植性,運(yùn)用 IoC容器[6]來配置構(gòu)件間的關(guān)系是一個(gè)很好的方法。

        IoC指不直接創(chuàng)建對(duì)象,而只是描述它們的創(chuàng)建方式,容器負(fù)責(zé)來將這些聯(lián)系在一起。這種控制權(quán)由應(yīng)用代碼轉(zhuǎn)到了外部容器的行為,稱為反轉(zhuǎn)。IoC的主要作用有:(1)描述組件間的依賴關(guān)系,減小其創(chuàng)建成本;(2)對(duì)組件的組裝可以脫離于代碼控制,減小其耦合度;(3)充分利用組裝的靈活性,便于測(cè)試。

        IoC容器的主要任務(wù)是根據(jù)對(duì)象的配置文件(一般為XML)去動(dòng)態(tài)地創(chuàng)建該對(duì)象,并完成配置文件所規(guī)定的依賴關(guān)系的組裝。但是,C++本身并不具備反射機(jī)制,以至于無法直接通過C++來動(dòng)態(tài)創(chuàng)建對(duì)象并動(dòng)態(tài)調(diào)用其方法,所以容器需要其他實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象的機(jī)制。另外,為了保證某些特殊對(duì)象的唯一性,容器將采用單例的設(shè)計(jì)模式來實(shí)現(xiàn)這個(gè)特性。

        2.2.1 對(duì)象的動(dòng)態(tài)創(chuàng)建

        對(duì)象的動(dòng)態(tài)創(chuàng)建一般是通過反射機(jī)制來實(shí)現(xiàn)了,而C++本身并沒有反射機(jī)制,為了在程序運(yùn)行時(shí)動(dòng)態(tài)地識(shí)別對(duì)象類型并創(chuàng)建對(duì)象,就必須把那些需要具備該能力的類信息記錄起來,這樣才可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建。

        本系統(tǒng)用類 GRuntimeClass來描述所有有用的類信息,并提供靜態(tài)方法CreateObject來動(dòng)態(tài)創(chuàng)建對(duì)象,這樣,每個(gè)需要?jiǎng)討B(tài)創(chuàng)建的類(如GTexture)都需要有一個(gè)對(duì)應(yīng)的 GRuntimeClass對(duì)象(如classGTexture),所以在定義 GTexture時(shí),需要額外地定義一個(gè)靜態(tài)對(duì)象classGTexture,并對(duì)classGTexture初始化。

        由于對(duì)象的動(dòng)態(tài)創(chuàng)建往往是根據(jù)其名字來創(chuàng)建的,所以可以將這些 GRuntimeClass對(duì)象放進(jìn)一個(gè)全局的map(GRuntimeClass::m_mpRuntimeClasses)中,這樣就可以快速地根據(jù)名字尋找到對(duì)應(yīng)的 GRuntimeClass對(duì)象并動(dòng)態(tài)地創(chuàng)建所需的對(duì)象了。當(dāng)然,這些額外地工作可以通過宏來簡(jiǎn)化,比如使用DECLARE_DYNCREATE來申明classGTexture和 CreateObject,而使用 IMPL EMENT_DYNCREATE來實(shí)現(xiàn)和初始化。

        在創(chuàng)建對(duì)象時(shí),有一種情況是需要特別處理的,就是有些類它只有一個(gè)實(shí)例,為了實(shí)現(xiàn)這種特性,本引擎采用了單例的設(shè)計(jì)模式。在傳統(tǒng)的單例模式中,單例類有一個(gè)靜態(tài)的對(duì)象,并提供一個(gè)全局的訪問點(diǎn),通過這種方式來保證類對(duì)象的唯一性。在本引擎中,這個(gè)靜態(tài)對(duì)象(m_pSingletonObject)和全局訪問點(diǎn)(CreateSingleton)被移到了 GRuntimeClass中,這樣通過 GRuntime-Class的CreateObject方法來動(dòng)態(tài)地創(chuàng)建對(duì)象,用CreateSingleton方法來動(dòng)態(tài)地創(chuàng)建單例。

        2.2.2 配置文件解析

        IoC容器需要實(shí)現(xiàn)根據(jù)給定格式的配置文件(本引擎采用XML)來動(dòng)態(tài)地創(chuàng)建對(duì)象,并組裝其依賴的其他對(duì)象。本引擎用類 GIoCContainer來實(shí)現(xiàn)這個(gè)功能,GIoCContainer有一個(gè)靜態(tài)的IXMLDOMDocumentPtr類型的成員變量pXMLDoc,首先通過該變量的load方法來讀取配置文件,然后,GIoCContainer提供了一個(gè)靜態(tài)方法GObject* CreateObject(char*beanId)來動(dòng)態(tài)創(chuàng)建對(duì)象,并組裝其依賴對(duì)象,該方法算法如下:

        GObject* CreateObject(char*beanId){

        獲取靜態(tài)對(duì)象pXMLDoc;

        if(pXMLDoc==NULL)

        載入對(duì)應(yīng)的XML文件;

        獲取 beans節(jié)點(diǎn)的 IXMLDOMElementPtr對(duì)象;

        遍歷beans節(jié)點(diǎn)中的所有bean節(jié)點(diǎn)

        {

        if(bean節(jié)點(diǎn)的id為beanId)

        {

        if(bean節(jié)點(diǎn)的scope不為prototype)//不是單例

        {

        object = GRuntimeClass.CreateObject(bean的class);

        遍歷bean節(jié)點(diǎn)中的所有property節(jié)點(diǎn)

        {

        propertyInstance= CreateObject(property的ref);

        動(dòng)態(tài)調(diào)用方法使object的名為property的name的對(duì)象為propertyInstance;

        }

        }

        else{//單例

        object = GRuntimeClass.CreateSingleton(bean的class);

        遍歷bean節(jié)點(diǎn)中的所有property節(jié)點(diǎn)

        {

        if(object的名為property的name的對(duì)象==NULL)

        {

        propertyInstance= CreateObject(property的ref);

        動(dòng)態(tài)調(diào)用方法使object的名為property的name的對(duì)象為propertyInstance;

        }

        }

        }

        return object;

        }

        }

        return NULL;

        }

        3 實(shí)現(xiàn)

        本引擎實(shí)現(xiàn)了從一個(gè)場(chǎng)景配置文件來動(dòng)態(tài)生成相關(guān)對(duì)象,這些對(duì)象將作為工作流的輸入數(shù)據(jù),當(dāng)工作流啟動(dòng)后,工作流按照其流程來渲染所有三維物體。配置文件獨(dú)立于程序,當(dāng)需要修改場(chǎng)景時(shí),引擎無需修改源碼,而只需要修改相應(yīng)的配置項(xiàng)則可。下面是使用該引擎實(shí)現(xiàn)的一個(gè)具體實(shí)例,在該實(shí)例中,將渲染一個(gè)草地和藍(lán)天的場(chǎng)景,草地是個(gè)平板對(duì)象,天空是個(gè)半球體。實(shí)現(xiàn)該實(shí)例,只需在場(chǎng)景配置文件中添加上這兩個(gè)對(duì)象,配置文件如下:

        <bean id="ground"class="GPlane"scope="prototype">

        <property name="m_strTexturePath"value="c:ground.jpg"></property>

        <property name="m_fLength"value="800"></property>

        <property name="m_fWidth"value="800"></property>

        </bean>

        <bean id="sky"class="GGlobe"scope="prototype">

        <property name="m_fRadius"value="800"></property>

        <property name="m_dAlfa"value="15"></property>

        <property name="m_dBeta"value="15"></property>

        </bean>

        <bean id="gview"class="GView">

        <property name="m_lpModels">

        <list>

        <ref bean="ground"/>

        <ref bean="sky"/>

        </list>

        </property>

        </bean>

        圖3顯示了該實(shí)例的最終渲染效果。

        圖3 實(shí)例渲染效果

        4 結(jié)束語

        D3D是當(dāng)前3D渲染的主流技術(shù),它實(shí)現(xiàn)了管道流水線渲染三維物體的過程。D3D的API采用COM組件的形式,這樣使得程序的設(shè)計(jì)繁雜化,易讀性較差,而以一般的面向?qū)ο笏枷雭矸庋b則增加了各個(gè)對(duì)象的耦合。本引擎采用了以工作流的設(shè)計(jì)思想抽象了管道流水線的渲染過程,并采用IoC容器來協(xié)調(diào)工作流各構(gòu)件的依賴關(guān)系,提高構(gòu)件的重用性和移植性,從而剝離了應(yīng)用程序的邏輯與D3D具體渲染的關(guān)系。

        本引擎的創(chuàng)新點(diǎn)在于:(1)采用工作流的設(shè)計(jì)思想來設(shè)計(jì)并封裝D3D的API;(2)利用 IoC容器在構(gòu)件組裝方面的開發(fā)性來配置引擎中的對(duì)象。目前還只能渲染一些基本幾何體,下一步將會(huì)以更開放的形式,來渲染復(fù)雜的骨骼動(dòng)畫等。

        [1] 林少芬,姜明.CAXA三維實(shí)體設(shè)計(jì)教程[M].北京:機(jī)械工業(yè)出版社,2005.

        [2] 李江平.Direct X中3DMAX模型的應(yīng)用[J].湖北工學(xué)院學(xué)報(bào),2003(4):58-59.

        [3] 況衛(wèi)飛,彭四偉.三維渲染引擎編輯器的研究[J].電子設(shè)計(jì)工程,2009(9):91-92.

        [4] 周演,陳天滋.基于Direct3D的大規(guī)模地形渲染技術(shù)研究[J].鄭州輕工業(yè)學(xué)院學(xué)報(bào):自然科學(xué)版,2008(6):107-111.

        [5] 杜園園,侯彤璞,郭艷霞.Direct3D場(chǎng)景中3D模型的處理方法[J].遼寧石油化工大學(xué)學(xué)報(bào),2008(4):86-90.

        [6] 朱啟明,汪詩林.基于IOC容器的工作流引擎的設(shè)計(jì)[J].微計(jì)算機(jī)信息,2008(21):10-12.

        猜你喜歡
        管理器引擎實(shí)例
        應(yīng)急狀態(tài)啟動(dòng)磁盤管理器
        Windows文件緩沖處理技術(shù)概述
        藍(lán)谷: “涉藍(lán)”新引擎
        商周刊(2017年22期)2017-11-09 05:08:31
        無形的引擎
        河南電力(2015年5期)2015-06-08 06:01:46
        基于Cocos2d引擎的PuzzleGame開發(fā)
        高集成度2.5A備份電源管理器簡(jiǎn)化鋰離子電池備份系統(tǒng)
        快速導(dǎo)出QQ群消息
        電腦迷(2014年2期)2014-04-29 19:21:13
        完形填空Ⅱ
        完形填空Ⅰ
        One?。牛睿纾椋睿濉。蹋澹妫糁皇O乱粋€(gè)引擎
        日本最新一区二区三区在线视频| 少妇人妻偷人精品一区二区| 国内精品九九久久久精品| 精品久久久久88久久久| 手机在线免费av网址| 亚洲无人区乱码中文字幕能看| 中文字幕日韩精品有码视频| 日本高清h色视频在线观看| 亚洲国产av一区二区三区四区| 国产精品毛片99久久久久| 日韩av一区二区无卡| 91精品国产色综合久久| 亚洲成a人片在线观看无码3d| 三年片免费观看大全国语| 69天堂国产在线精品观看| 久久伊人久久伊人久久| 视频在线观看免费一区二区| 色诱视频在线观看| 国产999精品久久久久久| 五月天婷婷一区二区三区久久| 亚洲国产成人久久精品美女av| 视频在线观看一区二区三区| 北条麻妃国产九九九精品视频| 六月丁香婷婷色狠狠久久| 亚洲成a人片在线观看中| 亚洲av色香蕉一区二区三区潮| 日本在线视频www色| 亚洲国产另类精品| 色综合久久久久综合999| 成人短篇在线视频夫妻刺激自拍| 亚洲精品中文字幕视频色| 巨大巨粗巨长 黑人长吊| 亚洲欧美综合在线天堂| 中文字幕日韩人妻高清在线| 综合久久精品亚洲天堂| 国产成人av在线免播放观看新| 亚洲∧v久久久无码精品| 亚洲αv在线精品糸列| 亚洲综合在不卡在线国产另类| 国产麻豆精品精东影业av网站| 洗澡被公强奷30分钟视频|