DirectX 9.0c Game Development Journal of RPG Programming Self-learning log 15:drawing with DirectX Graphics (drawing with DirectX graphic) (第8-9 section)

Source: Internet
Author: User
Tags drawtext

This article by Harry _ Spider-Man original, reproduced please indicate the source! If you have any questions, please contact [email protected]

This time we continue to tell Jim Adams old brother's RPG Programming book Second edition of Chapter 8th: Using Fonts (use fonts), and section 9th: Billboards (Billboard). The two sections are not much, so put it in one issue.

Original translation:


2.8 Using Fonts ( use fonts )

One flaw with DirectX 9 is that it does not support fonts. Older versions of DirectX (before DX 8) can manipulate the font-drawing functions of Windows. In DX 9, you must manually draw a font onto a texture surface, and then draw each letter of the font as a small polygon with texture mapping.

Managing a texture that contains fonts is a bit too laborious for just drawing text, but thanks to D3DX, you can take advantage of a special object Id3dxfont, which can handle these texture mapping fonts for you. The Id3dxfont object contains 7 functions, but we are only interested in 3 of them here.

These 3 functions are:(note: The following Begin function and End function are now gone.) In addition , the DrawText function is not the same as the current version. This is a good illustration of what I mentioned earlier, "even if there is a lot of difference between DirectX 9 ." Please see my supplemental text later in this section for details. )

Id3dxfont::begin. This function represents the beginning of a text drawing operation.

Id3dxfont::end. This function represents the end of a text drawing operation.

Id3dxfont::D rawtext. This function draws the text.



One of the fourth functions you might find useful is id3dxfont::onresetdevice. When you lose control of the display device (for example, when the user switches to another application), you lose resources, such as your font object. As long as you lose the resources (as indicated by the error code-consult the DX SDK documentation for more information), you will have to invoke the Onresetdevice function to recover these resources.


Before you go far, you can start by looking at how to create a font!

2.8.1 Creating thefont ( Create font )

In order to use the Id3dxfont object, you must first use the D3dxcreatefontindirect function to initialize it:

HRESULT D3dxcreatefontindirect (  idirect3ddevice9*pdevice,//Device to associate font to  Constlogfont * Plogfont,   //structuredefining font  id3dxfont   **ppfont);    Pointer to Createdfont Object

Watch out


Because Id3dxfont is a COM object, you always have to remember to release it after you run out of it.


You provide this function with a previously initialized device object and a pointer to the Id3dxfont object you are initializing, but what do you think of the Plogfont parameter?

As you can see, Plogfont points to a logfont (which represents the logical font) structure, which looks like this:

typedef struct TAGLOGFONT {  LONG  lfheight;  LONG  lfwidth;  LONG  lfescapement;  LONG  lforientation;  LONG  lfweight;  BYTE  lfitalic;  BYTE  Lfunderline;  BYTE  lfstrikeout;  BYTE  lfCharSet;  BYTE  lfoutprecision;  BYTE  lfclipprecision;  BYTE  lfquality;  BYTE  lfpitchandfamily;  TCHAR  lffacename[lf_facesize];} LOGFONT;

Oh, hello, a lot of information ah! But you can safely skip the settings for most of the members in the LogFont struct and set them to the default values I gave. (brother, you did not give the default value Ah!) The only thing you need to change is lfheight, Lfweight, Lfitalic, Lfunderline and Lffacename.

Starting with the simplest members, you can set Lfitaic and lfunderline to 0 or each to set or clear the use of italics or underscores. You use the lfweight to set the bold level you are using when you draw it, you set it to zero to get a normal font, or you set it to 700来 to get bold characters. Lfheight represents the point size of the font (poing size). The value of lfheight is a bit peculiar because it does not take a direct dimension in nature. Instead, you must give it a negative value that represents the height at which it is measured in pixels. For example, for a font that has a height of 16 pixels, you use a value of-16. (but for the current Id3dxfont object, you do not need to add the minus sign again. )

The last is Lffacename, which is the name of the font you want to use. It can be Times new roman,courier new, or any other font installed on your system. You only need to copy the name into the Lffacename member. Here is an example of the Times New Roman font with a point size of 16:

g_pd3ddevice = pre-initialized deviceobject//hWnd = handle to parent window Id3dxfont *pd3dfont; LOGFONT LF; Clear out the font structurezeromemory (&LF, sizeof (LOGFONT)); Set the font name and heightstrcpy (Lf.lffacename, "Times New Roman"); lfheight =-16; Create the font objectif (FAILED (D3dxcreatefontindirect (g_pd3ddevice,                                                               &lf,&pd3dfont))) {    

2.8.2 Drawing with Fonts ( draw with font )

Once your Id3dxfont object is initialized, you can use the Id3dxfont::D rawtext function to begin drawing the text:(now the version of the DrawText function prototype is different, see SDK documentation. )

HRESULT Id3dxfont::D rawtext (LPCSTR   pstring,//String to Printint      Count,   // -1lprect   prect,   // Area to draw text Indword    Format,  //0d3dcolor Color);  Color-to-draw with

The only thing to be aware of when using the DrawText function is the prect parameter, which is a pointer to a rect struct that contains the area used to draw the text. You can set the area to the size of the screen, or if you want to include text in a specific area, use the coordinates of the screen. The RECT structure looks like this:

typedef struct TAGRECT {  LONG left;   Left coordinate  LONG top;    Top coordinate  LONG right;  Right coordinate  LONG bottom;//Bottom coordinate} RECT;

The last argument of the DrawText function is color, which determines the color used to draw the text. Use a handy D3dcolor_rgba or D3dcolor_colorvalue macro to define the color of the drawn text.

Oh, yes, there's one more thing. You must clip your call to the DrawText function between the Id3dxfont::begin and Id3dxfont::end functions. These two functions tell Direct3D that you are ready to render the text.

The following example assumes that you have initialized the Font object and is ready to draw the text:

g_pd3ddevice = pre-initialized deviceobject//pd3dxfont = pre-initialized Font object//Setup the RECT structure with Drawablearearect rect = {0, 0, 200, 100}; Begin the drawing Code Blockif (SUCCEEDED (G_pd3ddevice->beginscene ())) {     //Begin font Rendering    Pd3dxfont->begin ();     Draw some text    pd3dxfont->drawtext ("I can draw with text!",-1,                                        &rect,0, D3dcolor_rgba ( 255,255,255,255);     End Font Rendering    pd3dxfont->end ();     End the Scene    G_pd3ddevice->endscene ();}


The author wrote a font program to demonstrate the use of Id3dxfont objects. But because of the words in the Scarlet letter in front of me, you can't compile them directly. So I made a corresponding change to it. This should be the first essential change I've made so far. Since the vertices are not used here, the parts that are related to vertices, such as vertex declarations and drawing elements, are not available, and because the changes are too large, I have not used the shell framework that I updated before, but I have made changes based on the author's code, in order to make it easier for everyone to see.

To play better, I got two Id3dxfont objects, one for displaying English and one for displaying Chinese. The effect is as follows:

There are a few noteworthy places to note:

1. The Id3dxfont object in the current DirectX 9.0c version has no begin and end functions.

2, the current DirectX 9.0c version of the Id3dxfont object DrawText function parameter list is different from the text, the first parameter, the specific meaning can see the DirectX SDK documentation, for our purposes, set it to 0.

3, about the name of the font. The first font can be any font that is installed on the system, that is, any font under the C:\Windows\Font folder. As for the name of the font, right-click the font file, and in the "details", find the "title" column, which is the name of the font you want to use.

Here's the code:

Font code

The following continues the translation of section 9th:


2.9 Billboards ( Billboard )

Billboard Technology (billboarding) is a cool technique that allows 2-d objects to appear in three-dimensional form. For example, a complex object such as a tree can be rendered according to a side view of a modeling program, and then drawn in a textured form on a rectangular polygon. This rectangular polygon is always facing the point of view, so no matter what angle the polygon is viewed, it seems that the tree texture is always observed from the side it was rendered (2.21).

Many programmers use billboard technology to make games, because they can easily implement it. A perfect example of using billboard technology can be seen in the N64 Paper Mario ("Paper Mario") game. All game characters are drawn with 2-d and then mapped to polygons by textures. The game also adds a little trick, which allows you to see the polygon of the billboard when the character turns around, giving the graphic a funny style.

Billboard technology works by using a world matrix that aligns polygons with perspective. Because you already know the perspective (or you can get a perspective transformation matrix), you just need to use the opposite angle of view to construct a matrix. You don't need to change the position of the polygon because you only care about its angle.

The first way to construct a Billboard World matrix (which you can apply to a mesh model or polygon) is to use the opposite value of the perspective you already know. For example, suppose a vertex cache with vertices is already set up. The angle of the observer is stored in Xrot, Yrot and Zrot, while the coordinates of the Billboard object are Xcoord, Ycoord, and Zcoord. Here's how to create a matrix for rendering the Billboard vertex cache:

g_pd3ddevice = pre-initialized Deviceobjectd3dxmatrix matbillboard;d3dxmatrix matbbxrot, MatBBYRot, MatBBZRot;D 3DXMATRIX Matbbtrans; Construct The Billboard matrix//use the opposite angles of the viewpointto align to Viewd3dxmatrixrotationx (&MATBB Xrot,-xrot);D 3DXMatrixRotationY (&matbbyrot,-yrot);D 3DXMatrixRotationZ (&matbbzrot,-zrot); Use the Billboard object coordinates topositiond3dxmatrixtranslation (&matbbtrans,xcoord, Ycoord, Zcoord); Combine the Matricesd3dxmatrixidentity (&matbillboard);D 3DXMatrixMultiply (&matBillboard,& Matbillboard, &matbbtrans);D 3DXMatrixMultiply (&matbillboard,&matbillboard, &matbbzrot);D 3DXMatrixMultiply (&matbillboard,&matbillboard, &matbbyrot);D 3DXMatrixMultiply (&matbillboard, &matbillboard, &matbbxrot); Set the Matrixg_pd3ddevice->settransform (D3dts_world,&matbillboard); Continue to draw the vertex Buffer,which was aligned//to the face of the viewport, but at the PropercooRdinates. 

After the last line of code, the world transformation matrix is set up and can be used to render the Billboard object.

The second way to create a billboard world matrix is to get the current perspective transformation matrix from Direct3D and transpose it (inverse). This transpose of the matrix will correctly let all the objects face the observation point. You just need to use the translation matrix of the mesh model to put it right in your world. Here's how to construct the Billboard matrix from the perspective transformation matrix and use it to draw the Billboard object:(the code here has a small error, and the following has been corrected.) )

g_pd3ddevice = pre-initialized Deviceobjectd3dxmatrix Mattrans, Matworld, Mattranspose; Get the current Direct3D view Matrixg_pd3ddevice->gettransform (D3dts_view,&mattranspose); Get The billboard ' s rotation matrix. D3dxmatrixtranspose (&mattranspose,&mattranspose); Create the mesh ' s translation matrixd3dxmatrixtranslation (&mattrans,xcoord, Ycoord, Zcoord); Multiply them together to form Worldtransformation matrixd3dxmatrixmultiply (&matworld,&mattranspose, & Mattrans); Set the World Transformation Matrixg_pd3ddevice->settransform (D3dts_world,&matworld); Continue to draw the vertex Buffer,which was aligned//to the face of the viewport, but at the proper coordinates.

Billboards are a powerful technology; in fact, it is the foundation of other special effects-such as particles.


In order to demonstrate the Billboard technology, the author wrote a billboard program, the effect is good. And then I rewrote it a bit. This time the scope of the rewrite is also very large, because the use of the shader method has produced an essential effect, this is the "dragon book" the second edition of the 12th Chapter 3 of the method written.

Here's what the program does when it runs:

Here's the code:

Billboard code

DirectX 9.0c Game Development Journal of RPG Programming Self-learning log 15:drawing with DirectX Graphics (drawing with DirectX graphic) (第8-9 section)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.