The text in the game is implemented in several ways, such as geometric mapping on the screen, vector drawing, and even the use of standard message boxes only.
In 2D and 3D games, text is usually drawn with mapped geometry
Dynamic text system constructs those text strings by loading a single map of any letter contained in the font
The Create vertex cache here is dynamic:
The code is set up as follows:
HRESULT D3dtextdemo::createtextvertices (float width, float height) {HRESULT d3dresult; Vertexpos vertices[] = {//create vertex matrix {XMFLOAT3 (width, height, 1.0f), XMFLOAT2 (1.0f, 0.0f)}, {XMFLOAT3 (width,-heigh T, 1.0f), XMFLOAT2 (1.0f, 1.0f)}, {XMFLOAT3 (-width,-height, 1.0f), XMFLOAT2 (0.0f, 1.0f)}, {XMFLOAT3 (-width,-heigh T, 1.0f), XMFLOAT2 (0.0f, 1.0f)}, {XMFLOAT3 (-width, height, 1.0f), XMFLOAT2 (0.0f, 0.0f)}, {XMFLOAT3 (width, height
, 1.0f), XMFLOAT2 (1.0f, 0.0f)},}; Create a vertex description D3d11_buffer_desc Vertexdesc;
Create a vertex description ZeroMemory (&vertexdesc, sizeof (VERTEXDESC)); Vertexdesc.usage = d3d11_usage_dynamic; Dynamic cache can dynamically update vertexdesc.cpuaccessflags = D3d11_cpu_access_write via CPU; Dynamic write in order for the CPU to be able to write access to resources in the GPU vertexdesc.bindflags = D3d11_bind_vertex_buffer;
Bind vertex Cache const int sizeofsprite = sizeof (vertexpos) * 6;
const int maxletters = 24;
Vertexdesc.bytewidth = Sizeofsprite * maxletters; D3dresult = D3ddevice_->createbuffer (&vertexdesc, NULL, &Amp;vertexbuffer_); The child resource parameter is set to NULL we dynamically update the content of the vertex cache so that we do not need to set any data if (FAILED (D3dresult)) {dxtrace_msg ("FAILED to create vertex buffer")
);
return false;
} return true; }
Some changes have been made here:
(1) Set use identity as d3d11_usage_dynamic to allow our cache to be dynamically updated via CPU
(2) Set the CPU Access ID as D3d11_cpu_access_write in order for the CPU to be able to continue access to the resources in the GPU
(3) When Createbuffer, we set the child resource parameter to NULL
The settings for the DrawString function:
Sizeofsprite----the size of a single sprite in bytes. An elf is a two-triangle of 6 vertices
Maxletters----render up to a few
Length----The lengths of the strings we need to render
Charwidth----The width of a single letter on the screen
Charheight----The height of a single letter on the screen
Texelwidth----The width of a single letter in a texture image
Verticespreletter-----Store constants for all vertices in each sprite
The function is set as follows:
Unlike using a circular index to calculate vertex positions, we use the letter itself to produce the coordinates of the map.
This can be calculated by using the ASCII code of each letter.
BOOL D3dtextdemo::D rawstring (char* message, float StartX, float starty) {const int sizeofsprite = sizeof (vertexpos) * 6 ; Size as a single Sprite a sprite is a two-triangle const int maxletters = 24 consisting of 6 vertices; can easily render 24 letters int length = strlen (message) at a time;
We need to render the string length//If the character length is too long to cut if (length > maxletters) length = maxletters;
The width of a single letter on the screen float charwidth = 32.0f/800.0f;
The height of a single letter on the screen float charheight = 32.0f/640.0f;
The height of a single letter in the texture image float texelwidth = 32.0f/864.0f;
Constants that store all vertices in each sprite are const int verticesperletter = 6;
Then update the content in the dynamic cache D3d11_mapped_subresource Mapresource; HRESULT D3dresult = D3dcontext_->map (vertexbuffer_, 0, D3d11_map_write_discard, 0, &mapresource);
Access to the objects in the cache via map is accessed via Maoresource (FAILED (D3dresult)) {dxtrace_msg ("FAILED to map Resource");
return false; } vertexpos* sprintfptr = (vertexpos*) mapresource.pdata;
Get a pointer to a child resource pdata can loop set the string that needs to be assembled and the geometric pattern const int indexa = static_cast<char> (' A '); const int INDEXZ = static_cast<char> (' Z '); for (int i = 0; i < length; ++i) {//handy string Float Thisstartx = StartX + (charwidth * static_cast<float> (i)); Sets the starting position of each character by width float thisendx = thisstartx + charwidth; The end position of x is float Thisendy = starty + charheight;
Height setting Sprintfptr[0].pos = XMFLOAT3 (Thisendx, Thisendy, 1.0f);
Sprintfptr[1].pos = XMFLOAT3 (Thisendx, Starty, 1.0f);
Sprintfptr[2].pos = XMFLOAT3 (Thisstartx, Starty, 1.0f);
Sprintfptr[3].pos = XMFLOAT3 (Thisstartx, Starty, 1.0f);
Sprintfptr[4].pos = XMFLOAT3 (Thisstartx, Thisendy, 1.0f);
Sprintfptr[5].pos = XMFLOAT3 (Thisendx, Thisendy, 1.0f); int texlookup = 0;
Represents the first letter (a) and then increments int letter = static_cast<char> (Message[i]); if (Letter < Indexa | |, Letter > INDEXZ) {//grab One index past Z,which are a blank space in the texture Texlook
up = (Indexz-indexa) + 1;
} else {texlookup = (letter-indexa); } FloaT Tustart = 0.0f + (texelwidth * static_cast<float> (texlookup));
Float tuend = Tustart + texelwidth;
sprintfptr[0].tex0 = XMFLOAT2 (Tuend, 0.0f);
sprintfptr[1].tex0 = XMFLOAT2 (Tuend, 1.0f);
sprintfptr[2].tex0 = XMFLOAT2 (Tustart, 1.0f);
sprintfptr[3].tex0 = XMFLOAT2 (Tustart, 1.0f);
sprintfptr[4].tex0 = XMFLOAT2 (Tustart, 0.0f);
sprintfptr[5].tex0 = XMFLOAT2 (Tuend, 0.0f);
Sprintfptr + = 6;
} d3dcontext_->unmap (Vertexbuffer_, 0);
D3dcontext_->draw (6 * length, 0);
return true; }
How do I read the map and render the text in the map?
(1) First import stickers in D3dcontext_
D3dcontext_->iasetinputlayout (inputlayout_);
D3dcontext_->iasetvertexbuffers (0, 1, &vertexbuffer_, &stride, &offset);
D3dcontext_->iasetprimitivetopology (d3d11_primitive_topology_trianglelist);
D3dcontext_->vssetshader (solidcolorvs_, 0, 0);
D3dcontext_->pssetshader (solidcolorps_, 0, 0);
D3dcontext_->pssetshaderresources (0, 1, &colormapfortexta_); Import stickers here
d3dcontext_->pssetsamplers (0, 1, &colormapsampler_);
(2) then through the map function in drawstring
HRESULT D3dresult = D3dcontext_->map (vertexbuffer_, 0, D3d11_map_write_discard, 0, &mapresource); Access to objects in the cache via map access through Maoresource
//mapresource accesses the contents of the resource
Then we get a pointer to the pdata of the sub-resource to loop through the geometric pattern of the string that needs to be assembled.
We use a for-loop iterator to iterate through the string
The role of Texlookup:
The beginning of x is the end of the left x of the sprite is the right side of the Sprite, which is equivalent to the beginning of the X and the width of each letter.
Mapping coordinates: The ASCII code of the current letter and the ASCII of a are poor if the current letter is a 0 B gets 1
Cyclic index I starts with 0 increments
And the texlookup variable is represented by 0 and incremented sequentially
Texlookup = (letter-indexa);
Letter is a char-type character so that the ASCII code of the character can be introduced to determine which character this is
About setting the transparency:
Mixed Description object:
Id3d11blendstate* Alphablendstate_;
Then set the alpha channel:
D3d11_blend_desc blendstate;
ZeroMemory (&blendstate, sizeof (blendstate));
Blendstate.rendertarget[0]. blendenable = TRUE;
Blendstate.rendertarget[0]. Blendop = D3d11_blend_op_add;
Blendstate.rendertarget[0]. Srcblend = D3d11_blend_src_alpha;
Blendstate.rendertarget[0]. Destblend = D3d11_blend_one;
Blendstate.rendertarget[0]. Blendopalpha = D3d11_blend_op_add;
Blendstate.rendertarget[0]. Srcblendalpha = D3d11_blend_zero;
Blendstate.rendertarget[0]. Destblendalpha = D3d11_blend_zero;
Blendstate.rendertarget[0]. Rendertargetwritemask = 0x0F;
Float Blendfactor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
D3ddevice_->createblendstate (&blendstate, &alphablendstate_);
D3dcontext_->omsetblendstate (Alphablendstate_, Blendfactor, 0xFFFFFFFF);