在DirectX 9.0中渲染文字

9.   字体

本文翻译自《Introduction to 3D Game Programming with DirectX 9.0》第九章“Fonts”,敬请斧正!

 

在游戏中,文字信息的显示是必不可少的。本章将讨论在D3D中使用的三种显示字体的方法。同样,这里只列出每种方法的演示程序的主体框架。学完本章将达到如下目标:

l          学习如何使用ID3DXFont接口渲染文字

l          学习如何使用CD3DFont类渲染文字

l          学习计算游戏帧速度的方法

l          学习使用D3DXCreateText函数创建3D文字

9.1. ID3DXFont

要在D3D程序输出文字,使用D3DX库提供的ID3DXFont接口很方便。其实该接口是使用GDI实现的,所以,其执行效率有所降低,但是它可以很方便地处理复杂的字体和格式。

9.1.1.    创建一个ID3DXFont

可使用D3DXCreateFontIndirect函数创建ID3DXFont

HRESULT WINAPI D3DXCreateFontIndirect(

    LPDIRECT3DDEVICE9 pDevice,

    CONST D3DXFONT_DESC *pDesc,

    LPD3DXFONT *ppFont

);

译者注:我所使用的DirectX SDKMicrosoft DirectX 9.0 SDK Update (Summer 2004),也就是使用DirectX 9.0c的那个版本,在较早的版本里,该函数的原型有所不同:第二个参数为CONST LOGFONT *pLogFont,它是GDI中的结构。以后,如无特别说明,将以DirectX 9.0 SDK Update (Summer 2004)中声明的函数原型为准,特此声明

使用这个函数时,需要一个D3DXFONT_DESC结构:

D3DXFONT_DESC d3dFont;

memset(&d3dFont,0,sizeof(d3dFont));

d3dFont.Height=25; // in logical units

d3dFont.Width=12;  // in logical units

d3dFont.Weight=500;// boldness, range 0(light) - 1000(bold)

d3dFont.Italic=FALSE;

d3dFont.CharSet=DEFAULT_CHARSET;

strcpy(d3dFont.FaceName,"Times New Roman");

ID3DXFont* font=0;

D3DXCreateFontIndirect(Device,&d3dFont,&font);

如果你使用的是LOGFONT结构,则:

LOGFONT lf;

ZeroMemory(&lf, sizeof(LOGFONT));

lf.lfHeight = 25; // in logical units

lf.lfWidth = 12; // in logical units

lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)

lf.lfItalic = false;

lf.lfUnderline = false;

lf.lfStrikeOut = false;

lf.lfCharSet = DEFAULT_CHARSET;

strcpy(lf.lfFaceName, "Times New Roman"); // font style

ID3DXFont* font = 0;

D3DXCreateFontIndirect(Device, &lf, &font);

另外,还可以使用D3DXCreateFont函数创建ID3DXFont的对象。

9.1.2.    绘制文字

得到ID3DXFont接口后,绘制文字就很简单了,只需要调用ID3DXFont::DrawText方法:

INT ID3DXFont::DrawText(

    LPD3DXSPRITE pSprite,

    LPCTSTR pString,

    INT Count,

    LPRECT pRect,

    DWORD Format,

    D3DCOLOR Color

);

l          pSprite –输出目标,为ID3DXSprite对象指针,可以为NULL值,此时字符串输出到默认对象

l          pString –需要输出的字符串

l          Count –字符串的字符数,如果为-1,则以0字符为结束标志

l          pRect –绘制字符串的区域

l          Format –文字的输出格式

l          Color –文字颜色

例如,可以这样使用该方法:

Font->DrawText(NULL,

    "Hello World", // String to draw.

    -1, // Null terminating string.

    &rect, // Rectangle to draw the string in.

    DT_TOP | DT_LEFT, // Draw in top-left corner of rect.

    0xff000000); // Black.

9.1.3.    计算帧速率

帧速率用FPSFrame per Second)表示。首先声明三个全局变量:

DWORD FrameCnt; // The number of frames that have occurred.

float TimeElapsed; // The time that has elapsed so far.

float FPS; // The frames rendered per second.

每秒计算一次FPS,这里计算的是平均值。我们也可以有足够的时间去读FPS值,而不至于因FPS的快速变化而产生较大误差。

每渲染一帧,累加一次帧数和所用的时间值:

FrameCnt++;

TimeElapsed += timeDelta;

这里的timeDelta表示两帧间的时间间隔。每过去一秒,就可以使用下面的公式计算FPS了:

FPS = (float)FrameCnt / TimeElapsed;

计算完成后,需要将FrameCntTimeElapsed重新置0,这样下一次的计算结果才正确:

void CalcFPS(float timeDelta)

{

    FrameCnt++;

    TimeElapsed += timeDelta;

    if(TimeElapsed >= 1.0f)

    {

        FPS = (float)FrameCnt / TimeElapsed;

        TimeElapsed = 0.0f;

        FrameCnt = 0;

    }

}

9.2. CD3DFont

DirectX SDK的安装目录下,提供了很多有用的代码CD3DFont类就位于其中。该类使用纹理三角形和Direct3D渲染文字,而不是通过GDI渲染,所以,其效率高于ID3DXFont。但是,CD3DFont不支持复杂的字体和文本格式,如果只需要高速渲染简单的字体,CD3DFont应是首选。

使用CD3DFont类时,需要加入以下源文件:d3dfont.hd3dfont.cppd3dutil.hd3dutil.cppdxutil.hdxutil.cpp。这些文件可在DirectX SDK的安装目录下找到。DirectX 9.0 SDK Update (Summer 2004)中,该类却消失了,所以,该节内容只适用于较早的DirectX 9.0 SDK版本!

9.2.1.    创建CD3DFont对象

创建CD3DFont的对象,就像创建一个普通的C++对象一样,其构造函数如下:

CD3DFont(const TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L);

l          strFontName –所使用的字体名称

l          dwHeight –字体高度

l          dwFlags –可选的标志,如D3DFONT_BOLDD3DFONT_ITALICD3DFONT_ZENABLE等。

得到CD3DFont对象后,还需按顺序进行初始化,如:

Font = new CD3DFont("Times New Roman", 16, 0); // instantiate

Font->InitDeviceObjects( Device );

Font->RestoreDeviceObjects();

9.2.2.    绘制文字

使用CD3DFont对象的如下方法渲染文字:

HRESULT CD3DFont::DrawText(FLOAT x, FLOAT y, DWORD dwColor,

    const TCHAR* strText, DWORD dwFlags=0L);

l          x –屏幕的x坐标

l          y –屏幕的y坐标

l          dwColor –文字的颜色

l          strText –要绘制的字符串

l          dwFlags –可选的渲染标志,可为0或下面的值:D3DFONT_CENTEREDD3DFONT_TWOSIDEDD3DFONT_FILTERED

例如:

Font->DrawText(20, 20, 0xff000000, “Hello, World”);

9.2.3.    资源清除

在删除CD3DFont对象前,还需作一些清除的工作:

Font->InvalidateDeviceObjects();

Font->DeleteDeviceObjects();

delete Font;

9.3. 函数D3DXCreateText

该函数用于创建3D文字Mesh,原型如下:

HRESULT WINAPI D3DXCreateText(

    LPDIRECT3DDEVICE9 pDevice,

    HDC hDC,

    LPCTSTR pText,

    FLOAT Deviation,

    FLOAT Extrusion,

    LPD3DXMESH *ppMesh,

    LPD3DXBUFFER *ppAdjacency,

    LPGLYPHMETRICSFLOAT pGlyphMetrics

);

l          pDevice –D3D设备

l          hDC –描述字体的设备上下文句柄

l          pText –要渲染的字符串

l          Deviation –TrueType字体的一个属性,该值不能小于0。如果为0,则使用字体的默认值

l          Extrusion –字体的深度,相对于Z坐标轴

l          ppMesh –返回生成的Mesh对象指针

l          ppAdjacency –返回邻接信息。如果不需要该信息,可使用NULL指针

l          pGlyphMetrics –结构GLYPHMETRICSFLOAT的数组,返回轮廓矩阵数据。如果不需要该数据,可以设该参数为NULL

下面就举例说明如何使用该函数创建3D文字的Mesh对象。

// Obtain a handle to a device context.

HDC hdc = CreateCompatibleDC( 0 );

// Fill out a LOGFONT structure that describes the font’s properties.

LOGFONT lf;

ZeroMemory(&lf, sizeof(LOGFONT));

lf.lfHeight = 25; // in logical units

lf.lfWidth = 12; // in logical units

lf.lfWeight = 500; // boldness, range 0(light) - 1000(bold)

lf.lfItalic = false;

lf.lfUnderline = false;

lf.lfStrikeOut = false;

lf.lfCharSet = DEFAULT_CHARSET;

strcpy(lf.lfFaceName, "Times New Roman"); // font style

// Create a font and select that font with the device context.

HFONT hFont;

HFONT hFontOld;

hFont = CreateFontIndirect(&lf);

hFontOld = (HFONT)SelectObject(hdc, hFont);

// Create the 3D mesh of text.

ID3DXMesh* Text = 0;

D3DXCreateText(_device, hdc, "Direct3D", 0.001f, 0.4f, &Text, 0, 0);

// Reselect the old font, and free resources.

SelectObject(hdc, hFontOld);

DeleteObject( hFont );

DeleteDC( hdc );

这时,Mesh对象已经得到了。最后,直接使用DrawSubset方法渲染即可:

Text->DrawSubset( 0 );

译者注:上面的例子代码,使用的是较早的DirectX 9.0 SDK,不是Summer 2004版本。

9.4. 总结

l          如果需要渲染较复杂的字体和格式,使用ID3DXFont接口会很方便。但是该接口是使用GDI实现的,故效率较低。

l          CD3DFont类可以快速的渲染简单的字体。该类实用D3D的纹理三角形渲染文字,故速度较ID3DXFont为快。

l          使用D3DXCreateText函数可以创建文字的3D网格模型。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值