第九章
D3DX库提供接口ID3DXFont,该接口用于在Direct3D应用程序中绘制文本。该接口内部使用GDI在绘制文本,因此该接口在性能上略有损失,然后正是由于该接口使用了GDI,才能够处理一些复杂的字体和格式
可用D3DXCreateFontIndirect函数来创建一个ID3DXFont接口对象
HRESULT D3DXCreateFontIndirect(
LPDIRECT3DDEVICE9 pDevice,//device to be associated with the font
CONST D3DXFONT_DESC * pDesc,//D3DXFONT_DESC structure ,describing the font
LPD3DXFONT * ppFont//return the created font
);
例:
D3DXFONT_DESC df;
ZeroMemory(&df,sizeof(D3DXFONT_DESC));
df.Height = 25;
df.Width = 12;
df.Weight = 500;
df.MipLevels = D3DX_DEFAULT ;
df.Italic = false ;
df.CharSet = DEFAULT_CHARSET;
df.OutputPrecision = 0;
df.Quality = 0;
df.PitchAndFamily = 0;
strcpy(df.FaceName,"Times New roman");//font style
ID3DXFont *font = 0;
D3DXCreateFontIndirect(Device,&df,&font);
需要先填充D3DXFONT_DESC结构
也可用D3DXCreateFont函数获取指向ID3DXFont接口的指针
获取了ID3DXFont接口指针,只需调用ID3DXFont::DrawText即可完成文本绘制
INT ID3DXFont::DrawText(
LPD3DXSPRITE pSprite,
LPCSTR pString,
INT Count ,
LPRECT pRect,
DWORD Format ,
D3DCOLOR Color);
#pSprite 指定字符串所属的ID3DXSprite对象接口,可设默认值0,表示在当前窗口中绘制字符串
#pString 指定将要绘制的字符串的指针
#Count 字符串中的字符个数,若为-1,则认为pString指向一个以NULL结尾的字符串,ID3DXFont::DrawText将自动对字符个数进行统计
#pRect 指定字符串绘制矩形的区域的位置
#Format 指定了字符串在pRect指定的矩形区域中的格式化方法,该参数是一系列可选标记的某一个或某种组合
#Color文本颜色
例:
Font->DrawText(0,"Hello World",-1,&rect,DT_TOP|DT_LEFT,0xff000000);
用ID3DXFont和CFont计算并显示了程序每秒绘制的帧数(FPS)
例:
首先实例化如下3个全局变量
DWORD FrameCnt = 0 ;// the number of frames that have occurred
float TimeElapsed = 0;// The Time that has elapsed so far
float FPS = 0;//The frames rendered per second
每秒计算一次FPS,从而得到一个较准确的均值
每当一帧绘制完成,我们对变量FrameCnt进行自增,并为变量TimeElapse增加自上一帧绘制结束时算起所经过的时间timeDelta
FrameCnt++;
TimeElapsed += timeDelta;
每秒过后,用如下公式计算FPS
FPS = (float)FrameCnt/TimeElapsed;
然后再重设变量FrameCnt和TimeElapse,准备计算下一秒的FPS均值
void CalcFPS(float timeDelta)
{
FrameCnt++ ;
TimeElapsed += timeDelta;
if (TimeElapsed >= 1.0f)
{
FPS = (float)FrameCnt / TimeElapsed;
TimeElapsed = 0.0f;
FrameCnt = 0;
}
}
CD3DFont 可借助Direct3D和映射有纹理的三角形绘制文本,绘制文本时用的是Direct3D而非GDI,该类不支持ID3DXFont所支持的复杂的字体和格式
CD3DFont(const TCHAR * strFontName,DWORD dwHeight,DWORD dwFlags = 0L)
#StrFontName 一个NULL结尾的字符串,指定字体名称
#dwHeight 字体高度
#dwFlags创建标记,可选,该参数可为0或以下组合,D3DFONT_BOLD,D3DFONT_ITALIC,D3DFONT_ZENABLE
实例化一个CD3DFont类对象之后,必须调用如下方法来对字体进行初始化
Font = new CD3DFont("Times New Roman",16,0);
Font->InitDeviceObject(Device);
Font-> RestoreDeviceObjects();
文本绘制:
HRESULT CD3DFont::DrawText(FLOAT x,FLOAT y,DWORD dwColor,const TCHAR* strText,DWORD dwFlags = 0);
#x 屏幕坐标系中文本绘制起点的x坐标
#y 屏幕坐标系中文本绘制起点的y坐标
#dwColor 文本颜色
#strText指向所要绘制文本的指针
#dwFlags 绘制标记,可选,可设为0,或下列组合,D3DFONT_CENTERED,D3DFONT_TWOSIDED,D3DFONT_FILTERED
例:
Font->DrawText(20,20,0xff000000,"Hello World");
在删除一个CD3DFont类对象之前,必须首先调用一些清理函数
Font->InvalidateDeviceObjects();
Font->DeleteDeviceObjects();
delete Font ;
D3DXCreateText函数用于创建文本3D网格
HRESULT D3DXCreateText(
LPDIRECT3DDEVICE9 pDevice,
HDC hDC,
LPCTSTR pText,
FLOAT Deviation,
FLOAT Extrusion,
LPD3DXMESH * ppMesh,
LPD3DXBUFFER* ppAdjacency,
LPGLYPHMETRICSFLOAT pGlyphMetrics);
调用成功返回D3D_OK
#pDevice 指向于网格相关的设备
#hDC一个设备环境句柄,包含将用来创建网格字体的相关信息
#pText 指向确定所要用于生成文本的字符串的指针
#Deviation TrueType字体轮廓的最大弦偏差,该值必须为非负,弦偏差等于原始字体的一个设计单位
#Extrusion沿z轴负方向度量的字体深度
#ppMesh 返回所创建的网格
#ppAdjacency返回所创建的网格的邻接信息,如果不用该值, 指定NULL
#pGlyphMetrics指定LPGLYPHMETRICSFLOAT类型结构数组指针,该结构包含了字形的度量数据,如果不关心字形的度量数据,可设0
例:
使用该函数创建文本3D网格
//obtain a handle to a device context
HDC hdc = CreateCompatibleDC(0);
HFONT hFont ;
HFONT hFontOld;
//Fill out a LOGFONT structure that describes the font's properties
LOGFONT lf;
ZeroMemory(&lf,sizeof(LOGFONT));
lf.lfHeight =25;
lf.lfWidth = 12;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = 500;
lf.lfItalic = false;
lf.lfUnderline = false ;
lf.lfStrikeOut = false;
lf.lfCharSet = DEFAULT_CHATSET;
lf.lfOutPrecision = 0;
lf.lfClipPrecision = 0;
lf.lfQuality = 0;
lf.lfPitchAndFamily = 0;
strcpy(lf.lfFaceName,"Times New Roman");
//Create a font and select that font with the device context
hFont = CreateFontIndirect(&lf);
hFontOld = (HFONT)SelectObject(hdc,hFont);
//Create the text mesh based on the selected font in the HDC
D3DXCreateText(Device,hdc,"Direct3D",0.001f,0.4f,&Text,0,0);
//Reset the old font and free resources
SelectObject(hdc,hFontOld);
DeleteObject(hFont);
DeleteDC(hdc);
调用网格的DrawSubset方法
Text -> DrawSubset(0);