http://www.5178c.cn/article/6/2006/200605173892.html0 A: N1 k) D8 \( w
4 o# l! E# _! [& ~7 d
在DirectX 9.0中渲染文字 . M" M4 J, a- u5 u. F/ S
作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin
5 D3 T0 T7 `9 s, L' s减小字体 增大字体
! b" }5 Q' U1 c, `* e
' N( y- b3 l: ]/ S( \
! n' y: s, n: M5 D& S L1 w, s3 L6 \# A
) Q4 R1 n' N7 n
" F: q, r# S% C, [( z# j& H
, t: C1 ~- }/ o: \! `* V1 {9. 字体' T) f- n4 C) ~' T8 a
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />; q1 I/ P' u6 g* @# i9 ]; z
$ b9 q% ?/ L% H/ c
/ i, ]+ X6 Q! ]9 J6 k# O
( ?1 E; M; ~ g- Z在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:
1 M5 h: L9 o8 t
# U) L- _0 r/ e" h: rl 学习如何使用ID3DXFont接口渲染文字( X7 p$ j x8 C7 o+ b- t
8 j( b$ ?* B/ O+ ^' n, q
l 学习如何使用CD3DFont类渲染文字1 ~/ q3 F/ \6 I- i0 D
: B+ g* m7 X* G" p! o) ?) j* el 学习计算游戏帧速度的方法
+ H/ ]9 |( ~. f$ T8 |5 M5 a8 o1 g& h0 ]' \+ ?( |2 r- \1 f$ V! N
l 学习使用D3DXCreateText函数创建3D文字
* _- U4 R5 }" b6 ^6 P% @8 d/ q; }0 C- c0 i2 ~. d
9.1. ID3DXFont. T( G9 t. o$ t4 Y3 V O
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。7 V0 a; q* U3 b3 X3 P% I/ l
; G' D8 L) _! B# Q9.1.1. 创建一个ID3DXFont
* G5 C3 x+ ]7 g" G( R) ]可使用D3DXCreateFontIndirect函数创建ID3DXFont:
8 B1 |5 V1 {) @, C( a1 o4 f! y' w5 w) l, ~9 e: {
HRESULT WINAPI D3DXCreateFontIndirect(
0 h% s) K. @2 P$ d8 X3 D& Q: h9 v, \4 F' L* J
LPDIRECT3DDEVICE9 pDevice,
, ^1 _3 H$ ?3 h. F: n# ?" f* r
. o# j1 f3 z4 Z/ h! e CONST D3DXFONT_DESC *pDesc,0 q- N4 T- K" k; l& b
3 j$ g7 N; i# J8 \/ r5 [6 d) m LPD3DXFONT *ppFont
" S3 B2 H+ ? k: B4 M2 s8 X7 ~) |% c, B0 |3 |6 e) P8 c4 V& b8 d/ X
);- G" T7 U; R$ ^; T! I, b
. `+ W9 i( Q4 z" M( a+ q3 C, X
6 _, ?# y1 e r5 h O) I2 P! N& S译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!- z/ s3 @2 M1 S; E8 T$ R
0 R& i: q! G) [8 ]1 [
使用这个函数时,需要一个D3DXFONT_DESC结构:7 j$ {( Y# m6 W
6 g* s3 E% N* O) Q4 P) K5 z& a* ~- l
D3DXFONT_DESC d3dFont;" R+ B I' u0 g, w7 Y3 u
2 [+ d( [- v* j9 r' K" ^/ Fmemset(&d3dFont,0,sizeof(d3dFont));
1 }9 B- }, k4 r5 i
: ^. m- g! q8 ~, c9 hd3dFont.Height=25; // in logical units
8 n8 d! @; a& @2 o
& ^/ r6 ]7 o* Y$ h1 vd3dFont.Width=12; // in logical units
, m; f7 G4 `5 q0 x) o R$ ]) R0 N6 V% C* Q& o
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
( t6 q5 x5 X8 Y, j$ s/ V" g0 ?+ z$ V2 g4 L2 u
d3dFont.Italic=FALSE;
5 M, m7 V( @" v1 B. S- _, K5 y" b( p3 I1 v1 b
d3dFont.CharSet=DEFAULT_CHARSET;
! a8 v4 D1 \5 Q; v$ N) f& R
' X; A5 Q9 n* |0 @1 Istrcpy(d3dFont.FaceName,"Times New Roman");
V$ I" c* N8 }0 L# x# H, w0 @- O: z; a' [
ID3DXFont* font=0;
0 }' J8 E6 c- a9 Z- F* f; o7 E" z2 O8 i% ~( w) U; Y9 [
D3DXCreateFontIndirect(Device,&d3dFont,&font);
+ q' K0 e( h8 i1 X- g
# r J" l M6 r* \% f
7 M) [4 e/ B/ ^- K! p! n如果你使用的是LOGFONT结构,则:; z2 i8 V& I: C7 h* Z3 ~6 C5 O
# ~' H5 {/ f& ~5 z: }8 w1 O: b
LOGFONT lf;
$ m2 K" M a, j- p0 |2 K. t: ~. v, T6 |+ k9 A7 V
ZeroMemory(&lf, sizeof(LOGFONT));' `9 [, j6 J: C0 u0 z, e: Z
5 d) H6 _1 ?0 Llf.lfHeight = 25; // in logical units$ y" i# ~4 G- s4 }& [1 u
- W m7 p7 _4 o) b+ v! Z
lf.lfWidth = 12; // in logical units% o2 D4 n% Y5 G2 A$ E
( c% v& U/ m( ?) N" y; T7 `lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)% A, q: H* o- Z5 d* p/ W0 t$ r
" C& Y8 n6 U3 k( K- n6 q, C
lf.lfItalic = false;' K5 `, S+ Z$ s( V P
4 y! J/ U2 z( c1 I$ R
lf.lfUnderline = false;
$ m. B Y1 q3 s4 l K
1 j! K5 v/ R- \# R+ Plf.lfStrikeOut = false;
! t; h% `' p* m7 i% ^6 s y2 e2 @& J+ @& n$ l/ J
lf.lfCharSet = DEFAULT_CHARSET;) L% d W: I. i* X J) T* Z
" \1 ]/ F$ I; B, _
strcpy(lf.lfFaceName, "Times New Roman"); // font style
- R. Y9 Y% Y/ g, V/ f* }0 U# D
4 j% g: i/ Q1 W1 d/ ? ^! sID3DXFont* font = 0;
$ e) ^' W* W& u4 W+ E# p+ q5 R8 p
4 q" I& Q+ m2 O3 G' ZD3DXCreateFontIndirect(Device, &lf, &font);
! ^9 l5 E; V. \5 p8 z, j* v" M0 h
+ `" J" |$ g* d4 a+ |
- z+ E1 p5 i( Y& _3 R5 J; L另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。% @/ i/ T+ U+ \
9 w- P+ u' G! {# n4 V$ B9.1.2. 绘制文字# m' }- n1 D& Q* y
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法: H; k6 M9 v9 t& {: r r- e3 Z
5 C1 y' g" w3 j* m1 z2 S% k
INT ID3DXFont::DrawText(
6 V+ m; j5 S9 B' a! D" W* D; T5 F4 z! c: F$ ?; ?) _
LPD3DXSPRITE pSprite,+ i" |) Z L1 P0 B" o4 S( H
5 ^# a# w1 Z- {% o
LPCTSTR pString,, |& w- K" R, S3 f# D7 ]3 q
1 s; E& E/ k: l5 b
INT Count,3 X: m ~+ ?$ ~, _ N5 a- c; p% O
7 k9 w0 @) e/ F
LPRECT pRect,4 x# H0 S) O% d' l
2 R, H6 Q9 E! M% J0 G y; X
DWORD Format,/ z( C1 L. `4 u4 |" p' H7 R
5 M. g a( X& m0 @. U0 e, E
D3DCOLOR Color+ E9 Q+ V/ r! E
/ K7 A6 j) G! c9 b0 a7 O- Z; B8 p+ d);. j% q0 l. M5 t5 g) U2 M1 S5 Y
) [2 A$ d2 C6 z2 h5 m1 O, N
* J$ f4 e' c6 v2 I$ l# V, Y
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象
; X0 e1 [0 D* b3 m s0 w$ v
' w' R% U% X k2 D% C2 N& ml pString –需要输出的字符串& W/ t) s% ?! W7 `" U: o7 j- c$ R- v" C
! Q' ?: I. u" c% r
l Count –字符串的字符数,如果为-1,则以0字符为结束标志- E& [* k' X9 ?! Y/ {
9 k1 q+ v/ Q8 `
l pRect –绘制字符串的区域( A; ]& k7 d# e b7 C
' m r7 l+ M; @- _6 u4 L( m! Rl Format –文字的输出格式
, P- Y9 t" V. s4 C# R3 f
5 s9 z! o, f6 ^: Zl Color –文字颜色' P6 ~9 S( e) }. r$ I, e
- o% Y2 X% P! H
例如,可以这样使用该方法:; U4 {! H e3 j; x5 |% ^
: a3 x/ F- }/ J8 s# bFont->DrawText(NULL,5 g X( q% V, f% B
- h1 G7 h8 y. }8 M9 a$ U "Hello World", // String to draw.
$ ~' x( T$ C3 a: P4 o, l, v* d/ D4 i, c" j% T
-1, // Null terminating string.& L9 n! o, ~7 p f1 O- @5 v
8 k* u0 ?. @/ Z. m; H &rect, // Rectangle to draw the string in.
( U& X1 a8 e$ n" r7 @: w3 t v2 d+ B. j
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
0 d+ T" {8 A5 e6 {& B3 ~9 g. f, }/ L
0xff000000); // Black.8 g0 [+ R+ c o* H! L2 F
, z. ?7 h: M# t
. F% a0 y1 v! [. h
9.1.3. 计算帧速率
+ T1 u6 K0 v. Q+ D3 Y: A1 f帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:- C5 E% P% ?5 f
+ `" {7 n) s& E2 {; V1 r+ h `3 a: h0 d
DWORD FrameCnt; // The number of frames that have occurred.
' y, U6 w2 A& d' U a4 u8 f/ z' @$ i( f' \8 T- C/ V1 r: h
float TimeElapsed; // The time that has elapsed so far.
# H7 g- [+ Z# f, } d+ Y: p& N
7 c0 D" X& Z2 hfloat FPS; // The frames rendered per second.
5 @2 Z! I; x. y7 v5 a1 _
- j4 S) _; ]( K
: `6 F2 f" Y9 z9 F" R每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
0 ~1 l3 s5 S+ Y2 Y( w% X; y
3 ^& h$ Q9 c8 v; u, h+ U* Y每渲染一帧,累加一次帧数和所用的时间值:
1 t/ O. k+ X" N+ a$ l- n5 n- N9 u2 f6 f1 ]( O, L( x5 I, n$ h F
FrameCnt++;2 Z0 R- A. D( q- a2 X, \/ E
" l1 F2 l5 n4 E! V* g
TimeElapsed += timeDelta;
# \! l5 ~2 ]$ n3 a0 h0 f
" A" c3 l; ~$ w, f4 L, I" b& F" @: L# d7 O, K% @! X$ K
这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
$ s2 f4 `4 k3 N* F- S+ ?$ N) n" H" [! o6 z
FPS = (float)FrameCnt / TimeElapsed;1 M$ T- l. D: [4 A, ?/ w2 Y
3 o4 ]! L* z) u& }6 e! q
' M* ?4 p! ?4 k: z# G. g* {
计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:% ?1 N: V7 i- N. ?4 o
/ I; U5 J! \+ w6 z9 H4 J4 G& i
void CalcFPS(float timeDelta)
5 j3 R8 ?$ q; ?( K
7 \. M3 P* Q9 g$ c, S& L) f{
7 I) ~8 p" v# C! w% m5 @8 d' B+ B" T3 u- v( @. }; R
FrameCnt++;
9 b8 x7 f$ o# D
7 ~4 f# X: V" Y7 @2 g0 m6 \; z/ h TimeElapsed += timeDelta;# Q" N2 E% E8 _7 T# }
, E+ [" X1 s% @- e
if(TimeElapsed >= 1.0f)7 b3 |+ _7 r- L- Q0 D( i0 q/ v1 W
" ^% P$ m: H/ n- e3 I! I4 [/ [ {
, U# `' X5 K9 s# e' R4 S' l, Q2 P( p9 y; I
FPS = (float)FrameCnt / TimeElapsed;
" ~: m1 I1 z8 I
! `/ C) W5 S. C- R1 G+ b- J TimeElapsed = 0.0f;7 k) A) z4 O( X; U5 S! X' f
! d7 T3 K9 k }; U5 |! d/ U# q
FrameCnt = 0;' {1 [3 r1 N8 U" i' \* f
( T, r* m1 C A- D8 G }/ h2 W5 a! N) q; {
2 [9 H! m. P4 d
}
. C9 o6 ~0 D! @5 z2 S/ h- c4 }* I 0 v/ X. j+ y5 \' ]' v
7 `0 s* X" w. [0 ^
9.2. CD3DFont" Z4 P4 o( i* Q
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。
+ p, X5 D( }% Q+ U: P' s7 G# R. a, i$ s0 c, j! g0 F/ J3 P
使用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版本!
- k2 m) V/ u2 \% q7 G
Y& K4 ]8 N# l6 v6 r) i8 E9.2.1. 创建CD3DFont对象( U8 P A8 T, c1 f& { u. u# F
创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:1 S$ X9 b* f E% r
( W6 ]- E+ H* u! @- F
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);
/ v* j2 d1 a+ J0 ]* v2 L( y
$ H- F; U, j/ P. i% @9 e3 K9 y/ a: \* @$ n, P
l strFontName –所使用的字体名称
, A! y; u" ]8 F
4 ^' ~' [, N1 i- w* x' W, G4 ]l dwHeight –字体高度
8 r& Z' q3 Z6 n, r* S) L
+ O- Q3 l) }$ m& M6 Q. ^9 il dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
- `7 B' H- B5 t. z- i1 K: g: b) V4 H' K
得到CD3DFont对象后,还需按顺序进行初始化,如:9 ~- O) j9 w1 ^; _* G% Q% u
) u- j6 N% `2 O5 r; C0 o
Font = new CD3DFont("Times New Roman", 16, 0); // instantiate
8 r- ]3 \. p, h7 ?- ~1 w1 I; m( t+ e" Y9 X$ P' y
Font->InitDeviceObjects( Device );
9 D) r" I/ T$ T/ c- r! O+ o
5 p" C$ |. L4 Z1 K* Y9 W- `6 vFont->RestoreDeviceObjects();" S0 ?2 M! b6 M: A/ ^8 A2 v
% x8 n6 c/ \1 ]/ g/ Q/ M, k
3 C+ l" ]7 @. P7 S9.2.2. 绘制文字/ g; R* ^6 u- I! b# S7 r% X0 `' C
使用CD3DFont对象的如下方法渲染文字:
2 b g4 ^4 O& J- o5 P
- m. O8 q1 G/ _& M/ _. W9 nHRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
; z5 u0 r7 L9 \3 z v! `4 ~) K. {7 ]+ v9 v# S/ e: v; y
const TCHAR* strText, DWORD dwFlags=0L);; v& @ g* ~5 l6 J: |
1 I% v. l# g E m, e9 v# w4 p2 J8 O( v: \
l x –屏幕的x坐标; S7 A, s" d7 q* C
" t+ r! X4 i" h3 Sl y –屏幕的y坐标
* T6 `4 t& W% t* L6 b q/ b! B
$ [& `* ?3 h- t3 [, g( J, sl dwColor –文字的颜色" v1 k# O2 ?& U1 ?: o' D9 u$ }+ p7 c2 E
3 \, b1 \0 T0 B Z
l strText –要绘制的字符串
2 B# N- a: K8 x6 T) _' Y* u% n8 o7 J1 B3 I P, a: [
l dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
+ }8 V1 Z; }! O, j0 L' }! I2 F1 [7 `1 }2 r4 }/ E) \# o: m
例如:
9 A: f9 h( _7 L; |
& q8 F& V4 ^4 s8 J2 ?9 `5 f. {3 bFont->DrawText(20, 20, 0xff000000, “Hello, World”);
' c8 l% f$ T/ J1 b/ O $ b$ }9 g% n# t, S6 E% M$ G+ q5 N
l2 J) B' ?; F( Q
9.2.3. 资源清除4 V8 m2 d# u" \) R
在删除CD3DFont对象前,还需作一些清除的工作:
$ d* a' F% e/ h# b4 R( e3 T5 Y P' O( U0 n2 @- G3 T& I4 L7 P
Font->InvalidateDeviceObjects();
- K- A i7 G( i5 i
5 m/ f1 f: p7 Y' u% |. U/ gFont->DeleteDeviceObjects();
2 [$ m4 p6 L3 G* s, N
0 C/ O) x' o( U; @& m! x6 C8 a7 }delete Font;
4 S' T) t4 w) ~, K. Z 5 j$ ?% }4 {6 M0 A
! [3 Q7 {7 W: x! Z$ { h9.3. 函数D3DXCreateText, Q5 q2 A. h. S7 {6 ^* Q4 x8 e- Y
该函数用于创建3D文字Mesh,原型如下:
/ c# g. S' {; G6 O* U t: A" v' y7 q& c$ j
HRESULT WINAPI D3DXCreateText() d. t& c/ ^6 \5 u" y8 k/ t- v
8 O x- y9 }9 E0 N LPDIRECT3DDEVICE9 pDevice,
; z7 z+ F$ y; W8 g, m0 R0 U6 o1 H6 o: s% K, M% k
HDC hDC,
1 z% }3 N: f, h6 l/ Y
a7 N {8 G% ?9 A' B LPCTSTR pText,
* c& J* o0 H/ ?! k8 D5 ~
6 o; z3 q2 U4 `% P FLOAT Deviation,
( |, u9 W* ]) `: `3 [& j' H
" {4 ?) J# B6 r6 g8 L7 g" Y1 T0 a FLOAT Extrusion,
% Z$ V0 K4 [& M Q; e' V
5 X6 `% V! e4 Q! a6 V5 ^! b LPD3DXMESH *ppMesh,
: n0 i5 V) x3 ^5 O( K p' o
; _) w# F7 p8 ]& X LPD3DXBUFFER *ppAdjacency,/ \& h+ ^" V7 i5 R/ c
4 a; \5 T! A1 c! c- U( P, Z1 }
LPGLYPHMETRICSFLOAT pGlyphMetrics. |' H) ]( J& a; a9 G
+ F3 i; s/ D) w9 A. p
);& \% e$ r) j7 Y" Y$ C1 Y- D. C& z
) i2 u2 w R4 @! v: a& C" m
/ }' O ~' P; m8 |+ ?1 g* o
l pDevice –D3D设备
4 ~: z" K$ P, F- C1 g9 _% y1 ]5 A+ ?1 `
l hDC –描述字体的设备上下文句柄" C, Y6 k. i y1 T
! E8 m# k$ u* |' D# _; M: ql pText –要渲染的字符串, m: Y5 d; s. S& _7 o# x
5 j5 Q& g$ H) F h6 ~. Q# _* Jl Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
# p7 V9 L! x9 H5 o* o
1 | m& S) \1 Y% Q+ Ul Extrusion –字体的深度,相对于Z坐标轴; R- C9 E# @- ~/ F. z
* i% U: f" z: s
l ppMesh –返回生成的Mesh对象指针
' N. ^6 K! f' k* x/ q. g/ l2 O, h$ F
1 i# @/ K4 m m( gl ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针; J4 A% J0 S& ~3 ^
6 I& j7 }( c8 z1 z. Nl pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL5 F# \3 V1 \# e5 Q
) c) W0 ?; Z* n下面就举例说明如何使用该函数创建3D文字的Mesh对象。& \% `. V" r4 w; E
# t: y- A; F5 U& h: {, R; q// Obtain a handle to a device context.# D% r. a' h# ~# b+ M. g, E) N
0 L2 I- b8 W0 e. h' c; qHDC hdc = CreateCompatibleDC( 0 );' [* x! O$ ^. Q
' x4 [: |3 u; I// Fill out a LOGFONT structure that describes the font’s properties.7 L% Y* ^" m+ S8 I7 O$ D. o
2 N1 T z. f* A8 ^LOGFONT lf;
8 V1 _" W3 B( ?% }+ r: \! W# n" z& y
ZeroMemory(&lf, sizeof(LOGFONT));6 t6 s9 i6 d3 c9 V) x, a
, ^; @ g" S- k) P6 `) C8 }, ?lf.lfHeight = 25; // in logical units
+ |: E1 X$ G+ w) w7 a; B$ Y9 h4 i6 ]# w& O- e% D% N3 n/ g3 I2 l
lf.lfWidth = 12; // in logical units' G- m P) y1 K
2 C4 k# e( z2 `- w
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold) n8 K% _& C% \4 Q) T. N
8 R8 R; E" n. G; v" w. clf.lfItalic = false;9 t& Y. F p5 x# l9 X9 h
/ b/ [2 u/ T$ m- N! }: J1 clf.lfUnderline = false;
: f8 `) |- B/ C! X$ d1 y8 a( i
, y6 ?& P$ R. Y9 h" z- M$ b# c$ H* p; P% Elf.lfStrikeOut = false;0 Q; r- q# ^# |
& S8 f1 g ]( g' ?* Y; _
lf.lfCharSet = DEFAULT_CHARSET;- G/ h% Z( J* F% m9 m
6 c( f a4 G2 x4 b6 i( M
strcpy(lf.lfFaceName, "Times New Roman"); // font style
( B2 R3 t, \# e) z! B9 f
?) t8 o: H" S5 s# |* A* ]// Create a font and select that font with the device context.
: }& A3 o. z; S7 V6 d+ y" ~" L5 I! X8 V" j+ g& b+ K( |
HFONT hFont;, q: S, i# _" D" G% b! W
* i ]! q5 C/ Q. J/ E! j6 e* c' SHFONT hFontOld;
0 d H4 M1 Y- [- d5 ]; I* {' K5 Y# T& P
hFont = CreateFontIndirect(&lf);: `) D$ U7 g5 f U
5 P/ r7 `3 {2 X
hFontOld = (HFONT)SelectObject(hdc, hFont);8 U' c. l5 f+ N% f
9 {; d. A2 A! s, Q' J// Create the 3D mesh of text.0 z- |* @* c8 L! l4 m9 d- z# b* Z; P
2 P, X; S+ C6 k) @3 `8 M
ID3DXMesh* Text = 0;
6 t6 y+ T% I- [2 ^3 c p3 W' a1 P1 q
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);
+ Y: P" v* Q; p" l6 W
8 s0 P5 L( C* t6 r; W; ?. V# p// Reselect the old font, and free resources.+ t' G* a/ @' Q6 b
4 u/ f' V% _( V3 v! R8 o4 {SelectObject(hdc, hFontOld);
L! q. S/ J1 [' e% D! B2 k
9 n( J# F, ?0 ?8 R3 _* j" z& }DeleteObject( hFont );
4 {4 j4 I9 F+ b$ Y0 n0 p7 r$ V* J( B. a$ {9 {
DeleteDC( hdc );# Z& ?$ Y+ l1 [1 I
' B; E( ~1 m7 p, P: Y6 o
9 m7 o- F; H% S这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:
' {: z: z4 K" G% Y: O& a0 p) M: s S% r$ L7 Z
Text->DrawSubset( 0 );
& ^) t# o7 w; ]7 z7 p
, r1 @8 ~2 ]% ?& C. ~1 Y3 R
. {3 s- j9 j3 ^+ H/ g2 g' H译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
2 n3 {; X6 y5 R. g9 F/ O8 l- p) X7 N/ V: U
9.4. 总结
4 ^4 a! I. D1 O u8 Vl 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。( O- r8 l/ {3 x: q
6 j* E0 n8 K% E
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。' c4 g! o: _# E$ d
9 @/ e- l q5 I* jl 使用D3DXCreateText函数可以创建文字的3D网格模型。 |