• <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>

            D3d9的一些更新 (轉)

            由于Aug 8造成的D3D9恐懼癥已經完全消除了,這一章將會給大家介紹將3D引擎轉向D3D9的各個方面,包括終于出現的全屏幕模式。從這章以后,我將使用D3D9作為講解的語言繼續D2D教程。

            【OP結束,開始正片】

            『Why?』

              估計大家首先要問的就是“Why?”為什么要前進到D3D9?理由如下:
            1、D3D9修復了D3D8已知的所有Bug,因此運行起來更穩定,速度也要快。
            2、D3D9提供了許多便利的新功能,雖然絕大多數是面向3D的,但是也有不少2D適用的,比如IDirect3DDevice9::StretchRect,以及對IDirect3DSurface9的改進等等。D3DX庫就更多了,比如D3DXSaveSurfaceToFileInMemory,一開始沒發現這個函數有啥用處,現在基本離不開了。
            3、HLSL。就像上一話我說的那樣,D2D教程以后會有PixelShader的內容。我可不想拿匯編來寫Shader,會死人的(祝賀我吧,終于拋棄匯編Shader了……)。雖然說這不是決定性的理由,因為還有Cg什么的,不過我想編寫顯卡無關的代碼,因此我不去研究Cg(反正和HLSL差不多)以及R2VB之類。
            4、ID3DXFont,往下看你就知道了。

            《D3D的變化》

            『界面名稱變化』

              一句話:8改成9就行。

            『“創建”型方法的一個統一變化』

              許多Create*()方法,比如創建設備、創建紋理、創建頂點緩沖等等,多了一個HANDLE* pSharedHandle參數,無用,NULL之(看來微軟原打算弄個共享句柄之類,不過被D3D10巨大的變化浮云了)

            『創建D3D設備的變化』

              D3DPRESENT_PARAMS的FullScreen_PresentationInterval變成了PresentationInterval,也就是說即使在窗口模式下也可以做到垂直同步來防止撕裂現象(2D的福音啊)。相應的,D3DSWAPEFFECT_COPY_VSYNC消失了,反正這個效果也不咋的,消失了也好。
              要做到垂直同步需要給PresentationInterval賦值D3DPRESENT_INTERVAL_DEFAULT或D3DPRESENT_INTERVAL_ONE。其中D3DPRESENT_INTERVAL_ONE的效果比D3DPRESENT_INTERVAL_DEFAULT好一點,不過相應的也會占用多一點點系統資源……真的只有一點點而已,實在是無所謂的……
              如果不要垂直同步,想要看看實際禎速的話,D3DPRESENT_INTERVAL_IMMEDIATE。
              注意在窗口模式下,你只能使用這三種Present模式,全屏幕模式下就可以使用別的(但是要首先檢測D3DCAPS9以查看顯卡是否支持)。不過我感覺對99%的游戲來說,有這三個就足夠了。
              另外在窗口模式下,BackBufferFormat也可以設置成D3DFMT_UNKNOWN,D3D會自動獲取當前桌面的格式設定成后備緩沖的格式,省去GetDisplayMode。實際上,窗口模式下的后備緩沖已經不需要和桌面格式相同,你可以通過IDirect3D9::CheckDeviceFormatConversion來檢查,如果這個設備支持這兩種顏色格式之間的轉換,就可以給程序的后備緩沖設定上不同的格式。我試過在桌面格式為32Bit(D3DFMT_X8R8G8B8)時將程序的后備緩沖格式設置為D3DFMT_R5G6B5(16Bit),發現了速度提升,也就是說這個設定是有意義的。
              可創建的設備類型多了一種D3DDEVTYPE_NULLREF,在安裝了D3D SDK的機子上等同于D3DDEYTYPE_REF,在其他的機子上,這種設備實際上沒有創建真正意義的D3D設備,只是允許你創建的紋理、表面等資源,但是Render、Present等操作都會無效(實際上這些資源都創建在了D3DPOOL_SCRATCH池里,不管你設定使用的是什么POOL)。也就是說,僅僅在模擬基本的運行而已。你可以用這個設備來編寫一個利用D3DX函數庫進行圖像格式轉換的程序,比如把一大堆不同的格式轉換成易于D3D9使用的DDS格式。因為實際上沒有創建設備,你甚至可以編寫成控制臺的,通過GetConsoleWindow的方法獲得HWND。Mercury 3用的MIF格式的轉換器就是這么做出來的。注意D3DDEVTYPE_NULLREF只能用在IDirect3D::CreateDevice時,其他的方法都不行。

            『創建表面的變化』

              創建表面(Surface)的方法變成了IDirect3DDevice9::CreateOffscreenPlainSurface,參數很簡單不用多說,需要注意的是可以選擇POOL了。

            『設定FVF的變化』

              設定FVF時,原來通過IDirect3DDevice8::SetVertexShader,現在有了一個專門用來設定FVF的方法:IDirect3DDevice9::SetFVF。這是個很好的變化,省得把FVF和Shader弄混(題外話:也就是因為這個變化,讓Shader在設備Reset后得以保存,不錯不錯)

            『獲取后備緩沖』

              D3D9現在允許有多個后備緩沖交換鏈,不過對于2D來說,基本不需要這種東西,IDirect3DDevice9::GetBackBuffer多出來的第一個參數賦值0即可。如果你有興趣,可以去研究一下這個玩意,有時候可以用來做分場。

            SetStreamSource』

              這個方法的功能被擴展了,對比參數就可以知道,多出來的OffsetInBytes允許你選擇一個頂點緩沖的Offset,D3D9將從這個Offset之后開始讀取數據。因此你可以把幾組用來渲染紋理的正方形頂點存儲到一個頂點緩沖里面。

            SetSamplerState』

              這個是D3D9的新方法,把原先SetTextureStageState的一些功能獨立了出來,和2D關系最密切的就是紋理過濾了。原先的D3DTSS_MINFILTER變成了D3DSAMP_MINFILTER,相應的D3DTSS_MAGFILTER也變成D3DSAMP_MAGFILTER,D3DTSS_MAXANISOTROPY變成D3DSAMP_MAXANISOTROPY。另外還有更多的,比如紋理尋址等。你去看一下D3DSAMPLERSTATETYPE枚舉類型的內容就知道它“遷移”了些什么。
              這個變化對于Shader來說很方便。改成Sampler的東西在PixelShader過程也會有效,而沒有更改的東西在PixelShader就不會有效了。D3D8時候把這些全都放在了一起,容易造成混亂。

            SetRenderTarget』

              D3D9現在允許多重RenderTarget存在,不過我們基本上只用一個,RenderTargetIndex設為0,第二個參數仍然是需要設定的表面。與D3D8相同的是,在設定之前仍然需要先通過GetSurfaceLevel獲得表面才行。

            『頂點緩沖的鎖定』

              注意IDirect3DVertexBuffer9::Lock的第三個參數,從原來的BYTE**變成了void**。也就是這樣了……

            『其他的一些變化』

            1、CopyRects變成了UpdateSurface。和UpdateTexture一樣,只能從D3DPOOL_SYSTEMMEM拷貝到D3DPOOL_DEFAULT
            2、增加了一個比較有用的IDirect3DDevice9::ColorFill方法,作用是向D3DPOOL_DEFAULT的某個區域填充顏色,和Clear的功能類似,但是在使用目的上要比Clear明確的多,并且由于不牽扯深度緩沖之類,速度要快一些。
            3、增加了一個IDirect3DDevice9::StretchRect方法,通過這個方法就可以在D3DPOOL_DEFAULT的表面或紋理之間進行帶過濾器的縮放操作,免去利用Render的過程,非常有用。不過這個方法由于使用了硬件處理,限制較多,請大家仔細看SDK文檔的Remarks部分。

            《D3DX的變化》

              D3DX的變化實際上相當的多,但正如我一開始所說,基本都是面向3D的。需要我們注意的有以下幾種:
            1、D3DX***FromFile之類的函數支持的圖像格式增加了,不過所增加的都是很少見的格式。平時基本上還是用BMP、TGA和PNG就足夠。
            2、增加了D3DXSave***ToFileInMemory,將會把文件寫入內存。這個函數的作用似乎不是很容易想到,但是如果你要寫一個集成了轉換、打包功能的工具,這個就很有用了,省去了通過臨時文件操作造成的各種問題。另外如果你熟悉某種圖形文件的格式的話,還可以通過直接訪問這個文件獲得RAW信息。注意,這類函數寫入的是一個ID3DXBuffer,這個東西很簡單,只有兩個特定的方法,一看便懂,不再多言。
            3、增加了一個ID3DXLine,可以方便你在2D上畫線,創建ID3DXLine的方法是D3DXCreateLine。這個東西也不復雜,使用方法有點像ID3DXSprite,稍微研究一下就能弄懂,注意每次Draw的是D3DPT_LINESTRIP。用它比直接用頂點緩沖的好處是可以方便的打開反鋸齒,效果嘛……基本滿意。
            4、增加了一個ID3DXRenderToSurface,“理論上來說”方便了利用RenderTarget的過程……不過我感覺反而弄得復雜了。創建的方法是D3DXCreateRenderToSurface,有心情的朋友自己研究看看吧,我就不講了。

              ID3DXSprite和ID3DXFont在Summer 2004的DX9 SDK(也就是第一版DX9.0c)開始發生了很大變化,下面詳述:

            『ID3DXSprite』

              你會發現ID3DXSprite::DrawTransform不見了,取而代之的是其功能被整合到ID3DXSprite::SetTransform里面,也就是說為了縮放和旋轉,我們不得不和矩陣打交道了。其實也不會太復雜,因為我們只是做一些矩陣運算,學過線性代數的朋友肯定會很熟悉,就算你不怎么熟悉線性代數,也沒關系,D3DX函數庫提供了現成的矩陣運算函數,你只要用就行了。

            D3DXMatrixScaling
            D3DXMatrixRotationZ
            D3DXMatrixTranslation

              按照順序調用這三個函數……或許學過3D的馬上就想到這點了,的確是沒錯啦。注意順序哦:Scaling -> Rotation -> Translation,簡稱SRT(看過全金屬狂潮嗎?看過的話這個單詞很好記吧^_^),弄錯了可是得不到正確結果的。
              你是不是想到把同一個D3DXMATRIX當作參數使用三次?錯啦!你要用矩陣乘法。創建三個D3DXMATRIX,比如mat1、mat2、mat3,分別用這三個函數將其創建為縮放矩陣、旋轉矩陣和平移矩陣,然后在ID3DXSprite::SetTransform時,這樣寫:

            SetTransform(mat1 * mat2 * mat3);

              有夠麻煩的是不?ID3DXSprite方便了做3D的,可害苦了做2D的,所以我已經不直接用這個了(什么叫不直接用?往下看)。

            『ID3DXFont』

              大家來歡呼吧!Summer 2004改進的ID3DXFont徹底槍斃掉了上一話那個字體引擎……
              這東西的改進,怎么說呢,應該說是改頭換面吧,速度、效果都和以前不是一個數量級??蓱z的PixelFont,才存在了一話就要被拋棄了。
              ID3DXFont多出來的幾個方法,Preload*()這類的,就是把一些常用的字的字模提前讀取到內存里面加快速度,同時還可以使用ID3DXSprite渲染,進一步加快速度。雖然內部仍然有GDI的部分,不過很明顯工作方式發生了極大的變化。根據我的估計,這次的ID3DXFont很聰明的利用GDI獲得文字的輪廓,然后通過紋理來渲染。這樣的速度就快得多了,而且文字質量也得到了很好的控制,基本和直接用GDI的質量相同了。
              由于PreloadCharacters()和PreloadGlyphs()不是那么好理解,一般用PreloadText()就行。建議將所有ASCII字符、標點符號和部分漢字預讀進去。這個預讀過程略微有點慢,而且根據預讀的文字數量和你創建文字的字號,占用的內存也不同。這里給大家一堆文字,你Copy過去就行:

            引用

            const char strPreloadText[] = " 1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM~!@#$%^&*()-=[]\\;',./_+{}|:\"<>? 、。·ˉˇ¨〃—~‖…‘’“”〔〕〈〉《》「」『』〖〗【】?。ⅲ#ぃィΓВǎ?,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}我人有的和主產不為這工要在第一上是中國經已發了民同";

              注意第一個字符是空格哦!把空格預讀進去可是很重要的^_^
              看上去并不多,因為要考慮到內存占用及速度,我只預讀了一些符號和五筆的一鍵字。這些字符在24號字時候已經占用了快1MB了,比起PixelFont字庫占用的要大得多。天知道ID3DXFont到底預讀了些什么……
              PreloadText()的第二個參數不要用strlen,sizeof(strPreloadText)即可。
              然后就是利用ID3DXSprite來渲染。注意ID3DXFont::DrawText的第一個參數就是LPD3DXSPRITE,因此如果要利用ID3DXSprite,要將ID3DXFont::DrawText放到ID3DXSprite::Begin和ID3DXSprite::End之間。這就是我剛才說的不直接用ID3DXSprite的意思,ID3DXFont會完成ID3DXSprite的全部調用,你不用擔心。
              另外你應該注意到ID3DXSprite::Begin增加了參數,實際上DX文檔里面沒說,但是示例里面有,如果想讓ID3DXSprite發揮作用并且最大幅度的提升效率,參數上設定D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE即可。意思很明白:打開Alpha過濾和紋理篩選。這里DX文檔上有個錯誤一直沒改:文檔里給出的是D3DXSprite__SORT_TEXTURE,但是你可以試試,絕對報錯。
              剩下的就沒啥了,ID3DXFont的使用方法上一話已經講過。要注意的是D3DXCreateFont和D3DXCreateFontIndirect都發生了變化。D3DXCreateFont已經不再牽扯GDI了,D3DXCreateFontIndirect所使用的結構也變成了D3DXFONT_DESC,相對于LOGFONT結構,除去了一些用不著的參數,增加了一個MipLevels,就是MipMap等級啦,不用多說,2D下只用1。其他的上一話都有。實際上由于D3DXCreateFont已經不再關聯GDI,D3DXCreateFontIndirect的存在僅僅是由于歷史原因(為了兼容像我這種人的使用習慣),大家還是用D3DXCreateFont吧,省事。
              截圖就不貼了,沒啥意義。你可能覺得直接向后備緩沖上DrawText還不夠好看,那么就先畫到一張紋理上,然后將紋理錯位渲染到后備緩沖并且打開線型過濾,就可以達到和PixelFont相同的效果了。
              速度嘛……我畫了整整一屏幕字,在不緩沖文字的情況下(這個“緩沖文字”和ID3DXFont的文字緩沖可不是一回事啊!看過上一話的都應該知道我這里指的是什么),速度仍然在120FPS以上。或許你會覺得速度還是有點慢,但是,如果用D3D8的ID3DXFont畫上這么一屏幕,基本就只剩20FPS了。
              使用ID3DXFont替換掉PixelFont的優勢就是可以方便的自定義字體字號了,并且也不再受GB2312字庫的限制。所以大家都換了吧……都換了吧……把PixelFont忘了吧……

            『穩定的DX9 SDK版本』

              我現在用的是April 2006,而且應該會用很長時間。August 2006我是肯定不會去用啦!即使我不再恐懼D3D9,也會對這個SDK避讓三分的。其實對于2D,我感覺用到April 2006就足夠了,之后的DX9 SDK主要在D3DX的3D函數庫部分進行更改……其實也是秋后的螞蚱蹦達不了幾天,D3D10馬上就要出來了。要說D3D10啊……你還是看我另外一篇日志好了,總之打死我都不拿它做2D。

              實際上僅僅是2D的話,從D3D8轉向D3D9并沒有多少變化,主要是穩定嘛!只要你不調用一些D3D9專用的功能,即使拿D3D9來做2D,在絕大多數顯卡上還是能夠運行的。嗯……GF2等級以上吧,GF2之前的,也太老了,無視好了。

            《再上點菜好了:全屏幕模式》

              其實并不是多么復雜的問題,讓我拖了這么久……不拖了,這里就教給大家如何做全屏幕模式以及如何處理設備丟失的問題。

            『創建全屏幕模式』

              D3DPRESENT_PARAMS里面,Windowed設定為false,并且一定要設定BackBufferWidth和BackBufferHeight,完畢。
              哈哈,就這么簡單,或許早就有人嘗試過了,但是你試試按下Alt+Tab,再切換回去,保證你什么都看不到。
              之前曾經說過,DX8之前的版本,在全屏幕下工作比在窗口下容易,到DX8之后就則完全顛倒過來。因為在窗口模式下不用擔心設備丟失(除非你更改桌面分辨率),全屏幕模式下就會有這個問題了。下面詳述:

            『設備、資源丟失』

              設備丟失會發生在全屏幕模式下切換回桌面時(不論是通過Alt+Tab還是QQ上有人給你發了張圖片-_-bbb),而且如果在調用IDirect3DDevice9::Reset(從現在開始就是D3D9了啊!忘記D3D8吧……)的時候發生錯誤,設備也會丟失。
              設備丟失會造成資源丟失:所有創建在D3DPOOL_DEFAULT池的資源都會丟失,需要重新創建,其內容當然也會消失,需要重寫。
              然而創建在D3DPOOL_SYSTEMMEM和D3DPOOL_SCRATCH池的資源不會受到影響。創建在D3DPOOL_MANAGED池的資源也不會丟失,而且在設備重新可用的時候,D3DPOOL_MANAGED池的資源也可以立即投入使用,內容也不會改變。看這個池名字:托管池就能知道,D3D幫你處理了所有問題。
              因此避免設備丟失后資源丟失的簡易方法就是將所有資源創建在D3DPOOL_MANAGED池內。不過這并不是個好方法,這意味著不能用渲染對象——記得嗎?RenderTarget只能創建在D3DPOOL_DEFAULT。實際上最好的方法是跟蹤所有D3DPOOL_DEFAULT資源,比如利用std::list,將所有D3DPOOL_DEFAULT資源勾住,在設備發生丟失的時候釋放掉資源,設備可以繼續使用的時候重新創建資源,記得把數據寫回去。對于其他的池就不用這么折騰了。

            『當設備丟失之后』

              不論通過任何方式發生了設備丟失,所有的操作幾乎都會失效,只有Release()可以用——其實D3D會保證有部分操作可以成功,但是也僅僅是“可以”成功而不是“一定”成功,所以你還不如認定丟失的時候全都會失敗比較好——以及IDirect3DDevice9::TestCooperativeLevel。因此在設備丟失之后,你應該停止整個游戲循環,而通過反復調用IDirect3DDevice9::TestCooperativeLevel判斷設備是否可用。

            『IDirect3DDevice9::TestCooperativeLevel』

              這個方法檢測當前的設備狀態。返回值有四種:D3D_OK一切正常,D3DERR_DEVICELOST設備丟失,D3DERR_DEVICENOTRESET設備可以Reset。另外還有D3D9新增的D3DERR_DRIVERINTERNALERROR,遇到這個你就完蛋了,基本不可能恢復了,終止程序吧。
              按照順序來講,如果游戲在正常運行,D3D_OK會返回;如果發生了設備丟失并且在這個時候不能恢復,比如全屏幕模式的時候用戶切換到了Windows桌面,就會返回D3DERR_DEVICELOST;如果用戶又切換回了游戲,設備可以恢復了(還沒恢復呢!只是“可以”恢復而已),就會返回D3DERR_DEVICENOTRESET。
              另外,IDirect3DDevice9::Present也會返回類似的值,不過你最好別指望這個,老老實實的用TestCooperativeLevel。因為Present在設備可以恢復的時候還是返回D3DERR_DEVICELOST(外一句:D3D10的時候TestCooperativeLevel就會完全整合到Present里面了,可喜可賀可喜可賀)

            『處理設備丟失』

              看下面的偽代碼:

            switch (IDirect3DDevice9::TestCooperativeLevel()){
              case D3D_OK:
                GameLoop();
                break;
              case D3DERR_DEVICELOST:
                break;
              case D3DERR_DEVICENOTRESET
                OnLostDevice();
                IDirect3DDevice9::Reset();
                OnResetDevice();
                break;
              default:
                QuitGame();
                break;
            }

              GameLoop()就是你的游戲運行的過程了。把這個switch寫在我們游戲框架的GameMain()部分,具體的位置可以看任何一話附帶的源代碼。
              好像我一直沒有講IDirect3DDevice9::Reset的參數啊?因為只有一個參數,就是指向D3DPRESENT_PARAMS的指針。把你第一次創建設備時使用的D3DPRESENT_PARAMS結構保存起來,供Reset來用。
              OnLostDevice()就是Release掉所有D3DPOOL_DEFAULT的資源,OnResetDevice()就是Create*()恢復啦!你可能注意到ID3DXFont、ID3DXSprite等等都有同名的方法,就是在這個時候調用的。如果你沒有這么做,也就是說還保留著任何D3DPOOL_DEFAULT的資源的話,IDirect3DDevice9::Reset就一定會失敗。
              另外在OnResetDevice里面你還要重新進行SetRenderState、SetSamplerState等等,Reset之后這些東西也丟失了。實際上Reset和重新創建一次設備類似,所不同的是重新創建設備的話你需要連D3DPOOL_MANAGED的資源也Release掉。這個話題就不討論了。
              從代碼可以看出來,D3DERR_DEVICELOST時程序什么都沒做,只是在傻等。我認為這是一個好習慣,因為實在不能保證在D3DERR_DEVICELOST時除了Release還能干什么,與其這樣還不如等設備能用了再說。

              實在懶得管資源的話,全部D3DPOOL_MANAGED好了。至于渲染對象?自己想辦法。

            『人工制造“設備丟失”』

              “干嘛還要制造設備丟失???”如果更改游戲分辨率、色深、切換全屏幕及窗口狀態,進行這樣的操作也要通過Reset,同樣的,Reset之前也要釋放掉所有D3DPOOL_DEFAULT資源(其實嚴格來說,還有更多的資源也要釋放,不過在2D下基本不會創建這類資源,你就不用管了)并且調用ID3DXSprite::OnLostDevice之類的方法。這就是人工制造“設備丟失”了。實際上在這個過程設備并沒有真正的丟失,只是會有一段時間處于不可用的狀態,此時Reset尚未返回,整個D3D設備就好像死了一樣。舉個例子,你切換桌面分辨率,會有那么一段時間顯示器上什么都不顯示,然后很快就正常了。和這個現象是同一個原因。Reset成功后記得恢復資源。
              你可能注意到這里的Reset和上面的Reset不是一回事。的確是這樣,這里是為了重設狀態而不是恢復設備。因此更改分辨率、色深的Reset需要寫到switch外面,也就是別和它攪和的意思-_-bb。而且你只需要OnLostDevice -> Reset -> OnResetDevice。記?。赫_的調用Reset不會造成設備丟失,這個概念別弄混了。

            『切換全屏幕模式時的注意事項』

              注意WindowStyle的變化。切換成全屏幕模式后,只能使用WS_POPUP,不然顯示會變得怪怪的,你可以通過SetWindowLongPtr函數更改窗口外觀,第二個參數指定GWL_STYLE即可。別忘了WS_VISIBLE啊!不然你什么都看不見。

            『更詳細的文檔』

              我這里只是簡單討論了造成設備丟失的原因及處理方法,更詳細的內容你可以參考DX SDK文檔的Lost Device文章,人家是權威的。

            【以上,正片結束,后面是ED】

              我們前進到了D3D9,趕上了時代。
              我們創建了全屏幕游戲,趕上了時代。
              我卻變得一腦子漿糊,被觀眾拋棄了。
              哈哈,開玩笑啦,不過這一話很亂倒是真的,因為不論是更新到D3D9還是設備丟失,牽扯的東西都太散太雜,結果弄得這一話也是一盤散沙(居然又沒有附帶代碼)。唉,大家就忍了吧,忍不了的話就來PIA我吧。

              關于更新至D3D9更多的內容,你可以參考SDK文檔的《Converting to Direct3D 9》。

            【以上,ED結束,后面是……】

              第一季完結了……
              回過頭來看看,從第一話創建一個Windows窗口,到這一話的設備丟失,話題的層次一直在深入,現在已經深入到了不再是“學習”而是“研究”的范圍。我也不再想僅僅是搞“教學”而是想和大家“討論”。不過第一季主要還是教學吧。能堅持著看D2D教程到現在的,應該基本能夠寫出完整的2D Demo來了吧。如果有什么問題的話,歡迎提出,我在看到后會立刻回答的……只要你這個問題不太RP的話……
              那么,第二季會是什么樣子?
              第二季就不再是教學了,而開始我和大家的討論過程。第二季的第一話,也就是第09話,我將提供一些高級技巧給大家,并希望有興趣的朋友和我一起進行這些技巧的研究。另外在第二季里面,我們還要創建一個2D圖形引擎。原來打算給大家講解Medux 2,不過現在感覺這東西實在小兒科,絕對會讓大家B4的。那么既然如此,干脆介紹Mercury 3好了,有意見無?
              透漏一點下一話的內容吧:模糊精度和多次紋理渲染,嘿嘿,聽上去挺高深的是不?實際上超級簡單,就看你能不能想到而已。
              希望你在看完這一話之后,返回去再把前面的內容看看,相信你會得到新的收獲。搞不好你還能抓出幾個Bug呢!因為我是想到什么寫什么,沒個章法,Bug是難免的。
             


            附加:

            Direct3D中的字體與文本顯示
            圖形系統中為了獲得當前運行程序的相關信息,往往需要在屏幕上顯示文本,Direct3D的功能擴展接口ID3DXFont對此提供了方便的解決方法。

             

             

            創建ID3DXFont對象

            使用接口ID3DXFont繪制文本,首先需要通過函數D3DXCreateFont()創建ID3DXFont字體對象。ID3DXFont接口封裝了Windows字體和Direct3D設備指針,D3DXCreateFont()函數通過Windows字體和Direct3D設備指針創建ID3DXFont對象,該函數的聲明如下:

            Creates a font object for a device and font.

            HRESULT D3DXCreateFont(  LPDIRECT3DDEVICE9 pDevice,  INT Height,  UINT Width,  UINT Weight,  UINT MipLevels,  BOOL Italic,  DWORD CharSet,  DWORD OutputPrecision,  DWORD Quality,  DWORD PitchAndFamily,  LPCTSTR pFacename,  LPD3DXFONT * ppFont);
            Parameters
            pDevice
            [in] Pointer to an IDirect3DDevice9 interface, the device to be associated with the font object.
            Height
            [in] The height of the characters in logical units.
            Width
            [in] The width of the characters in logical units.
            Weight
            [in] Typeface weight. One example is bold.
            MipLevels
            [in] The number of mipmap levels.
            Italic
            [in] True for italic font, false otherwise.
            CharSet
            [in] The character set of the font.
            OutputPrecision
            [in] Specifies how Windows should attempt to match the desired font sizes and characteristics with actual fonts. Use OUT_TT_ONLY_PRECIS for instance, to ensure that you always get a TrueType font.
            Quality
            [in] Specifies how Windows should match the desired font with a real font. It applies to raster fonts only and should not affect TrueType fonts.
            PitchAndFamily
            [in] Pitch and family index.
            pFacename
            [in] String containing the typeface name. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
            ppFont
            [out] Returns a pointer to an ID3DXFont interface, representing the created font object.
            Return Values
            If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

            Remarks
            The creation of an ID3DXFont object requires that the device supports 32-bit color.

            The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateFontW. Otherwise, the function call resolves to D3DXCreateFontA because ANSI strings are being used.

            If you want more information about font parameters, see The Logical Font.

            示例代碼如下:

            D3DXCreateFont(g_device, 50, 20, 20, 0, FALSE, DEFAULT_CHARSET, 0, 0, 0, "Arial", &g_font);

            posted on 2009-09-12 07:40 RedLight 閱讀(2387) 評論(0)  編輯 收藏 引用 所屬分類: 3D渲染技術

            <2009年6月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            導航

            統計

            公告


            Name: Galen
            QQ: 88104725

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            相冊

            My Friend

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            三级片免费观看久久| 久久久久久久99精品免费观看| 久久福利青草精品资源站免费| av国内精品久久久久影院| 国产日韩久久久精品影院首页| 久久伊人中文无码| 伊人久久综合精品无码AV专区| 国产精品久久久天天影视| 精品国产乱码久久久久久浪潮| 久久亚洲精品国产亚洲老地址| 久久久久久久久久久久中文字幕 | 久久天天躁狠狠躁夜夜av浪潮| 久久精品国产清自在天天线| 久久国产精品99久久久久久老狼| 亚洲欧美国产精品专区久久| 国产精品久久久久AV福利动漫| 少妇久久久久久被弄到高潮| 99国产欧美久久久精品蜜芽| 久久国产免费直播| 久久亚洲国产精品五月天婷| 国产精品久久久久aaaa| 一本色综合网久久| 麻豆精品久久久久久久99蜜桃| 99久久免费国产精品| 狠色狠色狠狠色综合久久 | 久久亚洲精品视频| 久久精品天天中文字幕人妻| 无码国内精品久久综合88| 久久涩综合| 久久国产精品视频| 久久亚洲高清观看| 99久久免费只有精品国产| 久久免费视频观看| 久久久国产精品网站| 国内精品伊人久久久久AV影院| 亚洲国产精品无码成人片久久| 久久久噜噜噜久久中文字幕色伊伊 | 久久久国产精华液| 亚洲国产成人精品91久久久| 久久99精品久久久久久噜噜| 久久精品亚洲日本波多野结衣|