文档章节

D3D中的字体绘制示例

rise-worlds
 rise-worlds
发布于 2016/06/20 13:35
字数 1815
阅读 10
收藏 0
技巧如下:

字体的绘制需要使用ID3DXFont对象和 D3DXCreateFontIndirect函数。

DirectX SDK文档对ID3DXFont做了简要的说明:

The ID3DXFont interface encapsulates the textures and resources needed to render a specific font on a specific device.

The ID3DXFont interface is obtained by calling D3DXCreateFont or D3DXCreateFontIndirect.

我们来看看SDK文档提供的关于 D3DXCreateFontIndirect的使用说明:

Creates a font object indirectly for both a device and a font.

Syntax

HRESULT WINAPI D3DXCreateFontIndirect(LPDIRECT3DDEVICE9 pDevice,
    CONST D3DXFONT_DESC *pDesc,
    LPD3DXFONT *ppFont
);

Parameters

pDevice
[in] Pointer to an IDirect3DDevice9 interface, the device to be associated with the font object.

pDesc
[in] Pointer to a D3DXFONT_DESC structure, describing the attributes of the font object to create. If the compiler settings require Unicode, the data type D3DXFONT_DESC resolves to D3DXFONT_DESCW; otherwise, the data type resolves to D3DXFONT_DESCA. See Remarks.

ppFont
[out] Returns a pointer to an ID3DXFont interface, representing the created font object.

Return Value

If the function succeeds, the return value is D3D_OK.

If the function fails, the return value can be one of the following:

D3DERR_INVALIDCALL The method call is invalid. For example, a method's parameter may have an invalid value.
E_OUTOFMEMORY Microsoft Direct3D could not allocate sufficient memory to complete the call.

Remarks

The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateFontIndirectW. Otherwise, the function call resolves to D3DXCreateFontIndirectA because ANSI strings are being used.

该函数的第二个参数使用了一个结构体D3DXFONT_DESC,来看看它的具体定义:

Defines the attributes of a font.

Syntax

typedef struct D3DXFONT_DESC {
    INT Height;
    UINT Width;
    UINT Weight;
    UINT MipLevels;
    BOOL Italic;
    BYTE CharSet;
    BYTE OutputPrecision;
    BYTE Quality;
    BYTE PitchAndFamily;
    TCHAR FaceName[LF_FACESIZE];
} D3DXFONT_DESC;

Members

Height
Height, in logical units, of the font's character cell or character.

Width
Width, in logical units, of characters in the font.

Weight
Weight of the font in the range from 0 through 1000.

MipLevels
Number of mip levels requested. If this value is zero or D3DX_DEFAULT, a complete mipmap chain is created. If the value is 1, the texture space is mapped identically to the screen space.

Italic
Set to TRUE for an Italic font.

CharSet
Character set.

OutputPrecision
Output precision. The output precision defines how closely the output must match the requested font height, width, character orientation, escapement, pitch, and font type.

Quality
Output quality.

PitchAndFamily
Pitch and family of the font.

FaceName
A null-terminated string or characters that specifies the typeface name of the font. The length of the string must not exceed 32 characters, including the terminating null character. If FaceName is an empty string, the first font that matches the other specified attributes will be used.

If the compiler settings require Unicode, the data type TCHAR resolves to WCHAR; otherwise, the data type resolves to CHAR. See Remarks.

Remarks

The compiler setting also determines the structure type. If Unicode is defined, the D3DXFONT_DESC structure type resolves to a D3DXFONT_DESCW; otherwise the structure type resolves to a D3DXFONT_DESCA.

Possible values of the above members are given in the Microsoft Windows Graphics Device Interface (GDI) LOGFONT  structure.

当然,在设置的时候我们不需要设置所有的属性,只要设置其中的几个主要属性就可以了。

我们可以这样设置字体的属性并创建字体:

   D3DXFONT_DESC           font_desc;

   //  create the font
    ZeroMemory( & font_desc,  sizeof (font_desc));
    
    
//  set font descripter
    strcpy(font_desc.FaceName,  " Arial " );
    font_desc.Height 
=   32 ;

    
//  Creates a font object indirectly for both a device and a font
    D3DXCreateFontIndirect(g_d3d_device,  & font_desc,  & g_font);

通过ID3DXFont::DrawText方法我们可以绘制字体了,来看看它的具体使用信息:

Draws formatted text. This method supports ANSI and Unicode strings.

Syntax

INT DrawText(LPD3DXSPRITE pSprite,
    LPCTSTR pString,
    INT Count,
    LPRECT pRect,
    DWORD Format,
    D3DCOLOR Color
);

Parameters

pSprite
[in] Pointer to an ID3DXSprite object that contains the string. Can be NULL, in which case Microsoft Direct3D will render the string with its own sprite object.

To improve efficiency, a sprite object should be specified if ID3DXFont::DrawText is to be called more than once in a row.

pString
[in] Pointer to a string to draw.

If the Count parameter is -1, the string must be null-terminated.

Count
[in] Specifies the number of characters in the string. If Count is -1, then the pString parameter is assumed to be a pointer to a null-terminated string and ID3DXFont::DrawText computes the character count automatically.

pRect
[in] Pointer to a RECT  structure that contains the rectangle, in logical coordinates, in which the text is to be formatted. As with any RECT object, the coordinate value of the rectangle's right side must be greater than that of its left side. Likewise, the coordinate value of the bottom must be greater than that of the top.

Format
[in] Specifies the method of formatting the text. It can be any combination of the following values:

DT_BOTTOM
Justifies the text to the bottom of the rectangle. This value must be combined with DT_SINGLELINE.

DT_CALCRECT
Determines the width and height of the rectangle. If there are multiple lines of text, ID3DXFont::DrawText uses the width of the rectangle pointed to by the pRect parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, ID3DXFont::DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, ID3DXFont::DrawText returns the height of the formatted text but does not draw the text.

DT_CENTER
Centers text horizontally in the rectangle.

DT_EXPANDTABS
Expands tab characters. The default number of characters per tab is eight.

DT_LEFT
Aligns text to the left.

DT_NOCLIP
Draws without clipping. ID3DXFont::DrawText is somewhat faster when DT_NOCLIP is used.

DT_RIGHT
Aligns text to the right.

DT_RTLREADING
Displays text in right-to-left reading order for bidirectional text when a Hebrew or Arabic font is selected. The default reading order for all text is left-to-right.

DT_SINGLELINE
Displays text on a single line only. Carriage returns and line feeds do not break the line.

DT_TOP
Top-justifies text.

DT_VCENTER
Centers text vertically (single line only).

DT_WORDBREAK
Breaks words. Lines are automatically broken between words if a word would extend past the edge of the rectangle specified by the pRect parameter. A carriage return/line feed sequence also breaks the line.

Color
[in] Color of the text. For more information, see D3DCOLOR.

Return Value

If the function succeeds, the return value is the height of the text in logical units. If DT_VCENTER or DT_BOTTOM is specified, the return value is the offset from pRect->top to the bottom of the drawn text.

If the function fails, the return value is zero.

Remarks

The parameters of this method are very similar to those of the Microsoft Windows Graphics Device Interface (GDI) DrawText  function.

This method supports both ANSI and Unicode strings.

This method must be called inside a IDirect3DDevice9::BeginScene ... IDirect3DDevice9::EndScene block. The only exception is when an application calls ID3DXFont::DrawText with DT_CALCRECT to calculate the size of a given block of text.

Unless the DT_NOCLIP format is used, this method clips the text so that it does not appear outside the specified rectangle. All formatting is assumed to have multiple lines unless the DT_SINGLELINE format is specified.

If the selected font is too large for the rectangle, this method does not attempt to substitute a smaller font.

This method supports only fonts whose escapement and orientation are both zero.

我们可以这样使用该函数:

    RECT rect  =  {  0 0 , WINDOW_WIDTH, WINDOW_HEIGHT };

    //  Begin scene
     if (SUCCEEDED(g_d3d_device -> BeginScene()))
    {
        
//  draw some text
        g_font -> DrawTextA(NULL,  " Programming is fun! " - 1 & rect, DT_CENTER  |  DT_VCENTER,  0xFFFFFFFF );

        
//  end the scene
        g_d3d_device -> EndScene();
    }

完整源码如下:

/* **************************************************************************************
PURPOSE:
    Font Demo

Required libraries:
  D3D9.LIB and D3DX9.LIB
 **************************************************************************************
*/

#include 
< windows.h >
#include 
< stdio.h >
#include 
" d3d9.h "
#include 
" d3dx9.h "

#pragma comment(lib, 
" d3d9.lib " )
#pragma comment(lib, 
" d3dx9.lib " )

#pragma warning(disable : 
4996 )

#define  WINDOW_WIDTH    400
#define  WINDOW_HEIGHT   400

#define  Safe_Release(p) if((p)) (p)->Release();

//  window handles, class and caption text.
HWND g_hwnd;
HINSTANCE g_inst;
static   char  g_class_name[]  =   " FontClass " ;
static   char  g_caption[]     =   " Font Demo " ;

//  the Direct3D and device object
IDirect3D9 *  g_d3d  =  NULL;
IDirect3DDevice9
*  g_d3d_device  =  NULL;

//  the font object
ID3DXFont *  g_font  =  NULL;

// --------------------------------------------------------------------------------
//  Window procedure.
// --------------------------------------------------------------------------------
long  WINAPI Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
switch (msg)
    {
    
case  WM_DESTROY:
        PostQuitMessage(
0 );
        
return   0 ;
    }

    
return  ( long ) DefWindowProc(hwnd, msg, wParam, lParam);
}

// --------------------------------------------------------------------------------
//  Initialize d3d, d3d device, vertex buffer, texutre. 
// --------------------------------------------------------------------------------
BOOL Do_Init()
{
    D3DPRESENT_PARAMETERS   present_param;
    D3DDISPLAYMODE          display_mode;
    D3DXFONT_DESC           font_desc;

    
//  do a windowed mode initialization of Direct3D
     if ((g_d3d  =  Direct3DCreate9(D3D_SDK_VERSION))  ==  NULL)
        
return  FALSE;

    
//  retrieves the current display mode of the adapter
     if (FAILED(g_d3d -> GetAdapterDisplayMode(D3DADAPTER_DEFAULT,  & display_mode)))
        
return  FALSE;

    ZeroMemory(
& present_param,  sizeof (present_param));

    
//  initialize d3d presentation parameter
    present_param.Windowed           =  TRUE;
    present_param.SwapEffect        
=  D3DSWAPEFFECT_DISCARD;
    present_param.BackBufferFormat  
=  display_mode.Format;    

    
//  creates a device to represent the display adapter
     if (FAILED(g_d3d -> CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd,
                                  D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
& present_param,  & g_d3d_device)))
        
return  FALSE;     

    
//  create the font
    ZeroMemory( & font_desc,  sizeof (font_desc));
    
    
//  set font descripter
    strcpy(font_desc.FaceName,  " Arial " );
    font_desc.Height 
=   32 ;

    
//  Creates a font object indirectly for both a device and a font
    D3DXCreateFontIndirect(g_d3d_device,  & font_desc,  & g_font);

    
return  TRUE;
}

// --------------------------------------------------------------------------------
//  Release all d3d resource.
// --------------------------------------------------------------------------------
BOOL Do_Shutdown()
{
    Safe_Release(g_font);
    Safe_Release(g_d3d_device);
    Safe_Release(g_d3d);

    
return  TRUE;
}

// --------------------------------------------------------------------------------
//  Render a frame.
// --------------------------------------------------------------------------------
BOOL Do_Frame()
{
    RECT rect 
=  {  0 0 , WINDOW_WIDTH, WINDOW_HEIGHT };

    
//  clear device back buffer
    g_d3d_device -> Clear( 0 , NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA( 0 64 128 255 ),  1.0f 0 );

    
//  Begin scene
     if (SUCCEEDED(g_d3d_device -> BeginScene()))
    {
        
//  draw some text
        g_font -> DrawTextA(NULL,  " Programming is fun! " - 1 & rect, DT_CENTER  |  DT_VCENTER,  0xFFFFFFFF );

        
//  end the scene
        g_d3d_device -> EndScene();
    }

    
//  present the contents of the next buffer in the sequence of back buffers owned by the device
    g_d3d_device -> Present(NULL, NULL, NULL, NULL);

    
return  TRUE;
}

// --------------------------------------------------------------------------------
//  Main function, routine entry.
// --------------------------------------------------------------------------------
int  WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line,  int  cmd_show)
{
    WNDCLASSEX  win_class;
    MSG         msg;

    g_inst 
=  inst;

    
//  create window class and register it
    win_class.cbSize         =   sizeof (win_class);
    win_class.style         
=  CS_CLASSDC;
    win_class.lpfnWndProc   
=  Window_Proc;
    win_class.cbClsExtra    
=   0 ;
    win_class.cbWndExtra    
=   0 ;
    win_class.hInstance     
=  inst;
    win_class.hIcon         
=  LoadIcon(NULL, IDI_APPLICATION);
    win_class.hCursor       
=  LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground 
=  NULL;
    win_class.lpszMenuName  
=  NULL;
    win_class.lpszClassName 
=  g_class_name;
    win_class.hIconSm       
=  LoadIcon(NULL, IDI_APPLICATION);

    
if ( !  RegisterClassEx( & win_class))
        
return  FALSE;

    
//  create the main window
    g_hwnd  =  CreateWindow(g_class_name, g_caption, WS_CAPTION  |  WS_SYSMENU,  0 0 ,
                          WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, inst, NULL);

    
if (g_hwnd  ==  NULL)
        
return  FALSE;

    ShowWindow(g_hwnd, SW_NORMAL);
    UpdateWindow(g_hwnd);

    
//  initialize game
     if (Do_Init()  ==  FALSE)
        
return  FALSE;

    
//  start message pump, waiting for signal to quit.
    ZeroMemory( & msg,  sizeof (MSG));

    
while (msg.message  !=  WM_QUIT)
    {
        
if (PeekMessage( & msg, NULL,  0 0 , PM_REMOVE))
        {
            TranslateMessage(
& msg);
            DispatchMessage(
& msg);
        }
        
        
//  draw a frame
         if (Do_Frame()  ==  FALSE)
            
break ;
    }

    
//  run shutdown function
    Do_Shutdown();

    UnregisterClass(g_class_name, inst);
    
    
return  ( int ) msg.wParam;
}

效果图如下:


本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/07/03/871686.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
Nebula3绘制2D纹理

上次已经绘制过基本图元了, 这次只不过要贴张图而已..... 本来我想用Graphics的Model渲染流程来做, 不过这一层太高级了, 都是什么场景管理资源映射之类的 做低级的事情, 就要用低级的API嘛 ...

长平狐
2012/11/12
85
0
在D3D窗口中渲染WINDOWS的基本控件

最近没怎么上文,因为做的东西可能较简单,不好意思发了。不过清明要来了。有大块时间Coding了。呵呵。今天接到CSDN上一朋友的提问:如何在D3D独占模式下显示WINDOWS窗口。这个问题提的好。不...

长平狐
2012/11/19
587
0
在D3D窗口中渲染WINDOWS的基本控件

最近没怎么上文,因为做的东西可能较简单,不好意思发了。不过清明要来了。有大块时间Coding了。呵呵。今天接到CSDN上一朋友的提问:如何在D3D独占模式下显示WINDOWS窗口。这个问题提的好。不...

长平狐
2013/03/19
92
0
练习项目03:绘制生成PDF折线图(上)

练习项目03:绘制生成PDF折线图(上) Python自动化运维2017-12-211 阅读 PythonPDFPython教程reportlab 这个练习项目来自《Python基础教程(第2版)》,案例原名为“画副好画”。 不过因为P...

Python自动化运维
2017/12/21
0
0
EasyPlayer RTSP Windows播放器D3D,GDI的几种渲染方式的选择区别

EasyPlayer-RTSP windows播放器支持D3D和GDI两种渲染方式,其中D3D支持格式如下:

xiejiashu
2017/12/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Cantata 8.0有哪些新变化

Cantata 8.0 于2018年5月发布,这一重大版本的升级在以往技术的基础上增添了关键性新功能,并且对用户界面进行了全面改进,这个文档简要介绍了8.0中的主要变化。 Cantata 于2018年5月发布,本...

旋极科技
17分钟前
7
0
在线客服系统企业用的如何?

现在很多企业都在使用在线客服系统,但是销售订单没有显著增加这是为什么呢? 一:我们企业的客服人员是否有做好真正的接待工作? 是否每天都有对网站上的访客进行接待? 相关管理人员有没有做...

唯喏
26分钟前
5
0
Hystrix实现主线程和子线程的ThreadLocal上下文传递

问题描述 我在使用日志链路追踪的时候(基于SLF4J MDC机制实现日志的链路追踪),我发现使用Hystrix线程池隔离的时候,我不能将子线程没有复制主线程的MDC上下文(Slf4j MDC机制 ),导致日志链...

xiaolyuh
32分钟前
5
0
基于CentOS7搭建GitLab

基于CentOS7搭建GitLab 12018.11.02 16:38:51字数 959阅读 3790 本文作者:蓝雄威,叩丁狼高级讲师。原创文章,转载请注明出处。 一、简介 Git Lab GitLab是利用 Ruby on Rails 一个开源的版...

linjin200
33分钟前
3
0
AJAX技术

1.1 准备工作 因为AJAX也需要请求服务器,异步请求也是请求服务器,所以我们需要先写好服务器端代码,即编写一个Servlet! 这里,Servlet很简单,只需要输出“Hello AJAX!”。 public class...

Pak_key
34分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部