Advertisement Jump to content
Sign in to follow this  

TTF implementation.

This topic is 1207 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi All,


I'm trying to draw to the screen using Directx11. did some reading and found TTF. but i cannot seem to get it working and would like some help. currently just trying to display the letter "H". my application is displaying 3d object at 0,0 and i have a orbiting camera.


I figured i could massage the tex, co-efficient and position data into my existing PositionTextured structure and dump it to FontShader. 


I seem to be constructing the PositionTextured struct okay, but what should be an "H" is displayed as a white square very far in positive z. my objects are displayed in negative z.


here is some relavant code.

TTF::Font *m_font;
std::vector<PositionTextured> params;
ID3D11Buffer *m_pFontBuffer;
struct PositionTextured
    PositionTextured(float x, float y, float z, float u, float v) : pos(x, y, z), tex(u, v){}
    PositionTextured(D3DXVECTOR3 position, D3DXVECTOR2 texture) : pos(position), tex(texture){}
    D3DXVECTOR3 pos;
    D3DXVECTOR2 tex;

void DOIT::BuildDisplay()
std::string msg = "H";
TTFCore::Triangulator2D<TTFCore::vec2t, TTF::TriSmall> triangulator2DI;
for (auto &m : msg)
    TTFCore::CodePoint cp(m);
    m_font->TriangulateGlyph(cp, triangulator2DI);
    TTFCore::Mesh mesh;
    for (auto i : triangulator2DI)
        PositionTextured pt0;
	pt0.pos.x = triangulator2DI[i.i0].x;
	pt0.pos.y = triangulator2DI[i.i0].y;
	pt0.pos.z = 0.0f;

	PositionTextured pt1;
	pt1.pos.x = triangulator2DI[i.i1].x;
	pt1.pos.y = triangulator2DI[i.i1].y;
	pt1.pos.z = 0.0f;

        PositionTextured pt2;
	pt2.pos.x = triangulator2DI[i.i2].x;
	pt2.pos.y = triangulator2DI[i.i2].y;
	pt2.pos.z = 0.0f;

	if (i.coef != 0)
	    pt0.tex.x = 0;
	    pt1.tex.x = 1;
	    pt2.tex.x = 2;
	    pt0.tex.x = 0;
	    pt1.tex.x = 0;
	    pt2.tex.x = 0;

	pt0.tex.y = i.coef;
	pt1.tex.y = i.coef;
	pt2.tex.y = i.coef;

HRESULT result;
D3D11_BUFFER_DESC vertexBufferDesc;

//prepare a description of the vertex buffer
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(PositionTextured) * params.size();
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;

//set subresource data to point to  our objects vertexdata
vertexData.pSysMem = &(params[0]);

//create buffers in our object
result = m_pd3dDevice->CreateBuffer(&vertexBufferDesc, &vertexData, &m_pFontBuffer);
if (FAILED(result))

void DOIT::Render()
if (params.size())
        m_pImmediateContext->PSSetShader(m_pFontShader, NULL, 0);
	m_pImmediateContext->IASetVertexBuffers(0, 1, &m_pFontBuffer, &stride, &offset);
	m_pImmediateContext->Draw(params.size(), 0);

and my shader code.

Texture2D txDiffuse : register( t0 );
SamplerState samLinear : register(s0);

cbuffer ConstantBuffer : register(b0)
matrix World;
matrix View;
matrix Projection;

cbuffer TransparentBuffer
float blendAmount;

struct VS_INPUT
float4 Pos : POSITION;
float2 Tex : TEXCOORD0;

struct PS_INPUT
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD0;

PS_INPUT output = (PS_INPUT)0;
output.Pos.w = 1.0f;
output.Pos = mul(input.Pos, World);
output.Pos = mul(output.Pos, View);
output.Pos = mul(output.Pos, Projection);
output.Tex = input.Tex;
return output;

float4 PS(PS_INPUT input) : SV_Target
float4 color = txDiffuse.Sample(samLinear, input.Tex);
color.a = blendAmount;
return color;

float4 PSGray(PS_INPUT input) : SV_Target
float4 color = txDiffuse.Sample(samLinear, input.Tex);
float fLuminance = 0.299f * color.r + 0.587f * color.g + 0.114f * color.b;
return float4(fLuminance, fLuminance, fLuminance, blendAmount);

float round(float val)
return sign(val) * floor(abs(val) + 0.5f);

float4 PSFont(PS_INPUT input) : SV_Target
float3 tpos = float3(input.Tex.x * 0.5f, max(input.Tex.x - 1.0f, 0.0f), input.Tex.y);
float alpha = round((tpos.x * tpos.x - tpos.y) * tpos.z + 0.5f);
return (float4(1.0f, 1.0f, 1.0f, 1.0f) * alpha);



Edited by garusher

Share this post

Link to post
Share on other sites

The vertices are in 'font units'.  This is the internal data type used in all .ttf files.  This web page; will explain all the terminology, what an 'em square' is, converting font units to pixels, what 'points' are, etc...


For example, to convert 'font units' to pixels you can do something like:

TTF::FontMetrics font_metrics = font->GetFontMetrics();
float units_per_em = static_cast<float>(font->UnitsPerEM());
float scale = (pt_size * screen_dpi) / (72 * units_per_em); // convert pt_size and screen_dpi into pixels

scale then is a scaling factor you can use to create a transformation matrix for the vertex shader, or pre-scale all vertices by that value.  Also depending on your coordinate system/transformations you may need to invert the y axis.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!