网页功能: 加入收藏 设为首页 网站搜索  
在Direct3D中渲染文字
发表日期:2007-03-22作者:[转贴] 出处:  

 在遊戲中,文字信息的顯示是必不可少的。本章將討論在D3D中使用的三種顯示字體的方法。同樣,這裡只列出每種方法的演示程序的主體框架。學完本章將達到如下目標: 

l 學習如何使用ID3DXFont接口渲染文字 

l 學習如何使用CD3DFont類渲染文字 

l 學習計算遊戲幀速度的方法 

l 學習使用D3DXCreateText函數創建3D文字 

ID3DXFont
要在D3D程序輸出文字,使用D3DX庫提供的ID3DXFont接口很方便。其實該接口是使用GDI實現的,所以,其執行效率有所降低,但是它可以很方便地處理複雜的字體和格式。 

創建一個ID3DXFont
可使用D3DXCreateFontIndirect函數創建ID3DXFont:
HRESULT WINAPI D3DXCreateFontIndirect(    LPDIRECT3DDEVICE9 pDevice,    CONST D3DXFONT_DESC *pDesc,    LPD3DXFONT *ppFont); 

譯者註:我所使用的DirectX SDK是Microsoft 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 unitsd3dFont.Width=12;  // in logical unitsd3dFont.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 unitslf.lfWidth = 12; // in logical unitslf.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 styleID3DXFont* font = 0;D3DXCreateFontIndirect(Device, &lf, &font); 


另外,還可以使用D3DXCreateFont函數創建ID3DXFont的對象。 

繪製文字
得到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. 

計算幀速率
幀速率用FPS(Frame 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;


計算完成後,需要將FrameCnt和TimeElapsed重新置0,這樣下一次的計算結果才正確:
void CalcFPS(float timeDelta){    FrameCnt++;    TimeElapsed += timeDelta;    if(TimeElapsed >= 1.0f)    {        FPS = (float)FrameCnt / TimeElapsed;        TimeElapsed = 0.0f;        FrameCnt = 0;    }} 

CD3DFont
在DirectX SDK 的安裝目錄下,提供了很多有用的代碼CD3DFont類就位於其中。該類使用紋理三角形和Direct3D渲染文字,而不是通過GDI渲染,所以,其效率高於ID3DXFont。但是,CD3DFont不支持複雜的字體和文本格式,如果只需要高速渲染簡單的字體,CD3DFont應是首選。 

使用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版本! 

創建CD3DFont對像
創建CD3DFont的對象,就像創建一個普通的C++對像一樣,其構造函數如下: 

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


l strFontName –所使用的字體名稱 

l dwHeight –字體高度 

l dwFlags –可選的標誌,如D3DFONT_BOLD、D3DFONT_ITALIC、D3DFONT_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_CENTERED、D3DFONT_TWOSIDED、D3DFONT_FILTERED。 

例如: 

Font->DrawText(20, 20, 0xff000000, 「Hello, World」);

資源清除
在刪除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 unitslf.lfWidth = 12; // in logical unitslf.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網格模型。

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 在Direct3D中渲染文字
本类热点文章
  DDraw和D3D立即模式编程手册
  矩阵求逆的快速算法
  本地化支持:OGRE+CEGUI中文输入:OGRE方..
  Direct3D中实现图元的鼠标拾取
  3D场景中的圆形天空顶
  OpenGL显卡编程
  一种高效的基于大规模地形场景的OCCLUS..
  一个完善的读取3DS文件例子
  如何制作一个可控制的人体骨骼模型
  Direct3D 入门之我见
  Slope(斜坡) 法线生成算法,在地形渲染..
  在Direct3D中渲染文字
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00987