Drawing Text with Dx11

Started by
5 comments, last by the incredible smoker 10 years ago

Hi,

My question is, what is the best way to display text in an 3d Game Environment with DirectX 11.

I Already know that this its possible with Graphical Fonts which are rendered to Quads and have done so.

But isn t there a better way to do this?

And if not -> does anyone know a tutorial or book where it is explained clearly?

edit: Wouldn t it be easyer to render the scene view to Texture and then Render the text to the Texture before presenting it?

Advertisement

I haven't yet attempted quad based text,so your experience trumps mine, but I'm guessing you could pre render commonly used strings, and use a single quad to replace them. As to your edit, It depends on your setup i guess. You may in fact want to render all your text to a separate texture before blending with the scene for certain effects, such as blurring the text or the scene independently from the other.

I Already know that this its possible with Graphical Fonts which are rendered to Quads and have done so.


"Graphical Fonts" are generally called "Bitmap Fonts" in this context.

Not really. Render your text in batches (one draw call should put as much text onto the screen as you can possibly do; not one draw call per character). This generally just requires a texture atlas (sprite sheet) for your fonts and a dynamic vertex buffer.

You can use signed distance fields (this SIGGRAPH paper or the libgdx docs) to pull off a lot more effects, all without the overhead of TTF rendering. In fact, to get really high quality distance fields, you're almost certainly going to want to pre-process the text and generate a bitmap font of your own.

Wouldn t it be easyer to render the scene view to Texture and then Render the text to the Texture before presenting it?


You'd be wasting a little bit of GPU memory in order to save on a tiny amount of GPU rendering time. It's not really much of optimization and it adds extra complexity to the font rendering code. Don't bother with this, unless you have some seriously complex fonts to render (and in these cases, you're probably best off just pre-rendering them as an image, like a logo screen).

Sean Middleditch – Game Systems Engineer – Join my team!

Thank you for your advice, i will try that! wink.png

Hi again!

I have tried now to create a class that handles the text rendering but that seems not work properly.
It runs and i get all the data i need from the files, but nothing is displayed.

Heres my code:

My Structures for handling the index Input From text File:



struct SignInfo
{
short Index;
char Sign;
float T_Coord_Left;
float T_Coord_Right;
float T_Coord_Top;
float T_Coord_Bottom;
};

struct TextInfo
{
int index;
char* message;
float startX;
float startY;
};

// for each ASCII Sign:
SignInfo info[255];

// array to add text each Draw call:
TextInfo TextInfoArray[10];



// Handles the adding of text to render:

void TextProcessor::AddText(char* message, float startX, float startY)
{
TextInfoArray[TextCounter].index = TextCounter;
TextInfoArray[TextCounter].message = message;
TextInfoArray[TextCounter].startX = startX;
TextInfoArray[TextCounter].startY = startY;

TextCounter++;
}

now the function that handles the rendering of the text:


void TextProcessor::DrawAllText()
{
int maxLetters = 32;
unsigned int vertexCount = 0;

float posZ = 1.0f;

D3D11_MAPPED_SUBRESOURCE mapResource;
HRESULT hresult = d3dContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapResource);

VertexPosFont *spritePtr = (VertexPosFont*)mapResource.pData;
int spritePtrCounter = 0;

for(int i = 0; i < TextCounter; i++)
{
int length = strlen(TextInfoArray[i].message);

if(length > maxLetters)
length = maxLetters;

vertexCount += length * 6;

float posX = 0.0f;

for(int j = 0; j < length; j++)
{
int letter = static_cast<char>(TextInfoArray[i].message[j]);

if(letter > 126 || letter < 32)
{
letter = 32;
}

float charWidth = 0;
float charHeight = 0;

charWidth = ( info[letter].T_Coord_Right * fontWidth - info[letter].T_Coord_Left * fontWidth );
charHeight = ( info[letter].T_Coord_Bottom * fontHeight - info[letter].T_Coord_Top * fontHeight );

/*
const size_t buflen = 100;
TCHAR buff[buflen];
_sntprintf(buff, buflen - 1, _T("charWidth: %f charHeight: %f PosX: %f"), charWidth, charHeight, posX);
MessageBox(NULL, buff, L"", MB_OK);
*/

float thisStartX = posX;
float thisEndX = posX + charWidth;
float thisEndY = TextInfoArray[i].startY + charHeight;

spritePtr[spritePtrCounter].pos = XMFLOAT3( thisEndX, thisEndY, posZ );
spritePtr[spritePtrCounter+1].pos = XMFLOAT3( thisEndX, TextInfoArray[i].startY, posZ );
spritePtr[spritePtrCounter+2].pos = XMFLOAT3( thisStartX, TextInfoArray[i].startY, posZ );
spritePtr[spritePtrCounter+3].pos = XMFLOAT3( thisStartX, TextInfoArray[i].startY, posZ );
spritePtr[spritePtrCounter+4].pos = XMFLOAT3( thisStartX, thisEndY, posZ );
spritePtr[spritePtrCounter+5].pos = XMFLOAT3( thisEndX, thisEndY, posZ );

/*
spritePtr[spritePtrCounter].pos = XMFLOAT3(thisEndX + Camera->target.x, thisEndY + Camera->target.y, posZ + Camera->target.z);
spritePtr[spritePtrCounter+1].pos = XMFLOAT3(thisEndX + Camera->target.x, TextInfoArray[i].startY + Camera->target.y, posZ + posZ + Camera->target.z);
spritePtr[spritePtrCounter+2].pos = XMFLOAT3(thisStartX + Camera->target.x, TextInfoArray[i].startY + Camera->target.y, posZ + posZ + Camera->target.z);
spritePtr[spritePtrCounter+3].pos = XMFLOAT3(thisStartX + Camera->target.x, TextInfoArray[i].startY + Camera->target.y, posZ + Camera->target.z);
spritePtr[spritePtrCounter+4].pos = XMFLOAT3(thisStartX + Camera->target.x, thisEndY + Camera->target.y, posZ + Camera->target.z);
spritePtr[spritePtrCounter+5].pos = XMFLOAT3(thisEndX + Camera->target.x, thisEndY + Camera->target.y, posZ + Camera->target.z);
*/

float tuStart = info[(int)TextInfoArray[i].message[j]].T_Coord_Left;
float tuEnd = info[(int)TextInfoArray[i].message[j]].T_Coord_Right;
float tvStart = info[(int)TextInfoArray[i].message[j]].T_Coord_Top;
float tvEnd = info[(int)TextInfoArray[i].message[j]].T_Coord_Bottom;

/*
const size_t buflen = 100;
TCHAR buff[buflen];
_sntprintf(buff, buflen - 1, _T("tuStart: %f tuEnd: %f"), tuStart, tuEnd);
MessageBox(NULL, buff, L"", MB_OK);
*/

spritePtr[spritePtrCounter].tex0 = XMFLOAT2( tuEnd, tvStart );
spritePtr[spritePtrCounter+1].tex0 = XMFLOAT2( tuEnd, tvEnd );
spritePtr[spritePtrCounter+2].tex0 = XMFLOAT2( tuStart, tvEnd );
spritePtr[spritePtrCounter+3].tex0 = XMFLOAT2( tuStart, tvEnd );
spritePtr[spritePtrCounter+4].tex0 = XMFLOAT2( tuStart, tvStart );
spritePtr[spritePtrCounter+5].tex0 = XMFLOAT2( tuEnd, tvStart );

spritePtr += 6;
spritePtrCounter += 6;
posX += charWidth;
}

ActivateAlphaBlending();

unsigned int stride = sizeof(VertexPosFont);
unsigned int offset = 0;

//View = &XMMatrixIdentity();
//World = &XMMatrixIdentity();

d3dContext->UpdateSubresource(cbView, 0, 0, &View, 0, 0);
d3dContext->UpdateSubresource(cbProj, 0, 0, &Proj, 0, 0);
d3dContext->UpdateSubresource(cbWorld, 0, 0, &World, 0, 0);

d3dContext->VSSetConstantBuffers(0, 1, &cbView);
d3dContext->VSSetConstantBuffers(1, 1, &cbProj);
d3dContext->VSSetConstantBuffers(2, 1, &cbWorld);

d3dContext->IASetInputLayout(inputLayout);
d3dContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

d3dContext->PSSetShaderResources( 0, 1, &colorMap);
d3dContext->PSSetSamplers(0, 1, &colorMapSampler);
d3dContext->VSSetShader(vertexShader, 0, 0);
d3dContext->PSSetShader(pixelShader, 0, 0);

/*
const size_t buflen = 100;
TCHAR buff[buflen];
_sntprintf(buff, buflen - 1, _T("Text Vertices: %d"), vertexCount);

MessageBox(NULL, buff, L"Error", MB_OK);
*/

d3dContext->Unmap(vertexBuffer, 0);
d3dContext->Draw(vertexCount, 0);

ResetTextInfoArray();
TextCounter = 0;

d3dContext->OMSetBlendState(originalBS, originalBlendColor, originalSampleMask);
}
}



void TextProcessor::ResetTextInfoArray()
{
memset(TextInfoArray, 0, sizeof(TextInfoArray));
}

Here is the Index File for the bitmap font:

i have created it with an helper programm and the pixel coordinates
the reading of the data works properly, i have teste it with message Boxes

[ASCII][Sign][Left_Pixel][Right_Pixel][Top_Pixel][Bottom_Pixel]
Width: 512 Height: 136
32 Space 0.302734 0.333984 0.772059 0.970588
33 ! 0.00390625 0.0117188 0.0147059 0.154412
34 " 0.0273438 0.0429688 0.0147059 0.110294
35 # 0.0566406 0.0839844 0.0147059 0.154412
36 $ 0.0957031 0.121094 0 0.191176
37 % 0.132813 0.169922 0.0147059 0.154412
38 & 0.179688 0.212891 0.0147059 0.154412
39 ' 0.226563 0.234375 0.0147059 0.0661765
40 ( 0.248047 0.259766 0.0147059 0.191176
41 ) 0.271484 0.285156 0.0147059 0.191176
42 * 0.298828 0.318359 0.0147059 0.0882353
43 + 0.332031 0.357422 0.0441176 0.154412
44 , 0.367188 0.378906 0.125 0.183824
45 - 0.390625 0.404297 0.0882353 0.110294
46 . 0.417969 0.425781 0.125 0.154412
47 / 0.435547 0.457031 0.0147059 0.183824
48 0 0.466797 0.492188 0.0147059 0.154412
49 1 0.503906 0.525391 0.0147059 0.154412
50 2 0.537109 0.5625 0.0147059 0.154412
51 3 0.574219 0.597656 0.0147059 0.154412
52 4 0.611328 0.636719 0.0147059 0.154412
53 5 0.648438 0.671875 0.0147059 0.154412
54 6 0.685547 0.708984 0.0147059 0.154412
55 7 0.720703 0.744141 0.0147059 0.154412
56 8 0.757813 0.783203 0.0147059 0.154412
57 9 0.792969 0.816406 0.0147059 0.154412
58 : 0.830078 0.837891 0.0588235 0.154412
59 ; 0.849609 0.859375 0.0588235 0.191176
60 < 0.873047 0.896484 0.0441176 0.147059
61 = 0.910156 0.931641 0.0661765 0.125
62 > 0.943359 0.966797 0.0441176 0.147059
63 ? 0 0.0234375 0.264706 0.411765
64 @ 0.0351563 0.0761719 0.272059 0.411765
65 A 0.0878906 0.119141 0.272059 0.411765
66 B 0.130859 0.154297 0.272059 0.411765
67 C 0.166016 0.191406 0.272059 0.411765
68 D 0.205078 0.232422 0.272059 0.411765
69 E 0.246094 0.267578 0.272059 0.411765
70 F 0.28125 0.300781 0.272059 0.411765
71 G 0.3125 0.341797 0.272059 0.411765
72 H 0.357422 0.384766 0.272059 0.411765
73 I 0.400391 0.408203 0.272059 0.411765
74 J 0.417969 0.433594 0.272059 0.411765
75 K 0.447266 0.470703 0.272059 0.411765
76 L 0.484375 0.503906 0.272059 0.411765
77 M 0.515625 0.554688 0.272059 0.411765
78 N 0.568359 0.595703 0.272059 0.411765
79 O 0.609375 0.640625 0.272059 0.411765
80 P 0.654297 0.677734 0.272059 0.411765
81 Q 0.6875 0.722656 0.272059 0.433824
82 R 0.734375 0.759766 0.272059 0.411765
83 S 0.767578 0.791016 0.272059 0.411765
84 T 0.798828 0.828125 0.272059 0.411765
85 U 0.839844 0.867188 0.272059 0.411765
86 V 0.878906 0.910156 0.272059 0.411765
87 W 0.919922 0.964844 0.272059 0.411765
88 X 0 0.0253906 0.529412 0.669118
89 Y 0.0351563 0.0625 0.529412 0.669118
90 Z 0.0722656 0.0957031 0.529412 0.669118
91 [ 0.109375 0.121094 0.522059 0.698529
92 \ 0.130859 0.154297 0.514706 0.698529
93 ] 0.162109 0.175781 0.522059 0.698529
94 ^ 0.189453 0.212891 0.529412 0.610294
95 _ 0.222656 0.25 0.683824 0.705882
96 ` 0.261719 0.271484 0.522059 0.558824
97 a 0.285156 0.306641 0.566176 0.669118
98 b 0.324219 0.345703 0.522059 0.669118
99 c 0.357422 0.376953 0.566176 0.669118
100 d 0.388672 0.412109 0.522059 0.669118
101 e 0.425781 0.449219 0.566176 0.669118
102 f 0.460938 0.478516 0.522059 0.669118
103 g 0.488281 0.511719 0.566176 0.705882
104 h 0.525391 0.546875 0.522059 0.669118
105 i 0.5625 0.570313 0.529412 0.669118
106 j 0.578125 0.591797 0.529412 0.705882
107 k 0.605469 0.626953 0.522059 0.669118
108 l 0.638672 0.646484 0.522059 0.669118
109 m 0.660156 0.697266 0.566176 0.669118
110 n 0.712891 0.734375 0.566176 0.669118
111 o 0.748047 0.773438 0.566176 0.669118
112 p 0.787109 0.810547 0.566176 0.705882
113 q 0.822266 0.845703 0.566176 0.705882
114 r 0.861328 0.876953 0.566176 0.669118
115 s 0.888672 0.908203 0.566176 0.669118
116 t 0.919922 0.9375 0.536765 0.669118
117 u 0.951172 0.974609 0.566176 0.669118
118 v 0 0.0234375 0.823529 0.926471
119 w 0.03125 0.0703125 0.823529 0.926471
120 x 0.078125 0.101563 0.823529 0.926471
121 y 0.111328 0.136719 0.823529 0.963235
122 z 0.146484 0.166016 0.823529 0.926471
123 { 0.173828 0.191406 0.779412 0.955882
124 | 0.208984 0.216797 0.779412 0.963235
125 } 0.234375 0.251953 0.779412 0.955882
126 ~ 0.261719 0.287109 0.808824 0.852941


Has Anybody an Idea what could be wrong?

if you need more information of my programm just ask for it...

Have you considered using the DirectX Toolkit?

Hi, this is how i render tekst :

Use 4 vertices per char, use a font texture.

Make sure you load the text from a file.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

This topic is closed to new replies.

Advertisement