天行健 君子当自强而不息

创建游戏内核(12)

 

本篇是 创建游戏内核(11)的续篇,其中涉及到的字体知识请参阅D3D中的字体绘制示例

 

使用FONT处理文本和字体

虽然ID3DXFont对象处理起来比较容易,但是设置字体却让人痛苦不堪。不要紧,使用FONT类就能快速并容易地得到字体。

来看看FONT类的定义:

class FONT
{
private:
    ID3DXFont*  _font;

public:
    FONT();
    ~FONT();

    ID3DXFont* Get_Font_COM();

    BOOL Create(GRAPHICS* graphics, 
char* face_name, long size = 16, BOOL is_bold = FALSE, BOOL is_italic = FALSE);
    
void Free();

    BOOL Print(
char* text, long x_pos, long y_pos, long width = 0, long height = 0,
               D3DCOLOR color = 0xFFFFFFFF, DWORD format = 0);
};

接着是FONT类的实现:
//-------------------------------------------------------------------
// Constructor, initialize data member.
//-------------------------------------------------------------------
FONT::FONT()
{
    _font = NULL;
}

//-------------------------------------------------------------------
// Destructor, release font resource.
//-------------------------------------------------------------------
FONT::~FONT()
{
    Free();
}

//-------------------------------------------------------------------
// Get pointer to font object.
//-------------------------------------------------------------------
ID3DXFont* FONT::Get_Font_COM()
{
    
return _font;
}

//-------------------------------------------------------------------
// Create font object.
//-------------------------------------------------------------------
BOOL FONT::Create(GRAPHICS *graphics, char* face_name, long size, BOOL is_bold, BOOL is_italic)
{
    D3DXFONT_DESC font_desc;

    
// check condition first

    
if(graphics == NULL || face_name == NULL)
        
return FALSE;

    
if(graphics->Get_Device_COM() == NULL)
        
return FALSE;

    
// clear out the font structure
    ZeroMemory(&font_desc, sizeof(D3DXFONT_DESC));

    
// set the font property

    strcpy(font_desc.FaceName, face_name);

    font_desc.Height = -size;
    font_desc.Weight = is_bold ? 700 : 0;
    font_desc.Italic = is_italic;

    
// create the font object
    if(FAILED(D3DXCreateFontIndirect(graphics->Get_Device_COM(), &font_desc, &_font)))
        
return FALSE;

    
return TRUE;
}

//-------------------------------------------------------------------
// Release font resource.
//-------------------------------------------------------------------
void FONT::Free()
{
    Release_COM(_font);
}

//-------------------------------------------------------------------
// Draw text.
//-------------------------------------------------------------------
BOOL FONT::Print(char* text, long x_pos, long y_pos, long width, long height, D3DCOLOR color, DWORD format)
{
    RECT rect;

    
if(_font == NULL)
        
return FALSE;

    
// set draw region's width and height
    if(width  == 0)  width  = 65536;
    
if(height == 0)  height = 65536;

    
// set draw region
    rect.left   = x_pos;
    rect.top    = y_pos;
    rect.right  = rect.left + width;
    rect.bottom = rect.top + height;

    
// draw text now
    if(FAILED(_font->DrawText(NULL, text, -1, &rect, format, color)))
        
return FALSE;

    
return TRUE;
}

要使用某个字体,使用FONT::Create函数来创建,必须给Create函数传递一个预初始化的GRAPHICS对象,提供一个字体名称,并指定字体的大小(使用像素高度的近似值)。

打印一行文本时,需要给FONT::Print函数提供一个指向要打印文本的指针、开始打印处的坐标、用于裁剪文本的边界框(bounding box,即文本区域框)的大小(width和height的缺省值为0,表示全屏)、文本的颜色(缺省为白色,而且要使用D3DCOLOR_RGBA宏定义颜色)以及文本格式。

下表列出了打印文本时可以使用的格式:
 

标志 说明
DT_BOTTOM 将文本对齐到边界矩形的底部。
DT_CENTER 在边界矩形中将文本水平居中。
DT_LEFT 将文本左对齐到边界矩形的左边缘。
DT_NOCLIP 绘制文本,不将文本裁剪到边界矩形中,用于快速绘制。
DT_RIGHT 将文本右对齐到边界矩形的右边缘。
DT_TOP 将文本对齐到边界矩形的顶部。
DT_WORDBREAK 当到达边界矩形的右边缘时,文本将自动切换到下一行输出。

 

下面来看看一个完整的示例:

点击下载源码和工程

/*****************************************************************************
PURPOSE:
    Test for class FONT.
*****************************************************************************/


#include "Core_Global.h"

#pragma warning(disable : 4996)

//===========================================================================
// Defines class APP which public inherits from class APPLICATION.
//===========================================================================
class APP : public APPLICATION
{
private:
    GRAPHICS        _graphics;
    FONT            _font;  
    
public:    
    BOOL Init();
    BOOL Shutdown();
    BOOL Frame();
};

//-----------------------------------------------------------------------------
// Initialize graphics, set display mode, create font object.
//-----------------------------------------------------------------------------
BOOL APP::Init()
{    
    
// initialize graphics
    if (! _graphics.Init())
        
return FALSE;    

    
// set display mode for graphics
    if(! _graphics.Set_Mode(Get_Hwnd(), TRUE, TRUE, 400, 400, 32))
        
return FALSE;

    
// create font object
    if(! _font.Create(&_graphics, "Segoe Script", 32))
        
return FALSE;

    
return TRUE;
}

//-----------------------------------------------------------------------------
// Release all d3d resource.
//-----------------------------------------------------------------------------
BOOL APP::Shutdown()
{
    
return TRUE;
}

//-----------------------------------------------------------------------------
// Render a frame.
//-----------------------------------------------------------------------------
BOOL APP::Frame()
{    
    
// clear display with specified color
    _graphics.Clear(D3DCOLOR_RGBA(0, 0, 0, 255), 1.0);

    
// begin scene
    if(_graphics.Begin_Scene())
    {
        
// draw text
        _font.Print("How are you, cloud?", 0, 0, _graphics.Get_Width(), _graphics.Get_Height(), 
                    0xFFFFFFFF, DT_CENTER | DT_VCENTER);
     
        
// end the scene
        _graphics.End_Scene();       
    }

    
// display video buffer
    _graphics.Display();
    
    
return TRUE;
}

int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    APP app;

    
return app.Run();
}

运行截图:


posted on 2007-09-04 17:58 lovedday 阅读(336) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论