冒险解谜游戏中文网 ChinaAVG

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

作者: shane007    时间: 2009-3-12 11:49
标题: 【汉化资料】在DirectX 9.0中渲染文字
http://www.5178c.cn/article/6/2006/200605173892.html* B0 y# T' b* R/ T4 [
# b7 c3 U* E2 d0 f, J4 U' @/ x9 I0 v
在DirectX 9.0中渲染文字 6 H' r- G$ G% M7 x
作者:佚名  来源:不详  发布时间:2006-5-17 12:27:04  发布人:admin
6 F3 Z% @6 R5 y8 ^+ Q减小字体 增大字体 ; Q* Q9 X. t" e
# T! u7 ?+ e) n! l' o" q( Q% ]
  p) X$ j7 q3 r! ?2 Z$ R% J

! I. Y5 Q5 h. ~/ z" [& x9 T1 u4 L  N7 v2 g- Y

( y' h4 M- _' c
! o. W/ u9 N! w6 k2 ~9 x8 {- k; r9.   字体' o2 M0 r6 G; k7 b+ a9 h! \5 m$ m. x- s
本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />0 }- ]4 ]8 U0 U4 K& e) U% z, c
# w- }/ [) M, W6 g' r4 k/ ?: m

6 }! v- u$ G; J6 {
5 l& r, V( }9 Z$ C& F; f7 _' v; R4 [在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:
8 G' q8 l$ K. l3 }: z* B  n% p; |( @6 W  M/ f
l          学习如何使用ID3DXFont接口渲染文字, z# ^9 o. `& @$ C6 Y- X
: E7 f& E6 ]/ z1 k" g, y+ A; R
l          学习如何使用CD3DFont类渲染文字7 [7 p/ h; b4 ?/ [" V
+ o* D  N; v6 w0 k* a. q
l          学习计算游戏帧速度的方法; q$ f& M1 w1 L# R; o7 H
  r( t& [' F( f
l          学习使用D3DXCreateText函数创建3D文字) ]# i5 V+ U! Q8 G

. d* G2 V6 ?2 F  X9.1. ID3DXFont
) S. k6 U& h3 K5 r7 u要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。6 j/ b1 m+ }  a
' [# ], g. j6 o/ P7 w# t/ D  |
9.1.1.    创建一个ID3DXFont. P/ U7 y) J; N- Q" R, }
可使用D3DXCreateFontIndirect函数创建ID3DXFont:1 S8 W- r( N  W) ?- |! ?

3 T/ j6 {3 r; ], Q6 [& gHRESULT WINAPI D3DXCreateFontIndirect(
2 C7 b3 Q/ |( i1 }- _
4 c% H7 a. ]7 z; H. }" a! I7 I5 d/ A    LPDIRECT3DDEVICE9 pDevice,7 e2 Q; _0 ?2 V, f

5 ?+ [# Q* L; R/ X) M% q8 O" @    CONST D3DXFONT_DESC *pDesc,
# }; I2 {3 @( k
7 U! a$ [( d: U7 z    LPD3DXFONT *ppFont/ i. n- t. V; z$ m1 C
7 r; w7 e/ m" w8 g- x2 G
);" P/ @$ F2 X1 f3 U" }2 E

  p6 K# c* d4 x* E% d8 {: ^9 X) b. g; [# J. u0 D8 W% B" I% F
译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
+ ]5 J' ], ^1 d- [  E  F
1 U( p/ R, l5 r; J% x8 a使用这个函数时,需要一个D3DXFONT_DESC结构:# e% Z0 D/ ]  e2 m$ T2 |
/ z* q# y1 x" f  }& ~; C" u" P
D3DXFONT_DESC d3dFont;
; X4 P- c3 j( H
. y! }& s+ F, G; `& t* L. ememset(&d3dFont,0,sizeof(d3dFont));
; v. v4 y$ t2 j! O
3 i# S  l6 C$ l0 a$ {. K: ld3dFont.Height=25; // in logical units
& v9 S5 m) r" x% o& p" n6 S% W" y
! S- a6 \7 @- h' G7 ?* C: Fd3dFont.Width=12;  // in logical units! `( e3 L) [; b: T
1 z6 D4 V! A! P# F/ \! E" S  `2 L
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
7 j* W/ j; q! G' P( k$ F: f9 R; _% K0 L3 e) q$ J1 S
d3dFont.Italic=FALSE;
8 p' B. ?$ W9 N% M+ I  }: m! o8 j  s3 E
, d/ `0 g1 }' o# c% {d3dFont.CharSet=DEFAULT_CHARSET;* L/ n7 G8 y" f9 [

6 l8 ]$ Q4 I% S. @  N* bstrcpy(d3dFont.FaceName,"Times New Roman");
; P7 \6 {4 i1 D% |! V4 I  B- z( X1 q6 @' z
ID3DXFont* font=0;6 [( L2 i' J1 a3 B4 i1 D

; q7 b3 a6 q6 j3 n8 KD3DXCreateFontIndirect(Device,&d3dFont,&font);- ^- e% v" E2 N8 D2 \

3 Q1 J5 E7 p8 ]( O; E. t' d# P% O* \7 J& V9 s. R& d
如果你使用的是LOGFONT结构,则:
+ O+ T) x9 Y# ?1 j$ T7 A0 U
5 m- \1 n$ ^* cLOGFONT lf;
+ O& a5 L; v( B$ A* ^( L, Y0 z" `0 ?7 L
ZeroMemory(&lf, sizeof(LOGFONT));! X' L) k& l4 N+ A7 \" A

$ x5 e$ m# |7 [7 r! klf.lfHeight = 25; // in logical units4 g/ C8 j+ P4 c7 m8 x: b" [5 J

" N0 b0 R2 N. j5 H' r6 a( plf.lfWidth = 12; // in logical units6 H4 t5 H4 E! `$ R7 ]
, j1 [* `" a9 U3 U
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
; L3 D. c$ U8 S9 v: h& H  H0 y5 B  D8 o  R9 o
lf.lfItalic = false;3 E' E7 o0 g( Z! L8 R3 E1 Q
1 l7 q, t1 H: b/ S9 l
lf.lfUnderline = false;
: O4 R  g) a, X  ^* ^3 W* V. c! c- F; d  {/ O1 C+ U, s8 _. _
lf.lfStrikeOut = false;* f3 S3 G. `8 T8 P
: y# T9 D# v/ `! n& k" a
lf.lfCharSet = DEFAULT_CHARSET;
& A* A  O3 G/ @! s& R4 t; m/ _/ S5 ^8 \, A1 q1 V7 I4 h6 M/ U
strcpy(lf.lfFaceName, "Times New Roman"); // font style& D+ s5 a0 P! f/ ~& l2 R5 |

* {7 o; M) i/ P: ^' z( VID3DXFont* font = 0;
5 V4 p& m/ L" ?2 j" n# v6 ^# g" y# I- ~; t- N
D3DXCreateFontIndirect(Device, &lf, &font);" G- G  n8 W4 `; P0 H6 Y

/ w4 {) y; W  }! o  F$ A# o
3 t# l0 K5 _; p( a另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
5 |7 L6 ?5 i* w+ H4 ^/ C- y- E
" B/ g% J, ^0 y% J2 o9.1.2.    绘制文字5 Q$ h+ O2 w/ {+ B5 ^9 i
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:
8 Q* R; s4 ]3 j' t$ P- Q
0 n: F9 d0 G2 n% M" |# ?9 z7 j- I9 ~INT ID3DXFont::DrawText(
& i# m, [7 B2 C* A: y' y( k1 I' C
+ C( ~& `+ P/ J. I0 ]    LPD3DXSPRITE pSprite,$ f7 x( f; @; {3 p
. J  O# G7 r- Q4 d  R  d
    LPCTSTR pString,
4 \" o; u" K" U1 F7 o/ j4 g* R% u! P. P6 n6 S1 o  d
    INT Count,
% E9 Y7 ?" D( ?2 f2 ^8 n% Q0 L9 q, \' T9 X- {2 F9 J) Z
    LPRECT pRect," X8 ]! C$ [* O  V( F. F
* }3 I5 K9 _8 {+ C$ Q( k' ~1 b7 k
    DWORD Format,  s4 B) d. ?' p+ D+ I- \

1 E) S8 g: c4 D$ n+ K" M( @5 y' `    D3DCOLOR Color
3 m/ Z( J+ A% O* {- L1 Y* V8 y# P9 E
);, L$ t4 |* Q5 Y) R( Y8 |4 Z
7 ^( A: p& C( T& a
7 c" B$ t7 G) `% v+ u
l          pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象$ q2 h- ?- F8 [, c0 _9 v
! s$ S8 x  Z% c- h( a* D5 k' T
l          pString –需要输出的字符串
- l" h9 j' e* b. R: s" K2 p3 P4 f+ c3 C+ `; P# P
l          Count –字符串的字符数,如果为-1,则以0字符为结束标志0 Y0 I) l4 A4 r! j
: P3 B3 t3 t. x, J1 X
l          pRect –绘制字符串的区域. Q4 r2 J) D: A3 W4 u  u. r2 W

; Q4 @" w" t4 P+ H& t2 A" Ml          Format –文字的输出格式
; @" ?9 v" U/ x: b0 k: ^
# j! K' n0 F* B2 K( yl          Color –文字颜色+ {. w& n* k$ `
8 N% I3 V6 P8 _& X" W
例如,可以这样使用该方法:+ ]; w4 d. l5 s& Y* i7 {& |& U

. x) U$ D: N$ `6 |Font->DrawText(NULL,9 a& t- b, c5 H+ B1 R

# V1 U1 ~$ d5 ]& e8 N    "Hello World", // String to draw.
4 e+ Y/ A, F9 V& S$ o  l
0 j7 ~/ Y  _0 {( @! R5 [    -1, // Null terminating string.
. t% Y; Y/ l5 I# |; T2 r) F/ F8 t3 b9 z
    &rect, // Rectangle to draw the string in.
2 ~- P* k1 o6 k; e' {% H) l# I6 Z7 d4 s% ?
    DT_TOP | DT_LEFT, // Draw in top-left corner of rect.8 j0 k. o9 F. K9 b6 {

' T8 e$ W) \" z    0xff000000); // Black.
2 z. |! V7 p5 {+ G* E
2 r( E2 R/ m2 O( H% D' p
5 y0 O, B; Z1 h9 A9 g0 F1 `9.1.3.    计算帧速率/ }% j2 L& r" b
帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:; b8 T: R2 c( x  A) S5 x: l* y
! O8 y: ~+ W- n9 d- H" @
DWORD FrameCnt; // The number of frames that have occurred.5 _3 p9 a2 v% Q5 |/ t

% L  G3 ~6 j1 I# n2 L0 B' zfloat TimeElapsed; // The time that has elapsed so far.
* @  m6 c: ]3 q" k) D. w" e% h- {
float FPS; // The frames rendered per second.
2 r' o" X& U# W! R( Q 4 E( |# W% w* ]0 i( \! n
1 i8 S# {9 H4 f  M/ t% W) }
每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
8 ?' N. O, Y& I  s
% ?- s9 |+ t5 i' o5 l  m每渲染一帧,累加一次帧数和所用的时间值:& [2 u2 W* e3 g# f6 j2 \$ n1 l+ d
9 D2 U* t( q+ s* _! B1 g; n- P
FrameCnt++;+ w$ g* u: z1 A. t* h5 D" [& _
6 u$ ?, Y3 q1 u& I4 W; N( q. t
TimeElapsed += timeDelta;
! I% b/ b. O- \' b - U' `% @3 O6 N& C' ~; S
$ G  d0 ~6 M1 V1 _' g/ u) w' H
这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
" t2 K( k1 l1 x" E5 |- U. `
  K; k* y  q! `& P/ E# P; H6 HFPS = (float)FrameCnt / TimeElapsed;. F% m- a: P: ~. [: W6 v
/ u3 W& |$ H! t5 X

: w( n+ p: `! J8 y7 z' W, j' t计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:
7 A" B! O* n4 k- Z# p' T# K- u1 N& [/ I1 `+ E' A( Y9 X
void CalcFPS(float timeDelta)
0 [0 |3 Q. ?3 w1 U& I- J$ m9 H' j/ f( S0 P  S
{
; s# b0 g) D$ E2 p6 R
6 u2 P# q" a( q/ f6 C    FrameCnt++;- Q7 p+ I5 U' Y* _8 T5 @9 n" f5 S

' l; D# v0 ?& W* |- g7 M- _$ z    TimeElapsed += timeDelta;
' G6 U8 s8 L0 F0 c# |" t8 o
% ^. b9 @7 U4 m, b& [3 R# v" z! m8 [    if(TimeElapsed >= 1.0f)
% O* Q! r2 w0 `! s( S6 P! t* J% i
    {. X( T1 M+ _% w# e: f! M, f0 Q
- j7 u( q0 N6 J
        FPS = (float)FrameCnt / TimeElapsed;
* T& }/ {3 d8 ]! \. a* t* Z8 P" j2 o3 _+ r' X3 S; i/ _$ I
        TimeElapsed = 0.0f;
0 _1 u2 p. r4 V' B7 [2 t0 @% S- ^6 P3 S  t1 m
        FrameCnt = 0;9 N" e  E. L! G: s

! L( Q. [9 {* E! f4 B, Y3 E+ b    }4 V" a& e: O2 M! @7 c
# ^6 R/ j8 u- z. A
}& S- {) d7 v  l* G" u

) K0 a' ], L9 e6 v
, E9 E9 `4 N9 g! H! U9.2. CD3DFont: ?% R& v# c% ?# J) t; b9 p
在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。
3 j) |& i9 e% D# M2 `& \/ P3 g1 ?, `7 |0 q( N
使用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版本!
9 T+ x1 _6 |3 ]3 |& p( N' l
' ^' f- i( m" ^% @9.2.1.    创建CD3DFont对象
5 f  c  @9 l, i; C+ N1 ^) K# H( J创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
: d* T7 l' K$ b. }) k7 }9 n  n4 h/ j  M* s' R8 r+ A
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);3 Q3 B7 A4 ^/ v5 _1 F! ^

/ a4 F' l5 D% H. C5 ?0 w; t% V
' \) \; |6 G$ xl          strFontName –所使用的字体名称
0 }. Z) O3 U7 `# K" U4 I& ?; r& e4 h7 e
l          dwHeight –字体高度
! F/ y: n# j# i- T2 H7 R+ L/ Z- T0 p- N: ]* a( f
l          dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
6 m% a; g- l) d/ q5 d9 u5 G: ^8 @  K. v# r& ?0 d
得到CD3DFont对象后,还需按顺序进行初始化,如:  [+ H5 \' j, E4 X* f7 u" l, `- l9 y, I& X

( B, G6 h% W; S3 ]: ?& HFont = new CD3DFont("Times New Roman", 16, 0); // instantiate
6 n& w2 W) X4 V
7 x, s5 v' N% m! P/ c% KFont->InitDeviceObjects( Device );) j2 \- C" ^7 z, {' N% M

2 \* v& K; N5 @( \8 x# S5 ~. s4 WFont->RestoreDeviceObjects();/ c7 A# c1 m7 H5 q6 J
! z5 {9 O0 L7 F1 {
( N' h2 p" N" R1 J; Z
9.2.2.    绘制文字
7 q; X# X8 G' Z使用CD3DFont对象的如下方法渲染文字:
/ Z2 x$ U* [- I" l5 b' c* y# A4 y2 r
HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
7 R, c# h8 r0 X2 B% V3 k6 v, ^* x$ F/ z  d# g% M9 B+ B
    const TCHAR* strText, DWORD dwFlags=0L);" E. R9 Y/ E) W% ~6 L5 e

( W& T, F1 F9 n) B$ Z
: M$ T7 z1 P3 ^- f" zl          x –屏幕的x坐标% S# k) l/ h2 w. H1 W

7 Q* v) @/ k6 zl          y –屏幕的y坐标
( {  {6 a, L! W/ L/ Z6 F$ J1 @5 ]' y+ X$ a! J; u9 R: d* `- w
l          dwColor –文字的颜色9 L% b% @1 m0 t/ O! Z; x6 C2 M
3 u& E' I' p5 F$ @& F! m
l          strText –要绘制的字符串/ P& N3 d1 ]6 x3 `
5 G% k6 F/ m$ l  R; v
l          dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。3 P% f  K! [+ Y& _, Y! f6 l; B

4 c% A* I3 y: Z7 V; G& n例如:( z* i) j  H/ z5 Y* `& _

# W* y- a, P  R9 T9 ^Font->DrawText(20, 20, 0xff000000, “Hello, World”);4 v6 E8 S6 j* H9 F0 w" i( J2 j0 V, A1 y

5 K! o, K( u6 R* a
( C( l' T" d9 R" e' E& U9.2.3.    资源清除
, v2 v" {  S) {, ^9 T在删除CD3DFont对象前,还需作一些清除的工作:' f$ H1 ~  B+ Z, T+ \. E+ f% v. P

' R5 _# h4 C% M- s3 P& `Font->InvalidateDeviceObjects();3 S  k3 B; V1 r6 J) i
4 z* ]: v0 p: [& S$ E5 G4 C) D
Font->DeleteDeviceObjects();
- J3 H* L$ z4 d" O
) q; H: X$ Z" b/ O1 O5 bdelete Font;" \. J1 s8 X! Q* d3 @+ p6 e
) F0 ?, X) `, [' i% {: @, z: o
) ~$ g1 J5 w2 v  u3 m& I& }7 F
9.3. 函数D3DXCreateText
7 l1 W; W; ?$ E6 ?$ L! e; D1 R该函数用于创建3D文字Mesh,原型如下:- w& N: H* y7 v& A7 B

( T/ f0 E; g1 V9 R) \HRESULT WINAPI D3DXCreateText(
5 c' [$ D9 L9 h
! j7 z2 k" @* M    LPDIRECT3DDEVICE9 pDevice,
% i+ B$ y5 N. E# o  F: S9 M
, E% z' i. Z3 {: s" I    HDC hDC,
6 t7 x1 `" l# c" A
* P- ^+ i0 k' }% p1 ]    LPCTSTR pText,  O( Z, X: p% n# j
5 M, q6 y: s, A  U) O  C+ n) S3 L
    FLOAT Deviation,
, k' q2 h3 X0 A9 `3 \! S! X; R* G. y, l: V) [4 r2 G
    FLOAT Extrusion,( }8 s2 F* U+ I( X1 G) ]
4 W9 K$ ]8 ?0 d
    LPD3DXMESH *ppMesh,
0 P5 ^# t% `; m9 E1 N: U' {6 Y6 S* L: x' D! s: B
    LPD3DXBUFFER *ppAdjacency,
2 u. u# V; i+ ^8 V  r) H8 T; s- q  Q9 G$ G  Y% o
    LPGLYPHMETRICSFLOAT pGlyphMetrics4 }( n0 C6 [& D- C0 y

# l9 G5 u7 f9 J) n);
* I; k" ~7 U$ a2 }8 F# ?  Y / S4 t- j2 r9 h9 g% b9 v4 W

& M$ d9 {. c7 T' f' r9 Z6 Hl          pDevice –D3D设备- t8 v( H% A: k9 Y) O" a

. O% y' b" U2 g6 J1 O2 x+ |l          hDC –描述字体的设备上下文句柄# {6 c5 i- p2 J' Y6 Y8 _+ w: n
9 ]- I0 d! `% O; ]4 ~4 |
l          pText –要渲染的字符串8 y/ W. E/ {! n% e1 e! ?# d6 C* ]
' [+ B% W" |, X- N
l          Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值% |6 D% B/ M: P5 K: m  s1 i1 S

* r1 A) U6 ]' E) L% z; |l          Extrusion –字体的深度,相对于Z坐标轴
/ H. l1 o) h/ b' p  ^. y* a8 u) {) v. G5 ^2 }( m9 }- }
l          ppMesh –返回生成的Mesh对象指针
3 ~, [# h- z2 @! G: F/ t) L9 B" V& Z
l          ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针' a0 _# O. A7 y7 t2 P4 [: O
. ~, ?" y% D/ {: r! J( ]
l          pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL
( J8 g1 R0 i# A/ L$ o+ X4 O0 S% l
1 F! W  }  C$ p下面就举例说明如何使用该函数创建3D文字的Mesh对象。' ?4 w4 c! s; p- l, t6 M" Y
6 j6 u3 |5 s8 r( a; `
// Obtain a handle to a device context.
# Z5 e3 Q7 U- ^/ G
; a1 b& e- u$ e) o0 i9 eHDC hdc = CreateCompatibleDC( 0 );
9 l+ O, m" y4 D- e! k* i+ q* \( g* [# E" q# n' S
// Fill out a LOGFONT structure that describes the font’s properties.
0 I8 a' h6 A/ }% u7 D6 y7 W' P$ g' P; |4 W" s: |
LOGFONT lf;+ B1 P1 D) C7 U, |7 D- U

' m7 d/ E; E1 P* z8 NZeroMemory(&lf, sizeof(LOGFONT));. d2 A6 s9 w6 A

- }& z  L! S  E9 ]. zlf.lfHeight = 25; // in logical units
( c+ R# G4 n0 |/ i4 k; p8 |+ X
, D( d% Q  m0 E1 H1 a1 t" Olf.lfWidth = 12; // in logical units4 h8 I# Z5 l: w9 B

/ H9 z; `1 l! K. b: _; V3 Klf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
1 |" l+ C  u% @. V: }* u, J8 O* x' d. G
lf.lfItalic = false;* [) U8 @1 t, \# a& v+ n
, }& u0 r# r/ i
lf.lfUnderline = false;5 c6 E. Z) z( v3 w8 M* h2 c: q+ k

) K: ?  L, @& J8 i& s- ^lf.lfStrikeOut = false;
" B4 W1 D0 D9 A8 W9 U  G& i/ s  i8 M1 i
lf.lfCharSet = DEFAULT_CHARSET;  m8 _4 c; o' p* T; [
6 m& h9 Q. M! O
strcpy(lf.lfFaceName, "Times New Roman"); // font style' t0 m$ S2 A+ G9 F
& g8 `  W4 F) H- H! x
// Create a font and select that font with the device context.
% ~- j: }9 f  y( {/ m+ G! P
1 Z' X( Q: x; @: qHFONT hFont;( X. {3 Q& A/ C- y

9 j9 v, N4 q9 v9 J0 N& ?HFONT hFontOld;) t* _6 N% b. D9 Q, Q
' J; P. k: ]( y: N7 N% c. J
hFont = CreateFontIndirect(&lf);2 y+ U  Z0 \; |& G- c2 E4 t& o

8 t) Z1 J- K7 U5 G4 L( L) M5 ]hFontOld = (HFONT)SelectObject(hdc, hFont);+ E% J4 s$ x' N( `8 j& {

3 \# @+ m8 C* m, ^( {// Create the 3D mesh of text.
( R0 T  ~8 |5 P% I$ ?1 _- ~0 r, G% r3 i
ID3DXMesh* Text = 0;5 x" s7 W9 @  E0 R
# F6 o1 W8 h# ?0 e5 B: M
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);
/ C; z- h5 e4 U4 n  ^" X3 A% m/ Y1 G: b
// Reselect the old font, and free resources.
# V# h3 B6 \7 b9 J
& z2 h( R, r0 w$ VSelectObject(hdc, hFontOld);
* y2 x) a/ o$ x" o" o8 z- Q* w7 Y9 [* \
DeleteObject( hFont );  @  H$ T: b* W; a1 H( ?
% R$ k: @5 x' M) }) c" @% x
DeleteDC( hdc );# N* q( @+ C+ j; J5 j

: `$ q' O* S4 F8 W4 _  g( Y; {: Z7 X3 L7 z& ^
这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:  y! u1 i2 h0 ?
, `, }& H7 Z/ ^+ e& A
Text->DrawSubset( 0 );6 n6 Y  T! S" r% M! D
9 |$ p+ ~1 H" y- ^. i& E) J5 _4 z" E

5 U/ V7 ]% C3 P2 {5 K  R译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
9 F, |$ c( G) q0 K- R) c8 ~6 S3 l8 ^- ^4 y% s( `: t
9.4. 总结  ?0 Q* z4 N9 D
l          如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。( c% P, c" L8 u, c. F

# e: }! |# k) ?3 k& Ql          CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。8 c' L) G7 L- n2 I8 z
) Q% `& f5 `9 U2 k* u
l          使用D3DXCreateText函数可以创建文字的3D网格模型。




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