青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

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徹底槍斃掉了上一話那個字體引擎……
  這東西的改進,怎么說呢,應該說是改頭換面吧,速度、效果都和以前不是一個數量級。可憐的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 閱讀(2444) 評論(0)  編輯 收藏 引用 所屬分類: 3D渲染技術

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導航

統計

公告


Name: Galen
QQ: 88104725

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

相冊

My Friend

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美在线观看一区| 久久影院午夜论| 亚洲免费网址| 亚洲经典三级| 亚洲第一在线综合在线| 国产日韩欧美麻豆| 国产精品高清免费在线观看| 欧美一区二区三区视频免费| 久久免费视频在线观看| 免费成人av在线| 久久精品日韩| 精品999日本| 国产视频久久久久久久| 欧美午夜精品久久久久免费视| 久久精品动漫| 久久久精品一品道一区| 欧美一级在线视频| 欧美亚洲在线观看| 亚洲免费中文字幕| 欧美一区三区三区高中清蜜桃| 亚洲久久在线| 亚洲一区二区三区777| 亚洲精品国精品久久99热一| 欧美影院视频| 久久综合网络一区二区| 麻豆九一精品爱看视频在线观看免费| 国产亚洲网站| 亚洲精品久久在线| 欧美激情一区二区三区成人 | 亚洲一区二区三区777| 99re视频这里只有精品| aⅴ色国产欧美| 久久精品国产v日韩v亚洲| 久久综合网络一区二区| 欧美精品情趣视频| 国产精品一区二区a| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美在线视频网站| 欧美国产欧美亚洲国产日韩mv天天看完整 | 久久久久久9| 亚洲高清毛片| 欧美中文字幕在线视频| 国产精品久久久久高潮| 亚洲免费播放| 亚洲第一精品久久忘忧草社区| 一片黄亚洲嫩模| 欧美日韩一区二区三区视频 | 久久亚洲精品欧美| 精品9999| 激情成人在线视频| 欧美日产在线观看| 欧美一区二区三区四区在线观看地址 | 久久久国际精品| 亚洲精品一区二区三区不| 国产精品五月天| 国产美女扒开尿口久久久| 久久久亚洲高清| 欧美成人亚洲| 伊人伊人伊人久久| 亚洲欧美日韩国产中文 | 久久久亚洲高清| 香蕉久久夜色| 亚洲精品三级| 久久久久久9999| 国产精品日韩一区| 亚洲一区二区视频| 亚洲一区二区久久| 国产精品区二区三区日本| 亚洲婷婷在线| 亚洲毛片av| 久久成人18免费网站| 正在播放亚洲| 国产精品男女猛烈高潮激情| 亚洲区一区二| 亚洲电影在线| 老司机一区二区| 亚洲激情一区二区| 亚洲欧洲综合另类在线| 夜夜嗨av一区二区三区四季av| 免费一级欧美片在线观看| 欧美在线免费观看| 欧美激情日韩| 一本色道久久| 日韩视频免费在线观看| 久久疯狂做爰流白浆xx| 国产一区二区毛片| 久久综合九色综合欧美就去吻| 久久亚洲春色中文字幕久久久| 国产精品你懂的| 久久琪琪电影院| 老牛影视一区二区三区| 亚洲精品一区二区三区在线观看| 亚洲激情一区| 国产精品裸体一区二区三区| 免费高清在线一区| 国产一区视频观看| 一本色道久久精品| 国产欧美成人| 亚洲全黄一级网站| 国产精品私拍pans大尺度在线| 国产精品红桃| 亚洲日本欧美| 亚洲国产美女| 老**午夜毛片一区二区三区| 欧美在线观看一区二区| 亚洲欧洲在线看| 精品电影在线观看| 亚洲激情偷拍| 亚洲精品国产精品国自产观看浪潮 | 亚洲亚洲精品三区日韩精品在线视频| 国产精品v亚洲精品v日韩精品| 欧美刺激午夜性久久久久久久| 欧美色另类天堂2015| 久久中文字幕一区| 国产日韩欧美在线| 久久久蜜桃一区二区人| 午夜精品久久久久久久99水蜜桃| 欧美色图首页| 一区二区三区视频在线观看| 一区二区三区高清| 国产精品卡一卡二卡三| 欧美伊人精品成人久久综合97| 欧美在线啊v一区| 在线日韩视频| 久久精品欧洲| 日韩一区二区精品| 老司机成人网| 午夜精品理论片| 亚洲国产一区二区视频| 国产精品美女999| 新狼窝色av性久久久久久| 欧美激情精品久久久久| 亚洲国产一区二区三区a毛片 | 欧美一区国产二区| 在线观看日韩av先锋影音电影院| 久久手机精品视频| 久久综合给合久久狠狠色| 亚洲精品日韩在线| 久久久国产精品一区二区中文| 最新高清无码专区| 欧美在线中文字幕| 欧美亚洲第一页| 亚洲国产成人在线| 国产欧美精品一区二区色综合| 亚洲精品国产精品乱码不99按摩| 国内成人精品视频| 欧美在线日韩| 久久成人这里只有精品| 欧美揉bbbbb揉bbbbb| 在线视频一区观看| 亚洲一级免费视频| 欧美日韩在线播放一区| 日韩视频二区| 日韩一级成人av| 国产精品久久久久99| 亚洲精品三级| 中文精品视频一区二区在线观看| 欧美日韩激情小视频| 亚洲国产婷婷香蕉久久久久久| 精品99视频| 欧美成人网在线| 亚洲日本视频| 亚洲一级网站| 欧美日韩午夜| 亚洲一区二区三区成人在线视频精品| 亚洲欧美中文另类| 亚洲国产99精品国自产| 欧美黄网免费在线观看| 亚洲一区免费视频| 久久综合综合久久综合| 99综合在线| 国产精品超碰97尤物18| 校园春色综合网| 亚洲人成艺术| 欧美在线观看你懂的| 亚洲精品国产品国语在线app| 欧美日韩在线精品| 久久久久se| 一本到12不卡视频在线dvd| 久久久777| 一本高清dvd不卡在线观看| 国产亚洲网站| 欧美无乱码久久久免费午夜一区| 欧美在线观看你懂的| 亚洲精品午夜| 亚洲亚洲精品三区日韩精品在线视频| 精品99一区二区三区| 欧美日韩调教| 欧美激情在线免费观看| 欧美一级久久久久久久大片| 亚洲人成网站精品片在线观看| 欧美专区日韩专区| 99在线|亚洲一区二区| 国产在线精品二区| 国产精品久久久久久久7电影| 蜜桃av综合| 久久久久久综合网天天| 午夜在线a亚洲v天堂网2018| 亚洲精品乱码| 亚洲第一在线综合网站|