http://www.5178c.cn/article/6/2006/200605173892.html& k; y/ u! f' R7 H! ` q. u
7 w* F& f/ U+ y/ D1 ~2 j在DirectX 9.0中渲染文字
8 y& x5 W4 X7 n" A4 ?4 g作者:佚名 来源:不详 发布时间:2006-5-17 12:27:04 发布人:admin
, D ]0 W8 C: D8 X+ e减小字体 增大字体 0 M4 \' t4 e i
" X6 b& H) S7 L/ D5 H
- e0 t% H6 k! U/ C5 ^$ ?# N, G* ]3 V
p' a7 }! u2 w) Y% H# O0 R0 X! O* u, e/ H3 m
. M: P: a, {4 b- d9. 字体
1 q+ R M2 v9 b* X% {; m h本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />5 E5 R) j' W' U% @
0 C- k7 j0 z4 x, X5 ?. [+ W8 Z
3 y# I- g! Q6 E
, r) i5 r3 U' g# U; q在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:7 c7 s" W+ _6 b3 M
& ]/ B0 T5 R# T% Kl 学习如何使用ID3DXFont接口渲染文字
" J5 }4 g4 t( N; ~: Y/ N
D1 i; H# g1 w9 U. wl 学习如何使用CD3DFont类渲染文字
7 ~& G; @* K" i' F6 p
2 J' j( M0 F8 I: E. e* P: gl 学习计算游戏帧速度的方法( b& y6 I: t5 i8 p2 e
9 ]( z$ Q& f% b' D7 X$ g2 x1 N: s
l 学习使用D3DXCreateText函数创建3D文字, J; t1 B3 g U& G- `* J/ c) b& m3 k
" H' T7 e% H: K# T C# S9 _( v
9.1. ID3DXFont
- E% c8 k; u2 {1 s2 c W3 A要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。& M' j3 [8 m+ F/ f( W
( j' E, }) R# O3 H. C& S. U
9.1.1. 创建一个ID3DXFont F& ]- w) T3 J5 z. Z7 w) ?
可使用D3DXCreateFontIndirect函数创建ID3DXFont:$ Y$ d, B. ^$ r4 B5 ~+ G* B, O
6 n- N6 e& r) v
HRESULT WINAPI D3DXCreateFontIndirect(
0 C" R/ ]/ M" \7 C* \: _; u1 f% u0 h! D1 e* n6 V r- _5 j3 f6 M9 m
LPDIRECT3DDEVICE9 pDevice,
$ b5 L$ y* |- A
) i9 x5 `* a* T/ z5 A8 V CONST D3DXFONT_DESC *pDesc,
6 G: @3 l+ a% `% }0 a' \% v( {% N/ ]; p; r0 B7 R
LPD3DXFONT *ppFont
( {+ |5 Z7 g/ H! H6 T5 F, l1 ~% V7 \2 w3 }* C! K) d5 B
);
, i @- u' o$ U# s7 b8 ^
' X" e8 z* w/ w _
1 J) v& u0 D( {/ K9 h( @! e译者注:我所使用的DirectX SDK是Microsoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明!
* t2 \; q: Q% C0 T9 u& l6 ~
+ w# ?1 P6 P2 m+ u* u R使用这个函数时,需要一个D3DXFONT_DESC结构:
) a8 B& Y9 r6 y4 \' O) \5 o
8 S8 f6 N) m" _; ^: a) g7 ~D3DXFONT_DESC d3dFont;
1 E: F2 E2 k5 d n" Z8 S, u; R0 {. Z
memset(&d3dFont,0,sizeof(d3dFont));
0 M- ?1 K; `* k* `
) R( ^5 F9 O% A" fd3dFont.Height=25; // in logical units" a* _% [2 V. ~0 T" H5 O- t* W R
, _. Z3 G+ \1 H$ X0 P* d, Cd3dFont.Width=12; // in logical units2 }6 w' N; l- Y; P
+ N% S3 r% x% f; Z1 `! F( ^4 a
d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)! D9 ]; W' \0 u! F/ B. I
" s4 }1 y1 t6 E' M: M6 s g. d
d3dFont.Italic=FALSE;; p3 E/ S' W1 q1 _8 u6 N
0 D+ A: u/ V; y# U. ~. Hd3dFont.CharSet=DEFAULT_CHARSET;
0 m% k1 _& t3 g/ ]3 ?4 Y
0 ]' y$ [! T* I, _, w* y; b7 Xstrcpy(d3dFont.FaceName,"Times New Roman");+ M& M" S) D Y, D4 i4 w4 {
( h U! e0 m6 m+ v0 ?: x
ID3DXFont* font=0;
! i+ H2 L7 F. U _- y- C4 Q7 S5 e
D3DXCreateFontIndirect(Device,&d3dFont,&font);+ G8 q2 ]- {8 c! m
$ L* c) F9 m' e5 z
( Y F$ `2 S: S V5 f如果你使用的是LOGFONT结构,则:
/ S( A8 U/ q3 m. [5 ~- x& ^
# n9 k" \$ x6 ~0 r% GLOGFONT lf;7 n) D4 O: b$ @) S
9 @7 w2 w1 t% E ?9 jZeroMemory(&lf, sizeof(LOGFONT));' h2 Q2 R) B$ `0 {. c
. E2 A2 x* _+ N+ p5 V9 R
lf.lfHeight = 25; // in logical units
7 k6 h% V$ k: h1 @8 n3 | R {6 y0 G; e( d) z& T
lf.lfWidth = 12; // in logical units
7 v; C: g) M# l3 `4 Z8 E1 K D# ]! `! b5 w9 Y& @+ N2 R
lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
. E2 K! G2 Z" }3 d! c4 x/ E7 A9 u( C/ `8 j+ i
lf.lfItalic = false;
! j- x& h, a+ d; \2 ~, z9 U" T$ `! I+ e
lf.lfUnderline = false;) S+ j- w4 {- ]9 `( E
\) |: V% Y% y
lf.lfStrikeOut = false;7 Y ?' y* ~" w7 l
; }3 l) t6 F& q( Z
lf.lfCharSet = DEFAULT_CHARSET;
3 F$ z# C$ z# V9 X' f
b: C/ `2 @% E6 _% Y! I2 n, Estrcpy(lf.lfFaceName, "Times New Roman"); // font style
3 @9 B0 _. A5 A/ z. H! k1 k$ W
# u; c7 e% O# W9 ^3 D0 QID3DXFont* font = 0;5 y) R, I1 t* J/ K- n
5 T! ^5 T# Q- B$ ED3DXCreateFontIndirect(Device, &lf, &font);
V9 m8 f7 [" h' l# J% e % K& i' |, z6 V. e, \7 [
: ]# T [" J7 T7 y0 B
另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。& M0 w: N1 D6 x
' w. U+ W% R( g6 U# J; M, [9.1.2. 绘制文字
2 f, Q- Y* b' K# K- p- v得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:! G5 c: x5 n2 r7 g- \
! o5 {5 q! C- C& q; \; {) U. EINT ID3DXFont::DrawText(
+ L n" w7 D+ y/ z r2 d- |, Q( n& h1 ~$ S! J1 z+ f( x5 E$ {5 A) ?
LPD3DXSPRITE pSprite,, a. B. h0 l/ ~ N
: u# {+ g$ P7 l! O0 r9 u
LPCTSTR pString,6 a$ O& r. C: U/ z5 [1 K7 s# P7 q3 `
- b, l* p! ?% C, F' H9 m INT Count,
3 d$ U* ^ o$ D3 Z% g8 u. w3 M' L, l2 i* k
LPRECT pRect,+ A, k: a" a5 }
, ~% X* W8 g( j& Z DWORD Format,+ C* w( N; _! Z* L) `& G% O V, `
* ^6 g' I- Z# S/ g; g7 U) M
D3DCOLOR Color
( p/ e% S) }# l7 \- [- E
& e/ K' M |& X);4 C3 A6 r; o, A& W/ m
6 a* a3 O: ^5 T* l/ w4 H, x0 l, }, l, n* t
l pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象
! P$ H6 M; M) ]) L7 h! Y( @* S: E- P- S& W; U- O8 v
l pString –需要输出的字符串2 y% K; B5 H% M6 n
X$ l4 Y5 g5 p" }l Count –字符串的字符数,如果为-1,则以0字符为结束标志7 M5 [0 h4 I0 S$ \! B1 \. a
9 \) e% q- w. Z2 l( k& [2 I4 a
l pRect –绘制字符串的区域
) o8 @; r& Z4 [5 Q0 a% M0 X9 e2 K$ M/ X9 P
l Format –文字的输出格式
) d0 q, N# d- m7 Q) v7 \0 X0 D; k3 b
l Color –文字颜色
7 C+ [9 t9 c1 b) [0 [
8 X4 `2 ^1 p4 W$ U( q" }3 b例如,可以这样使用该方法:. c! w) R4 w) A/ D! K2 t
7 P: V( \ D* m l( J) r8 c
Font->DrawText(NULL,
. y, X! X& O" ?' w
( r& q3 @) {2 X# `( Z "Hello World", // String to draw.
+ _5 c1 R5 K+ c5 r5 t6 v, M4 n W0 i4 u2 V2 S8 E0 L2 a& J
-1, // Null terminating string.
3 M; V) x0 P& j$ r3 U
' I+ s2 V9 z# e& A8 }+ k &rect, // Rectangle to draw the string in.
: f( N2 \/ m4 W3 {$ J: S! j0 R0 w! D
DT_TOP | DT_LEFT, // Draw in top-left corner of rect.
- L" a2 t2 w9 f. h) }, j/ K' ]2 M. |9 j; |( Z
0xff000000); // Black.+ @# i( Y' X% Y
4 H( l2 y/ f6 B
- g# K5 m/ W3 W5 {
9.1.3. 计算帧速率: k- F2 v1 ?" w1 D2 G* l
帧速率用FPS(Frame per Second)表示。首先声明三个全局变量:
+ `1 J: J7 a3 |0 b' ]& X6 [) u s7 f9 a' p: W6 ]& h* a
DWORD FrameCnt; // The number of frames that have occurred.
; h, O5 W/ G. n# ?1 a! s' Q7 k8 O; a) w1 A* W) d7 t
float TimeElapsed; // The time that has elapsed so far.
" [; V. v5 z# I8 g ?2 ~4 P1 {( }# z( Q! Q+ l3 T
float FPS; // The frames rendered per second.+ W1 u! A9 ?! h2 J5 i F! i2 B9 |- w
4 |1 i& |2 V9 y6 {: E
/ }5 ?6 r2 I e3 C每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。: K( H, P7 M5 B6 w9 s
8 Y& q2 A+ i7 [: `' c- Y+ V
每渲染一帧,累加一次帧数和所用的时间值:( K! B* z3 E* S$ f* `
# d, d3 ]: v0 n$ P8 l9 P3 z
FrameCnt++;
* F' C0 Y4 T3 ?: j+ ?* y
+ z4 N y. a/ e4 j% ZTimeElapsed += timeDelta;
_( t$ k1 O6 Y$ \0 v! |; f2 S' f
$ a: Q% e$ X& _
* r/ F3 @5 ^6 Q/ L; x6 T这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:6 R( R! D# r: e- A. @8 m
! ?+ \) b# c1 @' z0 E# w2 U2 }FPS = (float)FrameCnt / TimeElapsed;
* F. }# z/ I: Y% W 4 h8 B! l$ `) B( j8 W4 s6 |" K
# G" ]$ O2 {; F3 U4 u计算完成后,需要将FrameCnt和TimeElapsed重新置0,这样下一次的计算结果才正确:
, b7 Q+ p: k/ _: V4 A7 k+ s7 }6 }4 y L6 `3 M+ S$ B
void CalcFPS(float timeDelta)
3 U, Y" m n$ p7 K/ ?+ ?( Y2 ^, J
: A/ X- }. F4 {- o( G( b{
% J$ D/ O: Y3 Z& W! t n, O) g- J u. k. ?6 |
FrameCnt++;
: ?' F* x: p9 i, d. L
! `: F8 V' ^( p0 l/ ^ TimeElapsed += timeDelta;
* c& L5 ~) @9 J+ C- a/ i" V
* |# K$ O2 u; ]% l1 a- s& S' C if(TimeElapsed >= 1.0f)3 l7 j6 `& B! O$ V9 b/ [
5 z% w! r- p4 c4 d1 c% E
{4 \- D5 r9 Z6 {+ U0 m, M
Z$ ]: Q, M# E3 n$ b7 @5 |5 U. `
FPS = (float)FrameCnt / TimeElapsed;2 w8 h ^+ k1 f7 V. P
' A9 O' v( F4 d9 U TimeElapsed = 0.0f;
' y) v: g& Y+ T/ z$ X) d4 }6 `+ c4 Q' F: c, K9 N
FrameCnt = 0;
L; A. W( M |2 W7 q/ S* w8 {
}/ d( Q- c- b7 T f, ]- x
0 X$ I7 `4 z% e4 G1 M; V5 {}. R) y* q6 {4 }9 s' B
* q3 _* O+ W% ~" X+ L0 [- Q
4 P* c7 a( I4 g8 w1 }) y9.2. CD3DFont
' P% Q! [- K8 y3 Z. R! i在DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。9 y: M- W: Y* K! i0 ?
J; I6 B5 h4 z4 z, o0 u7 R A使用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版本!" K9 k- u8 ~) _. |
' X. `) V# W, b( X N- @( S x! |. i9.2.1. 创建CD3DFont对象* }; K% l* k6 _
创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:
& a2 @1 M L/ L: R5 B
5 |$ q- i( E# Q4 j" E3 H* d" M, u* UCD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);# O+ P% W5 z4 S5 P f6 m' T
# s- b6 I, x8 j2 C
) T! _! `% H( ~" d1 @l strFontName –所使用的字体名称
# l$ e3 C" Y( B% Q5 G5 W
1 |( c& _+ f: E5 w Q% q6 \l dwHeight –字体高度
, }5 D; r( m7 L+ ]6 v; x% Q! f
$ S8 d) Y) U0 Z) U3 u. nl dwFlags –可选的标志,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_ZENABLE等。
* y1 q8 W0 O$ w3 X" I
* K$ t! W! t9 J2 s4 n得到CD3DFont对象后,还需按顺序进行初始化,如:: z1 ?) T! Y6 h2 p
) n+ c* g! Y/ B* o8 w& {+ GFont = new CD3DFont("Times New Roman", 16, 0); // instantiate
: g. x4 l( l' m7 N4 N5 P6 p0 |) n4 p! z3 ~& t+ d, `9 H1 H+ @) n: \
Font->InitDeviceObjects( Device );
6 G. q, A* p& c) z1 H# T( C2 g' s1 [: ^% N, \: Z( o
Font->RestoreDeviceObjects();0 @$ p; i2 Y) M+ X1 V6 ]$ E
( s) {' K4 |( X" v0 u; {) y- Z9 o( R% k g- Z; N( i
9.2.2. 绘制文字$ `6 e, I+ l2 M$ k8 r' r7 U
使用CD3DFont对象的如下方法渲染文字:' {! t+ k+ D9 l! |% q4 D4 t2 S
5 ^, ^4 z1 i* }/ l9 e/ yHRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,
' _* U& B/ R% Q h' t9 ]6 H! Q2 Y& F9 J' T% g* w7 w* O
const TCHAR* strText, DWORD dwFlags=0L);. A* w! K$ G% I0 ?2 F$ z
" G8 S! Y! r, y. S) C, y5 K; x: a& I8 l5 r( n
l x –屏幕的x坐标
1 {" \; z3 d0 i+ j5 d! ?8 }9 a+ B
7 \3 k/ {2 u) O4 K5 @' v8 o Sl y –屏幕的y坐标
! K( e9 M) t- {# [2 ~- S5 z; H% r% z+ f" R. A4 y# \% G
l dwColor –文字的颜色
" {+ ?% ~ T& J) s! Q* n& n# M4 I7 X3 H( E1 l) {' {
l strText –要绘制的字符串 D9 I% \; p9 t' [0 l3 C
# G; U% y* I) n! g. {" b) l, Kl dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。
& |/ L& b/ @! D/ w4 C# F q% F7 f) w' U' A: f& q e
例如:9 w& L( g9 g+ C# P. W
( j* g0 A9 N% U& x/ u
Font->DrawText(20, 20, 0xff000000, “Hello, World”);
6 c5 U4 M( L$ w: H# P 2 T, T' A9 j% L7 j
$ J# f. A, d3 d% `3 _- g9.2.3. 资源清除
% h8 u7 u6 g! R在删除CD3DFont对象前,还需作一些清除的工作:
I# i3 M5 u6 G! @0 V4 K" s& i$ @
Font->InvalidateDeviceObjects();" c$ q% P6 H; I" d! e! ]5 K* D4 e
! t2 q; r+ R) |5 V' w
Font->DeleteDeviceObjects();7 z. Z4 w7 K+ K
* w& L" @3 b8 n8 Odelete Font;- q; G4 L$ O& a+ s" [
: X$ Y+ C0 I; o) \: U$ f) A
4 e8 |5 o8 y o9 L/ U! u& Q
9.3. 函数D3DXCreateText5 v: _6 J `& u0 i5 o' O
该函数用于创建3D文字Mesh,原型如下:4 O9 a/ {8 p! o
" c4 I. U/ c, F! `0 D
HRESULT WINAPI D3DXCreateText( ]' f% y* c. R0 Z- K
7 h! ]0 |) W- G6 K, N
LPDIRECT3DDEVICE9 pDevice,
; G3 @# y+ z. r' G; D5 J
8 s/ j5 ]$ ]' Q/ h& g9 e: J, r. O HDC hDC,
6 N6 y3 I: e* x( v ?1 j
1 M3 v; {6 [5 i* C5 T% g( P LPCTSTR pText,
$ ?0 G6 Q( J! Z, h6 e! N& N, { u- [% G. T! n
FLOAT Deviation,/ O$ Z; u9 _9 \
8 v& C$ C L9 y/ R) z8 E: [
FLOAT Extrusion,
! N- s2 [; i; [# j6 V* U1 h( I
W f0 g' O: h5 [+ @ LPD3DXMESH *ppMesh,
2 O6 N( ]9 H. a8 A h/ u3 H
+ e8 ~0 V. ^6 S4 Y5 L LPD3DXBUFFER *ppAdjacency,, k& M$ ]& r* g
3 w1 V6 [; ~4 b! O% _ LPGLYPHMETRICSFLOAT pGlyphMetrics) U8 C6 x1 A, j1 W; ]
4 A8 q: q+ U. L* `) K# w4 j
);, e. U3 l" C% G8 p8 p
) g* Y! G1 c8 O% G& x) f! m& I. w1 p/ {. l" r6 t" F; w
l pDevice –D3D设备
0 B# N% G7 I5 y T' }: y: F9 H: \5 |# T: Y7 g
l hDC –描述字体的设备上下文句柄; [6 p x' p1 x" s7 g( K* t; }
! m, h) S% g- U7 e8 k( }
l pText –要渲染的字符串
! d1 F' D8 F: E" v9 ~1 h
3 {8 O1 \$ c6 S6 Z& Wl Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值3 P9 U$ v. J m9 Q6 t; t
2 ^1 A" x# Y% s" `l Extrusion –字体的深度,相对于Z坐标轴& x& N# ]. I: _- `
& X; J1 Q/ ]# U# R3 a$ Y( E
l ppMesh –返回生成的Mesh对象指针
& B/ m, X( b* B4 y9 N$ c1 x9 x O& h1 U; m
l ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针% h# @+ a3 i: v& x; P4 r7 ?- k
7 \, \7 P9 Y$ O. x* Y8 g7 E
l pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL1 F$ `3 d, M' ~2 Y* n1 }; e0 _
6 M: {1 k8 O8 \' P
下面就举例说明如何使用该函数创建3D文字的Mesh对象。$ A2 L% O# A0 q5 ~6 ?5 R: \( I3 M
' b/ M4 k8 g- O
// Obtain a handle to a device context." p0 @0 p9 i7 k7 x) K+ W& P
' |0 t& l1 Z9 F& w3 C- q
HDC hdc = CreateCompatibleDC( 0 );
: _- i+ C" M) ?. H; w4 f8 q
, q& K: B, k- _4 n' [/ u6 K// Fill out a LOGFONT structure that describes the font’s properties.$ D% s+ B$ e+ ]! {0 k9 J+ S9 s; P
% M( J2 \; {+ E0 {! b( XLOGFONT lf;6 n- R/ o& ^+ |4 ?' Q
: l( U- a( L( e: Z" Z; d* OZeroMemory(&lf, sizeof(LOGFONT));0 P2 h- w2 i' p0 \* s) e; ~. R
1 H" T: z0 n0 v) z% L
lf.lfHeight = 25; // in logical units: H! x2 O, s# V( n9 P0 ~
5 Z0 E6 c. J" K2 Z' plf.lfWidth = 12; // in logical units4 m. I: f: N4 \# x1 R
6 g9 f% C0 K" E8 f" O& H1 ?lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)
3 b6 q( l6 h) O- p( d1 D
+ M: |% k5 z5 m7 Klf.lfItalic = false;
$ |5 `9 N7 C8 g9 e
Z$ f, n* g& `% A6 i4 E, e/ tlf.lfUnderline = false;
7 g; k n. t. c* b! Y* G! ^
& f9 q7 a4 X. d, r& Xlf.lfStrikeOut = false;. e$ W; f9 H$ ^+ I; i
$ I8 n# y& I& c1 K4 N3 l. jlf.lfCharSet = DEFAULT_CHARSET;
3 x7 \6 q; B( p: V% \' ~; b* V/ x% W% a1 t/ |8 R& o
strcpy(lf.lfFaceName, "Times New Roman"); // font style0 @! z9 ~5 s; L' u+ ?! W
( E: ?- } R/ ]; f9 u+ r: k
// Create a font and select that font with the device context.
" }! Z. n/ F- z, s3 F. p5 h2 `0 ]' q$ g+ N
HFONT hFont;
. Q& f. Y0 e# T
% w- E& F* w8 Z+ p' LHFONT hFontOld;
, T/ d8 S9 M& G4 ]" y0 ~' S0 [8 v* J: S4 d( w) f6 X! o
hFont = CreateFontIndirect(&lf);
1 f- i# _' s6 {# g$ K) i8 G# p3 R, M+ {$ Z8 Y X9 p0 k
hFontOld = (HFONT)SelectObject(hdc, hFont);
- f8 ?- ^( ?. q0 Y! {; H; H3 `8 A% a0 y3 B; F
// Create the 3D mesh of text.2 Q1 d" G( h" E! p3 B4 u ~
$ ]) A- L1 m1 LID3DXMesh* Text = 0;* s8 n8 q; ^0 b& r+ X( \/ g. {; }
* e3 u9 F ]1 n; \/ X) y# Z2 YD3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);6 b# U1 I" m/ V
5 N: K4 d- Y4 P* y j2 C+ R
// Reselect the old font, and free resources.
( L9 v& r9 I3 s- q& k
6 z6 Q; u S! }SelectObject(hdc, hFontOld);
% `/ t# s, d; Y$ K& J' r" a# [# E. k
DeleteObject( hFont );
6 D% T" x1 w: y$ A* w; E
* S! ~1 S' u* vDeleteDC( hdc );3 e: d1 U4 H) g ^ p
3 M; r0 A5 A2 F" ]0 W) [, b7 [
/ t( t5 A _* m5 v这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:& l# e7 z4 N0 q7 ?
+ I( P q6 M& g ?1 Y: B$ `; @/ x# A1 v
Text->DrawSubset( 0 );
5 V6 s& M* @7 C p8 }4 a# n 4 x+ B7 B9 p& k6 L1 Q0 q
$ q6 a9 Q* k1 D译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。
7 h/ Y$ g2 u6 u7 I6 E( O Z F" H, }
C* R- h S+ I: a9.4. 总结. i; _% _; i5 w# i2 m, F" m
l 如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。8 Q" ?7 y' w' K( Y; F6 t
) @) c9 `' p0 F/ I2 @ vl CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。1 `5 \( N$ m: d6 R* J% U: x0 r
$ ?: y% Y+ h4 S7 W4 c7 J
l 使用D3DXCreateText函数可以创建文字的3D网格模型。 |