http://www.5178c.cn/article/6/2006/200605173892.html) A m, }+ ]/ @5 m
1 @' n9 o; V. e0 O) y: f在DirectX 9.0中渲染文字
) P$ p' d( l" a2 R+ v0 d1 i, d4 n( B作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin
& ?/ b- J# U9 q$ z) L减小字体 增大字体
$ \) G+ `7 Y# X* Q% F2 S6 |9 P5 H9 ~
' a7 N4 h' Z3 p2 c% p# Q
! x) K/ G6 A; B; O# H) p. N2 W9 S; }* l' R
" |- O4 R# k9 B' K( J5 |/ T
4 V8 ?% A) w" e) b# p# v" d9 R
9. 字体
! `# a& U7 a- O2 r( B9 z本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />
! w0 f/ R( V$ ^% y) m) Y0 u2 U/ [* d; h
" a I6 k6 C; Y
. U1 S- f1 B. [3 Z( N
在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:: y9 d0 v8 g `+ _1 H* b/ D$ j
; {2 x. I% I1 C* Y
l 学习如何使用ID3DXFont接口渲染文字
* }$ x! C' h! f3 U/ B. v5 E
* t! D& g9 H) c' L: }% @% Yl 学习如何使用CD3DFont类渲染文字2 o2 O7 L: C4 v
3 C# |& I1 \* |) ?5 Xl 学习计算游戏帧速度的方法/ E; e& @/ o2 i; V; N- h
0 B( n" r9 b& w% t9 k+ x6 s- k' {
l 学习使用D3DXCreateText函数创建3D文字
- k* q; W( x5 O$ G$ K# \% y2 g, A) C% E
9.1. ID3DXFont. D+ n: f8 y1 s) d. E3 r4 e8 f
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。
% T4 \6 w8 x! }' r# X2 W. Z+ r X& f6 G8 H) p% d; @
9.1.1. 创建一个ID3DXFont/ M! U+ L5 w9 Y* R
可使用D3DXCreateFontIndirect函数创建ID3DXFont:7 K6 F. Q$ y `+ a/ l9 Z
: b8 Q$ y. s" X( D) h' h% qHRESULT WINAPI D3DXCreateFontIndirect(
( K+ A" ~' o% O: m" P! ^- t# _4 d3 I# T6 {
LPDIRECT3DDEVICE9 pDevice, Y) D# ?: o- t* y: t# K7 i
; N% l! e* V, f CONST D3DXFONT_DESC *pDesc,4 i- _4 ]. j3 b, ~
; q) a0 O& n0 m& v7 u LPD3DXFONT *ppFont) c- j- a& P5 P# t- }7 Z- {; ~. A
1 X. D4 t! P# w
);
) {- n0 @9 R, A' C# ~/ A+ v1 b
# o# e. c. P/ t: j6 j' C! ~" D
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
7 p+ K+ \* ]6 s) o7 j+ Q; H7 w/ W8 ^, z
使用这个函数时,需要一个D3DXFONT_DESC结构:& R. e, i9 y/ U
7 Y; z# Y) n4 j. x3 I' @
D3DXFONT_DESC d3dFont;
' D0 C" ^6 Z4 L; Y! j& \7 X
' p7 Y0 U a8 _- zmemset(&d3dFont,0,sizeof(d3dFont));
& p& u9 y' @5 ^/ I9 Y& h2 M3 S) r( c0 u x) N( p
d3dFont.Height=25; // in logical units5 N3 T2 x2 p, ?) \
$ w& q" E; M0 |4 u
d3dFont.Width=12; // in logical units
% q2 ~1 d8 T& L, C4 p& e' F6 b/ s: D$ l" d9 r5 a
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold): n9 z. u. Y0 O# s" o) k
1 p$ C& G3 k0 j( \d3dFont.Italic=FALSE;& B. L6 ^* y8 E0 S9 ^8 D
# } v0 }. q! z* d6 ]d3dFont.CharSet=DEFAULT_CHARSET;
% z* z3 w6 e- r* x7 @! L b b0 r: Z$ z5 M8 k; Q0 [8 U
strcpy(d3dFont.FaceName,"Times New Roman");$ n) {7 r! Z% M. r0 [1 H
: p0 z" |' j9 w4 O8 ~
ID3DXFont* font=0;
6 V3 Z8 ]: @" i. _7 c0 Z0 D3 V
3 Q: H7 H2 d) s8 _! ^. |6 ?D3DXCreateFontIndirect(Device,&d3dFont,&font);$ F* T7 A- a7 H$ J8 E, w/ q5 e r4 P* s
5 q+ a2 Q5 b( ?
8 T* ^6 o- |5 P如果你使用的是LOGFONT结构,则:5 d/ O* `/ {, B* `" z, x) F1 y# K
B) H% q M) ~( g- b" F- J
LOGFONT lf;6 k3 a6 `( t1 Q8 B- R% a
6 w: ^0 K/ y6 y/ j/ zZeroMemory(&lf, sizeof(LOGFONT));
- R0 v- W5 t" \6 y0 E$ ^. L2 o& T, X9 D# s( K0 C9 ]) ]: J
lf.lfHeight = 25; // in logical units
* _; g% Q; e7 o/ E
_+ x+ h$ d; G0 A; E5 u$ rlf.lfWidth = 12; // in logical units
% ^/ H$ ~/ z1 D9 n/ l( K8 `: r6 s# l% Z4 g& H& a
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)+ s y5 g- ]& S' M% A% A/ U
q" v% B5 R7 w# ~* X' p% j# m& i2 b! |
lf.lfItalic = false;
) |. R+ X8 A/ f) {; u6 ]9 W. o& A
& V/ C: V* [0 O7 [$ o( _4 y ^1 @lf.lfUnderline = false;+ a* T/ C8 h4 P) w, J
6 J# G" c H! m6 y
lf.lfStrikeOut = false;$ V, O. o; Z' b; H7 ?# [
% b; E" {2 O* M3 w* _lf.lfCharSet = DEFAULT_CHARSET;# b7 _7 Q# n2 \8 ]& g' Y. ^: ]$ K
+ W* ?7 R) Q' a0 B4 C: R4 ystrcpy(lf.lfFaceName, "Times New Roman"); // font style
% d; ?8 B) l7 K, D
* H+ H% S) y: TID3DXFont* font = 0;) g( V, ^- E+ ^6 X( D
/ v5 w3 z0 y& G9 s/ H# }) y$ M5 G
D3DXCreateFontIndirect(Device, &lf, &font);
, h* e1 N) g) w! r6 G1 D8 M* n
/ y! {) N+ @( _5 C# t' [/ {( ^2 [, L: t! z% I& H! ?0 n
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。9 v \7 D' [% x7 d9 J
4 `" r% Q) a. ]8 P
9.1.2. 绘制文字
^/ {0 t2 \: j V& A得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
% `( f& N+ e1 {! W/ y1 p' R3 C" R
$ H+ i v; S# |$ hINT ID3DXFont::DrawText(
: E. c, B7 e" r+ B% G) ]8 W+ u; h
LPD3DXSPRITE pSprite,
2 E9 J2 F( d2 ]$ X
0 c7 L: C. {; K LPCTSTR pString,
& Q q7 X+ Q+ A; t' _+ o' `0 U7 ~2 D8 Y( S
INT Count,2 I3 x; p( J1 V! A" Q5 z
! x) C, ]) {: S6 q
LPRECT pRect,, O# D) d0 I3 n. ^
3 Q1 d& f2 n; A, p
DWORD Format,3 @ D$ ]6 t+ k3 k! P$ n
% }* C6 q/ t7 i( |
D3DCOLOR Color0 n& c$ Y# `+ c9 `0 @, B. J
7 K" n1 Y$ Y- e; }# |6 ]% {
);% ~/ Y9 }3 O" \6 d
1 H& Z# i2 A& O
% I$ V) G0 X+ e1 e; Il pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象& J( c* Z& e+ ]9 u8 y+ y, `
1 D y% J6 S5 M% o" P, D0 ul pString –需要输出的字符串
: V3 s+ U( ^- F9 J6 o" D6 ]
5 }5 B1 Y, u" [0 f1 a0 I' D1 S8 Ql Count –字符串的字符数,如果为-1,则以0字符为结束标志) N: |& }0 H! K/ o
" | S: p2 u: E9 _2 Y7 R
l pRect –绘制字符串的区域4 Y' l' e) U: E0 [# E" P* l
1 S0 d0 u6 H. m' C P- R
l Format –文字的输出格式
2 b: m' k I: \1 T. @" w) @3 |9 N2 r6 g: P
l Color –文字颜色. w4 r4 ?& n: ~3 A! j; ]; g
! a6 v/ L5 x' A
例如,可以这样使用该方法:
' K- v' ~4 e, O; ~: I' q6 O
, I! Q8 y+ B3 J: lFont->DrawText(NULL,
3 x- O z8 l3 |& a
$ S) D: M- |( @3 R$ {2 ? "Hello World", // String to draw.1 `- l/ h% F& Q8 x7 e6 _8 P
* Q# I4 y. M: P. M; Y -1, // Null terminating string.
; C5 q8 x/ h3 A1 _7 f2 M0 I- L. y4 l s
&rect, // Rectangle to draw the string in.3 n) T* }" u! S9 Y/ B/ K, O. f/ Q
* h% T* a* E1 o4 V! ` DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
. v0 x- c" ]* d6 y. T; G' w' C' D9 C! r' @4 Y7 T
0xff000000); // Black.
: d, W, C+ }9 n) R* _! z% |
% V4 L2 s* @7 L; |2 N
2 S+ ]' N" u6 k. R! k9.1.3. 计算帧速率
& X0 [5 W) Z3 p0 D: n' ?3 n0 z帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:
0 E+ N9 L6 `( S+ ^; Q% G4 d0 C# i3 h8 t! r! t( J
DWORD FrameCnt; // The number of frames that have occurred.
7 a6 ?7 R8 P/ z! T# m$ a; x0 g+ M6 R( D6 `' B7 G( S+ h S
float TimeElapsed; // The time that has elapsed so far.0 ]% o2 u1 z0 ^, Z0 I# c9 Z
/ q, m/ L: V( T7 ~float FPS; // The frames rendered per second.1 y( j% I i: L
2 H; Z$ _: z* Z; a+ |
0 D# k' V K7 }8 U& @
每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
, W: w/ E' [2 i4 s* V3 K7 a, u# v% Z% d4 ~* z5 T" |; v: x# y
每渲染一帧,累加一次帧数和所用的时间值:
$ c1 l+ [: [+ C2 D8 d$ q4 K3 V4 X: e# S5 w6 J
FrameCnt++;1 w/ j* ^. J( S1 Z+ u7 a, R( I
5 d- C1 v4 _ J) f
TimeElapsed += timeDelta;! M& j# G) B& S* c& U) {" ?
8 [8 y+ M# e" ?5 _7 P* }! i
. p' f# B7 K* K/ n) Q这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
+ ]- j' V7 \8 e2 v! U) u9 b( i& p9 c$ p2 i( E+ I4 c- ?
FPS = (float)FrameCnt / TimeElapsed;6 V$ \4 G+ l( k3 F6 g
5 R: _+ i6 ^7 H
" s9 L# W N' ~" [$ T# L计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:5 v9 p+ _" q/ F- C
) U% u/ b; r3 p, O8 C/ s/ W# _void CalcFPS(float timeDelta) X% j& f' [0 \( Q* f6 w% a
# r, R- b, G* X& H5 t{+ n( Y/ s) E, U5 t
0 w; S4 s9 ?0 M1 W0 Q) y1 ^ FrameCnt++;5 b& r& J3 r2 }+ y& {1 x
) d& u/ q& T9 O$ k9 j TimeElapsed += timeDelta;' d1 d. v4 G0 L
5 p- i S6 c' m; K' i' x# l if(TimeElapsed >= 1.0f)5 D l9 }8 n2 o* w I" O
/ k1 A5 \4 l) ?( @2 E B
{
6 c `8 A' p, F& N/ j" x6 s( A; {/ j/ k: d
FPS = (float)FrameCnt / TimeElapsed;
$ R4 @; u) e- m; @2 Y B! {
, \" C& N, B9 \" p( e$ q TimeElapsed = 0.0f;* x. M o1 C9 b% y
2 d* ?$ k) g& A" U, R5 ? q
FrameCnt = 0;) x. ^% e1 O4 G# W0 P- F9 L7 o U
% V/ x6 b6 y6 C7 b! b! Q+ r' v' D }
! x8 f. _- h" a. B/ {' P- ^( Z* u! X$ Y/ D7 V! C" Y
}
/ y7 T. F2 e3 T2 C- A# @
. T6 m5 ~; m: z5 g! B
2 K6 M8 J8 X& J: f9.2. CD3DFont
9 Y( J$ f, Q9 i1 A, a$ Y$ J在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。& i' n C( O4 O2 y0 i, l
4 N. T; c+ ?" @* T: q
使用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版本!
3 _6 T4 F8 a/ [+ c# n, Y' n( D: B) \; ]. Q
9.2.1. 创建CD3DFont对象
1 ^" P$ x3 B$ s6 t$ H6 G. j创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
, e. y0 g/ k z: Z. {( q8 f2 ?
# Q1 m. D9 K- i/ T- `CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);
2 P2 Y# @9 p) ^. R% c5 t9 b) B
0 _- p& O' |: y$ X- Z7 H! K( a! o# h+ i* j7 \: y2 ]9 x
l strFontName –所使用的字体名称3 U( A, Z! k& G4 h
/ w% ?' r; K( i5 _
l dwHeight –字体高度 I Q7 Z' y2 C, Z/ ]
0 M# w, b. w1 G7 @9 H1 fl dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
$ y" ~8 @5 v$ o! L1 P5 P
6 D( p& `* s) L! w- c得到CD3DFont对象后,还需按顺序进行初始化,如:
% o* c* k9 p+ S! ^( l' f6 W1 B2 P3 \" i5 O8 c0 R
Font = new CD3DFont("Times New Roman", 16, 0); // instantiate. j% n$ b6 _+ W$ W& O
; Y& e/ T( M. q; U
Font->InitDeviceObjects( Device );: r6 n. j) x5 p% E; g: D; Y
) G! u- e. ?$ q1 }' ^5 qFont->RestoreDeviceObjects();
9 O4 s" N. ]5 v . H) f. i$ ? `3 [- j% |1 u6 |: @
* |7 ^+ N6 P' d. o3 ^+ m9.2.2. 绘制文字) H/ {# c2 v4 F3 ` F3 v, R. X
使用CD3DFont对象的如下方法渲染文字:
$ S0 a8 j6 z0 H% H& f5 g+ F- p$ M' J: C( L" N
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
9 |: _3 ~7 n3 T- u1 E$ k! Z o
7 j/ L- y* u% j1 \/ u. P5 M' x const TCHAR* strText, DWORD dwFlags=0L);: }/ O% h& z7 g6 L. O' \/ o9 J
! `( |' Y ]7 _- B$ {* y$ c
9 A, \: k$ c' ~0 [
l x –屏幕的x坐标
* z1 `9 E9 l' }' Q* u/ `7 i' \9 q3 d
l y –屏幕的y坐标
& N+ t1 o- u) X$ O$ C
. G; I# v0 b* V' wl dwColor –文字的颜色
5 e: ?) f) n$ @ n' @: ?
3 \$ ?' X; g' X; y/ m; T" Ml strText –要绘制的字符串
; [4 J) [( ]/ h
5 o% {& O3 @) p- Z' y& Ml dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。% s7 e% l8 K0 `/ A6 k
( d/ Y* `. g1 X9 V例如:
% @9 W' S0 N E( j6 z8 b: M Y1 j4 \* E4 K, u3 g
Font->DrawText(20, 20, 0xff000000, “Hello, World”);$ d$ o' H( E2 \8 I
: ]( \3 X9 E/ B/ w- Z; R
# p2 a. A2 K, n* K9.2.3. 资源清除9 k2 W" `6 n9 f. X ~+ a! n
在删除CD3DFont对象前,还需作一些清除的工作:
" Q& R/ q& S) x2 b# U& w
8 U0 w6 x4 i h1 }Font->InvalidateDeviceObjects();
0 h: o' T1 g+ S! E% }9 u/ y3 m Y9 r& R, d$ @% o
Font->DeleteDeviceObjects();
: R, l, z+ v8 h1 S" J2 Y4 I5 x4 m9 z% J' I7 P1 v
delete Font;1 v# T G L0 I
% W& c1 F/ w9 B' Y5 H( b8 a
$ ^6 \1 M' w- j. d5 U/ t9.3. 函数D3DXCreateText% ]7 n: A# f6 h& w& m
该函数用于创建3D文字Mesh,原型如下:) _3 E3 H3 n5 ?1 N
; [" A+ t: J! m- C7 tHRESULT WINAPI D3DXCreateText(
* G2 ]; d) m3 o8 u$ r* p# d* Q; ^
7 H: e) C7 s# |. T {3 r LPDIRECT3DDEVICE9 pDevice,
' L+ h5 T% K$ m% g) S
- s! a/ H- X5 Z2 I$ n; g5 m0 r HDC hDC,; K& C# {2 n; |4 A" I$ t- x0 c
3 I+ F4 F# c. n( ^0 c# | LPCTSTR pText,
6 e' R [+ i4 j; V1 h; L Y8 z1 h) }/ \) x
FLOAT Deviation,
2 p/ G( { ?; ?9 \' q0 U, `% R0 B @3 ~
FLOAT Extrusion,
2 F$ r8 q; J1 V; _ P) t
$ m: i) U0 w; e LPD3DXMESH *ppMesh,: {2 Z6 b" S/ D. q/ ^$ T( C
6 p n# N" H4 M! ~% `& @, z
LPD3DXBUFFER *ppAdjacency,7 `. p, {( X* J, i
7 c$ E) q3 Z6 }& C
LPGLYPHMETRICSFLOAT pGlyphMetrics
# E/ \; c: \& A! a! S& J
5 \. I6 g w9 t$ V: P);
3 B4 O7 K+ a a. _ : e& k( U" u) e( Z3 y
. {) }7 |. j" S1 V; n( jl pDevice –D3D设备
' S' @; W% L& l. V# _; D$ Y8 a: a; i9 x, ?, Q+ c* z6 W( x
l hDC –描述字体的设备上下文句柄. B6 l) L$ X& c3 c- l* s5 c
4 S$ B5 [; ]; q$ t3 c
l pText –要渲染的字符串! J6 d% {8 K, ?
0 [, n! R8 I4 b2 l0 i; p. ql Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
, B* C& K8 A- F6 I; l
: J9 f5 x4 S8 s- m& P3 vl Extrusion –字体的深度,相对于Z坐标轴
" T; v1 f9 w8 { I4 d! H: G0 `" ~; G6 M' A" ^0 G! X& S
l ppMesh –返回生成的Mesh对象指针
; @' v- I% B% D/ G. x" t( l
! h9 d* m/ c. n5 o0 pl ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
9 l- `0 O, C( y5 g, j2 W. ~$ w* w" M1 U6 |3 ^) f9 ^% M% N
l pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL% w2 U; r+ c9 O" f/ E- _* O7 y3 ]7 j
+ N- h, E2 O+ G( r8 W. U下面就举例说明如何使用该函数创建3D文字的Mesh对象。
, l; ^1 G% i6 ?2 Q4 N! V3 n z l% s c6 j
// Obtain a handle to a device context.1 N8 B0 G, L2 [' p4 T8 V
6 b0 O; a- t# j; W" ~
HDC hdc = CreateCompatibleDC( 0 );4 I5 M7 S, s( H1 L( D" K
' x. a0 P1 I% b8 [// Fill out a LOGFONT structure that describes the font’s properties.- A+ L J9 r# p6 N
" r U5 N: k9 E. j" L$ T7 U$ Q
LOGFONT lf;
7 L0 W ^0 z; a W& w4 O6 z4 h) T3 p; @4 |
ZeroMemory(&lf, sizeof(LOGFONT));
6 I# n" R. e% f) t* }; ~: F
) \4 k, x) ^* S8 p2 [) u7 _8 Klf.lfHeight = 25; // in logical units" W6 Z0 m6 \9 y, l: f+ u6 u
" k) A% P* T8 olf.lfWidth = 12; // in logical units
( }5 l0 X- m$ ?7 t; i- _2 F- w# T+ `( D6 O) w
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
n" x8 P) R C! p
& h! W+ `5 Q/ T8 W% t. O2 L$ r3 ^; Elf.lfItalic = false;2 o5 v: Z! w7 u) T# Z& }/ F
: F& H9 `4 e5 Y9 g: K7 mlf.lfUnderline = false;
' {2 x+ h) P, {) s! i4 \: h# U8 J9 f2 P- i1 n
lf.lfStrikeOut = false;
8 q" O2 {' `) x% O3 B7 m3 q3 d
lf.lfCharSet = DEFAULT_CHARSET;; _' ^( e+ H5 a! c7 W: ^1 d U: t
3 u/ _1 u5 ^) h1 w3 w5 ?strcpy(lf.lfFaceName, "Times New Roman"); // font style
% {8 E" g& Z( \, w6 H( j6 W3 N0 i' M& y( D2 b
// Create a font and select that font with the device context.) P. S+ M2 D, T3 ~( }- f8 `4 D: N" J
8 |6 k- K1 Y, ~# ~' IHFONT hFont;8 y) k- L }$ l3 Q! r
( E' ]- `* j0 R) L5 E: WHFONT hFontOld;
" H; K1 [- J9 W4 \. m
6 H/ X$ Y% F) Q) }1 p7 Y" ?hFont = CreateFontIndirect(&lf);
5 @1 C6 H- z v2 W
: j9 C" q6 i; G5 M" lhFontOld = (HFONT)SelectObject(hdc, hFont);
1 G* S) i# m: _5 L% ?
5 A/ h4 _( A$ D' R, n7 z! Q// Create the 3D mesh of text.' @# f0 H7 u4 a) @0 H# J( C' N [
* h+ A* k% v- R r0 c7 C
ID3DXMesh* Text = 0;: Q- o6 j, _! t* P% W
* e# u9 Z, E) F2 v9 J0 p
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);
0 n- h% I1 m( v8 D1 A" p. f$ N) Q8 C' Z7 U
// Reselect the old font, and free resources.! k5 c1 g9 k# _4 \% [" m4 I
0 \2 |% B5 N- B& T$ ?: ZSelectObject(hdc, hFontOld);8 r4 x7 s* S+ Q& T" J$ F8 ^6 a/ R
7 c4 J0 S5 R2 h
DeleteObject( hFont );
( Q, i* X- V0 f' u: L
# B. p0 b: e2 K" n, fDeleteDC( hdc );3 K( |. N4 H- Q# G/ n4 a" K
7 j2 `' g e9 X; P* B' R8 U8 z; J7 a
* {% _) V1 d. {$ n* t这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:$ l" C+ U# p' J z* z
8 D, W% F! Z' I: u+ C/ z
Text->DrawSubset( 0 );2 F- t v$ b" \" @& s: e3 z5 N
8 _- ^7 E4 o- b
# P% t' t R$ w9 l! p! E# f% R1 Y! c9 g译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
8 X) a$ H* y! i- N; c- x$ ^! R( ^/ _2 c% Z4 o- l' G3 g
9.4. 总结, j+ b$ Y, N& v5 f5 y: X3 w* Y
l 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。
9 g2 R; D; d) D: I @6 z I7 ?2 \! ?( q4 r5 F+ _
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。3 `" o2 ^6 q6 V. n
4 R) D5 z. w6 B" Q Z. _l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |