http://www.5178c.cn/article/6/2006/200605173892.html
$ V. n2 w, l- Y. d4 Y: g# i* s1 y$ W0 l* s: Y2 \8 D
在DirectX 9.0中渲染文字
/ a7 L+ n9 U3 C5 @, O作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin $ F) Z' o) t$ L. g X
减小字体 增大字体
+ P& `; B7 T0 K5 m8 t1 ]9 ]5 q
' d! s# n3 o+ G9 ~/ x
% V p9 C/ N, K2 o6 G! v) K. _' d
% e1 x# T4 a7 A F8 M5 e& N6 _0 O) E! Q/ d5 W T
1 E) {8 o5 }0 U" ?# Z
) g7 f: I! ~4 O0 Z9. 字体( F. o: d5 Q& p! c8 F: G* s
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />! i( x3 I4 H& \* {
@9 A! Q- p# |1 `0 W+ l
( N4 v* M- H1 j" i x9 Q4 E1 T% I; `! F1 h
在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:
# O! @; ?1 b3 F+ A/ ~
+ P" V. a4 _% i. v2 g; y5 X' Ql 学习如何使用ID3DXFont接口渲染文字
# {; f1 w( e7 q3 G0 Q; l6 ?5 e% ^; q+ r6 T+ ~* q
l 学习如何使用CD3DFont类渲染文字
, c( v' T+ @- Y- t9 R5 Z" e# f0 \) _; d W5 d, g; Y
l 学习计算游戏帧速度的方法; \8 U1 i9 K6 R8 g& e. O; a7 L% r+ o
/ v; ~7 o! F4 `1 v
l 学习使用D3DXCreateText函数创建3D文字5 M* N0 y2 h3 k- h. ~8 t
/ e6 u; a" Z, \, B
9.1. ID3DXFont' {! k- ~- n7 ?: W
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。& [. K u# \& N1 _: |
+ _% I/ V! B. B, F6 O( s* m
9.1.1. 创建一个ID3DXFont
: y- p4 O+ c/ o. _' ~! o Q. e可使用D3DXCreateFontIndirect函数创建ID3DXFont:
G! p' \- @" X1 e2 j0 a' B
}8 z2 M9 w# f0 T0 O2 j7 |* _HRESULT WINAPI D3DXCreateFontIndirect() j: D3 K' X4 E* k \0 Y
% A) V$ P* Q: N8 L LPDIRECT3DDEVICE9 pDevice,
% [4 H9 Q3 C; E3 Z6 L6 ]2 V, U. L; J2 `& U6 U: p
CONST D3DXFONT_DESC *pDesc,
5 M6 P: b& h- k. e) `) u- u$ k. w$ i% B0 G8 o6 z" A
LPD3DXFONT *ppFont
8 K4 n3 x, N3 K; M9 v$ X: s8 N# R1 U9 z" l5 }
);9 T3 ~' z8 W) j* f$ Y H
" y2 ]2 E7 Y2 }
! D8 O8 L: \. B9 {$ J4 @4 u4 |
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
* E. c5 w8 X$ |) x1 _' B" u- s# h: |# F
使用这个函数时,需要一个D3DXFONT_DESC结构:
! w% ^2 p: ]1 Z& Q4 b: D9 b- h
8 o; f' R1 o1 _6 _5 U8 o- I$ B: k. P$ ND3DXFONT_DESC d3dFont;
1 v) n. n; ~1 @* I6 ^& |: N+ d: r* G! L2 r$ s) @
memset(&d3dFont,0,sizeof(d3dFont));% e6 G1 b* p* y; i2 m
8 S7 _- o$ x. _7 Q" y* ~d3dFont.Height=25; // in logical units
( B7 [6 J& C. v8 g, n. d J; H7 n" H/ W8 Q( v; l5 @
d3dFont.Width=12; // in logical units6 Y* `: r) h0 N$ j5 e9 A
: b0 ~) ^1 I: ?3 c- V6 bd3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)7 W* w0 A, c }
* M0 j" O9 F8 sd3dFont.Italic=FALSE;' Y- K. L" ], G. h2 A/ u
1 L8 @8 N5 Q( n! N! `& x+ Z/ z( Y- ~
d3dFont.CharSet=DEFAULT_CHARSET;
* x; e, ~; Z( E% _: B6 N. h" Q/ ?5 B5 C* {
strcpy(d3dFont.FaceName,"Times New Roman");2 n* f! B5 X5 S, {* m! e
( v. v9 q: i! g, l6 j4 q+ WID3DXFont* font=0;
6 i; @5 k3 d2 o& Y; X5 r# R( c
D3DXCreateFontIndirect(Device,&d3dFont,&font);
; ]5 n3 e% J* ^: z) \0 P# c' J# t8 _
1 E; R7 S) \' ~3 ]7 Y! y9 x- y4 E% A7 P, U2 y; X
如果你使用的是LOGFONT结构,则:
1 X. k; U* k& a: y; f. Y
9 q+ q" R! w/ K7 P" `: R9 b( [7 BLOGFONT lf;) f4 B2 d$ i/ \6 Z
2 N; ?2 k0 l- K0 ?" t
ZeroMemory(&lf, sizeof(LOGFONT));
4 |, |6 Z4 U# J8 Z
7 U- t% Z4 z O$ w# h5 d9 x0 [lf.lfHeight = 25; // in logical units
' C k5 E, _1 g2 }: m" b- H
/ y5 |4 T! o2 I/ x1 V, j p0 ^9 slf.lfWidth = 12; // in logical units R8 _* c7 l) l- z, g! d
6 T- C7 D; P( m0 I$ Z7 i
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
5 G/ d' i' }2 U" q( ~) Z4 ~3 c$ A3 t( x% r5 n* P f& o' x, R
lf.lfItalic = false;
: s- K2 l+ `+ x, L' T% h& \2 L% Y2 J8 F3 a( G5 [6 g) M+ S/ ]7 O) p: r
lf.lfUnderline = false;
* R7 X K1 C0 W& J$ Q: K7 s' H( H3 b( P
lf.lfStrikeOut = false;
( Y$ Y) E; s' O" v$ B1 @) T
$ A0 X. p* a& ?9 ~* Dlf.lfCharSet = DEFAULT_CHARSET;; V$ a: B2 a% {# o+ E, d
5 u% ?0 ?- Z2 R8 v; X8 q& A' Z
strcpy(lf.lfFaceName, "Times New Roman"); // font style
9 |! z7 G3 [5 z! X5 S2 T" V4 C+ f' i5 m, g {: @+ x( j
ID3DXFont* font = 0;
2 I+ F% X' D7 K' c- D0 o9 E* d( d+ x( w' \" T& V) e$ s
D3DXCreateFontIndirect(Device, &lf, &font);
; F& u4 a4 ~4 w7 A; Z+ U
! n+ m9 m7 x# Z' C* ]* j+ L2 J S7 A! O- e# L; F4 M: W: J
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
" w3 j8 P) N+ R; N9 N- e4 C1 m+ S
9.1.2. 绘制文字
, [4 z6 N0 q5 o' I得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
% }6 c$ q6 R4 \* u, y
& j6 F! i( T( V: OINT ID3DXFont::DrawText(+ m8 R4 N1 T7 Y1 b
. s0 c% ~% W# T5 x LPD3DXSPRITE pSprite,; D. `2 r3 T# _/ B. u
( I+ p9 E3 D: \8 V
LPCTSTR pString,# K3 R# ~2 I; t L, b
$ `; q) p* p0 r4 m3 v INT Count,
8 S s& A! C a% K7 r4 ]5 Q' z2 D
( ^7 W7 F) j& L4 Q" z LPRECT pRect,7 z" ^( y8 X; F4 T. c6 x/ ^
4 @7 W. S2 |# N. R# J DWORD Format,7 }( j5 k3 l* T2 C7 t4 u2 L. {
& q2 p% w2 B) L7 t
D3DCOLOR Color( S1 Q2 _, {7 y% R8 H
1 x: H5 N5 g6 q! u( G K
);+ }1 }! i" Y/ Y, P" x
0 W' |. |. r+ T; f& R. f
9 h z# J" a3 r _( t
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象$ O% K7 N# F L, d
0 Y7 w5 M6 `& A
l pString –需要输出的字符串
7 Y. _+ |7 `) L5 A- o4 }) E! L, @. D/ [4 g6 B& N5 G$ R/ E; L3 V' G* j
l Count –字符串的字符数,如果为-1,则以0字符为结束标志9 a6 X2 G5 L2 a
# [7 W6 z7 k- l( U" o3 nl pRect –绘制字符串的区域% [1 H0 t# u; }& t
+ A+ D, F+ y. `# Bl Format –文字的输出格式
& u$ D# B" ~2 v4 z9 r! ~- l
5 P# u% J% u6 S9 b/ O3 r% c* U/ a7 |l Color –文字颜色, x) u: {" W6 [, m1 ]9 l
. u2 B; X9 C+ k% c# d: d
例如,可以这样使用该方法:
: H c7 ^) u2 j; ~/ g0 I; r5 V
/ Q; y' K! X4 |4 W5 {. T# lFont->DrawText(NULL,
+ x# _. Q4 p& {( t6 A$ ]0 K
$ l( j+ @1 d( J. { "Hello World", // String to draw.* v4 `1 _) k( J2 P$ j
; P- `7 O- b( N' h/ M& ` -1, // Null terminating string.
; T& X# \/ [# a) D( v8 X. p3 K7 X
, P! M' N- j5 X% w" J2 U. a &rect, // Rectangle to draw the string in.1 ]4 Y' P9 O( ?) }
5 x( G0 |, z, Z7 X! _/ j
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
# O$ T Y; C* y1 w% _/ L3 U R, m3 E7 q# D6 M7 N6 C' M, Q \
0xff000000); // Black.% O' C$ t- v9 v7 ^$ U
5 l% F7 c) w m) Q1 D% r% e
) `" G9 p6 b- i8 R2 w' d7 W9.1.3. 计算帧速率
! E- d# R5 Z1 X帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:; t3 C& [5 B; S: h% Q5 y
: E1 r1 A. _% _& {DWORD FrameCnt; // The number of frames that have occurred.
$ P; v' K$ D0 v# F) p/ c+ ^
- A8 \5 G6 C* o4 x4 Cfloat TimeElapsed; // The time that has elapsed so far.
$ e/ ~/ U& z+ T0 S, h) S' N$ h6 L( z; C, f% b, r
float FPS; // The frames rendered per second.
8 [( Z9 t/ D& c) g 5 }: Z" i5 @4 M3 ]# l) B( {* d1 X
: D* @3 o5 |+ q7 `; Y. N# \每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
+ ]# W+ N( Z- l3 B1 m% {' v' y# x1 \9 o; L* ?
每渲染一帧,累加一次帧数和所用的时间值:
. H5 t( A! [0 B3 _+ o: c8 ^& r; O ?
FrameCnt++;
# F; w5 B$ f6 z5 B4 V4 @5 P, u6 c/ e( P: ^" N
TimeElapsed += timeDelta;: u) z+ N/ J) j. H
" h' G9 O: U4 V, \* Y1 ]) Y
7 _, h8 r1 x c1 ~% k, A这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:/ j9 a$ F* r s: K% [+ B
6 M% E' z6 o: \- O4 @: }2 zFPS = (float)FrameCnt / TimeElapsed;3 ^; n* w, n2 q$ ~# }% j
0 w1 e) K& k$ F) k, J7 X6 b) L" ` J3 f9 I2 i& t" G- q" K. x# B/ W# d
计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:% y/ N& V# U8 K" i4 h9 q( u/ F: w/ ]
& Q* A( S( C$ L, B e- ~( V
void CalcFPS(float timeDelta)- I- G% B- x1 a$ A5 G% B( Q
5 Y( p& [4 p }( H{
% t6 r7 y3 n& b5 }: r/ u6 o" q r+ k2 @: s+ Q
FrameCnt++;
. x$ ^1 w E! V+ C
" b* q& ^7 {3 K1 y TimeElapsed += timeDelta;8 a/ @9 l& V+ N$ B( |
* G' Q2 m# [, K0 U: n
if(TimeElapsed >= 1.0f)( |0 l& y# O4 D/ B" a
9 i* t8 G- W4 L5 t) b
{- m: g5 b, `1 D6 m# @; p% D( w
1 D8 P" ^6 j" A' |7 y FPS = (float)FrameCnt / TimeElapsed;8 d) s; g+ w0 v' t1 P8 X i
/ T3 U, X, N3 M$ c5 q0 _! Z+ l- N5 A8 I
TimeElapsed = 0.0f;
+ n- R. D' j0 w8 J G. ]0 k: Y( Y2 n1 u9 `4 J/ z7 @; v
FrameCnt = 0;' w8 m) c3 ]5 a) E& E6 }: X$ O
- \8 u& J$ r& G( |- y. ~ }+ z4 {( W- \% P( R; _& d
/ h7 _, d, y# z
}9 E0 ?/ R7 [2 X1 l
3 d/ W Z4 c- v9 ~* ]0 X0 g
n' G4 }) M* ?2 N) n7 q9.2. CD3DFont8 F! x$ R; L& k* r- H6 T
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。
, [0 I& {1 I* t" d; b P
% d. p, `* | ?( g使用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版本!& Q/ M" d. X9 G. w. D; Z
. Z. u. N5 z4 o+ ^! G
9.2.1. 创建CD3DFont对象& u. d1 \: \+ @8 }- k4 R3 x! s
创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:. p& ~2 ~8 ?4 @. S* J Q
2 l m; b) t p% A$ k! PCD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);; q0 V" |5 ]) A7 c+ m/ ] o* {) y& a
+ Q6 p _& m9 ]* C8 p+ E3 P' I) D
' G3 b$ |7 L7 M3 s6 [1 G sl strFontName –所使用的字体名称
& _1 p& K k1 p! k5 V h" Y& \& O. T* T9 l# a9 k" `
l dwHeight –字体高度0 O# F4 T$ p% a* L3 \( C
6 M; c9 l7 m# d' el dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。# Q; F( `# U+ j3 l _
! y2 n! l0 O) Q" c. r- j得到CD3DFont对象后,还需按顺序进行初始化,如:" n l6 p' m* o: s% Q$ N9 l
1 t& w% ?4 P2 C+ i, EFont = new CD3DFont("Times New Roman", 16, 0); // instantiate& @1 J$ q, l: x
0 ?6 O, g9 I$ p0 A2 w# K
Font->InitDeviceObjects( Device );; ? r" k5 B9 B
, a* {% `, h4 s7 B1 K0 l: k
Font->RestoreDeviceObjects();. m6 k2 c$ r) x q0 k8 }6 T" n- `4 C* h
" T' S0 @( U. W: i1 Q; r
+ \ G+ C: K3 s' T* X. h9.2.2. 绘制文字. H m( `- u9 K8 O* z- E
使用CD3DFont对象的如下方法渲染文字:
o9 i; ^9 e5 Q; C, G+ y2 P G5 K f' ]+ Y: R
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,- g5 ~+ S6 G3 A% u/ z
3 B% \( S% x+ b6 _+ ]2 G/ ~- ` const TCHAR* strText, DWORD dwFlags=0L);
5 ?& l* v; `$ a8 Z2 [5 B / G2 f/ V4 S4 v' i# X' r
& K, V# O' `* b7 o1 ?- q$ u! e8 n$ F+ B
l x –屏幕的x坐标
0 r9 c/ L8 \5 {/ Z8 K8 Y
M3 d) r+ S5 w% Kl y –屏幕的y坐标
9 D) B8 y: x, Z7 u. T* o
* v p3 P1 d. \! d5 E4 Kl dwColor –文字的颜色# X" y# r7 m6 J: X# H
9 q- c% i; `$ P: m% T1 E, c
l strText –要绘制的字符串( T% k% j6 b' s8 h
) Q0 m% g; l9 J( n0 R* Y* jl dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
( W3 }% d' ?2 ^3 I4 N. x( {7 c+ V& S/ J: l/ C, O1 ]/ G& r
例如:
8 `9 x9 V& t' d6 k1 m4 S, m4 l9 {& a4 ?% I' n% |1 @
Font->DrawText(20, 20, 0xff000000, “Hello, World”);8 q4 o8 x& V# E' Z: D7 ^, x
6 j/ c) {2 ~7 x W* r; K$ _
" v2 t. w8 C& G0 Q5 v
9.2.3. 资源清除
8 V, _# a; x4 `! j# t2 f在删除CD3DFont对象前,还需作一些清除的工作:
& y; Y4 b+ `0 i2 s- [* s/ f t8 V; n: l$ o6 q8 @: y
Font->InvalidateDeviceObjects();% ~4 z( o6 E% m; R! W
' y: j* ~ [; y4 L# y$ T, mFont->DeleteDeviceObjects();0 q% Z, n1 Z C& W. {
" r0 X8 @" y1 a6 s6 c
delete Font;
8 Z0 ^0 H/ r" j7 h9 Y7 ~+ _# s
0 [; D+ K! w b+ Q& r
* F" y' }0 y9 w' u9.3. 函数D3DXCreateText
3 Y$ p5 }+ z; Y( }该函数用于创建3D文字Mesh,原型如下:' D- D5 L: ?3 V* c2 |, H9 Z" Z
7 h% s, o1 \4 g1 l, g+ N+ Z- y) w
HRESULT WINAPI D3DXCreateText(
# y1 Y1 {% o9 J; o# ~! h7 g8 |" e" Q$ l: U" }( m1 s
LPDIRECT3DDEVICE9 pDevice,
5 H8 A4 }+ P# F
( g9 p# K7 l1 k6 y/ C HDC hDC,2 e. H! v/ X! N% s6 b3 b/ C
/ \. E1 ?+ n2 A6 s% @9 n LPCTSTR pText,# L) _) J: \; M, r/ |
$ `5 ~# H7 W p1 c' X+ C3 |
FLOAT Deviation,0 P$ L8 T) [5 }% V$ O& X3 N% w
, Y! x8 R: v: }) ^ FLOAT Extrusion,
7 S5 Y; G" V6 m, ~4 Z
6 z0 u4 O. @- P' I. n6 H LPD3DXMESH *ppMesh,) V, G2 |) A0 r# |0 y
7 t' \0 l* Y4 p/ o LPD3DXBUFFER *ppAdjacency,& O% ?# k6 X/ E6 ~- q
( y. ~9 p" j3 J$ {: b9 m/ `5 G1 D
LPGLYPHMETRICSFLOAT pGlyphMetrics W" B3 W# m8 J% w% [( @
9 ~' m/ C0 S6 U$ j) K( n);3 O* S" S+ q2 f- H3 F0 F& V
3 x2 E! ?7 h% @6 B- X
/ b7 p: F/ O* h( }$ K1 I7 f9 l5 O- v' ?l pDevice –D3D设备
9 b# a C% ?2 b H5 H' H5 y% E! l; m3 y
l hDC –描述字体的设备上下文句柄
" Z J) c( {4 I3 ^/ |* D4 U9 Z! J) I0 N0 x0 {
l pText –要渲染的字符串
& A% X# E! \% K0 Z0 P7 T8 J7 o; C0 l5 K8 n- ~( [3 X
l Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值4 y- n+ L7 y2 y y o6 h+ f# P
* H+ m ?. r6 Q
l Extrusion –字体的深度,相对于Z坐标轴& g3 L6 T* ]) i" ~9 X6 M1 Q
5 O) F( ^% r( V" a2 [
l ppMesh –返回生成的Mesh对象指针
2 e0 d* z- c; r5 j2 z: u8 z8 B: I$ t2 a1 C& K5 O
l ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
. L3 N, @7 D* `
5 m! O' @6 _! @- K+ Jl pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL7 A& [. p* u: E7 s
6 ^# O4 E! M/ ~3 i8 g5 X; I
下面就举例说明如何使用该函数创建3D文字的Mesh对象。
8 @3 h5 z6 W5 }- |. e) y5 O0 ~: R1 _+ f$ f
// Obtain a handle to a device context.
" h4 }" X8 S" f) o
% H+ d; J; \& y! WHDC hdc = CreateCompatibleDC( 0 );
' C1 e- K4 g7 _7 H' X; y0 U* U9 u: Y4 l4 a2 h2 e9 I
// Fill out a LOGFONT structure that describes the font’s properties.
: d$ N, `+ v/ C: j. R3 N# o. H& n" O+ e- O
LOGFONT lf;3 Q- W$ j' n0 f4 I# Y: a2 T
R/ t! ^2 C( j1 W) Q; ~0 x
ZeroMemory(&lf, sizeof(LOGFONT));6 U5 w5 C& k( s v8 D
8 A5 {5 R* Z/ R
lf.lfHeight = 25; // in logical units
) }4 H+ w( z) F
% P& ?3 ]$ O) p/ A' ~lf.lfWidth = 12; // in logical units
6 {; q4 V& @& K+ r! { W7 j' J
: ]7 F+ R3 w' y4 B7 ?# r* A$ hlf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
; O8 |4 J* }) V- Z
: ?% @! C5 }$ M5 Q1 L9 Y; |, m/ ilf.lfItalic = false;, u* G5 h3 R/ {& q# m5 A( A$ O
; K4 N6 `+ L3 [5 M& P" ]
lf.lfUnderline = false;9 P* D5 s0 H8 s
2 n: z, h+ D+ N: a" ~6 { [5 hlf.lfStrikeOut = false;# R+ x7 t2 e) ]6 V& K" ]
+ \2 z" H' Q4 flf.lfCharSet = DEFAULT_CHARSET;
5 E% L/ `* |# i1 w
4 E3 N }8 A4 dstrcpy(lf.lfFaceName, "Times New Roman"); // font style0 Q! Y5 A4 D2 W' F" h! _. E& c: w
" r4 ~+ W8 H% C// Create a font and select that font with the device context.9 o9 }5 Q1 ^( S8 b" p* M4 q5 A
; n. C+ X+ ^% I: b7 }5 IHFONT hFont;. T: z+ E7 x2 j5 P
7 H. f$ N" y0 _" J) V
HFONT hFontOld;: N$ e5 ?4 ]2 ]& J6 O
( O% o: u; v f9 I" S( \
hFont = CreateFontIndirect(&lf);
9 W1 r( R/ x( S! | W+ `
5 B& u; L: E( |6 P* ohFontOld = (HFONT)SelectObject(hdc, hFont);& R6 c6 G8 R3 u; Z! e& q. S- H8 A
' E% V9 V r6 Q; T// Create the 3D mesh of text.$ P2 p' m7 } Q$ a# W, l
& O6 ]4 \; e* `ID3DXMesh* Text = 0;% v6 }2 G( _) m. m% v5 k
j0 [0 v$ c/ M# \
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);; L! O9 v. w% `, J, s! u/ r
/ g6 C, k; T4 W4 }+ l. m
// Reselect the old font, and free resources.
% C" \6 ~$ N8 A8 G- Y: Q v& E+ y& m9 Z
SelectObject(hdc, hFontOld);
! F/ L1 {; i$ l6 u! l, p4 ~6 d" V8 x5 L+ m1 y, l) X' G% X* S# A
DeleteObject( hFont );
7 _9 ~+ v8 ]+ ]" c7 f' z9 ?% V( J$ f5 S% ], q9 c/ n+ R0 z
DeleteDC( hdc );
( Q$ a% G7 B T8 `+ C" W
- o& C; | |& o9 j! W4 `4 n
* r) o( m" \! s# {' [0 S9 B这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:- `! x: L8 B, b. A
8 D# b8 Q- j1 [" K) I! F' s
Text->DrawSubset( 0 );
7 }" g* ^( p6 s: v
* {6 i* u+ E4 T% @8 _+ f% t4 p# _$ @% u4 c, ^% N
译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
- S% U/ }: X: L) j! E4 N _6 q/ k/ k/ F# L5 o; V0 H
9.4. 总结
& g9 N" f) O9 m/ V, Ql 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。* n$ }' ]2 i# E [
- {/ k7 ?) H- W/ q0 B# Q! i
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。) T1 d; G7 x; |2 L2 u( S- }
) [. [* U3 u7 p8 w% j
l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |