http://www.5178c.cn/article/6/2006/200605173892.html4 F: W% x* M( M$ }* N
3 {' T4 K0 }2 t% J& G在DirectX 9.0中渲染文字 2 |. R3 R0 t) _1 @8 }! J
作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin
$ H9 Y* I# `" q7 ?) Y5 t) L; f减小字体 增大字体 . [* u1 }- {3 X" E: t5 M
% Y- P4 w# Y# w- U |6 V: @# m. e$ u9 G1 h+ f
* o' a. x2 j( q; G0 e4 o) Y# Z5 [9 L& o6 ?
( B H- f$ O( N$ V( X$ d( V
9 [( h. Q, H3 G9 j( d
9. 字体
5 ]3 Q; q7 T6 ?7 `: y本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
" a/ I& t" J! F! Q, C* z3 v1 N
* d! D/ O, p8 e/ s% A 5 W& A" K! y1 L' _* W# r
: d+ a8 _1 p' I* ]0 ]" A
在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:6 D) E! O5 b& N/ M( }4 C% O
8 H% @7 [( R% f& N; `
l 学习如何使用ID3DXFont接口渲染文字
. k$ d& v& D4 h% r# k2 X) C# ^+ [& m) U7 j, s- n) K
l 学习如何使用CD3DFont类渲染文字
: \- @5 V, J# q- L' \
1 W) n4 E6 U: w; Al 学习计算游戏帧速度的方法
) f/ c# a$ @# V# X
, C0 J0 m# E4 o7 o* R& Ml 学习使用D3DXCreateText函数创建3D文字! d' r7 G. [4 b' R/ z
3 E: M3 h' v3 z( G: o+ c! a7 m! y9.1. ID3DXFont
) }2 d( j$ V N& ~* o要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。2 i' r5 j5 v- V( K
) l0 `8 b+ ^3 K* c9.1.1. 创建一个ID3DXFont
% x3 k3 a( G7 \可使用D3DXCreateFontIndirect函数创建ID3DXFont:/ s2 `$ ?& d) F4 ^8 X
& S3 u3 U2 d3 g( d R; ~4 c0 r
HRESULT WINAPI D3DXCreateFontIndirect(
4 l; T( T) `8 o4 t @- {9 X" d. A4 X1 W- L" P
LPDIRECT3DDEVICE9 pDevice,, q. Y( H0 ]% _' m5 b7 g
" a9 T: e: X1 V CONST D3DXFONT_DESC *pDesc,. \6 w9 P9 j/ b
9 ^' z8 ]2 q$ G9 ]+ z8 z LPD3DXFONT *ppFont
& V3 P; N7 \' _) T6 @2 P# u* O- {9 L) m3 w1 | x; S
);
/ r% V+ X3 g: i' N2 t* @' ]5 [ ! S% j# o* B3 {( _; h+ F# j1 I
4 ~5 Q J$ ]" S0 i9 i
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!6 y+ G! {& B4 q! @+ t3 @
" @' m3 j. K5 w) d% D使用这个函数时,需要一个D3DXFONT_DESC结构:: f+ \& T3 j7 P' \3 g4 Q
$ V, O: d0 @- S" sD3DXFONT_DESC d3dFont;& v2 C; Q3 z% `- d) f5 t! O
6 |& g* t9 r4 P- C* t; a6 L6 j
memset(&d3dFont,0,sizeof(d3dFont));
+ [! l! t2 F/ I6 U% T N5 p* ~. G9 p. {
d3dFont.Height=25; // in logical units+ z5 O) |. R+ h0 T/ L. l
; X/ A$ [; s, I- M1 a
d3dFont.Width=12; // in logical units
( `+ ~! S4 T J) T! ?
% D$ p" E) ^, l% K( G" od3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
: ?1 d! I* ?* D# A5 `# @& Y( C- z2 G' r0 [. x0 R* c
d3dFont.Italic=FALSE;
- Q8 u* W2 @# z
8 M, J* U/ g" w; v9 Qd3dFont.CharSet=DEFAULT_CHARSET;
6 ^" s/ C5 w+ s. a- W4 P: x9 t( `! z; f# |
strcpy(d3dFont.FaceName,"Times New Roman");; W! ~* G1 F* [" S
2 s2 ?0 N/ |( l: g& a% w
ID3DXFont* font=0;
0 j! A C* c) u3 q/ x' ^/ Q3 `
0 X% X8 F% r; Q) R" m/ F! D" d1 GD3DXCreateFontIndirect(Device,&d3dFont,&font);
0 Y" r9 G! I7 }2 @8 i; I! |2 `
5 a& M. Z) s. q! w/ J
" _, [ P( Y' t* Q7 d/ ]8 c- y如果你使用的是LOGFONT结构,则:
: \) r$ b! Z# v4 K8 c8 G+ M" A( `( F
LOGFONT lf;2 C8 m$ {$ F( M. q/ `3 A% d$ J
- k! H4 G( b4 r( a9 T8 `' e
ZeroMemory(&lf, sizeof(LOGFONT));) @8 p+ P" j! c* _
( \" i! @, u7 s+ E. d8 k, _lf.lfHeight = 25; // in logical units2 `4 B3 p* _, Z, x& e/ z" J( y
8 P4 R0 H$ {; d$ m" ^' Z! `
lf.lfWidth = 12; // in logical units4 s# t9 X' G0 }( ]7 a' K2 a( D3 ^, A
4 c# L. s9 ?( h, T9 |$ A
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
" w* [1 w' W8 g+ K
/ l+ O E$ {. v5 jlf.lfItalic = false;
" d* H# V8 G; `% u m/ d
0 X1 z! W4 }5 G1 b( t& g/ J! olf.lfUnderline = false; |. Z8 k: r+ K0 y5 n1 w" i! |# J
( l0 }9 t3 r$ y0 S1 |: x
lf.lfStrikeOut = false;7 G3 C: G$ z9 y( i
5 C" E: l( o- S, N6 N+ alf.lfCharSet = DEFAULT_CHARSET;
, u8 n1 U' L" y( S( D9 E( u9 J& Q# r' f+ Q" w9 @$ I6 Z
strcpy(lf.lfFaceName, "Times New Roman"); // font style
% [- L& ]( \* ~8 x4 T! e8 K( Q" `- w' `1 J) g& f6 t! f
ID3DXFont* font = 0;3 N% X. k9 i' _' C: n3 n
5 q& U8 \- N9 }' o# e, E7 x/ G# D' t2 C
D3DXCreateFontIndirect(Device, &lf, &font);# U0 h. M* d5 U4 C" T% r2 G
% J* W7 s( G W6 Q: G
; F1 _$ u) L _( u: n9 a" e3 E另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
+ l" a/ R8 L$ U8 Z, y( _) C3 F+ E* [. G/ @# A' [ ` X, x
9.1.2. 绘制文字) o* P- b! m. D8 t5 M" b
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:* N* m+ T1 Z/ f- |' S; f
: H- B% p# B/ A4 y. G4 m3 XINT ID3DXFont::DrawText(
3 h5 A" N) }# }2 q
# X: U' t; |5 H. J/ i LPD3DXSPRITE pSprite,: z, B, ]3 ?0 \. b
) m% m2 D* k1 O+ B. C
LPCTSTR pString,
. ^4 R' ^# f0 O$ n' k3 o8 Q+ T' z1 e
3 |, S4 l& i( y) C6 B- d6 u$ G+ U INT Count,8 W7 Z. T* n$ ^) |. G) [
# p e3 A0 D! d& r. X* U* N* z LPRECT pRect," k3 x1 z( T" }+ @) h) V& B
% a1 V- V" k6 H3 ^ DWORD Format,* ^) }. p% A. m5 A# h
8 N2 _' T6 F. O D3DCOLOR Color
. x4 ~( l, }. @ O6 z1 V
- a6 ^4 ]( w1 G9 o' l$ L7 X);1 _# S+ }$ N, `
7 I( k5 S Z4 I h% Z
/ l4 P7 @) S X. h- B$ v
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象
( @0 A z ]! o/ E' V r) {6 L+ `& ^
l pString –需要输出的字符串
{6 b; ?/ B4 Y u6 ?* H
7 z" G. `: M7 hl Count –字符串的字符数,如果为-1,则以0字符为结束标志
6 b: \% g; V. }9 O
! C3 ~: Q$ L" a6 r, G: M. w ul pRect –绘制字符串的区域
- b% W+ j- X1 T, T) `( i
% g2 {' T5 w3 d9 ?l Format –文字的输出格式
$ b. U$ I: y& g1 W% H* Q1 p: c# T7 v) r6 F" ?+ Y
l Color –文字颜色* b7 w0 J2 v( @- {
' t( u3 p' T8 Y3 e. m例如,可以这样使用该方法:
6 B/ j+ ?/ v2 S; v% ~& S, L% K# _( l/ }7 ]2 ^3 |4 z0 i0 T: V
Font->DrawText(NULL,
6 p$ P% D6 T, d( x3 c* }% y1 d* i- I7 V8 ^/ Y- T' v$ y& c' e0 `
"Hello World", // String to draw.
7 M8 L1 g' [" b; Q/ @
+ {! z8 {' v- k2 j/ v+ l2 R! W -1, // Null terminating string.$ C. D( G- _4 w" O7 p
& B/ s# b9 r: a; {
&rect, // Rectangle to draw the string in.
) Z" R" L. `, c& r6 Q' B2 j: A) e W% m
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
) m8 o# y' E2 [5 E0 A
3 a/ Z+ }& \# a" l ]6 j% r, g 0xff000000); // Black., v. D9 X4 ~* u
& ?) `2 N4 V! w9 m
7 K# d' x* ], p7 w& x" ~
9.1.3. 计算帧速率
2 S! ]. \+ m2 j: c9 K# F帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:# J# M4 S% r2 \ E/ f
4 n U# O5 \0 Y# @+ f: }3 \
DWORD FrameCnt; // The number of frames that have occurred.
/ G4 X; j& k+ A$ H9 q
9 ] K7 X+ _' \' Rfloat TimeElapsed; // The time that has elapsed so far.2 ]0 Y. Y& D( n. J6 S8 i
" d, ?: E% {8 c# vfloat FPS; // The frames rendered per second.
7 J; L4 O! h& X# G/ N, u ; Z! a7 M b2 m ~4 a4 l5 g3 Q5 c% Y
9 b' q# a$ \5 p( R) S, T每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。: {: T; O4 E: u1 H
! S# ^, u( x. _$ h每渲染一帧,累加一次帧数和所用的时间值:
" ?3 j) R) R3 ~; R3 [* d4 M; H7 x5 c9 c: a3 p
FrameCnt++;
4 }) ^; w# n* w2 V3 L- g& c _! `
% G, i' u! J, @) A& [9 N! E$ t9 A/ cTimeElapsed += timeDelta;; B8 @. P: Z2 P
7 A p4 M2 t4 H" v6 ?
9 D; e5 i3 G# Z2 K" i这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
2 r. @* b! W" S2 ?
4 @! x; j: Q2 ^; |FPS = (float)FrameCnt / TimeElapsed;
% r/ k( T r5 v9 @9 h, Q: [ ( c" a0 Q$ Z/ m c' p4 y; B. g; Z
, P3 `; L7 s4 C3 c& n计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:6 J! A! y. M ]) d
' F: z2 B& e" R% }$ K- @void CalcFPS(float timeDelta); q9 q! R3 ^* G) q: C: }
, ^7 ]* o& r3 U6 I{
4 Y! s2 P2 w/ w- V5 b
5 G$ W+ b" { t% g% T) _ FrameCnt++;. |- o8 O/ S8 y! X5 z7 p
! l& R8 p, a3 {1 e
TimeElapsed += timeDelta;" N$ H; q9 x; R) }5 n. Y- }" h
& I$ M; G6 x: ]1 } q; }2 r
if(TimeElapsed >= 1.0f)3 ^' D3 f6 W2 O) U
( G6 H7 C3 G" t2 s: A2 T
{
6 J6 w. P. N% r- w0 ]& b2 g& l
7 e. w: `4 w/ f/ P( x U FPS = (float)FrameCnt / TimeElapsed;: S* X8 r" {4 I; ]4 n8 I3 K9 S- Z4 g
) _5 f) A6 C6 k4 L* _( e- U
TimeElapsed = 0.0f;' z! p5 {: p" S p# i5 o
3 U4 J+ r9 H( o. {& g/ Q5 |0 L FrameCnt = 0;0 q% h J: C* {$ c+ f3 a2 c
% D& `2 m7 k& z& V! f
}
- R- v R# E4 f, ?5 A5 ?- j3 }7 l5 B5 S6 E9 Z
}
5 ^- M. @& Z/ X& w4 i* R
3 t7 x1 K9 E# n1 J3 ?5 W& s* y: S' K# O
9.2. CD3DFont
4 G x8 x( N7 ]5 j* \5 q. L( l2 d在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。: R3 H+ t' C% Y" n$ }
: k8 w; B u0 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版本!) J* b+ ]8 J5 n3 t! ~2 c2 c7 v
: [) }# O6 M: K
9.2.1. 创建CD3DFont对象
& N; O/ }. p$ W1 P, H: G" c' k创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
% r5 ^( W7 N$ M/ D
! E. \, A, f; I, |CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);
$ w. Z$ B, o) W6 ~& [( C' O% `
- ]' S% p3 A; h0 f" b$ ]2 w) s7 R# U) C& ^! w, Y) U
l strFontName –所使用的字体名称
K' R' u6 ~4 O1 V: z! I
0 e, ~: c" }1 Yl dwHeight –字体高度# n9 G \' {3 ?9 L/ q* I& @
1 G {. e0 u1 S) B2 p: M, h0 Q! T# x
l dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。( k' ?6 V" J( V5 n
- {, R" f) g8 I9 w得到CD3DFont对象后,还需按顺序进行初始化,如:( q6 c: t5 p) B
+ {4 B" H% q3 \1 {Font = new CD3DFont("Times New Roman", 16, 0); // instantiate
2 f/ t/ d0 P4 ~8 k. h) o2 p& ~/ N6 I1 a, u+ \0 H
Font->InitDeviceObjects( Device );3 s; @) }( U4 n9 @+ @
% \/ a- D3 I1 `7 O! ` {) Q7 ^
Font->RestoreDeviceObjects();3 E2 c+ [( n4 ~; E9 M6 N, ^% n( C
5 }5 I; d1 `/ G1 r% ]! ?: K; l9 `! N0 ^
9.2.2. 绘制文字
: p4 b2 B5 X$ ^# p# U6 o使用CD3DFont对象的如下方法渲染文字:, T+ S8 i* X4 c2 U* x6 R' s/ K
- v6 H) K4 P+ j ?1 b
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,9 X& l* n8 H% ]9 ~9 t6 L1 F
: T. k4 n8 ]1 c) O const TCHAR* strText, DWORD dwFlags=0L);
! ^0 ?% ^- {, {- T3 b( @ % b3 Z# n2 N% ^! ^/ K0 h2 \
9 C' b0 r- ~" y! b3 k
l x –屏幕的x坐标
i, W0 B+ u9 S" i4 q0 M; c" K. u* s+ c. g; s) ?( F, z- C- Y# Q
l y –屏幕的y坐标" d" o; S; j+ ]! [; F
, v9 w6 X6 ?2 Y; F8 J+ el dwColor –文字的颜色( }* Z$ N# O v z/ u
$ ^2 g/ N6 n7 M b9 L( e8 k) j" Sl strText –要绘制的字符串
6 M) S3 X% H" D$ E5 f8 t9 q1 l2 ^) s/ G) M% K$ c7 `3 c
l dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
3 O/ b" f0 ]/ I! }/ N( b* K& e( l3 S; {/ t
例如:4 I. ` V2 R8 I, Z& L% G
2 J6 \4 E8 p% }7 W" k8 u( \Font->DrawText(20, 20, 0xff000000, “Hello, World”);% x$ t' t5 |3 r4 L8 Y5 U
4 Y* Y, b$ u S
* ^4 U% | V) T- a& f1 x9.2.3. 资源清除
9 \6 Z% v* V+ t S8 \# {+ R$ D在删除CD3DFont对象前,还需作一些清除的工作:
! g5 E! A8 I- {2 e/ a8 _6 F p0 J$ r: l0 Q+ s
Font->InvalidateDeviceObjects();' t; G! ]) T+ B5 V7 o, @
3 j$ u: s ]' h* e3 F9 e1 p
Font->DeleteDeviceObjects();
& \, z8 O0 P1 M9 m; p
% Z1 x. P) P/ G; v7 C2 `delete Font;
8 r* z" N- \: f* y; |
& Q4 {: K9 T$ I( n$ A, O+ z: ? F) J( r y* T- f' Y- B( ]
9.3. 函数D3DXCreateText
6 \: m8 x0 p8 ]7 i, w5 u$ x该函数用于创建3D文字Mesh,原型如下:% a4 B- L9 Y L9 ^
6 q7 X; m* _4 A) t9 o0 E4 w+ s
HRESULT WINAPI D3DXCreateText(
" |; g# o$ ]7 |2 ^3 @5 N }; w% _2 }1 }% g0 Q
LPDIRECT3DDEVICE9 pDevice,
: y( I+ K1 @/ f" D' q4 b& V- f( Q+ v1 r3 `
HDC hDC,& e3 F( G+ s+ u; Q- |5 {) I
2 v, _# _ r! \' m& v LPCTSTR pText,/ }. c, x! Z9 M1 i2 J8 z: }
5 P& B% ~# V4 n3 _* E1 i FLOAT Deviation,
d4 n4 A; Q' L X4 E9 o& }2 c& Q5 l& r6 j" ], p$ l
FLOAT Extrusion,. y1 z4 R* F9 a1 }
) C% J4 j- o- J' f7 L/ l
LPD3DXMESH *ppMesh,
% w6 N; W1 S3 C2 E8 p% M# K8 x
) D A2 E- I& y LPD3DXBUFFER *ppAdjacency,
J8 R2 v2 h# `, q8 S4 H) u+ U
* o' Z& f; C( B LPGLYPHMETRICSFLOAT pGlyphMetrics& ^ x) k' `; |
0 ]! j% i/ ^8 G) l+ b* f
);
( K/ H+ o! q* c: b5 [ N7 w8 Q ( r8 u/ ^ d+ N! q# U
# [0 o8 l! d$ Q% yl pDevice –D3D设备9 Y9 a% }( H0 ]: H
n5 c; H6 \2 Z& F$ Zl hDC –描述字体的设备上下文句柄2 T) ]8 [ b$ E
. O3 X1 `$ \7 K8 w4 Il pText –要渲染的字符串" g" d6 ?! g0 t# C- s2 o
) {# G: r6 z& q5 i5 Al Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
5 A c% I6 L: A/ e) g; }4 ]
5 h' O- ?1 E8 i9 pl Extrusion –字体的深度,相对于Z坐标轴( k) g" r$ F0 y9 G& l% Y
7 {7 C& q* P& o3 f
l ppMesh –返回生成的Mesh对象指针
+ `5 w/ t, n( y- u, k3 f
" \! Q8 F* |( V( m1 x! Tl ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
. e% L. h2 r7 @9 c5 a3 ]& m6 \. h8 G" n* G
l pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL
6 o# m$ Q: e$ _
; g+ z4 d4 ?- p$ n1 q& a/ }% m; e下面就举例说明如何使用该函数创建3D文字的Mesh对象。
# ^( [$ u# P: R# [" }$ ^$ P. q- n! i' [0 L
// Obtain a handle to a device context.
/ ?* a1 B0 {( @: b; ^
+ v: ?3 l$ Y6 ` f5 Q3 {4 _5 OHDC hdc = CreateCompatibleDC( 0 );# I1 c& j5 U, q2 }& b2 c
3 `3 Y& P9 g. }5 m% k, \. A7 n% J// Fill out a LOGFONT structure that describes the font’s properties.
4 n5 f9 I- o7 n; V* ~! H, }
* M u s* z9 o# t) g; O) |7 |LOGFONT lf;0 |- C+ i0 @. B2 Y9 [
0 P! e: }( _- b$ RZeroMemory(&lf, sizeof(LOGFONT));
: A8 q" ?# G" {2 O8 z1 z% _0 S. V" G9 ]) y/ O8 l5 ~, R
lf.lfHeight = 25; // in logical units$ d9 Z$ Z+ M, q% `6 H4 p
& h% h: x; X: \* t: t8 Alf.lfWidth = 12; // in logical units
" p/ |3 |+ s" J% b- w& }" E: H: p% K1 Z
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
7 ^9 w% A1 f- Y. z! ~: L* B
0 v0 g9 g- D5 `lf.lfItalic = false;' M& A9 g2 Y5 [- d0 n- t: G0 F
o' s8 V+ V! q: W* K
lf.lfUnderline = false;
% i% ]7 k6 {& f0 u3 j2 c" n( `) w4 ?$ q- j: r% b& R, ?
lf.lfStrikeOut = false;
w* q6 T& }' K' h
$ Z1 t% c+ Q* X4 M% _+ ?4 g" Flf.lfCharSet = DEFAULT_CHARSET;- E1 ^4 O# q' R+ w9 e
! [8 B9 C! l! I" u& |; r& a) G! M
strcpy(lf.lfFaceName, "Times New Roman"); // font style
4 f. i# W/ y3 M x4 K: g
# y+ H1 B( @; I4 N( `( ?// Create a font and select that font with the device context.
) I0 J3 A+ Y- p6 a+ c
, p: k5 x- y4 Z xHFONT hFont;
0 C5 t! O1 s0 L9 R, F* s
; {7 ], m, R& D- e' c# IHFONT hFontOld;
( ~& X) U+ r& Q
4 s! a# t4 s1 ]hFont = CreateFontIndirect(&lf);2 [$ v& L. E9 f2 Q" J
* C& e$ N: k$ o/ o% V
hFontOld = (HFONT)SelectObject(hdc, hFont);( @+ h" ~+ v- P" K! F5 a
6 v% U2 H- v9 C* D4 @% x
// Create the 3D mesh of text.
% c ?4 ^0 }7 W' _$ I
* A3 W U& M; e1 [! Q4 m ^; IID3DXMesh* Text = 0;
3 j6 C" M4 X* X( b# _6 q; w0 W" m
. u$ f; H5 e. _7 jD3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);7 ^$ l4 z9 b6 ]- U1 ^' Q' p
! U# v4 s9 i& \# N) ?" N- D4 m( I// Reselect the old font, and free resources.
+ M0 e J. k# O% e. O) w) j5 p5 H' h
SelectObject(hdc, hFontOld);
" f- T$ D6 P& @5 ^* [" w5 s W3 F4 O! g- W B) p
DeleteObject( hFont );! o, _" R% K. t; `
# h/ e6 h/ V3 c$ ] n/ S" }DeleteDC( hdc );
" e: ~$ e) c% F8 S! M$ c 4 Q G% ]' h: E7 o+ m4 U
/ w8 m; v, W2 X' g/ `
这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:
: B3 m- H3 L4 m8 x) A4 r, o3 r. j. Z/ X' M/ E5 V' l" D
Text->DrawSubset( 0 );
0 z* J* q5 D* }& b( O6 K+ C
% v9 H5 E8 f# f- _; ?6 t; ]/ M/ o; A- J* S2 o) D- a; z
译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
. N: {1 i/ U! q& A) e) c* o
% M4 X$ S8 a' t4 u) r x8 @9.4. 总结
8 S. y3 s! A6 V% ?5 fl 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。
2 A& {8 h" k- L! {9 ~% o" x
8 X0 O1 b6 G3 El CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。
- z& w- }+ b$ \, Q# x
5 F% o$ m1 L f* I4 a1 V( I/ q" J \l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |