冒险解谜游戏中文网 ChinaAVG

标题: 【汉化资料】在DirectX 9.0中渲染文字 [打印本页]

作者: shane007    时间: 2009-3-12 11:49
标题: 【汉化资料】在DirectX 9.0中渲染文字
http://www.5178c.cn/article/6/2006/200605173892.html
; ?2 `9 ]. X7 D  N2 F0 A( ]+ x$ t/ }6 @$ B. J- f
在DirectX 9.0中渲染文字 8 m8 a+ S+ c+ g: F( t# y& @
作者:佚名  来源:不详  发布时间:2006-5-17 12:27:04  发布人:admin 1 P$ B0 b+ r3 P) [, {
减小字体 增大字体 ) s6 ?& s: B) }& \4 ?3 J/ W) T1 n
7 S- S' r- Q& m
8 J5 r( F  c8 |

- Q# t1 O4 w$ k  [$ w$ y7 _) K
; V/ E& H9 f/ ^# R! ^5 ~, g% J; h. H( P8 V0 h4 V' [
3 k" ~# p; D1 F
9.   字体5 I, X9 U* }/ ?. E  X; n  C2 z
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />5 w$ [- o- i) b! \" B9 H) r

- n5 \; ~' t' z2 I( L# x ! {* F" t" U2 z9 @

0 w" ?. C  {; b: t2 b6 k" y在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:
: U$ f* ~; u6 s- Q4 U) `  k8 f' c$ A! \2 g
l          学习如何使用ID3DXFont接口渲染文字
0 C) g. \* ?) Q; G- c7 o% l: l* ^+ b* s) {" _- I  l* `$ b9 u$ Z2 D
l          学习如何使用CD3DFont类渲染文字2 m7 p! Y% h& |8 U* ]4 z

' c. ^- G2 r2 B4 x$ @. hl          学习计算游戏帧速度的方法
3 @! d- V% D; X7 Y
/ h( I& u& Z! l. _  r3 k" t7 ^: ^l          学习使用D3DXCreateText函数创建3D文字) V  y8 j+ V( s
& \/ \( t2 C* Q! L- p$ |/ @
9.1. ID3DXFont& }! L  W! @( K& w+ R
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。- ~& H! S' |/ c5 J  M8 ?! K4 J

. A' F" S9 @# U1 Z! m$ K+ `9.1.1.    创建一个ID3DXFont
3 M9 S) W4 Q' y9 d可使用D3DXCreateFontIndirect函数创建ID3DXFont:1 z( J5 {' c9 U1 w

6 t- o; F* E4 X: u0 mHRESULT WINAPI D3DXCreateFontIndirect(
, f( t) z! u# X" U! J7 e. j4 f& x$ q% T) n2 D# u) U* h/ i
    LPDIRECT3DDEVICE9 pDevice,9 @* z8 z- T5 N& f

! B7 P/ B2 N' g& f: Y2 O) d1 T8 p    CONST D3DXFONT_DESC *pDesc,
: X- S& o* ~3 n& f/ \+ A; U4 B& f+ h7 t2 W- P$ h
    LPD3DXFONT *ppFont
$ r1 w* f) g6 I! u* }
* @6 l' v2 [  v);
2 ^( ~4 ]+ x& L( }" N- p* p 3 L; q  O! G% p2 n; g

/ |) k! a& U2 e0 y- Q6 T译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
1 n1 [: U: H# D
) c' G$ B8 D" R- R0 I: W* D使用这个函数时,需要一个D3DXFONT_DESC结构:
0 {0 E8 G$ K9 n; e+ I: K7 F& }! B! x: D9 n) d% i% S
D3DXFONT_DESC d3dFont;' {2 u! p5 d/ E2 \7 e. y8 q

7 \; O3 O$ ?! \. hmemset(&d3dFont,0,sizeof(d3dFont));
, R0 G- c/ |! Y6 S* k5 v8 v: k  Z$ r5 u. o# S) C
d3dFont.Height=25; // in logical units* j" x/ t5 ~  |
8 s4 k& q; [* A7 |% s9 ?8 X
d3dFont.Width=12;  // in logical units  B6 _" i4 W- j1 i( `
8 w1 z! p( ?! d9 K+ N# j+ A
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)1 v. r! E& M2 W

5 [9 L% Y7 H" G' M, K' bd3dFont.Italic=FALSE;
: z9 c7 v5 n) Q9 H/ k; J, T$ n. o& i9 C: v+ N1 e+ e) U
d3dFont.CharSet=DEFAULT_CHARSET;; ]& J  [$ Z# {- _2 h. G
0 ^+ J% i! I7 h5 Z. k) g2 s; y
strcpy(d3dFont.FaceName,"Times New Roman");% g- o# F$ C9 T* H0 ^/ m) j

$ m# @7 T$ P2 N% i7 V) rID3DXFont* font=0;8 @5 O" T2 N; n1 x
6 ~" b  o* V4 m" y3 ^8 Z
D3DXCreateFontIndirect(Device,&d3dFont,&font);! x% g$ v4 p3 @) y

" Y/ w* J% T4 w% R% m. F( p+ D1 t$ i; i- o) D: m5 F
如果你使用的是LOGFONT结构,则:4 J4 ?  |3 y# h% Y7 }
. W2 V7 C4 W( X2 ^; ]+ A$ P
LOGFONT lf;
. V- r7 D- V4 b; k% U+ o. o1 Z2 `+ E* |0 j% t7 l
ZeroMemory(&lf, sizeof(LOGFONT));! e) k* w6 \7 m4 c
# ]0 m0 w# F9 l" `& P# Q" C; d) [
lf.lfHeight = 25; // in logical units
! C/ \7 c+ v5 \, ?) y
$ L: m8 \# P' x. C6 t" ^lf.lfWidth = 12; // in logical units5 M' L  w/ f& v' [
6 Q; ]* f* Y6 f! n
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)5 [6 b5 \& V' i: ]

" F% q% r. G3 `$ Ylf.lfItalic = false;1 O. j: v" s) P( x! R  h& |

% l% r5 @2 |! l, Clf.lfUnderline = false;
2 L! v7 t3 X% L# j
# K1 g# p* l% ]2 [; R4 ?) ~lf.lfStrikeOut = false;
( n& q& Q; `; |4 [
: g% R, |& F; r, B" |lf.lfCharSet = DEFAULT_CHARSET;
( ^7 Z3 N/ {9 r! a) g* ]
/ J6 h: w) W5 Kstrcpy(lf.lfFaceName, "Times New Roman"); // font style
, m5 }  H+ O- r- H' z' d" j* M3 _) j& _
ID3DXFont* font = 0;
7 }+ I5 r5 G& b* ]: s) G
; y0 C7 Y9 X% s$ lD3DXCreateFontIndirect(Device, &lf, &font);8 E8 W0 W* S/ v7 ]7 ~- l
  k. |+ N" g" l' }% A, ?6 `. m
. ?& @( O6 T) B4 D) ]4 V
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。; M5 h! {' i# W. e. d

+ h3 Y( u0 |! j. L5 _+ p- [9.1.2.    绘制文字
' T& B' ~9 t% F, Z5 ~' |& p得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:; W& J5 x4 q& z7 }- l1 S

  _+ C+ t6 d1 x+ h5 NINT ID3DXFont::DrawText(
1 c% G/ C* l/ J1 p! |. f. _2 o% W7 e# H' H. |
    LPD3DXSPRITE pSprite,
6 c8 r. V2 S' z6 H+ `4 ?( H" r! I7 r& F
    LPCTSTR pString,  P2 R, I3 ?, F! a+ E* g9 O

9 u6 R; m( ?0 I    INT Count,
! X1 j- Y( y6 j& w
1 z; ]( T2 W! }    LPRECT pRect,
9 X5 s4 l, x1 v' g6 h; C5 i  {0 _1 [+ u5 W, h: B$ @
    DWORD Format,
+ A8 t" p( e. {: s9 V
% M# `8 @, K8 [/ `3 G    D3DCOLOR Color
' u3 B9 R) \+ ~4 j1 a  j7 l$ W8 b$ J+ ?+ P. L) h! Q' u2 I
);2 i0 u  @* a6 g' R8 r3 L  y. r& t3 b

) U1 `( y# h9 ^" T6 i) W! X, q
" {8 j( V( H+ J& }9 I# nl          pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象
/ R. k7 k9 C' |& f7 d* L' a  C; C/ b3 W7 P7 V
l          pString –需要输出的字符串. \8 S; a: \5 Z: }% H8 j: H8 I- F

+ W- d( L* c) K0 U$ t+ k* D. Tl          Count –字符串的字符数,如果为-1,则以0字符为结束标志- Y& A) k1 [3 V8 U2 F) V

1 ]5 x! r& Q! S% D' Nl          pRect –绘制字符串的区域
3 e9 ~( j& \) Q" J( G3 }1 o) I6 r* u
l          Format –文字的输出格式
/ h' G+ P) W0 Q9 a
( w& D1 ?- ~2 b( ^; r2 ^$ Wl          Color –文字颜色
2 _1 e6 Z8 J3 x( r* y% m5 R% ?0 L2 t- @" t0 w' \( b+ {
例如,可以这样使用该方法:
6 @) G' c8 o1 G/ Z: Y! G
& n; M2 V* x: O: ]* AFont->DrawText(NULL,9 I% a- `3 S, P
6 T" a6 b# W" m1 i0 i
    "Hello World", // String to draw.! W" @1 {/ s3 j/ B' M
. I) ]1 I7 \* R2 I
    -1, // Null terminating string.6 q4 _3 I, r" c; s8 a
+ d7 }. H; M7 r+ n
    &rect, // Rectangle to draw the string in.
- B3 L9 ]* m$ H- L. @# N- F5 G0 Y5 J; |0 T4 d
    DT_TOP | DT_LEFT, // Draw in top-left corner of rect.1 l3 A- y8 O4 {( W) {
1 f" X8 W% ^0 r, K& j+ t
    0xff000000); // Black., w2 D4 g: U* G. ^2 u3 H2 i5 l" _
2 S! O4 b, v( J! Y4 N; P" S- D

: b8 a, ~) L  `( A9.1.3.    计算帧速率1 s( Q6 R$ ?7 x) ^5 j$ ]0 i) V% O
帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:% X, T& ~& n. ?4 `; p# i9 ?5 a8 m/ A

, u( _  A& p& c; oDWORD FrameCnt; // The number of frames that have occurred.
' D' k/ p, \  k1 m  |) }2 Q
4 g& _# o" @2 hfloat TimeElapsed; // The time that has elapsed so far.
) E* H" T! ?" S' F! T1 F6 U% C9 p* K/ E7 W1 r( f; e: K
float FPS; // The frames rendered per second.
7 f" c: e3 ~7 j7 J
3 o4 ?5 Z' M6 b+ ^# I: W$ a& p0 H3 u- @3 D3 z& A' j
每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
$ Z0 z! c' O, e9 Q$ V$ C. L& `  R' B( \( z! l3 E
每渲染一帧,累加一次帧数和所用的时间值:9 O* l4 |5 r! a

5 b8 Y( J1 l, WFrameCnt++;
& p) m5 c) J( l7 z
, ~; \8 m' }( q( W' K9 z- m  {# s4 `TimeElapsed += timeDelta;
- W# ~# [# r- t7 }* w7 h
# t- v& q- l" x9 c
) j( J5 J2 D1 L0 P% C这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
$ Y- S5 s( v7 p4 P' V9 N1 T& R$ [% {8 G/ u7 Y+ m" L* g' A& p
FPS = (float)FrameCnt / TimeElapsed;
2 D  |; J/ W; D; T/ A4 u$ l
7 F! H# N2 T9 m+ G) }, G$ f
6 \$ h9 W: h. m  w1 I$ ^; T' B计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:1 _# M( O" c/ |8 W: R

8 K4 z( F5 E/ y# |void CalcFPS(float timeDelta)7 i* D4 Q) c0 x9 m1 O: w/ ~0 t6 R# [; z3 q

3 \% R  ?5 U& u{
, D1 }6 r  D2 R) T3 j
* d( U2 G6 r: C, [) C5 S( L9 u    FrameCnt++;4 y# f6 T/ {4 u5 R
/ p' {; |, \5 q. r" t
    TimeElapsed += timeDelta;
2 O5 b3 I2 h2 Z, [$ F- ~- b- l- I* _8 Y! m& h
    if(TimeElapsed >= 1.0f)4 u7 e7 u4 m! I7 E! y

' F3 b; T# Y$ }    {* Z: Y& C5 ?9 R1 j2 H0 J

5 W! J3 h- i5 H+ O7 U' |7 @        FPS = (float)FrameCnt / TimeElapsed;
1 y# k+ ]' I; S0 h2 [+ n# F9 b1 C' R; u8 j$ k
        TimeElapsed = 0.0f;( A' Z+ J# \8 D

% K6 h0 C  @/ d5 c, C5 j/ t5 Z  N        FrameCnt = 0;- ?, c2 I+ U& F, b" r6 {0 J

: @: h& _/ Y, z4 I" S# D    }1 |  r; ]/ {& E* a
+ d  A; t3 A' O
}
3 ?1 ?' b8 @7 ?& S2 C 5 h" \' O( g' @: z6 k

$ Q# C( P6 m$ k8 e* g' u" `8 t, _  z9.2. CD3DFont
: s5 r7 }) M. i0 N在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。, x7 U7 j4 X; y( r, y8 ~5 k

( V$ h* ^) |" J, s2 i1 r9 _9 g5 }使用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版本!
. Y( j) C, O3 X+ j
# @- Y8 Z# K0 e! J# u. s8 ~5 y6 `4 ?9.2.1.    创建CD3DFont对象
3 o5 J- L' L" G! W6 I创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
" s" c9 C, `# ?+ e- ]6 x0 E0 `% f6 d5 n2 C
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);  E+ V! z0 m/ e9 T  e
. ^! ~; X  }" R6 B" _/ L# i
# t: {6 w3 d+ z, e
l          strFontName –所使用的字体名称+ U$ e$ c* d# Q# r1 \
. n$ E2 s& s+ a: a# K; \9 j
l          dwHeight –字体高度
  O* ~) T. E& i( \; A2 j, J: I, }$ }6 z, q" I; m( `$ p: w0 E6 p
l          dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。2 X, e) j6 C9 l9 w
3 X2 B' Q3 m5 J  U* s' Z/ A
得到CD3DFont对象后,还需按顺序进行初始化,如:
* q8 w+ G3 |5 M1 j, G! l- Q3 G. i& i7 ]. _1 H9 V' v/ V# L1 r' R" a+ g
Font = new CD3DFont("Times New Roman", 16, 0); // instantiate/ I( ^7 T/ m1 v( Z+ k! P

* h) I; p. u) @3 B& b9 TFont->InitDeviceObjects( Device );
* l  @) B0 q; z) T' q' z" k4 K% w1 F; F% V' H' A
Font->RestoreDeviceObjects();
7 W! _$ ^. e$ Q  X2 \! b ! V, n! ]% p% {* J0 _. K6 o

1 f1 f" K$ n6 }) S6 B9.2.2.    绘制文字. A5 [; N  u" I1 [( R2 f: {
使用CD3DFont对象的如下方法渲染文字:
/ s9 o8 C( j$ [
5 C" `9 W& T6 a" M+ \HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,8 S1 C& ]. u7 y# t

" S% m" L- q: B" j, B    const TCHAR* strText, DWORD dwFlags=0L);
' v7 d' _0 K6 C" c2 W9 K
( S, h, _: ~# a3 z8 w3 L; [8 s/ q: O
l          x –屏幕的x坐标4 i5 t( x: Y5 Y: c* D1 ?/ p

) W! i+ \& J% x( r) nl          y –屏幕的y坐标& S2 i" E5 z& ]* o

4 Z8 T& Z4 c/ y% b+ w- m  E: Hl          dwColor –文字的颜色
6 `1 [1 `1 d+ x; z3 C
/ G, ~6 l1 E& U7 tl          strText –要绘制的字符串2 F3 F4 u2 l. J2 L

& k% z$ N' Z  E9 a. V- }l          dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
, m7 X4 V* K" T2 @7 j- Y$ y6 ?+ c5 r5 y( o3 @1 Y) W8 ^( E0 b
例如:
# W3 T$ ]' S: L. f
  y! O4 O5 l+ NFont->DrawText(20, 20, 0xff000000, “Hello, World”);+ ~. d& s+ b( w2 G- ?4 {7 Y5 e
* e# c  e! E/ G2 J2 h. m/ p

: }  J( I0 L' {$ a6 F9.2.3.    资源清除6 T) I) R8 v$ j7 ~& J
在删除CD3DFont对象前,还需作一些清除的工作:( k. h# s+ F+ o
2 s2 `, r# }! f  ?! A, X
Font->InvalidateDeviceObjects();
9 y: k; [+ w! X3 }! c% @: q4 r! ?7 H3 r; B! y/ a  h
Font->DeleteDeviceObjects();  v9 j( h: F) }( r1 u7 m, o

9 ]9 V, h( ?6 t* o6 Mdelete Font;) i8 ]1 n) A8 ^! _6 ?% g( d

2 v; G/ A8 y7 G
+ d6 |4 Y, M: k, t/ E9.3. 函数D3DXCreateText( o' s, w6 N: Q4 o* [
该函数用于创建3D文字Mesh,原型如下:
8 n7 r: W6 G# k( m1 Y
. ?: J0 Y9 d7 f$ f1 iHRESULT WINAPI D3DXCreateText(! Q+ B) `3 V# U% n% Y) S$ K: N

3 P  J# M( K" h, Q. W; D    LPDIRECT3DDEVICE9 pDevice,% w( y$ f; U$ ]: T# m7 O1 a& J

) l( f$ i3 _7 b- C7 m& N    HDC hDC,: m- L* N0 {4 \; }3 I

5 B& u! W) i& E' g! e    LPCTSTR pText,
' n6 Q9 p7 X6 C5 b
/ [8 ~7 A4 \4 I6 v% |9 D    FLOAT Deviation,
. o- i0 k8 Y& c6 t* ~# A7 Y4 T# s3 ]5 v% `
    FLOAT Extrusion,
% K9 J1 b* c& A" y! m! E/ H% b* n1 z+ q' s
    LPD3DXMESH *ppMesh,
( Y1 i" F% ]0 m: ?9 j8 A( W1 j& ?7 Z4 U8 u! f/ x" y
    LPD3DXBUFFER *ppAdjacency,
7 i- _) F4 h: k+ e# I' R( a0 K6 d1 t( M# G' F1 T
    LPGLYPHMETRICSFLOAT pGlyphMetrics
8 k0 v- Y/ n: T% }/ D, G) i
9 i4 q8 a1 M- X8 g# q);
5 Y; [6 u" E* s: T2 D; u: ` 1 F. i% f1 q( q& e) z. \

1 w/ j. T1 i" [3 E5 L* Bl          pDevice –D3D设备* Z3 N) ^9 j4 ?8 W* n
. U, p3 Q/ u8 u0 K0 R) c
l          hDC –描述字体的设备上下文句柄
) [7 r/ h3 B4 N3 I. C7 U  o- s  `8 n* f0 i
l          pText –要渲染的字符串
7 m$ a; ~7 x- ]4 @
; G* `& i) Z* \, D2 C5 g3 q" ]l          Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值; \5 O, q  l% w) {9 a2 L
# D* Z  q  q& E) d' j
l          Extrusion –字体的深度,相对于Z坐标轴8 G" k) ?3 N, P! W4 x% I: o

. P8 [% T/ k2 Ll          ppMesh –返回生成的Mesh对象指针
/ H& y9 |% m# }( [; n. g6 m6 G$ h( ]7 t0 x+ s" \8 |" |# h9 ~
l          ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
6 N$ \4 d( V" P5 [0 z/ o
8 ~2 W2 k0 c& V3 Tl          pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL  O1 J8 S, C* }2 r" r) D

, n  V2 e* }1 s4 x: f( w0 R下面就举例说明如何使用该函数创建3D文字的Mesh对象。5 ~; D) P9 A" I& M) b
5 @* t4 X0 M% {, {' F: I3 c
// Obtain a handle to a device context.- ]* s3 a8 Z+ _. R  V  D
3 ~+ k  q9 p! |6 K  ~5 A/ y
HDC hdc = CreateCompatibleDC( 0 );
8 `0 r( z* |. N
1 I9 ~+ S$ A3 x% p! }2 a// Fill out a LOGFONT structure that describes the font’s properties.
: b% `) u# @" f) H: J3 o" _, O4 ]3 E+ X
LOGFONT lf;
& N- _5 b% M0 o* R0 n/ W5 B" J/ r3 z1 }
ZeroMemory(&lf, sizeof(LOGFONT));
( D" ^1 B; G; R# m3 |: O& m- P$ F5 |- q- f* N( B. u4 S8 h; t
lf.lfHeight = 25; // in logical units% ^# @, t: s& ]* s2 X7 O

6 Z) T$ p2 ^/ r( o' w1 \1 plf.lfWidth = 12; // in logical units8 _1 e2 g' |1 h' T
- p% g1 O" L+ ]5 b6 @2 |9 o
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
8 q: D# w3 [0 j3 K0 L. u' `1 `
- W0 l2 m* Q0 M/ z0 rlf.lfItalic = false;
' R" ^' w- u6 a3 ]) A/ q6 A
- {- O+ B" l! a# P& Qlf.lfUnderline = false;$ C9 _$ B# I. Z0 F

  K+ Y# [/ A0 P- slf.lfStrikeOut = false;
/ A, N, ?2 t& c
+ i' D  Q3 v) i3 G  A* ^7 {lf.lfCharSet = DEFAULT_CHARSET;
( B1 W' D: e! K; U+ ]* ~1 P0 |! j7 R! Z# [4 v& H# R& \0 \
strcpy(lf.lfFaceName, "Times New Roman"); // font style
4 Y: @% e6 k$ L5 N9 |
3 s" v( M# `" D) }// Create a font and select that font with the device context.
& q2 G" m" i7 _- A$ h
  X: o7 m+ [0 l0 qHFONT hFont;
( p6 l# K. D0 y, g
, X0 Y! p7 G: Z) H3 P: W9 K6 o5 AHFONT hFontOld;
; T6 I4 K* w9 ]% ]& `! [0 ~9 {9 X( Z. e+ m: V2 S* R  e+ P
hFont = CreateFontIndirect(&lf);
* C) h( t8 E0 U8 Y) L% _/ z3 l- Y. |* D8 J. @1 P
hFontOld = (HFONT)SelectObject(hdc, hFont);! V; i1 ?) ?; n! O4 @

0 U5 L: F8 t: [! t, s  m. `( H0 g// Create the 3D mesh of text.3 {2 C( f+ a9 y  @$ i$ G, d

& V3 ?/ r, `: s8 f7 o1 }ID3DXMesh* Text = 0;
( Y$ @4 p$ _' w, T5 z5 {, {9 o% y# w) C8 a8 p9 e, s1 o$ I. U
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);, u3 ]: U* I1 V: A: \) O( Z

6 H& K# C# R5 T2 ~: f// Reselect the old font, and free resources.
0 J* ?7 O) s$ L* n  z
$ o3 d/ e% Y) r# v' SSelectObject(hdc, hFontOld);
% }9 v7 L, F9 N
, Y6 F# @6 s5 t7 rDeleteObject( hFont );  O2 a6 N' C' }/ x9 W
$ K% G2 r$ E' m* B
DeleteDC( hdc );
9 p* s4 V6 F, O$ J5 \0 `4 _: b2 ?
, X# C+ Q: o* d% _1 c+ [8 g( x$ A# U
这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:$ j7 d" ~4 n  R2 ^

' L  W5 |6 v1 P# V! `Text->DrawSubset( 0 );- p6 s0 h+ p$ ^

3 S, p  ?. {% l/ P
) X, O9 Q: {1 r9 z5 j6 S7 s) d$ F译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。0 c1 r) e; i  y/ V0 e$ o2 i
; R: k3 F( |: J0 k7 l6 Q
9.4. 总结
6 i" r8 u. a  K! Y* m$ \* fl          如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。2 |  m8 C! \! \' b9 g

% c' l- W4 b8 w9 H& r" [l          CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。
& v, S9 W7 |% |9 P. c! H  K: C+ z% w$ U# [
l          使用D3DXCreateText函数可以创建文字的3D网格模型。




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://www.chinaavg.com/) Powered by Discuz! X3.2