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

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>
            欧美高清视频一区| 欧美在线播放一区二区| 亚洲免费一区二区| 亚洲一区二区少妇| 欧美精品99| 日韩视频欧美视频| 亚洲免费伊人电影在线观看av| 久久久精品一品道一区| 久久频这里精品99香蕉| 国产婷婷色一区二区三区四区| 亚洲精品久久久久久久久久久久久 | 午夜精品免费| 久久九九久精品国产免费直播| 亚洲在线国产日韩欧美| 久久久久国产精品一区三寸| 亚洲区中文字幕| 欧美性猛交视频| 久久人人看视频| 一区二区三区三区在线| 久久综合久色欧美综合狠狠| 国产精品久久一级| 卡一卡二国产精品| 欧美在线观看www| 久久狠狠一本精品综合网| 亚洲一级二级| 亚洲午夜电影在线观看| 久久亚洲精品伦理| 国产精品伦理| 99精品99| 亚洲午夜羞羞片| 蜜臀av一级做a爰片久久| 亚洲男人天堂2024| 欧美在线日韩| 欧美在线一区二区| 欧美成人国产一区二区| 久热精品视频在线免费观看| 久久国产精品亚洲77777| 久久福利毛片| 国产精品久久影院| 亚洲一区二区四区| 一区二区欧美日韩| 亚洲欧美视频一区| 激情综合自拍| 亚洲香蕉成视频在线观看| 久久精品国产亚洲高清剧情介绍| 欧美久久久久久久久| 欧美三级在线播放| 国产免费成人av| 亚洲免费在线播放| 欧美性色视频在线| 欧美一区二区三区四区视频| 亚洲国产精品久久久久秋霞蜜臀| 精品va天堂亚洲国产| 欧美77777| 欧美激情在线观看| 亚洲视频免费在线| 99精品视频网| 亚洲欧美在线观看| 欧美日韩一区二区三| 久久婷婷一区| 亚洲美女av电影| 久久永久免费| 欧美日韩精品一区二区三区| 欧美高清视频在线| 久久成人国产精品| 亚洲人成人77777线观看| 一区二区日韩| 91久久在线观看| 香蕉成人伊视频在线观看| 免费的成人av| 精品91在线| 亚洲欧美日本在线| 宅男精品导航| 欧美高清不卡| 亚洲免费小视频| 欧美激情精品| 国产欧美一区二区色老头| 国产欧美日韩视频一区二区三区| 一区二区不卡在线视频 午夜欧美不卡'| 香蕉久久夜色| 欧美在线观看网站| 午夜精品久久久久久久久 | 亚洲免费av片| 久久免费少妇高潮久久精品99| 久久精品人人爽| 久久精品一区四区| 欧美尤物一区| 黄网动漫久久久| 久久福利影视| 巨胸喷奶水www久久久免费动漫| 国语自产偷拍精品视频偷| 一本色道久久88亚洲综合88| 99re6这里只有精品| 在线亚洲高清视频| 国产精品区一区二区三区| 久久久久久91香蕉国产| 国产日韩专区在线| 美腿丝袜亚洲色图| 这里只有精品在线播放| 欧美在线啊v| 亚洲美女在线国产| 国产女人18毛片水18精品| 久久网站热最新地址| 亚洲精品一区二区三区av| 亚洲激情女人| 欧美一区二区三区精品| 一本一本久久a久久精品牛牛影视| 欧美日韩精品福利| 久久成人在线| 免费久久99精品国产| 久久久久久91香蕉国产| 在线亚洲精品福利网址导航| 欧美国产成人精品| 香蕉国产精品偷在线观看不卡 | 日韩午夜在线视频| 欧美搞黄网站| 久久久青草婷婷精品综合日韩| 亚洲视频专区在线| 欧美久久久久久久久久| 老司机aⅴ在线精品导航| 久久精品国产视频| 久久不射2019中文字幕| 亚洲综合欧美日韩| 亚洲国产高潮在线观看| 国产日韩欧美一区二区| 国产精品国产三级国产普通话蜜臀| 亚洲精品永久免费| 亚洲国产综合在线看不卡| 亚洲制服av| 一区二区三区视频在线观看| 亚洲视频999| 欧美一区二区三区免费观看| 久久精品夜色噜噜亚洲a∨ | 亚洲精品极品| 亚洲自拍另类| 免费观看日韩av| 99成人在线| 久久天天综合| 欧美日韩一区二区三区在线视频| 欧美视频在线一区| 在线日韩视频| 亚洲国产精品va在线观看黑人 | 国产一区二区毛片| 国产精品国产三级国产a| 国产综合色产| 伊大人香蕉综合8在线视| 国产精品久久久久久久电影| 亚洲欧美日韩精品久久奇米色影视| 亚洲无吗在线| 欧美精品www在线观看| 一区在线视频| 麻豆成人综合网| 亚洲影院免费| 一本色道久久综合| 欧美1区2区3区| 亚洲第一福利视频| 猛男gaygay欧美视频| 欧美一区二区免费观在线| 国产精品久久夜| 欧美一区二区三区在线看| 日韩视频在线一区二区| 久久国产高清| 狠狠色丁香久久婷婷综合_中| 欧美在线视频一区| 欧美一区二区日韩| 国产区亚洲区欧美区| 久久爱www| 可以看av的网站久久看| 亚洲精品在线观看免费| 亚洲欧洲一级| 亚洲男女自偷自拍图片另类| 国产精品久久| 免费观看日韩| 国产精品高清网站| 久久综合成人精品亚洲另类欧美 | 亚洲一区影音先锋| 欧美一区2区三区4区公司二百| 精品69视频一区二区三区 | 亚洲午夜精品一区二区三区他趣| 亚洲欧美视频一区| 亚洲乱码国产乱码精品精98午夜| 中文av一区二区| 亚洲看片一区| 美女黄网久久| 久久综合综合久久综合| 欧美日本精品在线| 欧美肥婆bbw| 精久久久久久| 欧美激情一区二区三区全黄 | 国产欧美日韩亚洲精品| 欧美黄色免费| 影音先锋欧美精品| 欧美在线关看| 久久影视三级福利片| 国产欧美丝祙| 久久精品91久久久久久再现| 香蕉乱码成人久久天堂爱免费| 欧美日韩黄视频| 日韩视频二区| 午夜久久黄色|