http://www.5178c.cn/article/6/2006/200605173892.html
5 i1 H! y0 M6 L9 k5 a( x# W+ ^8 ?. \. p1 Q3 G* s" F
在DirectX 9.0中渲染文字 - b- l, [! D* l# h6 E$ ^' L9 t/ H9 I
作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin 9 }! s7 H9 G$ d8 z3 z9 J# t4 r
减小字体 增大字体
$ c4 p& a4 y' Y9 u( u+ u( p) i( [' E5 l8 u7 C2 V0 q& y' ^
9 z, _- v+ L# U, ^; r f
; j' j2 P# M _$ y% F6 p, t% p' \7 X* N. e. ?8 s" R( G. J& B3 F5 M3 k
7 j [ C; o, j; Z* p
! I+ q* ^* X3 {( G# E9. 字体: B0 c6 S* d5 T0 @; V
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
( q) o# j5 i. k5 r4 y# k6 q+ z$ X% D3 }! ~# ]1 h& X0 I
4 ] b* }, B0 S
2 G' }+ l6 q# k' |2 n在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:4 f( E* ]- ]' W0 N9 S
?! t7 k1 q8 ` g" a2 k3 z
l 学习如何使用ID3DXFont接口渲染文字
8 [. [5 U) @% k! W2 f
/ ?% ~* a; |+ h4 F2 J4 Ol 学习如何使用CD3DFont类渲染文字
1 i0 ^! X# H$ ~" y- Y1 i& e% g9 r9 U1 X6 U" M
l 学习计算游戏帧速度的方法
# ?; g$ e- y3 h# A, @" Y+ r- z8 K- D' h; x% x' d/ j6 d( K
l 学习使用D3DXCreateText函数创建3D文字
9 |8 ~- F: T* G2 v3 k# b
5 g; m. \3 c; e* X0 Z" [9.1. ID3DXFont
* m' ~2 T: u5 l! w6 V% i$ n( V$ R要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。8 u+ q+ P0 W$ |/ m/ ?: X
2 t A% c' O1 V/ m: d% D2 f$ p' u, w9.1.1. 创建一个ID3DXFont
- L" G1 u% j' U9 l可使用D3DXCreateFontIndirect函数创建ID3DXFont:
' F" V: J- L! s' R+ _
8 @; W9 @% r0 F! n" hHRESULT WINAPI D3DXCreateFontIndirect(* {3 Y3 x4 ~; h
Z0 K' ?( t2 e7 l LPDIRECT3DDEVICE9 pDevice,1 D( j& D/ E5 L/ I9 o
9 w8 d! D: [6 o$ y
CONST D3DXFONT_DESC *pDesc,
4 a6 x& R" _3 b n* ^
0 |# W% W* o2 m- m' l* x LPD3DXFONT *ppFont. S. Z5 M% t. h# F
0 c' O- }# Z( I0 p5 y9 A
);# J0 U+ M7 a% G- W/ q; v0 D
G& v: o8 h4 ^$ y* w1 C) e a5 K
8 _2 h) E5 o* z+ P
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!( g {- O4 E5 ?5 A
. e% j% {7 \# G e, C* o使用这个函数时,需要一个D3DXFONT_DESC结构:8 }7 h v! [- z/ m
7 e& ^; ]* m! \7 J
D3DXFONT_DESC d3dFont;0 Y% O: K" u" A: ~$ _: N, h
6 `* L) A4 I. f- k1 H; ~' {6 H( H& w
memset(&d3dFont,0,sizeof(d3dFont));
1 q( s- d w4 f0 N& T R: p( {) x
* M# K# c. _- m- A8 rd3dFont.Height=25; // in logical units
) \: y% \+ U' X) K+ m1 U! A q1 c/ H% T, j# s2 \ [& z
d3dFont.Width=12; // in logical units
J0 d7 C1 w' i9 ^! O( ]6 \" L8 j+ T% K
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
5 }( z+ K/ P# r6 U9 j" m* I
2 s4 M# j/ `7 |0 b2 Md3dFont.Italic=FALSE;
) c9 T6 {4 m8 Q$ l9 b9 d' j2 D4 t
2 h- Y8 i- W% t' C6 Dd3dFont.CharSet=DEFAULT_CHARSET;
$ A1 `1 T9 d: \, x. g4 }1 k9 r- O/ A: u
strcpy(d3dFont.FaceName,"Times New Roman");" `: j7 |9 V7 W9 T+ R
% u- Y8 R$ C i% C& h8 uID3DXFont* font=0;. \6 w# c( b; r( M1 s( S3 g
/ Z8 w- I P% H4 k4 M/ V3 j
D3DXCreateFontIndirect(Device,&d3dFont,&font);
0 A/ y4 Q0 a) k & y2 q" S O `- L
/ V3 K6 ]' H0 S) o如果你使用的是LOGFONT结构,则:+ j! `8 ~4 W3 \
f& _* ? U7 P: y' P# j1 S
LOGFONT lf;
6 V, a: h0 R! a: T. l5 o1 K9 k
ZeroMemory(&lf, sizeof(LOGFONT));4 B7 V, T$ g6 f9 ]
. N! h5 `- h% s, g7 v, g1 f: Rlf.lfHeight = 25; // in logical units- H0 I# c5 U9 a9 q$ j
% E3 L$ m- n$ ` B; J1 u3 c4 blf.lfWidth = 12; // in logical units
1 [) Y+ C& L. u2 [1 K$ m, Q8 J/ }1 O! ]
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)( S1 {2 q! R) z g3 \. Q! c) W
; ]/ t8 E/ }% `lf.lfItalic = false;8 H1 R! I7 M$ f- r5 q
6 I2 x9 A; J7 W- j$ ~' x8 K3 C
lf.lfUnderline = false;* N8 B4 ]* B- t6 d' P6 M5 P5 _4 l4 O3 s
# r0 P3 w- v5 d7 ^
lf.lfStrikeOut = false;" t0 S" {5 Q/ c8 M
5 S# H9 r& g. ^2 x. clf.lfCharSet = DEFAULT_CHARSET;
$ N' `1 e+ @# V7 e1 m/ t- D2 ]/ g; Y1 E
strcpy(lf.lfFaceName, "Times New Roman"); // font style+ h6 E5 z* p! \6 {# U
( R% ?! A1 ^) j9 z4 E! aID3DXFont* font = 0;
, x% _; k# p$ {2 D" |# X' W# U! a( h! S) r Q9 a" M) H2 \
D3DXCreateFontIndirect(Device, &lf, &font);# }, g3 e" b; ?& v- h3 ^7 N$ r4 O) T
) R( W9 X u m
* G/ i7 Z7 u8 H6 b
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
% h/ d5 z! E; Y0 }5 L7 d2 C0 c- z. L( H8 @5 }( u$ R8 I$ M+ K) g5 \
9.1.2. 绘制文字4 a; R8 h L \2 k4 O9 y( l, r4 v
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
- l5 i5 l. I2 e
/ z# g7 l- R0 _3 A$ uINT ID3DXFont::DrawText(# M D; q$ I3 i: R- Q& c: {
7 K6 O& `8 G! u/ i; ~7 j4 a0 U
LPD3DXSPRITE pSprite,
( m2 K* I* _( Z' C& \$ ~
' Z3 [$ a" ]3 g7 t" K9 ?; a LPCTSTR pString,, N- s# `9 p( M
: R8 A g5 l$ Y
INT Count,6 T# \, b6 _5 l4 Z2 B+ L: _
9 f. }! [- |7 n6 }+ ~. t7 N, v+ y LPRECT pRect,+ ?. I7 Z- W6 i
# i; \' g o1 ?, O
DWORD Format,
+ J# c1 j& K" l+ t' H( B
; X. \8 f! B8 q, M D3DCOLOR Color3 k- q- _' l# m
`$ d$ p) G' K% ^);
|! D9 Z: t) O3 K 8 V0 [3 P) R' g! g( ~
0 v0 G; B7 u) p" \5 I
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象# b+ k/ H- _( ^
3 E; r; T* D6 bl pString –需要输出的字符串8 J1 M" Q( {/ B1 w; C5 G
& G) c7 l5 a+ i8 f; _
l Count –字符串的字符数,如果为-1,则以0字符为结束标志) c6 S0 R$ Z7 v9 J/ u
( J P7 |: A$ I1 b5 C2 W
l pRect –绘制字符串的区域# r/ j: S' M( H- d8 J: r7 T% \3 c) {
/ o% i' ]( D& N3 Dl Format –文字的输出格式4 u8 M: }: v2 c) g0 k+ k9 _
( g1 q2 Z/ O, D3 d/ |1 ^. z g. Il Color –文字颜色
% V$ _) Y* g1 B9 L
% @0 ]& W2 w3 O; l Y, [例如,可以这样使用该方法:9 j/ l$ P4 p# O5 a' B3 S3 @
' }& P6 V: q& D. U7 J% @( y0 fFont->DrawText(NULL,
: u/ j- U3 A* d2 M9 g+ s
# Y p4 }4 y& X, p) k, D$ w" }4 Y% @ "Hello World", // String to draw.
9 a: D: j# q: @7 b
7 S4 w7 J% H9 R, q# m' c* M -1, // Null terminating string.% e$ u; A; V7 N/ y1 b% m" `
. r3 w: ^% a. Y6 }. Q: K) W: M &rect, // Rectangle to draw the string in.
. b7 e% p& ]5 H3 b8 {& X ^6 H8 s. I T$ C# `% _
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
6 [, C- b$ N$ {3 J2 n7 Z- P
, N) h# E& ]1 T- Q8 O. Q 0xff000000); // Black.- S+ \ l$ O+ @8 U2 X# Z
3 r! C' g- i& U/ x# V- L+ ^
! U( B9 M4 q# l+ W2 h8 j- i$ R9.1.3. 计算帧速率
3 |' u+ Y+ q7 V$ o1 @4 o帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:6 Y" g7 h: x3 q: z
: e( i3 [7 s4 B% p! u/ {4 F
DWORD FrameCnt; // The number of frames that have occurred." G) o* @# j% \4 |+ N7 r0 o
; o; p, n6 ^, H1 q% J
float TimeElapsed; // The time that has elapsed so far./ _# V5 R( U4 ?
" @$ ]# b- G `! n
float FPS; // The frames rendered per second.- ]: k6 \ _5 M2 F& a/ i: ^3 q
, V2 A+ A0 T2 U. K# k8 N; a/ k
- Z: Y" v+ @' w每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
$ F3 S: o1 t8 X; p% H% H9 Z! E/ i% U0 @$ j& I0 W
每渲染一帧,累加一次帧数和所用的时间值:3 ?1 x2 x P% k/ m2 M% c$ p
/ e0 R" y6 {5 ^' N) j! A% ]) y
FrameCnt++; M% _' b: M3 t: L
( o( W7 s6 `8 q5 x
TimeElapsed += timeDelta;6 Q7 G- k6 ]- o% @: S- I
% D2 H: E& @# s( Z# w4 B- B Q. g+ g: B1 C- Y( y
这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
I- b( {3 x, U# q) D" Z. k5 d# d. f W
FPS = (float)FrameCnt / TimeElapsed;' q; f3 F9 U. t- D
) \" k4 [& M1 o
u# V2 M* U/ _8 g4 p
计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:
+ ]% f. T# f8 V* F" b L4 g
) ^9 L# u5 C8 t! q5 bvoid CalcFPS(float timeDelta)4 G( p. a/ M) A8 e$ C, s. R8 C4 Y
+ q( O* }( `3 `{: G8 t. ]; i, f. {) N/ i8 B
0 _- D# h' U% v& z! N FrameCnt++;
& `7 L9 _: c+ {4 i$ {/ u H) h. y
TimeElapsed += timeDelta;
- p) u) L, l0 }
5 b: x! F0 P) ~3 M/ R5 n+ u: ^( J: H if(TimeElapsed >= 1.0f)- S0 y) {4 Z$ H3 m/ y) Y( B8 \
8 }- k" r i& B {
! L) _& @9 f( F5 J) h1 ?) z3 v5 Y
, Y9 E% F+ t, `6 r) W/ L FPS = (float)FrameCnt / TimeElapsed;
% }6 }7 ?1 }+ s6 l5 l; B3 @) U8 [$ \
TimeElapsed = 0.0f;( ^% M. T- M* U. i5 A4 o
( P. \. b( H0 U2 Z2 j$ w2 e+ v8 L FrameCnt = 0;
! v* o8 D. m# M/ u4 P0 i9 I1 f$ H, N0 W# S5 ]& _9 i! m
}
# d' O% L6 k" C. F) L
" G* Y- Y7 j7 |( [2 Y3 U, L# P}
- t3 }2 Q* W* d8 h- W 0 f- y9 r7 o7 G- v
. [$ m6 ]/ S, T8 }7 K6 M
9.2. CD3DFont8 q2 J! O! x; g
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。( w/ _5 n9 Q5 ]5 n! g& B, I+ X
8 i8 d5 Q; m) g4 z' P% f) ^3 ~使用CD3DFont类时,需要加入以下源文件:d3dfont.h,d3dfont.cpp,d3dutil.h,d3dutil.cpp,dxutil.h,dxutil.cpp。这些文件可在DirectX SDK的安装目录下找到。在DirectX 9.0 SDK Update (Summer 2004)中,该类却消失了,所以,该节内容只适用于较早的DirectX 9.0 SDK版本!
8 p3 S' ^' \% { j4 N5 b3 ^3 X& V! T- d# s
9.2.1. 创建CD3DFont对象
+ e @/ O1 {+ o; O" r: Q/ j. H创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
* _' }8 }. S, X1 e$ j2 v& N( w; ?; H. F4 u, R
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L); Q% h1 g7 h/ U, z, C
- h* `* H) S2 Y+ X3 k5 z1 F
& O1 t( t: B2 }. w5 r' R) Xl strFontName –所使用的字体名称
+ |9 V. a! g( E9 C! R* a& G7 h7 K& B" c4 ]/ `& F% O
l dwHeight –字体高度) o6 N* U! `) S. G9 B4 x0 E
0 V6 e( n+ S8 I
l dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
5 F+ q6 I; V( q9 r& H* |3 p' s5 u5 n6 x
得到CD3DFont对象后,还需按顺序进行初始化,如:5 V9 D$ j0 F0 e1 R+ T2 b0 S9 `
( m) \! J3 D7 f* yFont = new CD3DFont("Times New Roman", 16, 0); // instantiate/ n7 K3 o) }9 Q! d2 g
5 R5 |& G, D$ q+ z- q- o- dFont->InitDeviceObjects( Device );. x/ u; R( a5 o8 S/ k
) Q2 H/ |5 F2 Q4 }0 l$ f6 aFont->RestoreDeviceObjects();
, Y- q& U$ g/ {# d
: K3 ~, D+ j9 H! g" v4 ]; n
7 {3 F% P+ E' }. V# ?: p9.2.2. 绘制文字$ Y3 o. J' p% u- [& o
使用CD3DFont对象的如下方法渲染文字:7 \3 U; w% u/ |) S- R
5 Y+ r$ e# S8 C! S1 kHRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
8 q; S2 A1 W# C9 a6 i2 w( V, \# d1 I8 ]5 ]8 I0 o# |; u( T
const TCHAR* strText, DWORD dwFlags=0L);
) K' B! |3 K0 M 2 `* s$ k* F9 K
% u: G0 S4 t( p! C6 n: S
l x –屏幕的x坐标9 L6 x' j, W" U' I: ^8 Y+ y3 A0 C# s
4 O1 ?. u0 L" D `9 A) t/ x0 N3 U7 N
l y –屏幕的y坐标
+ ]) E: W- {+ c: C# x
8 p: F* g4 M% @* ?' ]6 ~6 B$ yl dwColor –文字的颜色
3 F& ]6 ~& i( X% [- J$ c1 ]
# E$ J A7 _9 p4 T) Jl strText –要绘制的字符串0 A3 C$ ] u! U! w* ?% e& O
: M/ O; t- Y: z; @
l dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。4 O; @4 |1 a' c7 \. C% ]$ L8 v
Z( W9 l% O2 V" [2 g例如:
" t( G Q( s5 w+ Y! S9 a
* X6 Q" u7 Z& v; kFont->DrawText(20, 20, 0xff000000, “Hello, World”);/ [; w; _ }3 z7 R& y: O. z
8 Y2 B U8 r2 m/ w- w# T) K
. F" d. P8 R, c9 M, ^+ x9.2.3. 资源清除
6 J) P( ~# h. v6 U/ A' t% _在删除CD3DFont对象前,还需作一些清除的工作:
! P) l8 R5 C% j6 B% {3 D* A( L% _1 y" g5 P5 G B
Font->InvalidateDeviceObjects();
* \" V; X! w& M
/ \8 H6 _. I ~- S+ N: F& bFont->DeleteDeviceObjects();
9 d! ~8 _$ |$ q8 O. t: m5 Y0 F4 ^4 @, e6 p) l
delete Font;; V8 a8 G9 _) |5 Y# ]% {+ k
) ?- E+ z: w, R) u& ~) K
; `/ \0 H, {( a- i6 q! P9.3. 函数D3DXCreateText# j, u$ O5 t+ K* O' B
该函数用于创建3D文字Mesh,原型如下:
, {0 D' f! l4 W; i" y! L0 T" I
2 G0 D1 \; H" N/ H/ z/ j$ }HRESULT WINAPI D3DXCreateText(
5 x- J" R4 r E# Y2 G) k, Y, B/ A
& }( a$ c" C: p# u9 O( m8 n LPDIRECT3DDEVICE9 pDevice,/ W3 K) Z7 t; Q( N; G& D/ p
4 \+ @( T4 x% Q @( q- a) S, Z
HDC hDC,
9 @8 q k( E; v* M, O
/ q, T/ Q. l3 S5 h1 [2 w0 b$ u LPCTSTR pText,+ y# N' K w4 x/ \+ V9 }2 c
; w- F3 k+ z* y; z7 E v1 H
FLOAT Deviation,& ^' b" {% k: m" J
9 g5 f9 W$ p3 f1 {
FLOAT Extrusion,: }, i$ @) H7 }+ a2 q" }5 n
& Y* {/ [+ _, v! b2 [7 l0 a
LPD3DXMESH *ppMesh,
4 c/ I) }4 N4 W, M1 O, H5 G$ t0 N$ ?' E" R, T
LPD3DXBUFFER *ppAdjacency," H4 L% g4 T1 h, t
+ @, P3 i& X( t0 o
LPGLYPHMETRICSFLOAT pGlyphMetrics
: V! r' q! a0 G4 h+ t% ?. ^8 ?& [( @
);
* F6 W. n' K1 [% Y+ i
( S0 r2 _9 o V' [
( f+ \& u# E( H/ c* tl pDevice –D3D设备) ~6 o& e9 ^8 V1 s, q& P
! H( E/ [" @' M0 V8 D% pl hDC –描述字体的设备上下文句柄
i0 n9 b4 t, [- r+ s/ y) E3 e5 |5 \4 S, K, `8 [
l pText –要渲染的字符串
8 `9 i; v2 O O0 }0 a! V. M( D
. o1 C9 r: E! h9 bl Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
P% o/ e# g! I+ \, g o( K* Y$ h5 X; D, l4 k9 p/ Q5 w0 B
l Extrusion –字体的深度,相对于Z坐标轴* J9 h3 z* k0 \$ X0 s; L
- y: [% b& A, L6 }
l ppMesh –返回生成的Mesh对象指针; P8 g. z+ y% t9 M
- m- ] W$ w* ?, D% O, p2 N, xl ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
4 P/ M2 A' n* B2 H2 T' E/ }) {" X5 U6 x) X0 l+ W0 P4 v
l pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL; o+ I6 G1 J- J6 Y
& s' H; v9 w* Z8 C$ y
下面就举例说明如何使用该函数创建3D文字的Mesh对象。& p* S* k1 p6 k: i3 c. E
6 F! L+ Z" s: w# x- V' c& J// Obtain a handle to a device context.; ~2 c- K0 j ^- _* d8 }" q x
3 O5 G" k5 j1 J" f1 p) d3 h/ k9 S# jHDC hdc = CreateCompatibleDC( 0 );- d* H5 j/ H# I8 U$ t1 W8 o7 k
# P# J2 n* a: ]/ h! l- H: P+ A// Fill out a LOGFONT structure that describes the font’s properties.
+ ~0 C: j0 n5 E
* K- M; }: `) F* ZLOGFONT lf;
, y8 @5 H5 q) z. P( k
& d0 N' g) `1 T- [) p6 CZeroMemory(&lf, sizeof(LOGFONT));
9 i! M1 L4 a( `) Z0 f& u, s' s$ J z: d/ Z: {
lf.lfHeight = 25; // in logical units9 z% U. q0 Q; b% c+ }
: G3 `: r& P( H9 Y- ?lf.lfWidth = 12; // in logical units
! K. O3 Y# S% C! o5 ^5 m6 Y* o5 k$ E% q
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
y" a3 c# y; c1 O5 N- r
8 H' Z" R9 X9 s* A& ?lf.lfItalic = false;
4 n( K5 k- ~0 F9 k4 L$ S
4 k- U- R& ~' [7 r$ W+ W. H4 X# Plf.lfUnderline = false;
" g( g+ _4 @ d/ b2 D! e# ]. {. p/ N1 L( `5 |$ \$ Z) u
lf.lfStrikeOut = false;
; |9 r- B* W6 s3 X2 S: g
4 f( D' E" q. B& |( a" Ilf.lfCharSet = DEFAULT_CHARSET;* c, s, G/ Y8 F. Y- B* F
8 a& I; z4 v; Q" v; I" b' I
strcpy(lf.lfFaceName, "Times New Roman"); // font style
7 v6 G8 ]2 k) R& s- {- q
0 Y& \! \+ n- k/ n% o/ T$ T// Create a font and select that font with the device context.
: O7 k) j# @% h2 W! W5 }5 C
5 F( V, @5 ]3 N) AHFONT hFont;6 H2 h. a" X9 e. U+ c G/ |* Y
, I+ ~& ~9 u: z( V. A. ?; ~' hHFONT hFontOld;7 O# C1 ^, o$ ~5 j
0 V: N& x4 S, q% ]+ k9 X
hFont = CreateFontIndirect(&lf);- o! e3 |; b4 G' r
/ U8 @, A5 a/ x4 t9 I2 b( WhFontOld = (HFONT)SelectObject(hdc, hFont);9 }) z/ ?6 k0 U4 M3 _2 E* {
# K$ }1 N2 t5 B, z- {+ [
// Create the 3D mesh of text.% R, S4 S) }3 h: ^ \4 @
. A% t @0 { Z @
ID3DXMesh* Text = 0;3 I1 T" J* P+ K8 r
" s5 p# L6 B( |$ S3 TD3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0); @" z1 y+ s% u
, R. w/ }0 {1 Z// Reselect the old font, and free resources.
4 g+ D i. f5 b9 N8 B" w" U# e6 m
, M- C1 G+ H/ y0 JSelectObject(hdc, hFontOld);' N, t; E. X. j2 U7 u% h) n
$ _$ T, {2 j" w
DeleteObject( hFont );
3 o2 n! w- U* }. C6 Z7 y
) I6 B& f6 z4 | Z9 d- ~5 JDeleteDC( hdc );( R( Y$ V2 b* E9 v: p1 } l
3 h/ u- v1 J D, O/ \# @
. G! Y1 ?0 M6 L3 @+ Y7 k/ Q3 ?
这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:
" ^) y; S5 e0 Z* A# t5 H3 }( A5 k0 d1 d. I
Text->DrawSubset( 0 );
( b# @4 e# ?' c, ?' ^( D
; ^" @* d" J* \- P: D8 U- o" K; x2 Q" J- \4 T. j& Q, X
译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。4 L1 ^6 k5 W2 c: y
n' }$ C, [0 g) A9.4. 总结
8 z( f* |. m. A8 E7 xl 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。8 d5 F6 F+ }) [1 D
* z7 O0 p/ [# ^7 _ S
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。
" j. q5 q6 Y. e3 j
5 h: I- T: A0 B, B. w/ Cl 使用D3DXCreateText函数可以创建文字的3D网格模型。 |