如果是制作一個(gè)游戲,文字是其中比不可少的一部分,這篇文章主要討論Direct3D中3中顯示文字的方式。
1. ID3DXFont
D3DX 庫提供了一系列基于ID3DXFont的接口來繪制文字。IDXDFont 是基于GDI 來繪制文字的。正因?yàn)榇,ID3DFont能提供非常復(fù)雜的字體和格式,但是效率顯然沒直接往顯卡上畫東西高了。
創(chuàng)建和顯示一個(gè)ID3DXFont通常需要如下幾個(gè)步驟
(1) 填充 D3DXFONT_DESC結(jié)構(gòu)體。
1 D3DXFONT_DESC fontDesc;
2 ZeroMemory(&fontDesc, sizeof(D3DXFONT_DESC));
3 fontDesc.Height = 25; // in logical units
4 fontDesc.Width = 12; // in logical units
5 fontDesc.Weight = 500; // boldness, range 0(light) - 1000(bold)
6 fontDesc.MipLevels = D3DX_DEFAULT;
7 fontDesc.Italic = false;
8 fontDesc.CharSet = DEFAULT_CHARSET;
9 fontDesc.OutputPrecision = 0;
10 fontDesc.Quality = 0;
11 fontDesc.PitchAndFamily = 0;
12 lstrcpy (fontDesc.FaceName, _T("Times New Roman"));
(2) 創(chuàng)建 ID3DXFont 接口 。
(3) 調(diào)用 ID3DXFont::DrawText() 繪制文字。
1 //Draw the scene
2 Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ffff, 1.0f, 0);
3 Device->BeginScene();
4 RECT rect = {250, 200, Width, Height};
5 font->DrawText(NULL,
6 _T("ID3DXFont"),
7 -1, // size of string or -1 indicates null terminating string
8 &rect, // rectangle text is to be formatted to in windows coords
9 DT_TOP | DT_LEFT, // draw in the top left corner of the viewport
10 0xffff0000); // black text
11 Device->EndScene();
12 Device->Present(0,0,0,0);
得到了如下圖 1所示的文字:
圖 1
嗯, 非常簡單!不是嗎?
2. CD3DFont
在以前版本的Directx SDK 中提供了一個(gè)類CD3DFont 來繪制文字,該類主要用紋理三角形和Direct3D來渲染文字,所以其效率要高于用ID3DXFont::DrawText() 。但是這種方法的缺點(diǎn)就是不能像ID3DXFont::DrawText()那樣有提供復(fù)雜的字體和格式。這個(gè)example在最新的Directx SDK中已經(jīng)取消掉,所以在這里也不過多介紹。個(gè)人認(rèn)為CD3DFont就是個(gè)雞肋。我看了下最新Directx SDK下的Text3D樣列,發(fā)現(xiàn)只用了ID3DXFont::DrawText()方法和下面介紹的D3DXCreateText方法。
3. D3DXCreateText
使用這種方式來渲染文字就會像渲染幾何體一樣來渲染。如下圖 2:
圖 2
使用D3DXCreateText()來渲染文字就是簡單的把文字認(rèn)為是一個(gè)ID3DXMesh,然后就以渲染ID3DXMesh的方式來渲染文字。 下面是一個(gè)簡單的例子:
(1). 首先需要得到我們屏幕的DC和我們需要?jiǎng)?chuàng)建的字體, 這里調(diào)用的是Win32的API和結(jié)構(gòu)體。
1 HDC hdc = CreateCompatibleDC(0);
2 HFONT hFont;
3 HFONT hFontOld;
4 LOGFONT lf;
5 ZeroMemory(&lf, sizeof(LOGFONT));
6 lf.lfHeight = 25; // in logical units
7 lf.lfWidth = 12; // in logical units
8 lf.lfEscapement = 0;
9 lf.lfOrientation = 0;
10 lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
11 lf.lfItalic = false;
12 lf.lfUnderline = false;
13 lf.lfStrikeOut = false;
14 lf.lfCharSet = DEFAULT_CHARSET;
15 lf.lfOutPrecision = 0;
16 lf.lfClipPrecision = 0;
17 lf.lfQuality = 0;
18 lf.lfPitchAndFamily = 0;
19 lstrcpy(lf.lfFaceName, _T("Times New Roman")); // font style
20 hFont = CreateFontIndirect(&lf);
21 hFontOld = (HFONT)SelectObject(hdc, hFont);
(2). 然后調(diào)用D3DXCreateText()接口來創(chuàng)建ID3DXMesh。
1 D3DXCreateText(Device, hdc, _T("Direct 3D"),0.001f, 0.4f, &Text, 0, 0);
(3).不要忘了刪除資源
1 SelectObject(hdc, hFontOld);
2 DeleteObject(hFont);
3 DeleteDC(hdc);
(4). 然后是D3D在典型的幾步: 設(shè)置燈光, 設(shè)置坐標(biāo)系, 設(shè)置攝像頭, 視口轉(zhuǎn)換
(5). 一切準(zhǔn)備完畢了, 就可以顯示文字了。
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
1 //Draw the scene
2 Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3 Device->BeginScene();
4 Device->SetMaterial(&d3d::WHITE_MTRL);
5 Text->DrawSubset(0);
6 Device->EndScene();
7 Device->Present(0, 0, 0, 0);
這樣一個(gè)如圖 2 所示的圖片就出來了。