9. Font
This article translated from "Introduction to 3D Game Programming with DirectX 9.0" Chapter 9 "Fonts", please ax!
In the game, the display of text information is essential. This chapter will discuss the three methods of displaying fonts used in D3D. Similarly, only the main frame of the demo program of each method is listed here. After learning this chapter will reach the following goals:
l Learn how to use ID3DXFONT interface rendering text
l Learn how to use cd3dfont class rendering text
l learning how to calculate game frame speed
l Learn to create 3D text using the D3DXCREATEXT function
9.1. ID3DXFONT
To output text on the D3D program, it is convenient to use the ID3DXFont interface provided by the D3DX library. In fact, the interface is implemented using GDI, so its execution efficiency has decreased, but it can easily handle complex fonts and formats.
9.1.1. Create an ID3DXFONT
You can create ID3DXFONT using the D3DXCREATEFONTINDIRECT function:
HRESULT WINAPI D3DXCREATEFONTINDIRECT (LPDIRECT3DDEVICE9 PDEVICE, CONST D3DXFONT_DESC * PDESC, LPD3DXFONT * PPFONT);
Translator Note: The DirectX SDK I use is Microsoft DirectX 9.0 SDK Update (Summer 2004), which is the version of DirectX 9.0c. In the earlier version, the prototype of this function is different: second parameters For const logfont * plogfont, it is the structure in GDI. In the future, if there is no special instruction, it will be based on the prototype declared in DirectX 9.0 SDK Update (Summer 2004).
When using this function, you need a D3DXFONT_DESC structure:
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);
If you are using the logfont structure, then:
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); additionally, you can also create ID3DXFONT objects using the D3DXCREATEFONT function.
9.1.2. Draw a text
After getting the ID3DXFONT interface, you will be simple, just call the id3dxfont :: DrawText method:
INT ID3DXFONT :: DrawText (LPD3DXSPRITE PSPRITE, LPCTSTSTST, INT Count, LPRECT, DWORD FORMAT, D3DCOLOR color);
l PSPRITE - Output target, the ID3DXSPRITE object pointer, can be a null value, this clock output to the default object
l pstring - strings that need to be output
l Count - the number of characters of the string, if to -1, the end flag is characterized by 0 characters.
l prect - the area of drawing strings
l format - the output format of the text
l Color - text color
For example, this method can be used:
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. Calculate frame rate
The frame rate is represented by FPS (FRME PER Second). First, declare three global variables:
DWord framecnt; // the number of frames there. Float timeelapsed; // The time That Has Elapsed SO far. Float fps; // the framees rendered per second.
FPS is calculated every second, which is calculated here. We can also have enough time to read the FPS value, not due to the rapid changes in FPS.
Every time you render one frame, accumulate the number of frames and the time value used:
Framecnt ; timeelapsed = TIMEDELTA;
The TIMEDELTA here represents the interval between two frames. To calculate the FPS using the following formulas using the following formula:
FPS = (float) framecnt / timeelapsed; After the calculation is complete, you need to reset the framecnt and timeelapsed, which is correct:
Void Calcfps (FLOAT TIMEDELTA) {FRAMECNT ; timeelapsed = TIMEDELTA; if (timeelapsed> = 1.0f) {fps = (float) framecnt / timeelapsed; timeelapsed = 0.0f; framecnt = 0;}}}
9.2. Cd3dfont
In the DirectX SDK installation directory, there is a widely useful code CD3DFONT class. This class uses texture triangles and Direct3D rendering words instead of rendering with GDI, so its efficiency is higher than ID3dxFont. However, CD3DFONT does not support complex fonts and text formats, and if only high speed rendering is simple, CD3DFONT should be preferred.
When using a CD3DFont class, you need to add the following source files: D3DFont.h, D3DFont.cpp, D3DUTIL.H, D3DUTIL.CPP, DXUTIL.H, DXUTIL.CPP. These files can be found in the DirectX SDK installation directory. In DirectX 9.0 SDK Update (Summer 2004), this class disappears, so the content is only available for earlier DirectX 9.0 SDK version!
9.2.1. Creating a CD3DFONT object
Create a CD3DFont object, just like creating a normal C object, its constructor is as follows:
CD3DFONT (Const Tchar * StrfontName, DWORD DWHEIGHT, DWORD DWFLAGS = 0L);
l strfontname - the font name used
l dwheight - font height
l DWFlags - an optional sign such as D3DFont_Bold, D3DFont_ITAlic, D3DFont_Zenable, etc.
After getting a CD3DFONT object, you need to initialize in order, such as:
Font = New CD3DFONT ("Times New Roman", 16, 0); // Instantiate Font-> InitDeviceObjects (Device); font-> restoreviceObjects ();
9.2.2. Draw a text
Rendering text using a CD3DFont object:
HRESULT CD3DFONT :: DrawText (Float X, Float Y, DWORD DWCOLOR, Const Tchar * Strtext, DWORD DWFLAGS = 0L);
l x - X coordinate of the screen
l y - screen Y coordinate
l dwcolor - color
l Strtext - String to draw
l DWFlags - an optional rendering flag, a value of 0 or below: D3DFONT_CENTERED, D3DFONT_TWOSIDED, D3DFONT_FILTERED.
E.g:
FONT-> DRAWTEXT (20, 20, 0xFF000000, "Hello, World"); 9.2.3. Resource Clear
Before deleting a CD3DFONT object, you need to do some clearance:
FONT-> INVALIDATEDEVICEOBJECTS (); font-> deletedEviceObjects (); delete font;
9.3. Function D3DXCREATEXT
This function is used to create 3D text Mesh, the prototype is as follows:
HRESULT WINAPI D3DXCreateText (LPDIRECT3DDEVICE9 pDevice, HDC hDC, LPCTSTR pText, FLOAT Deviation, FLOAT Extrusion, LPD3DXMESH * ppMesh, LPD3DXBUFFER * ppAdjacency, LPGLYPHMETRICSFLOAT pGlyphMetrics);
l PDEvice -D3D device
l HDC - Device context handle describing the font
l PTEXT - String to render
l Deviation -TrueType fonts an attribute that cannot be less than 0. If 0, the default value of the font is used.
l Extrusion - the depth of the font, relative to the Z coordinate axis
l ppmesh - Return the generated Mesh object pointer
l PPadjacency - Returns the adjacency information. If this information is not required, you can use the NULL pointer.
l PGLYPHMETRICS - Architecture of the structure GlyphmetricsFloat, returns the contour matrix data. If this data is not required, you can set this parameter null
The following is an example of how to create a 3D text of the Mesh object using this function.
// 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; D3DXCREATEXT (_Device, HDC, "Direct3D", 0.001F, 0.4F, & Text, 0 , 0); // Reselect The Old Font, And Free Resources. SelectObject (HDC, HFontold); deleteObject (HFONT); DELETEDC (HDC); At this time, the Mesh object has been obtained. Finally, you can use the DrawSubset method directly:
Text-> DrawSubset (0);
Translator Note: The above example code is used as the earlier DirectX 9.0 SDK, not the Summer 2004 version.
Summary
l If you need to render more complex fonts and formats, it is convenient to use the ID3DXFont interface. However, the interface is achieved using GDI, and the efficiency is low.
l CD3DFont classes can quickly render simple fonts. This type of practical D3D texture triangle rendering text, the speed is more than ID3dxFont is fast.
l Use the D3DxCreateText function to create a 3D grid model of text.