http://www.5178c.cn/article/6/2006/200605173892.html- ?- f, ?& @0 t: W7 t \) t0 H
5 h. N* c9 u" g6 `, f, L9 m在DirectX 9.0中渲染文字
6 F& I+ u& W# g" I& Q* N& B8 J作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin : u( W/ {- e: v# Y+ T! F; \
减小字体 增大字体 & K2 g1 b" x V% w& g# j3 d
" }0 U, P, V5 b" \9 b3 `5 {$ g
9 m3 D1 e: X; x; i. s8 |
$ t- M5 B) r5 v. N: x
( o% q- f; S8 x3 Z6 r* K8 L* i6 o c) e; y! n7 B! c. g& m
0 [$ n- |, c/ z; r2 V. ]9. 字体
! L4 x! G. B- M9 m9 C% W本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />0 s( |3 ~# ^/ ]
4 i8 u/ P3 i$ G) u3 _. p$ O! I
7 a5 B) J" i" ~; P% E2 S. |$ B0 A* W
在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:* A$ S- q( u% ?: n2 i* `. h
7 U, D4 _0 q) D; A* Q& N0 K3 z5 a
l 学习如何使用ID3DXFont接口渲染文字1 ?) p8 W$ J7 ?3 Q
- N( t) P( K' T( T) x
l 学习如何使用CD3DFont类渲染文字& T E% H: O8 N# \/ X
1 W4 J& P0 O1 F7 @
l 学习计算游戏帧速度的方法
- O, `& @$ Z. j8 Z& T n0 A; e" _8 f4 k' B
l 学习使用D3DXCreateText函数创建3D文字) u+ f: t4 f: Z
6 I1 ?' ] H# z9 @* l% D& N
9.1. ID3DXFont" n7 \; `; W# T# @1 s+ u$ y' O
要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。
0 V& f# |0 j& M% U3 O k9 W7 D# \1 [, w* m# J
9.1.1. 创建一个ID3DXFont( A& M: W' c% U+ L
可使用D3DXCreateFontIndirect函数创建ID3DXFont:
5 {+ w+ n1 K, [' {# E# Q8 s
6 F' Z. g- I3 ~* ?4 FHRESULT WINAPI D3DXCreateFontIndirect(0 K. u+ U- \: `7 \: w: U
( @) a" n/ R. P" v LPDIRECT3DDEVICE9 pDevice,
- _) @ o+ Q( `9 y4 O. E& J# i* D; d* r e! Q2 K- {
CONST D3DXFONT_DESC *pDesc,; O: j( g6 M9 @3 T
( a& } C, m0 c% x3 W x3 m
LPD3DXFONT *ppFont
. F9 f# l. o, `# M- k' ~2 A& s/ v0 a: v& s8 P
);5 o- `/ w( A0 T$ O2 J1 J9 w
8 i) {. u, `$ z7 g5 V8 U, R6 X+ D+ d
1 W0 z: [5 m' ^) h. 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)中声明的函数原型为准,特此声明!4 z( P" V5 U- A4 g5 g" r
* Z r' g" V) c! ~: N使用这个函数时,需要一个D3DXFONT_DESC结构:9 L, `* i0 i; m6 j) h
6 x) {# n$ [1 D9 PD3DXFONT_DESC d3dFont;0 F& D) m+ \ A2 V2 F( E9 q
* b1 V' l; d p: |/ U7 k" Vmemset(&d3dFont,0,sizeof(d3dFont));) b6 Y+ f3 N& |: B9 a1 F
" p' x6 ?4 T7 g q7 M5 I6 k- n5 kd3dFont.Height=25; // in logical units
3 D( r% b5 e0 J" a/ _2 ?) P2 i" b6 d6 a; ]0 Q
d3dFont.Width=12; // in logical units
, k7 c8 k0 m. q& N6 H
" O8 Y1 J3 ^/ Z( m2 Ld3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)
; j/ l* A6 H* `& @
- Q9 o9 l+ ~6 c ^d3dFont.Italic=FALSE;+ u& S2 z- ]2 y; E2 @! h
+ \ X. P1 B4 P) g! s0 id3dFont.CharSet=DEFAULT_CHARSET;
: g3 J5 ^8 e3 d T+ T* o2 v" w+ J! e8 K
strcpy(d3dFont.FaceName,"Times New Roman");' T* f% b& V7 G! ?5 G$ B. e
$ n7 X2 H+ U- i; F0 s3 T2 {7 QID3DXFont* font=0;9 e' l3 y% ?* `; s4 O0 A9 c1 O
+ T. N8 c g. {D3DXCreateFontIndirect(Device,&d3dFont,&font);
2 G# V9 L# S* Y - Q2 E8 h7 E$ r% e
/ P! l! ?1 f; t
如果你使用的是LOGFONT结构,则: U1 f5 @2 U" ^- H3 B
/ r9 l* W8 t- g GLOGFONT lf;; n4 o1 C2 j- |) A( q" F
: G- V+ t8 f4 v& R: ~9 `: rZeroMemory(&lf, sizeof(LOGFONT));& V9 G. I9 W: o' [# Q8 e/ p
- g( v8 f# ?( {5 N5 E7 k
lf.lfHeight = 25; // in logical units/ H4 {+ ]3 G. e4 w' B
7 |) i# s- j/ N6 M8 |lf.lfWidth = 12; // in logical units
8 T3 U& l' \- b- V2 {5 F1 `- ~
& @9 x, t7 n. X5 L% [0 N" ?2 Qlf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)6 M# _3 N) o7 ^7 R7 o+ s
/ Q2 f1 l& w* @. {
lf.lfItalic = false;. o$ Z8 L4 ~) t' S7 J1 T
: q5 I. L+ f/ \0 x3 g( n* g. H# E
lf.lfUnderline = false;2 I) b# W! w% m" p1 t) g
% h7 X- F$ n Y) \/ Elf.lfStrikeOut = false;
1 {* m1 i) K5 D- ~" W3 a0 w. V# h' Q
8 v, u, }. j; tlf.lfCharSet = DEFAULT_CHARSET;0 ?; G+ W- M t& y6 @6 V
, o H2 b) v( u7 _6 B6 F0 f4 ustrcpy(lf.lfFaceName, "Times New Roman"); // font style
1 r5 ~! n" ?7 x4 I8 s( Q: x: g, i" W5 o% h: A4 [8 t& }& h
ID3DXFont* font = 0;9 k' s4 J! P/ n6 i( s- |
- P7 Z# M, N0 i5 e/ I' TD3DXCreateFontIndirect(Device, &lf, &font);; i# F7 B$ q, H9 q
1 m, w1 Q# a* Y3 r& A2 L; T$ A1 c- {4 A* |
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。
; B$ `& U% m+ k k* ^/ _) Z( M% m9 [0 {3 c. R7 C
9.1.2. 绘制文字$ @& y# v. j }1 a
得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:8 }9 c* m9 V) A
& Q# d7 |* n! w0 H
INT ID3DXFont::DrawText(
8 W# W0 W }+ w5 N, f% S" v& K |0 [+ U0 [4 a, D& M: [
LPD3DXSPRITE pSprite,
3 X4 h7 ?6 I# q) I$ n" G
, _' P4 C7 v4 y( G, X1 _ LPCTSTR pString,
# U. N3 @; n4 _2 l5 ]" F; b
( _/ Z" I- z F) } INT Count,
* P& b p" R8 T" @$ o; j7 g& u- F3 L2 ]6 ~ Z! t
LPRECT pRect,& V3 k: Z. d: d1 Q
" O# Z7 Q& o& ]6 L, `2 X9 C; @
DWORD Format,
" {$ i% Q) T& R8 V# L" R, {
' i0 A9 A7 f5 V( [; ^ D3DCOLOR Color
0 f" r( y `4 v0 B: t) ~6 w5 i
. J/ I7 V4 @, ^, T+ u+ D* W- {);
5 A; s8 [9 P- z
' G/ i o* \% A3 T" F3 D. g( h0 k8 t4 D3 ]* J
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象8 |) W5 d4 m$ X
4 m$ K0 Q: p5 Y! Ul pString –需要输出的字符串
& |( U4 ?- Q( @) @ L2 j; d
0 M6 v' u& [+ y2 p3 o- Al Count –字符串的字符数,如果为-1,则以0字符为结束标志7 j7 t. w {) u# y U2 a' T
3 h- t) G \. z
l pRect –绘制字符串的区域
& C% ~4 u5 F, m4 W9 z/ z3 q- v' r8 A5 p% A: G+ m
l Format –文字的输出格式' |) H9 C) n$ n- k- ^
% Q: I2 x2 L& e% F/ {- fl Color –文字颜色 @& w% [# ~. q6 a/ V5 _4 d5 U( o
/ k7 [% T3 h; ~/ c" ?例如,可以这样使用该方法:
' w+ b Y" B# v. P. n: d, w
# ^8 j: x- i( \: v% a9 F( _+ JFont->DrawText(NULL,- P. \) H: n+ r
4 \; q: ~* Q0 }0 U9 k "Hello World", // String to draw.
5 H2 ?4 l w! j+ ]; t) f; Z+ N/ e3 |3 o, n
-1, // Null terminating string.
) [& J' A/ U0 n7 A }, y+ ?: h. j& {& p7 ~: T
&rect, // Rectangle to draw the string in." _& I4 B5 h4 w
; B% J1 T! z! T1 B2 D" _ DT_TOP | DT_LEFT, // Draw in top-left corner of rect.0 ]* h0 Q& `8 g+ ~) g
" I3 k8 S! _: g 0xff000000); // Black.
1 r1 x6 c" {3 v3 Y' S$ d 0 @. V) M, L" u$ u* Y' `# e1 p
/ p. ]$ D3 M K3 h! S9.1.3. 计算帧速率
/ k) M m7 T9 ?* \0 h# n( {* I帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:+ Y: u2 I3 G% ]; q. s' v, d: T
8 T9 W6 m$ u7 _% C' ?: \DWORD FrameCnt; // The number of frames that have occurred.6 M# x2 ~7 l6 h8 @# {+ q6 Y; `
5 @% n5 C' E+ c j- S' {' Zfloat TimeElapsed; // The time that has elapsed so far.
& E( v" O5 Y* Z6 @+ X2 g9 G1 B _& ^, V7 d2 w7 v; {- c
float FPS; // The frames rendered per second.* B2 I+ c0 g; c3 b* T6 w, v7 R
6 u* [. y: r' ?! ]; R" T& B
3 H5 R- l+ C9 [1 Z每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。
" G% L1 y. z) f: P& p I7 }8 }$ c! b6 b( {! b
每渲染一帧,累加一次帧数和所用的时间值:$ a- x( R" b% ~8 ?7 [& k$ i4 ?- D& u
7 s" H; G' }7 r; t5 t V: YFrameCnt++;
' {- R& S" E2 i" B6 y$ \5 c9 e
& U% b- H+ q9 k) b+ hTimeElapsed += timeDelta;
: O. c, [: k: C! T# Z 6 h7 C# N) z+ N# M! W$ S
1 N$ u+ [4 x4 U" g8 W这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:
" D2 X8 x% B% |. @! o' `# c! z' _ c. h' H
FPS = (float)FrameCnt / TimeElapsed;
, ~7 [; x9 V* ?& A' M9 c & _$ T( a$ m N# P: _+ @9 O
) t& _6 L) E0 O8 |计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:: W% l0 F! _: a8 w* R- l8 X
4 R& |: R5 P: D3 C* R G6 S' W
void CalcFPS(float timeDelta)
/ p; s& i. P, F* N1 `7 J3 d/ O9 h' p: h5 Z5 V/ K* {$ o& {
{. e6 L4 e7 f7 H+ c+ l& x' l5 ~
' c( [$ {; B( ? B FrameCnt++;' k0 }. C! w0 o2 s. ~
9 |& @5 n' F# m& G# `8 ]( y TimeElapsed += timeDelta;
]* c9 l, S9 ?& @ B- ?
, b, u, [4 a) t- ~* z/ s# @0 W if(TimeElapsed >= 1.0f)( R6 {0 a7 ]" w$ V* o; D9 h: Y
' J5 W. I% G7 A6 t" e
{
' L3 X4 f2 ]' r5 [4 c& X1 \8 v* c3 V; v; U2 q
FPS = (float)FrameCnt / TimeElapsed;
# r! ?0 i9 y: j$ r& P/ p1 q" U# c, D5 \
TimeElapsed = 0.0f;
1 ?4 b4 \& v5 O( L9 J$ A/ U2 V' K- [' G2 Z( I0 X
FrameCnt = 0;
6 F7 `7 v! R4 n& P
( w2 _# v1 T/ r }
, |9 ?% D3 o4 X( v
% ^/ k2 \2 Q l. [}- [7 M% i( ?1 L |1 z
' l7 B+ a1 a( l& o# X
9 t3 m0 Q7 m5 N( w9.2. CD3DFont
9 ], q# I9 n! ^! j' k" L9 T在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。
+ f& c& V9 N1 Q# h/ X7 C+ u2 Q
- ]) n0 O2 L3 Z) G9 k# M3 w R+ w使用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版本!1 O: S( S; B1 H- G! L$ S# Y9 E
0 i* J' P" x1 _$ E! B
9.2.1. 创建CD3DFont对象; ?' [: P$ [, N4 K+ Z* e) X7 s
创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:9 s4 d' L5 d) u+ S4 J
$ H% \ y6 a9 R6 @ O c4 a
CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);
( n/ }1 O3 I) n" T5 `8 Q
5 _0 w. R# i p( B1 t( w8 J
- D$ |. G: a5 Ml strFontName –所使用的字体名称
, _! E: B. h6 k$ R K3 z2 b0 N! i
l dwHeight –字体高度
+ z3 c' N& e' S6 `- @
3 I& |8 [ c0 y' N; h/ El dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
# q# ?; ?, |" ?- Q0 Q0 Y1 ]* v9 b/ z1 {1 g$ w, x& Y
得到CD3DFont对象后,还需按顺序进行初始化,如:; O) W* \5 f% F
1 ^7 V5 [" E0 f! ?" d2 {6 `
Font = new CD3DFont("Times New Roman", 16, 0); // instantiate
& c. T0 e Y; q& ~$ s9 `; f- w _
Font->InitDeviceObjects( Device );: ?. ]+ z: s+ ?; v6 U% k% Z9 Q/ {
6 x3 j6 ]$ m- v) c9 n- JFont->RestoreDeviceObjects();8 ]: e! A! S8 A+ ]
7 I% `0 c. p" L9 k" a0 w: J* Y% r5 g6 K7 e @' }* A6 X+ {
9.2.2. 绘制文字
$ y- A0 B0 P$ n使用CD3DFont对象的如下方法渲染文字:7 Y! H* v' {/ b& P. x( e
5 L- T; G, L5 b- n7 s T( RHRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
; ]0 t) G, X; {; c/ `! k4 p1 X4 h( X& _
const TCHAR* strText, DWORD dwFlags=0L);: O# ?) Y5 f2 ~) X/ K" Z
x) j! t+ {2 S6 P0 y3 Q3 @* Y
8 S$ ~7 `3 a' j d" c2 Ul x –屏幕的x坐标
6 t. j! c2 N% _' j% y8 N
9 B* Z! u1 C2 \! O" ~5 {l y –屏幕的y坐标
1 S; p5 X7 i( h/ R4 n$ D b: x: Z6 K \4 h9 d
l dwColor –文字的颜色
! |3 K+ f) R8 G$ m4 ]! q: w7 V
" t" Q! o9 l& l+ Wl strText –要绘制的字符串4 f3 S9 q! j. C
1 J& F O1 @" f" h3 R5 ^l dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
% |* x0 d1 r7 C5 }: `5 c3 P) W' W. u
) X3 Q3 K8 l7 _2 N& E例如:+ }; Y' |; f. w0 W/ e4 v& t9 v9 g
: C1 b0 t, V, m. r, G) t
Font->DrawText(20, 20, 0xff000000, “Hello, World”);
8 c7 x" y% {. _7 R 9 f7 T, R8 x- u6 L/ E& k6 Q$ R% \" L4 c
P! u4 o" H. O" Z' o
9.2.3. 资源清除
" {7 ?9 Y$ x s, f9 q在删除CD3DFont对象前,还需作一些清除的工作:/ Z8 i5 h$ k6 u8 g3 g
! _$ \1 t( \! N5 `/ w. DFont->InvalidateDeviceObjects();
3 l* L7 r( S5 |% |& H1 i @- T* H
3 ~. d3 y+ Y4 ` oFont->DeleteDeviceObjects();
2 G: O" R$ W/ |% v* l. S; O4 r& p5 T- e. o: C
delete Font;
, ]8 ]7 h2 K9 A+ f% f 4 c6 Q8 C0 `7 U( d6 h# C
" H4 E3 n) R1 C
9.3. 函数D3DXCreateText
' f* w4 [1 {5 Q/ N6 |( M5 n该函数用于创建3D文字Mesh,原型如下:
/ b" R5 O9 k8 F$ D- A! D7 ?$ Q9 d' ^( R$ W! L4 r
HRESULT WINAPI D3DXCreateText( T6 ~ H) Z5 m8 s; z- x% B2 _9 H
- I' P. L* \6 ` LPDIRECT3DDEVICE9 pDevice,
3 d+ w/ L' n/ q6 {$ \) M2 N' X8 z
G) k. U. E' C& Y( B+ R HDC hDC,, m' ]# R4 _0 ]- u/ ?7 S/ ~
; J7 x' Z% x- y& h LPCTSTR pText,
2 n! j2 ?* l2 M+ N6 w' s. O. S! S; c( G
FLOAT Deviation,9 o5 i+ |; ~8 u; W
" F0 q- Z: j, @ FLOAT Extrusion,
" y- x7 R) [; p6 t k# Z2 M2 F# m. R" o/ K) ]' N* O' r3 R! n
LPD3DXMESH *ppMesh,' i% \- y+ U0 O5 q- |8 z( m
7 i+ T* k1 r+ p& m8 Y LPD3DXBUFFER *ppAdjacency,
) q- q& I# ^ Q7 {
8 |5 l) L x( e* r LPGLYPHMETRICSFLOAT pGlyphMetrics8 R& J/ d" o) C: P p N* b
4 A* U6 b$ V" b# H+ h, x
);1 L6 w4 I$ @9 K% g% j7 O, @
' \) o" s7 Z9 \9 K
6 j% Y! z" |% W* p) V6 D1 x( U
l pDevice –D3D设备
6 i% |* J& O% w
* M$ a8 Z3 A! A5 Q2 h* X" ol hDC –描述字体的设备上下文句柄
. ^! a) a5 J; y v' n* @5 [2 o3 ]: C7 X5 g
l pText –要渲染的字符串5 G$ ^( I+ ?6 B4 q& C( i( s- s
2 o; M+ A; {- P2 k3 k2 W* c; ?l Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值
, K& o2 l* Y9 v0 y9 C% E) u. z1 o2 G3 T& g
l Extrusion –字体的深度,相对于Z坐标轴
) o* H( t2 t% B! E
( c3 k) s( ^, w2 ~l ppMesh –返回生成的Mesh对象指针
3 m, w4 L) t: P1 ~% @! W$ S" o2 I/ V$ H8 E
l ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针
2 v* J2 G. n3 Y! c4 x9 A9 H
6 G+ v+ N7 d4 e1 E, E$ o. y7 m# wl pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL
' i) L9 E/ d% ?; w0 V, H0 G4 V+ e3 I, C4 Y c2 a
下面就举例说明如何使用该函数创建3D文字的Mesh对象。 d: Q/ Y7 n# [% M8 m5 r' a- i$ X
" j! d7 }# R4 \) J// Obtain a handle to a device context." y) L9 A5 {6 L$ e, W) G& d
$ k7 i/ v% W' j' |6 CHDC hdc = CreateCompatibleDC( 0 );+ h7 h5 j8 M9 M% N
H7 W4 ?' e# a( |! U1 {
// Fill out a LOGFONT structure that describes the font’s properties.
+ O F3 R9 g4 B- X6 ^8 z0 K, Z# |# H8 P0 I' C' e# g) p8 u2 v
LOGFONT lf;
' D" F# T# B3 M& W5 I( s7 w- j' w3 A' N3 ^
ZeroMemory(&lf, sizeof(LOGFONT));
. i! ]8 s4 U8 a" m1 \& Q
+ v. I3 r/ s7 J3 Y; v4 L$ G) ]lf.lfHeight = 25; // in logical units
9 k) r9 H( [$ E1 C4 V* M" s
: O/ Q8 H) Q1 D6 E! B% H3 o$ vlf.lfWidth = 12; // in logical units0 c2 \6 D7 c' m. b
. u% Y" H, b/ c- B% Elf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
+ V9 c- l: T. b& L0 ]+ N( \, u2 n/ d7 J( ?, Y6 m$ T! H
lf.lfItalic = false;
5 n& z6 f, K9 H( L* O- s
% i: f8 K: C8 i; t7 Ylf.lfUnderline = false;
) P: d. }, \/ V V( M# ?! \! g% ^8 ~+ v7 H
lf.lfStrikeOut = false;9 E/ D, {/ m! X3 q6 d
1 r" ]$ R0 W8 K5 a7 a2 h
lf.lfCharSet = DEFAULT_CHARSET;2 C6 j8 Y; I# V, Z( b
4 F( E2 u) X) C- V7 W
strcpy(lf.lfFaceName, "Times New Roman"); // font style
; A8 g. x* x$ T! \. [2 ~4 v, N- N5 v" [3 S
// Create a font and select that font with the device context.
m' {% [$ s9 j
( N1 C& z9 n8 z6 XHFONT hFont;
) s! b& U- Q3 }# A% m8 z3 B" `6 H
; ~( H( }" s+ wHFONT hFontOld;
5 c' q. F8 [9 H! q' O' U& f# e' S% r; ~9 l% P
hFont = CreateFontIndirect(&lf);
# O/ K6 m( F$ G7 J, ]6 B' ?; d5 M( r0 l. I! ]2 ]" J
hFontOld = (HFONT)SelectObject(hdc, hFont);
! |+ t2 _0 K' S" v; M" F2 }
$ O, k% `: `% ^3 f0 V9 ?% Q// Create the 3D mesh of text.
; E6 z9 `+ [1 I3 r W5 x: E# ^( x" K( T7 c6 p' e
ID3DXMesh* Text = 0;( V" M2 V2 u7 K9 X3 C6 u
/ f# v* i5 e' u3 ~! [/ y9 Q6 ?* T3 ?
D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);
5 `) A6 q8 t+ H7 Y% V5 b
/ l. O0 A2 Q$ {// Reselect the old font, and free resources.
/ x/ D. e7 H' ~0 c3 s: a' J6 m6 i3 v6 o5 r5 h; E
SelectObject(hdc, hFontOld);- A2 z" S( y2 a: F# x3 i3 o
* L3 \# U+ Y% a, P3 c6 D9 VDeleteObject( hFont );) J. e- x8 J6 ^7 @+ C
4 e* x% ?3 P# O9 t, i; U" q- v5 n
DeleteDC( hdc );1 [' o/ J Q' h( J, m6 C
# x4 y4 V/ L/ E) G6 P
) h9 b- N; b" [( ?8 X) w
这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:" e% ]7 B: ? A! Y0 U
5 H6 U/ M# H' [& d; s+ o( q) _7 o& pText->DrawSubset( 0 );
) j, t9 Q. X, f7 Z$ f2 h# w1 X
d/ n: P- e- j/ F; `% b9 E
7 H, w: O: U q; M4 g/ G译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
& o( d3 P; T) C" B R% e6 O6 `! g: B( U9 }% _% p# _
9.4. 总结
4 C; P( b( {' _% sl 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。& a" I8 `! N8 q: H
" G/ G6 e# A( j7 h2 }
l CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。! W8 |# f) Y6 b3 _# z
3 E; m/ [( H0 ^% k
l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |