http://www.5178c.cn/article/6/2006/200605173892.html" l8 H5 g% `! S2 r/ c
; Y, D) r. h4 p9 E( I
在DirectX 9.0中渲染文字
2 H4 V3 D& X d作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin 3 B' K7 m% O5 W4 O+ b+ J, [% l
减小字体 增大字体
6 ?, y2 Q" A1 e5 u- k+ A5 g# Q' N s; c2 H6 z# x' H2 R" v- S3 n6 m
( j$ D, H! L% m* D9 t- l( c5 N' {& j# r# `' C1 A/ B6 _+ l9 q
4 ?, y8 |" k( U6 V- f# n* [* g' N5 e
3 ~* _( ^6 C& B
9. 字体( z0 a- l# v0 x) E
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
+ T8 f/ w* W/ Z3 A: i5 A A
" y# R% J) N0 d( G7 Y' B
; m- O) ^, l) ~4 S( V8 d
' _0 H6 z+ s1 s, v5 ^在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:
3 H; N" s4 y) ^' n5 b* ^9 L% H; ?. @! D
l 学习如何使用ID3DXFont接口渲染文字( _+ ^5 N' A+ k5 m: I
0 p" n6 M9 Y5 d8 }% w6 ?' dl 学习如何使用CD3DFont类渲染文字4 Z: M! j X5 J$ d2 T. I4 n
, [# s8 f( d$ K' R6 R4 E" k9 K
l 学习计算游戏帧速度的方法; D9 H ^) Q7 g( o, ^$ Y4 A
& V( C4 Y. T ?+ J. {l 学习使用D3DXCreateText函数创建3D文字
- }2 j! s9 I( \2 ^# W5 ]. s3 s0 b; @/ u( s
9.1. ID3DXFont
) i7 g6 v- c, e& k要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。8 W# x& L' e( c( c$ q, v
7 ^* B! X9 L: p& M% {" I
9.1.1. 创建一个ID3DXFont
7 Z! y. n! F! j8 {+ B2 Z' m可使用D3DXCreateFontIndirect函数创建ID3DXFont:
! B& }" d% R) T0 k9 M# ^7 J1 g# G9 {1 Q% Y/ M0 c; m
HRESULT WINAPI D3DXCreateFontIndirect(
* c6 M$ P' P' K+ \) E' o5 H8 @& t& M/ M; r7 I
LPDIRECT3DDEVICE9 pDevice,) _1 u8 M$ d$ z. n0 p* |! Q3 }) I
) j3 c# U# C) w! D& I& ]
CONST D3DXFONT_DESC *pDesc,) Q% t+ R; q5 S" K
+ Q1 ` R; b3 L3 x2 B J7 J
LPD3DXFONT *ppFont) Q4 |, z" U% j( m& e
* ~ B* A2 E; E' W$ g
);
- [. N2 V8 f8 a: J9 G O
0 d* k8 q4 f+ w( n' O- T, [) p" a& q2 _
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
0 v1 ^) W! o7 ?! T4 P; |. ^( S$ ^1 W1 h& P5 f0 o: M7 K6 x
使用这个函数时,需要一个D3DXFONT_DESC结构:
: f: O; O7 m+ N7 C4 f) ~/ u
" }' ~3 O" `% S! J3 B5 [D3DXFONT_DESC d3dFont;: H% }- c- x* L/ G% ?
$ P2 T5 y1 }: T2 ^# E v6 H
memset(&d3dFont,0,sizeof(d3dFont));5 @' c, T0 }* z
i$ I( f2 J R! g7 P
d3dFont.Height=25; // in logical units, h( i* b" B1 [2 j6 q5 ]9 g9 P7 F
7 B. t/ T8 M) K$ P# }
d3dFont.Width=12; // in logical units, D+ D. E* R& R; L/ l" `# z8 e9 L
" b$ Z7 }% }( o" I5 {) x
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
, a8 l' E4 l$ \' [" b) ~& a+ V* W4 T6 w, t, @
d3dFont.Italic=FALSE;8 A4 E( ^) v) t; B( w
% d, V( o" j7 S# j4 E" O5 _
d3dFont.CharSet=DEFAULT_CHARSET;/ c% ?% {" }* x% z9 N6 s
8 z$ p% f3 d, ] O8 q
strcpy(d3dFont.FaceName,"Times New Roman");
7 }) s/ y. c, T, z
$ [, @& w7 d# W5 Y( p! t3 |! K1 Y, yID3DXFont* font=0;
) {# X5 [8 V0 ]8 u9 U
# _: h* {' H4 F& S% gD3DXCreateFontIndirect(Device,&d3dFont,&font);0 Z3 |! D7 I* k# m9 x
4 h* T8 p% t3 j
( V/ N6 t; ?' u# z. ^; B, g; B
如果你使用的是LOGFONT结构,则:
! L9 t, g0 P4 P& m# Q# u/ u1 M! m: D0 F9 q
LOGFONT lf;
; w; {7 n/ C2 v! |1 |* h& W; M3 @
ZeroMemory(&lf, sizeof(LOGFONT));
7 T& L6 E- b+ i
1 t$ E! m( {2 clf.lfHeight = 25; // in logical units( h F% B0 Z! V+ X+ t0 X7 W
7 Z& _; S1 }0 Y' {3 e9 W
lf.lfWidth = 12; // in logical units
- Q- D4 G8 R7 A6 B9 v+ M% z- _% L1 k
8 ~( V/ I7 g6 n+ @lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)5 D' d; @/ {; x; F2 |* M8 M
9 d/ P+ v; ^: J( W- ^& alf.lfItalic = false;
: k; m% J% \9 }: a) U) P1 G
+ I7 C) ^7 C2 G7 A$ B) }5 qlf.lfUnderline = false;
6 C# x7 w3 W. }8 j4 r' v
" y1 L% M* S% L% t. b( Olf.lfStrikeOut = false;0 T3 g$ j8 p* i+ [
- ]6 m( R( }! y- wlf.lfCharSet = DEFAULT_CHARSET;
" K [! a2 @! H" m; i8 z5 |1 S2 }: W! k4 _
strcpy(lf.lfFaceName, "Times New Roman"); // font style
j- c7 b4 s8 {& M1 Y3 \5 E8 Y' j+ L \( ]/ H& q
ID3DXFont* font = 0;+ A+ X' Q/ @5 {1 j) z- F. G
( I! F( [) W" VD3DXCreateFontIndirect(Device, &lf, &font);6 F+ u2 C% Z& d1 Q; q' X
9 g3 a* R5 s: ]+ k" R. S8 q W
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。3 i4 ?' J& U, o. ^. O: C: B' e
4 O6 o+ p$ j! [- _, }- l% b0 {
9.1.2. 绘制文字5 N& o* R# b! J# r" M" [* B
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
/ @' w7 B" ?/ H; j. w! }. I1 Q/ I0 ?8 i# O# O0 p
INT ID3DXFont::DrawText(
1 Y, u9 {- a0 L4 q# @) H) x) U# P" _
8 Z# w' w/ a5 O# Z* M LPD3DXSPRITE pSprite,' {/ Z1 \3 L' }1 q" y. C7 b
0 L% I. o7 b5 v: M& r$ @ LPCTSTR pString,8 M# K: o3 j9 A7 i7 o5 d5 O
4 y8 _& N! s0 |8 o- a# g8 G0 _5 i
INT Count,
. E9 i0 S0 z! Z+ q A3 Z9 I+ s: u2 v% M1 W+ c$ \
LPRECT pRect,, P! o4 N; U9 a; G, w. ?( Q8 z. s4 n
- i" F; f( H- p! P& [ DWORD Format,$ l0 i+ M2 w0 E: B
. r4 U8 @1 Q2 D) Z- Y( G# O
D3DCOLOR Color# r5 e5 v; r! I* @
6 F/ ^. _' {# {2 u8 t0 l);% w; a9 @, f9 h. y/ w6 O, ]' b+ N8 X
) x; H& _1 t5 G
, {/ f% ?* o9 [- m$ {' g# Gl pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象4 a0 ~) b9 {& u0 L
! }# ]( | ]" ?- [
l pString –需要输出的字符串
" c. |/ {' z6 y2 Y8 K) \, q8 }1 f
l Count –字符串的字符数,如果为-1,则以0字符为结束标志
4 ?' ?+ i/ w- W2 L* j
9 q+ h) Y; @: \" L& hl pRect –绘制字符串的区域8 z9 a! P! F- I0 {8 ^
1 `& ~' G7 b' v- U7 `. R
l Format –文字的输出格式
, c$ a2 l# y% u7 R( f+ P2 f. V0 k- I
l Color –文字颜色
4 o. l. g I0 H% L9 `+ k6 x3 c0 F) w1 n6 ^0 p# ~8 U" m$ [
例如,可以这样使用该方法:: W, w: U# A1 N9 x5 b. l
# j7 k A q7 n' R! }* o7 E9 CFont->DrawText(NULL,
- U5 y# r1 b8 m0 a
3 G9 l% z7 c2 N3 q3 C "Hello World", // String to draw.- `( K4 L: @" r6 q# b7 [! S" j! S! q
, @2 |% U, H& h, l6 k6 |
-1, // Null terminating string.( E6 m- o2 s# G" M
+ z4 j( ^+ M8 P# i! @1 n4 E9 @% |
&rect, // Rectangle to draw the string in./ F( ]$ E% a( S8 T
4 R8 m: `" n3 F2 E# v DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
) W- g0 _9 P% w6 J; i5 @3 i# x# {( V: M: r& Q
0xff000000); // Black.% C/ k! d$ r+ ?% O* q
- f+ O8 I0 X, F# x _' O7 h+ j* |
" V6 h% y+ {' ] j* k3 Y6 i4 P
9.1.3. 计算帧速率
- P& m5 E: Z& s/ N帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:
0 M o0 k; T& ~% s" |
9 q0 d, g* j7 GDWORD FrameCnt; // The number of frames that have occurred.
0 `) E0 s4 o: I. B- G- x2 `9 `. x. ^" g6 y3 A/ P) P# o1 D( \3 ?
float TimeElapsed; // The time that has elapsed so far.
# d/ s r1 L0 }8 ?9 G# U& X, ^" S' L8 d0 ~7 C9 q9 B. s
float FPS; // The frames rendered per second.
% `3 r$ c3 o2 e5 a: @
T q5 Z- g% w
8 i/ l3 O) }; ~/ M每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。, n* Q( ?0 o9 i7 p
! j3 B q2 S5 k$ a$ O) f: y每渲染一帧,累加一次帧数和所用的时间值:2 U# I) Y5 s0 x; w; @' i
u% b) x. ~9 C& YFrameCnt++;
. F3 v) K$ {% ?; i* ~( d8 \
0 n0 U+ R3 X9 Z% Z9 BTimeElapsed += timeDelta;7 C6 }1 Z. E. O6 Y7 z; _: Z
6 |, Y" `* x1 ~* c) c
" x F0 i& L1 k! A' q3 [
这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
' W- z) a3 k8 K/ g D% ]6 O; b
0 [8 W) z( z/ }1 X; NFPS = (float)FrameCnt / TimeElapsed;
7 n. o. f2 _& x% N( F+ H3 P7 B - ?: H& c# A6 y7 B5 [$ e
4 m5 \3 e1 {. X8 e计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:( |/ b% H' d7 C# [' }7 k/ }" S$ G
+ c& q4 \/ M0 v0 w8 T: P4 nvoid CalcFPS(float timeDelta)5 I% s$ x) D* X: y
- y7 Q. \' t9 A6 o{8 l/ G! l& _$ E; r2 ?; f
7 V% d3 g' c, I6 F2 Q: s9 z
FrameCnt++;
2 G8 P8 B& h+ m! u
* n6 R* j8 J" J2 [ TimeElapsed += timeDelta;9 ^7 O/ ^) L( |' T% q8 _% p7 s
. b5 Y! h) `' |% u2 g, N- y
if(TimeElapsed >= 1.0f)( x1 Q4 x6 \. T/ i
: k1 s/ N- b2 D5 x
{
( @, j' m5 ]! N& S' P* W* I% |) g" X i3 }/ f5 Q4 b
FPS = (float)FrameCnt / TimeElapsed;* W$ b) i% J# [, t$ E
9 }# ^& K) S& u TimeElapsed = 0.0f;; Y2 o( r3 }# @! b8 }1 C
) @# ^; `$ b" \
FrameCnt = 0;% Z9 W- e' H# ?$ j+ O* K' x
' [! T1 I2 J" ]9 F n }) u% T9 _2 [- l, U1 ^) K* b% h
3 @4 E: V" S5 u' [( J8 S
}
/ ?# i' s2 s9 G' j3 y, w
/ O) m3 }" L' H* s: z' Q& g
$ s6 e9 T$ M* Z* h) X" i Q* f% U, C9.2. CD3DFont8 x, J/ u! b* d- c) d4 [
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。 Z% L8 ~- m) y/ ?
2 e6 G! @# U) \8 \ J5 p5 f1 L使用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版本!
# A( I0 C5 g, b" g- D) ~1 H
( N% |- q: [& R0 l9.2.1. 创建CD3DFont对象
7 ]) f, n0 K4 A" [# W# ^; z创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:' A4 x }; y% i; v) ~1 {; O6 p
) {% e. W& o% M' o8 N% ]CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);
; T: S5 R+ \1 {6 O 3 f. n0 J8 ?# A D. ?; x
' M3 W4 I- g' d& R- \l strFontName –所使用的字体名称
. Y4 Z7 o: }3 K1 @1 H( o$ _4 s7 m3 t' q& S: {% f
l dwHeight –字体高度# N B# S2 P* E' ^5 I& M8 D8 b
; @: h d, t# w% g7 M: H5 H
l dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。/ ]. |+ V7 ^1 F: i- X
6 V2 ?! K" A9 E: \% }1 K得到CD3DFont对象后,还需按顺序进行初始化,如:
$ N, z( `# C! Z: H/ a
& Y4 K3 T! j+ n' Z3 z, y8 wFont = new CD3DFont("Times New Roman", 16, 0); // instantiate& }1 e- Z0 |0 t1 F. c
1 T' p+ s. R3 [3 E) S! O: {Font->InitDeviceObjects( Device );3 z. m" B1 S( S
6 e f( c0 t; Z+ |: s6 C. K/ o
Font->RestoreDeviceObjects();
, Q1 c, ^- ~. l2 F& ?& H
5 O) ^; E) S) y, I1 b+ P9 e8 N) ]% N
9.2.2. 绘制文字& M; X0 y+ g* J& e; n1 K
使用CD3DFont对象的如下方法渲染文字:
& |5 b1 f4 _% `0 }) ~$ Z* t. K6 T; m! Z9 C
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
1 |: M4 u C4 d/ t- g& J2 W9 G ^. H9 w* X$ W: _" d$ J- V/ `( F
const TCHAR* strText, DWORD dwFlags=0L);
5 T$ F$ f+ W I5 O; Z: u
3 K# x* ~' k# E, d
A/ D5 Y+ A! |& m- E% t: fl x –屏幕的x坐标
5 s$ r; k! f8 H+ P$ W% K) E1 Q' q* X# F# J
l y –屏幕的y坐标
2 F# ~( J; k- n
5 w& P' J0 I8 |& C' X- al dwColor –文字的颜色
! @* G: ^" C5 w' I( G; A! p8 b E( o
7 A' f, ~( G, Nl strText –要绘制的字符串 a3 g0 Z E C2 k
; j$ Z" L7 N* c. rl dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。3 s+ p# S% N0 f7 D n
7 ~+ ^, |( j7 V& M. b' I) j例如:
& H. ?# f% Y4 V- `8 b; {4 t( b2 c6 s' B
Font->DrawText(20, 20, 0xff000000, “Hello, World”);
1 q( x ~0 { w
* z5 o% C: v+ t9 N
8 a8 V! k/ S5 [$ h5 O! t9.2.3. 资源清除" O& T4 _2 d0 J2 z+ {6 H
在删除CD3DFont对象前,还需作一些清除的工作:
, C, C; Y& R5 p' O* }6 I$ ?
: @8 ]( f# T: h- X7 C5 y" S0 K( ]Font->InvalidateDeviceObjects();
; ?+ @0 S4 [( z* Q' p/ [$ X
& w! v. ]7 j) ^. ]6 x/ mFont->DeleteDeviceObjects();% {6 n# J Z; g6 P, N) d
3 e' f8 [0 M, O' U0 {9 m4 g: Edelete Font;9 n2 i) ~! x. o
, H6 g. g2 a/ m4 ~; o. G* |* f3 u; O
9.3. 函数D3DXCreateText
- u$ r& ]+ O# O; B( L该函数用于创建3D文字Mesh,原型如下:* B0 }& F% G5 c2 J
7 n% I4 g8 ]) G4 Z pHRESULT WINAPI D3DXCreateText(
5 {. _$ `* H2 a$ l3 D/ \5 v
" c; r. X* {: U- R; V LPDIRECT3DDEVICE9 pDevice,
' V& R' h) Q! @" ^
) J% D6 e7 c* m; @$ x3 K S HDC hDC,
( P# ^( S$ w7 i2 K- q6 g5 q. b, f; a8 X
LPCTSTR pText,
2 L! a0 \4 u+ j7 b8 f( P6 |- N( j/ c+ W0 |# W1 y1 O! j4 Q
FLOAT Deviation,
; C/ ^) t I- S0 {+ ^% {2 ^$ n4 s) K% V- X6 N' m* [; }$ S$ m5 [
FLOAT Extrusion,& g# S, l( C% H- g! ?1 ~+ S/ u& Z
. w' i$ q; b+ M
LPD3DXMESH *ppMesh, A, a& [. T4 O8 H& }
3 n1 A( @; u( {4 O. ^5 v5 U LPD3DXBUFFER *ppAdjacency,
6 _/ _& [3 \, e3 p6 `; `+ \; X% J5 V
LPGLYPHMETRICSFLOAT pGlyphMetrics
% z7 q3 [ _9 Z7 z' q
X |/ K) ~2 ~6 u& s* \; f) d);
; E0 W. h# L6 N% h6 Z" G 1 q/ f/ N1 a4 J- t
+ p6 X$ w1 p# Gl pDevice –D3D设备4 X; e+ R9 y" V( V
& a) ?) I2 m: U6 Fl hDC –描述字体的设备上下文句柄. e) N# W& `; k& B' r4 E
( q+ Y3 P) X; n
l pText –要渲染的字符串
- m' }/ s7 |4 t5 Q
% ~, |% l, |6 ^, m( Fl Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值, @0 P% o) X2 R
6 G, A# d$ c& B( i$ y5 B
l Extrusion –字体的深度,相对于Z坐标轴! f1 q5 m4 J, N
7 l+ ?) J' Z9 o8 yl ppMesh –返回生成的Mesh对象指针, Y) Q" P) f% Q; [9 @
( e* G( P8 B9 _. L( g* J/ l. Ql ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
7 O* b! i$ p# d2 m
5 ?" A$ n) M- n8 _+ N1 ` n/ ul pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL
* H# V2 M" c$ `9 J# i+ R. S
( _& q! v: l5 K4 Z; z+ V下面就举例说明如何使用该函数创建3D文字的Mesh对象。
$ y/ f _2 g; \& H) x& z
# M# ?6 X1 x* @2 O// Obtain a handle to a device context.5 e8 |- l6 a9 |: F
1 f0 w# b. r: u" D9 D8 b
HDC hdc = CreateCompatibleDC( 0 );. e {/ P" }, w7 O9 l. @) x' Y& L6 e
7 @& S* u# [1 ]3 ]* c4 j// Fill out a LOGFONT structure that describes the font’s properties.
' I4 \' g. o: d7 ^1 s
; H- z) v: V; r2 \* vLOGFONT lf;
5 u6 y+ H/ ^8 Z r$ ]# O: N
& G/ I1 J4 S w0 n4 b* fZeroMemory(&lf, sizeof(LOGFONT));
% u0 n$ v( Q( n- v" t- k; Z S t7 Y" D
lf.lfHeight = 25; // in logical units
* `1 D- j. R K4 |& i: e, f6 _
% D4 B2 Z7 d& G1 E% zlf.lfWidth = 12; // in logical units. r* j: d4 m4 U1 Y! v
7 L5 X. k6 ?- O: a
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)# _7 T# F8 v) K" P( v' Y
0 j$ y/ |1 b1 k$ a0 `lf.lfItalic = false;( o7 k5 o) ^, f3 y
& d5 ~# L1 P" f' }- S
lf.lfUnderline = false;) o/ x# I9 f1 A
% \: b* f& u) K- X3 `/ r, @* llf.lfStrikeOut = false;; M! m( k1 u3 o- Q
2 Q1 K+ Z# {8 J& _. w' X3 i hlf.lfCharSet = DEFAULT_CHARSET;
: {7 y+ y. S1 C/ S- \$ @
* X% C6 c' d& H0 ostrcpy(lf.lfFaceName, "Times New Roman"); // font style4 r% Z6 J% ?% I3 S
$ E1 \2 N6 T8 G+ S) B0 ^
// Create a font and select that font with the device context.
w$ r& n3 ~# ?2 ]: p4 w
+ ^6 B6 J/ n% G0 G/ nHFONT hFont;
8 Q* i3 m# }0 s) G9 }, u* ?; h8 ?# i; x1 S
HFONT hFontOld;
; P) t) Z) L6 ~0 e: c3 O- a8 A+ O* W0 k: L
hFont = CreateFontIndirect(&lf);% q8 o- w. N$ L- q+ l6 m7 f, x$ V& }* F
2 c/ o2 \7 Z0 u0 ?/ h1 Q
hFontOld = (HFONT)SelectObject(hdc, hFont);7 O6 \" t+ t3 \/ J. m+ E; z4 j
/ H4 a+ a: F) y! m% E; x f( _// Create the 3D mesh of text.2 b7 b8 m8 w/ R1 M' N! H( X: W
" e# u" i, J Q; a$ X" [, H
ID3DXMesh* Text = 0;
: l# M4 a1 o& A3 l' n D) B, R& J
( [/ O% q9 s# m/ P; p# j& m' QD3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);6 b+ m( q$ M: a* M9 X/ \
- d$ P+ B% r9 @9 L2 @
// Reselect the old font, and free resources.
% ^5 `; V& W* I: B4 C2 z9 s% e( _5 ~ }; V+ P5 B3 u. l9 n$ n8 @6 t
SelectObject(hdc, hFontOld);7 H( p$ {: E$ n' S5 v- V
5 o6 G+ X; r. ^+ j" _
DeleteObject( hFont );
* l( Q3 J, f- ~+ w" h. |& i
! b4 Y% V/ P9 [# L$ J+ ~6 I" ADeleteDC( hdc );2 {. i; h! z2 u" a. I, L
6 h2 Q, U8 a4 _. F1 a
6 b' ^. r; x N5 V) |+ b这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:+ e5 ?! Z F$ A( Q# E3 m" I
# v' h4 v+ C+ f) K3 E x
Text->DrawSubset( 0 );! z! R5 M# Q, k8 i' @0 ~$ N* E8 |
: u# W: r- @3 x$ H& A3 O; ^
1 K$ j( @& m# u7 x( C" C译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
7 g3 Z" [* `# `- J2 ^/ U
6 o, g; k% p* D0 Q6 C( ^6 O0 w; r9.4. 总结
! V8 G% V2 L1 ll 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。
: G+ b B, x0 Z2 }! _: @" z
; R" g7 R& T3 L! e; I4 ?- n4 f. k6 e, W& Bl CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。1 }! u* T$ A7 u! s9 r/ w* T! x
5 M) Y7 [6 f' n/ R7 `3 V- o; pl 使用D3DXCreateText函数可以创建文字的3D网格模型。 |