http://www.5178c.cn/article/6/2006/200605173892.html
6 E) d8 Q( Z W: i" h. l) N2 P1 [( Y w/ ?8 O) n& t& ^% }) R
在DirectX 9.0中渲染文字 ( D6 _' @9 x! W2 ^
作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin Q9 a0 M1 L7 L5 y( d) X& x
减小字体 增大字体 7 c7 e- d1 u& n* b, f
3 B6 |- p0 \! z# S: n. Y9 M8 F% M
# t) ~5 M/ o L3 ?
1 ]# G+ y7 p" z' p( m/ y" x# i- I9 I5 q9 o
1 W* B! x H" N% m; s6 v6 t) s, X. j) {, P
9. 字体5 F, ]9 r* T0 [( O% B- l
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
7 r7 t' y2 V: n/ |' O- C9 [% }, v$ ?0 U* V
0 G0 ?9 {5 [, E3 f9 ^# j8 [0 `+ g1 o1 b2 g) i7 t8 w9 C
在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:( u$ M- ]$ i+ s8 S& ^0 F9 R/ R
" x2 \2 t0 F$ zl 学习如何使用ID3DXFont接口渲染文字, k# M4 {6 J. i0 {
! }5 | o- E) b6 t8 ?5 l
l 学习如何使用CD3DFont类渲染文字7 [; l& f J- h" {& o
" H( E3 ^9 A% o' Q3 s) w! z: T2 C% vl 学习计算游戏帧速度的方法 V& w# t+ Q! K: P' ~1 Q
0 }! x$ k# k- {& I4 vl 学习使用D3DXCreateText函数创建3D文字; O7 }9 \$ B5 M6 p0 N
+ a/ |; c/ s8 L9.1. ID3DXFont8 x7 {3 F: o/ }9 }3 E
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。/ }3 j3 ^/ ?& g. `) A3 ?
! Y5 K1 g2 q1 O8 ]% G0 j& m. d
9.1.1. 创建一个ID3DXFont
# x; R L9 ~$ Y可使用D3DXCreateFontIndirect函数创建ID3DXFont:+ R9 a) G& P, d' i! ~9 o2 P% ~
8 q+ d6 b7 z. C
HRESULT WINAPI D3DXCreateFontIndirect(
4 _" O, I6 B6 _' n& ^ ]3 N
0 B: u5 P# k" Z" F% I$ \/ D! j% _ LPDIRECT3DDEVICE9 pDevice,0 K. w h, N" v) L r/ t4 `
# t$ @4 [! {/ q: f
CONST D3DXFONT_DESC *pDesc,' |- a) J0 o0 F8 O8 c$ [
* E4 Q. ~" ^3 [1 I% X) t
LPD3DXFONT *ppFont& E2 h; S+ p' e6 r2 r- |
8 M& b9 u6 M) U i
);! f& d, V- C, ^
8 [+ h" J! Y X% I) |$ k% l: m2 C
; e7 K/ N: w" H/ S, O ?4 X译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明! M0 z2 u* f. U' J
# Q6 ?2 F) i7 W5 t; M' S使用这个函数时,需要一个D3DXFONT_DESC结构:
) J' s" v/ \0 q) ]) g3 ^
) M _" k0 H% J0 C' xD3DXFONT_DESC d3dFont;+ W6 M" g' I/ u6 z/ V7 G' ]
! z+ { u: [/ o' h1 ^+ Qmemset(&d3dFont,0,sizeof(d3dFont));- W' u* M2 O% Z5 D
6 T: `, W# p8 P- m& q$ @; C7 qd3dFont.Height=25; // in logical units
5 Z3 o: N# n! |8 z B, u
: T, Z" U2 ~( ]& R- D+ ^d3dFont.Width=12; // in logical units" W2 V% {* H- y, ?$ R- I$ P7 b
( }' P* @8 Q8 Bd3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
- N N. P9 M4 `5 K }# t3 a: q8 q8 d4 v3 H, J9 `) a" N
d3dFont.Italic=FALSE;9 r. z& W' {8 S" z
$ Y H# H8 v3 b# H3 d3 i; w' f0 x
d3dFont.CharSet=DEFAULT_CHARSET;) U- q" P( _- V
) o' B4 O' _: M, N' }* O$ nstrcpy(d3dFont.FaceName,"Times New Roman");0 J, N9 C: H8 [" c3 V/ h9 z% Z2 Z
6 N7 U+ H, `% d, N; T0 F! k r0 \6 P. Q
ID3DXFont* font=0;+ @' O% J' q' r
% O. ?- t! S% M2 ED3DXCreateFontIndirect(Device,&d3dFont,&font);* N8 ^. C7 D$ E5 Y. `- q
: t2 p/ F' X. M% b1 T% A" d( e- M9 f4 Y1 R
如果你使用的是LOGFONT结构,则:
2 Y! x- s" G% t) C2 r
" \' a8 p8 _" Z& y8 i4 d- S wLOGFONT lf;
' x$ R5 p( U5 d' W7 } p( u. [* _* `
ZeroMemory(&lf, sizeof(LOGFONT));1 X: \, S( a; j `+ f. e w
7 W/ R$ Q' h9 z$ Y* s' D' h& V6 }lf.lfHeight = 25; // in logical units3 ?% k4 }$ d) b2 K7 d
* O6 O8 z2 {/ C, C6 {
lf.lfWidth = 12; // in logical units
) A5 ?+ n; r r3 b# E& D* j$ E# C1 T L3 G6 C6 ^
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)0 K2 b" t4 R7 p
8 d8 O) o7 Z6 z" ~/ B6 Y
lf.lfItalic = false;( ]$ G( E) {/ y1 \- _" c/ o
) a. q8 x, Z& w7 h6 Q
lf.lfUnderline = false;; ]# q2 g* k* T# x0 d
" A: W' }! x3 h; |4 L' N% J3 alf.lfStrikeOut = false;7 k9 a7 ~8 L9 l/ q$ R( d: X
) _ S5 F, s" M) { `/ {! D
lf.lfCharSet = DEFAULT_CHARSET;3 X' Q. f! W( W- c
8 V2 C/ L+ t# |2 |- v* k
strcpy(lf.lfFaceName, "Times New Roman"); // font style
( g) R1 Z5 N4 |3 _0 l' M& ?0 b' Q: N5 K- E9 L% t; j
ID3DXFont* font = 0;
2 J; E: O2 e4 N1 x& M
4 s) }3 y% L, r; E6 pD3DXCreateFontIndirect(Device, &lf, &font);
: J4 x8 ]5 |5 \5 |6 \3 R 4 J9 g, r8 K& h9 \" ]
- ]- {1 }! h# j: z7 P- c另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
$ v0 l( s5 o1 M. M; w$ E ]; L7 ]
9.1.2. 绘制文字
5 I- o4 V, M; D" i. ]- r" h3 L得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
3 M% q! S+ }4 m2 E3 P# r, h$ ~- d8 L* O
INT ID3DXFont::DrawText(2 a7 L4 |9 G5 G3 E. ~* L* ~% `+ D
* I# m* J, X0 t$ V LPD3DXSPRITE pSprite,
+ e/ O* b2 ~4 n" ^, I* l, A6 X/ r* {) z) l E
LPCTSTR pString,
+ i0 c. n3 I- X1 m; p
$ ^/ s, J+ e- d1 K INT Count,
' Z+ u: t, z) o5 Z) _2 H' t
! O+ g M, ?+ s- ` LPRECT pRect,* P- ~; P+ A: s" D5 _
& T$ o! _$ p) g! S2 x% k+ Q+ ~ DWORD Format,% r! d. {' ?4 O: e8 _, c# Z
o7 `6 G7 {4 Z: ~1 l% D+ c3 @
D3DCOLOR Color7 H9 e1 O) a: {/ d( ~
. f/ |* |, A! c; D4 V);+ y9 l$ m7 Q7 I U6 q) ?
# H5 X9 s0 d0 c$ ~
7 F) U& ~8 x9 _) K- p: M2 T+ ql pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象
/ O2 {; b6 Y ~2 r4 A$ _6 ~/ j8 d- s
l pString –需要输出的字符串
0 D3 h* s' d& b- q0 a4 y
$ e, a( a7 w( A8 g7 Ol Count –字符串的字符数,如果为-1,则以0字符为结束标志
4 |: x8 T% |' i' \
( Y9 T, K0 o# G. Hl pRect –绘制字符串的区域* B0 W4 E* k6 ~3 g$ f# u* b
! Q7 s& S9 _8 z5 ll Format –文字的输出格式
n. J, S# c; t7 _, j9 m, _$ f1 Q% Z' B" j0 H* a1 o% v- G, \0 }
l Color –文字颜色
9 o. u- ?9 u0 `- u X3 d
1 h# T+ p9 B1 J- `9 d例如,可以这样使用该方法:
6 J6 k- f' _1 ?# u5 |
2 e2 g7 w2 S6 s0 v5 l! E5 ?; rFont->DrawText(NULL,! z d" Z* u% Q5 C: x0 | l( h
/ ?" @* R" c3 h$ S5 P/ `
"Hello World", // String to draw.
0 Y& T% o9 w: h7 w$ j& v
8 e4 A" F1 N0 `" e- _3 a* } -1, // Null terminating string.
# y1 M p2 W0 H1 [) E* `2 y! v5 ^; U! \( n" }7 G' R Y( Z
&rect, // Rectangle to draw the string in.1 R! e! S8 G' s
" i" E& }$ M9 a; ?' x# @
DT_TOP | DT_LEFT, // Draw in top-left corner of rect./ C' \9 W- U6 c0 w' Y; X
$ O2 d3 ?: w3 R: B: ]
0xff000000); // Black.
4 T! z* T/ U3 X 0 u% l5 P# @% k6 n
' G+ q% S9 F: W! ?9.1.3. 计算帧速率
9 |6 a# c# c; m$ d! N) i帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:
; r; P0 G+ U& g) y% B% E( p! N
DWORD FrameCnt; // The number of frames that have occurred.
2 u! P9 Q3 u! A1 u! F* a ]$ }2 }: s( k# v j
float TimeElapsed; // The time that has elapsed so far.8 U z. b1 E. X% I
6 M' r- e! T+ G$ o5 ?, Mfloat FPS; // The frames rendered per second.' R% O" J6 C8 j
- I; Z% \4 z! t- P
[$ ^: F1 j6 N; r! x
每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。( @* u4 b: W7 W( @# m: ?* f% y
" \2 u$ b$ O* h4 N
每渲染一帧,累加一次帧数和所用的时间值:
3 n9 U+ t! F3 D& X$ u8 \
- D& q/ O. ~ A4 ?FrameCnt++;
3 m4 ?8 ?/ x1 K1 m" b
" P& _ r. X( s# `0 f! ITimeElapsed += timeDelta;
- J4 S1 N. R# v: ^) e! x8 u5 o
! C( K$ ]4 ?" ?1 X
, K& h) L# z0 [5 K2 Q. a: {" h这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:. x4 j( `. n- Z! T" h
' ` i' c& u$ ?# C r& {! YFPS = (float)FrameCnt / TimeElapsed;) {! Y+ P# f6 ^- [
1 Y+ \: b1 K# e# Z1 [6 |) b9 o, V/ r- d
计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:
, ~9 ~, e4 L3 w3 j5 \: S8 f) d8 @- @- @! t3 f0 y
void CalcFPS(float timeDelta)
* c( X X4 R6 o- M8 u+ S. C: F- p. g- y( f6 R- ]( ?
{6 L" l* ^, }* _3 S0 m$ v0 e( A# P
$ e" B9 {# E) B$ A: g, R: C FrameCnt++;
! x* O- q+ J* @3 d+ I: f- C8 X- L' M' C" I6 C- d( `8 G
TimeElapsed += timeDelta;
& l0 q0 G5 A4 X8 n9 x
' o; l+ c% l* p- K% f if(TimeElapsed >= 1.0f). J) w0 s, z2 |7 m& e. D
7 D2 I( a6 A) u) W {9 f% [2 K2 A: l1 E+ ^: D
* x3 @6 f: x p6 u, Q FPS = (float)FrameCnt / TimeElapsed;
- ^) S4 `9 s" P) R& r" k7 |* d' x3 g4 Z' U; r$ k# P5 ?
TimeElapsed = 0.0f;# G0 J' r* e3 b3 o+ P
& u2 @# g9 I T- @# |! i FrameCnt = 0;; ?! U \/ N- x" q5 c1 y$ g8 H
! |1 w) V$ n5 N- n" ^1 _4 A6 q }
. [6 l7 _/ ]1 I7 L# M e$ C" w" F7 w/ Q# V2 ]- p7 {: [: P
}
+ B* K+ A) A. ] W) {2 }4 Z, P
i. v7 S# I" ^( _) h3 _1 t4 H, @1 [; o) C4 ]
9.2. CD3DFont, J; n* m& ^3 K! f4 s8 O. q+ ^
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。, o4 v% O" Z7 o7 ^ q" {
, Z8 t0 e5 y8 k4 J- W, H
使用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版本!
( G0 w* n& X* k3 ^2 d) \3 `8 p" }9 v K# }7 M
9.2.1. 创建CD3DFont对象$ m/ }, J( n6 b# }' r6 [% v5 c/ L
创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:1 \: x& U; E* Q
! \! l4 N% Z# j' K( o
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);% ~: L. a+ G% C) I, n
- f& x) T4 v9 f( e9 Q9 K) `% r
( y+ u# s* q1 ul strFontName –所使用的字体名称
* v3 y% R* ~( Q/ X4 f q) I7 H' y
' _5 T- z# R8 O+ o) bl dwHeight –字体高度/ g! v/ O* ?1 f* U/ X4 e/ G& b i
, h7 I7 I- m$ k
l dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
+ i8 Y) ?( P$ P$ t9 R" x, f5 Q" t+ Z$ E! N
得到CD3DFont对象后,还需按顺序进行初始化,如:$ w3 A3 P# F+ l* \8 C
4 O7 }3 S( r# x* R
Font = new CD3DFont("Times New Roman", 16, 0); // instantiate
& Y* G g+ V& g1 B5 p% ?0 b6 l* l1 e' }: U: y
Font->InitDeviceObjects( Device );) a% r( Q1 F) u: Q' F* a1 U. G. S" V
8 l- j* \1 ^( z* E1 R2 \' l& z/ Q+ eFont->RestoreDeviceObjects();4 X( }2 ^5 X4 m- Y- p5 X- C2 h- Z
; a! `5 ~% W9 C; `3 }1 T9 V# z& b
9.2.2. 绘制文字
! b2 t! X- E( J使用CD3DFont对象的如下方法渲染文字:$ U7 `$ q; e( f6 B6 _
6 Y1 d/ J1 ~' {* a. K
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
+ } |- U" T) s$ H3 P1 @4 E" \2 q, L! z3 ~
const TCHAR* strText, DWORD dwFlags=0L);
! }' }. K, f) P- q
8 D, p) P! {3 ~2 l* ~" q: T4 I4 o; `* ~. q0 t
l x –屏幕的x坐标8 a7 l5 w* V% ?+ b' L; I
4 Y: _8 }2 q& o: ]6 Wl y –屏幕的y坐标
, r3 T$ n: c6 j9 n4 {9 a. ~+ }" o6 O% m# @
l dwColor –文字的颜色
* j% ^; e5 x" |; I- s2 m0 Y& X; o7 A$ m6 d, }
l strText –要绘制的字符串
' J( ?9 h. V, I8 @
) y' J& v& M/ }0 I9 @/ Jl dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。, A' l) X7 k* v; f% M0 R
, c4 ]3 Q! l& W! J" g
例如:9 p+ L7 C2 g/ t% t# [7 x
( }7 d% ~3 M1 q0 H/ \
Font->DrawText(20, 20, 0xff000000, “Hello, World”);2 G# ~$ O) _# I A& A
6 b5 Z3 n+ V1 ~/ F( z; L7 j4 Q
4 @' @# ^4 i. P" B9.2.3. 资源清除9 a/ Q0 v4 l& G. p) {* O9 n
在删除CD3DFont对象前,还需作一些清除的工作:
( } w0 ?0 g# `$ e8 M7 J2 Q
9 d+ J( Q) f) j) |5 ZFont->InvalidateDeviceObjects();
* K% w, a6 I; S s: A
, y" v: n* D9 |: |% Z- U- U) o# j) M$ [Font->DeleteDeviceObjects();
3 X9 I, D3 e( ]* V3 B2 h
) n2 ~- \( l) @- edelete Font;
" R. i$ @4 M7 y* {" F 2 v- a2 p& ~+ `+ d# g: T
2 w& @2 i5 t8 Q, w5 R
9.3. 函数D3DXCreateText+ I D2 ^9 |, M o+ F
该函数用于创建3D文字Mesh,原型如下:
- j ]' z( A- J
! ^( u! N7 M" G( ` _ y: y1 u- e2 t4 u$ SHRESULT WINAPI D3DXCreateText(
* u( X+ x: `- E. r G, n8 H) B# H0 a9 h) }, o* C& R% V
LPDIRECT3DDEVICE9 pDevice,5 c# s& H$ s6 e! b+ l
, ?5 [. p$ Y2 F; ^( t HDC hDC,
% g% u! A; b7 R- \# F$ H: T4 y9 g' X0 [5 Y, D
LPCTSTR pText,
( Y1 \! _7 _% {6 b% F _! z3 F- `! L; Q( g" H7 K
FLOAT Deviation,
& ^: Q: |& T3 o4 O! v1 c& S3 z
" F; w y7 Q1 s) x2 A FLOAT Extrusion,
9 f/ L& F( D6 |" X2 k$ Q: i( }; O7 j. c+ X; t( d9 ?
LPD3DXMESH *ppMesh,+ S8 D7 [# l2 J# t& H8 S$ m3 c4 q
/ r Q: D3 h1 ?, p( t LPD3DXBUFFER *ppAdjacency,
: N0 j* x2 p* r% t" }, `. O- U) z" s) n# X
LPGLYPHMETRICSFLOAT pGlyphMetrics! d1 j1 x3 n' Q: X8 o
3 v5 Y: X! Q/ e2 V( ^* _/ y);: q; h( k9 ^ `9 M2 L# U4 v5 E8 c
$ v9 `( C+ M4 q" P' j0 H: P9 v
( ~* m3 j5 N6 u$ ]; o Sl pDevice –D3D设备3 e3 f1 v5 |* |5 l3 f' Z* `
0 _# K6 U9 W" Y, t$ e
l hDC –描述字体的设备上下文句柄- f2 ]" q, s9 b
) A ^" P; P3 s$ D( ]8 `
l pText –要渲染的字符串4 N/ h' x) }# \. R; ?, G# @
3 ?. f5 [2 n( W4 D+ Y9 x
l Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
. S- u# t& Z3 [/ G% I( }# L8 e5 V/ S
; |9 S, b5 {$ @, [" p+ _# O# Fl Extrusion –字体的深度,相对于Z坐标轴' Z. x3 U6 H8 `; U) K8 b! z
^+ {' n3 R1 W7 B( C g0 fl ppMesh –返回生成的Mesh对象指针
( @) Z6 S e- e0 M( j) V' Z9 {. Q: i$ u' ^3 d* F+ C4 o- W
l ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
, j; D7 g& @* N2 o
9 c/ P: r9 _9 N1 t/ M3 yl pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL
! G9 o* @( m4 ?& Y- v% R' \6 m* C/ ]& k" z2 `6 b7 w
下面就举例说明如何使用该函数创建3D文字的Mesh对象。; d* o; Y' H, J
' c. p: t: Y3 v% ~" \$ x4 `( L1 R' M/ k
// Obtain a handle to a device context.5 Q4 [/ a" W) D% w
& s9 n2 v3 M; x9 i; m! H% WHDC hdc = CreateCompatibleDC( 0 );) r% Y3 Q; B% d' `6 F l) T
7 k: f$ W! i1 }: l9 a; b: W, d) ^// Fill out a LOGFONT structure that describes the font’s properties.
" b$ [4 j- q7 w* x( V6 h5 C6 L- Q9 ?' @ B$ i- y R( x
LOGFONT lf;
; `+ [" {5 a% p1 y3 e+ U3 p$ p: z% V$ [' }& O- q9 B: B
ZeroMemory(&lf, sizeof(LOGFONT));
% L3 i) w7 O# K" ` F2 c+ @, B
2 h: p4 S+ }$ a/ B, |lf.lfHeight = 25; // in logical units
0 n9 y/ h3 {# x0 D& @& C( l4 q( |5 ?1 B$ I% @/ |
lf.lfWidth = 12; // in logical units3 }5 {" K( B+ x [
! X. e+ b5 D: q3 t
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)9 c2 m/ t# c- |4 m$ K+ k- O" J
" h6 W" I% |1 C; o- plf.lfItalic = false;7 _# ^8 n( h, X6 y
# o) w! t- K' n! ]5 O7 ]8 A6 d" {lf.lfUnderline = false;
+ q j$ a" s: K2 w* b$ W1 T9 a: _( A& ^% O* g8 w0 j2 x* _5 h) }6 d
lf.lfStrikeOut = false;5 D* A' S8 H1 T2 k) ]
/ M. w! v& E6 p6 v- Alf.lfCharSet = DEFAULT_CHARSET;
- h6 q6 M! j+ Q: N" p
* y- k6 K3 _' t% g3 L' b' M" Jstrcpy(lf.lfFaceName, "Times New Roman"); // font style- t8 p; H P# Y: \( f' s d
+ W& w% u7 J: S6 r7 V# w
// Create a font and select that font with the device context.' B3 x2 k+ N3 x" Y
0 C" }8 C5 C0 N# @2 h- ?
HFONT hFont;+ k# G3 w/ D D2 w- _0 _
0 s- o6 o( V, Z
HFONT hFontOld;
8 L9 `" [8 S5 l+ q& }/ ~
u# s' }8 u2 d- \hFont = CreateFontIndirect(&lf);; ~' X: I- P9 ~+ B# b. x
+ ~1 E5 u( _9 l' s& T8 ehFontOld = (HFONT)SelectObject(hdc, hFont);2 h- V6 w; G& L# J* w2 g- G- e
& W3 Y9 n: A) ^! t4 o& i// Create the 3D mesh of text.0 z' m, m& A4 k8 O* e4 `4 i
1 w j% r% z0 ?. ]5 wID3DXMesh* Text = 0;; |* K5 r, o% [: {$ }' a
! w/ ^( P" E& z: j% u6 \8 QD3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);
% j0 z- S" G* [& j5 l) }
, T+ f3 l1 D% a4 o3 m% J// Reselect the old font, and free resources.
6 M: w+ u& j% m* z, T+ Q. z
! ^5 Z& z( C9 ~SelectObject(hdc, hFontOld);
0 u' j! A+ P9 C8 x# ]
: W# M6 v7 ?- r& V2 }6 i4 b5 JDeleteObject( hFont );+ y1 I* X. o ] i
" }; {+ l$ X* w- }DeleteDC( hdc );/ ~% d$ m+ V0 ?- x9 L* h E
+ [% Z4 R6 w2 j- y" ?, ~
6 [: D4 c( {0 h& X5 u4 L1 w5 k这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:" `5 l' |2 r& a7 n
6 {& C$ c: z( w0 F7 SText->DrawSubset( 0 );# j3 O; I0 G5 F$ t" M
+ ?" Q+ g( F# u2 c) P6 e
5 ]5 t8 D+ L" {& Z9 I6 I译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。' G8 P3 f, P1 C
( w& A6 P% J/ R1 }8 R4 j6 \
9.4. 总结5 ^4 g+ u0 \: h4 l% [6 [
l 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。: }- p4 h+ v3 |6 H% i. D
8 e3 u& @3 Y' J# r0 ~* p! l& j5 g
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。
8 ^+ E* V6 o; \- h1 d* W. T {; |( J
l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |