top of page

​​Chap 8/100: ​Text Fonts

​

What I will Learn here?:

​On this Chapter we will learn how to render text fonts (part I) and reveal a secret of chap 7 the night sky.​

Later on we will cover also on this tutorial the implementation of a swap render between day and night with blend

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​​​Note:

Now you can understand better why we have a infinite terrain... Try it now you can see that on coordinates.

​​

​Let's check our current main source tree, except the LIBs:

​

Added source on White:

​

​│   Applicationclass.cpp
│   Applicationclass.h
│   counter.h
│   main.cpp
│   main.h
│
├───camera
│       cameraClass.cpp
│       cameraClass.h
│       frustumClass.cpp
│       frustumClass.h
│       positionClass.cpp
│       positionClass.h
│
├───game
│       playerClass.cpp
│       playerClass.h
​
│
​

├───graphics
│       spriteClass.cpp
│       spriteClass.h
​

│       textClass.cpp
│       textClass.h
│       textFontClass.cpp
│       textFontClass.h
│
├───input
│       inputClass.cpp
│       inputClass.h
│

├───loader
│       objModelV2Class.cpp
│       objModelV2Class.h
│
├───shader
│       shaderClass.cpp
│       shaderClass.h
│
└───system
        dx11Class.cpp
        dx11class.h
        SystemClass.cpp
        SystemClass.h
        xml_loader.cpp
        xml_loader.h

 

​

​​(main.h) ​

- Set for Chapter 8

​

​​​​​​​(textFontClass.cpp​)​ - ​This class is responsible to load a specific text type, it will handle the texture for the font, the font data from the text file.

​

​​​​​​​(textClass.cpp​)​ - ​The textClass use the textFontClass to render all our needed sentences.

​

​//The SetFps function takes the fps integer value given to it and then converts it to a string.
//Once the fps count is in a string format it gets concatenated to another string so it has a prefix indicating that
//it is the fps speed. After that it is stored in the sentence structure for rendering.
//The SetFps function also sets the color of the fps string to green if above 60 fps, yellow if below 60 fps, and
//red if below 30 fps.
//0

bool TextClass::SetFps(int fps)
{
    float red=0.0f, green=0.0f, blue=0.0f;

    // Truncate the fps to below 10,000.
    if(fps > 9999)
        fps = 9999;

    // avoid division by zero:
    if (fps == 0)
        fps=1;
   
    char strBuffer[30];
    sprintf(strBuffer, "Fps: %d  - ms: %4.2f", fps, 1000.0f/fps);

    if(fps >= 60)
        green = 1.0f;    // If fps is 60 or above set the fps color to green.
    else
        red = 1.0f;        // If fps is below 30 set the fps color to red.

    if(fps > 30)
        green = 1.0f;    // If fps is below 60 set the fps color to "yellow."

    if(fps < 30)
        red = 1.0f;

    // Update the sentence vertex buffer with the new string information.
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_FPS], strBuffer, g_ScreenWidth - 120, 20, red, green, blue));

    return true;
}


//The SetCpu function is similar to the SetFps function. It takes the cpu value and converts it to a string which is then
//stored in the sentence structure and rendered.
//1

bool TextClass::SetCpu(int cpu)
{
    char cpuString[16];

    // Setup the cpu string.
    sprintf_s (cpuString, "Cpu: %d %%", cpu);

    // Update the sentence vertex buffer with the new string information.
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_CPU], cpuString, g_ScreenWidth - 120, 40, 0.0f, 1.0f, 0.0f));

    return true;
}

#if TUTORIAL_CHAP >= 8

//02,03,04
bool TextClass::SetCameraPosition(float posX, float posY, float posZ)
{    char dataString[16];

    // Setup the X position string.
    sprintf_s (dataString, "X: %d ", (int)posX);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_X], dataString, 10, 170, 0.0f, 1.0f, 0.0f));
   
    // Setup the Y position string.
    sprintf_s (dataString, "Y: %4.2f ", posY);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_Y], dataString, 10, 190, 0.0f, 1.0f, 0.0f));

    // Setup the Z position string.
    sprintf_s (dataString, "Z: %d ", (int)posZ);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_Z], dataString, 10, 210, 0.0f, 1.0f, 0.0f));

    return true;
}


//05,06,07

bool TextClass::SetCameraRotation(float rotX, float rotY, float rotZ)
{    char dataString[16];

    // Setup the X rotation string.
    sprintf_s (dataString, "rX: %d ", (int)rotX);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_rX], dataString, 10, 240, 0.0f, 1.0f, 0.0f));

    // Setup the Y rotation string.
    sprintf_s (dataString, "rY: %d ", (int)rotY);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_rY], dataString, 10, 260, 0.0f, 1.0f, 0.0f));

    // Setup the Z rotation string.
    sprintf_s (dataString, "rZ: %d ", (int)rotZ);
    IF_NOT_RETURN_FALSE (UpdateSentence(m_sentence[TEXT_rZ], dataString, 10, 280, 0.0f, 1.0f, 0.0f));

    return true;
}
#endif

​

​​​​​(applicationClass.cpp)​ - CHANGES

​

​Here we initialize our Text Manager Class:

​

​    // [11] TEXT
    //-----------------------------------------------------------------------------------------   

    #if TUTORIAL_CHAP >= 8
    // Initialize the text object.
    if(!m_Text.Initialize(m_DirectX11, g_viewMatrix2D))
        {MyMessageBox(L"Could not initialize the Text Object");return false;}
    #endif//


I updated a little bit Chap 7 in order to support  more than 1 sky, day and night, here the swap flag:  

​

/ APPLICATION FLAGS:
// ------------------

#define SCENE_OBJMODEL    //CH04
#define SCENE_BANNER    //CH07
#define SCENE_CLEANSKY  //CH07
#define SCENE_DYNAMICSKY//CH07
#define SCENE_TEXT        //CH08

​

 

The swap is implemented here every 5 seconds, later on we can address it to the real time using 24h:  

​

#if TUTORIAL_CHAP >= 7 && defined (SCENE_DYNAMICSKY)


    static DWORD m_skyTime = timeGetTime(); // Absolute Time (Not Frame Time!)
    if(timeGetTime() >= (m_skyTime + 5000)) // 1 Second = 1000 ms
    {
        m_skyTime = timeGetTime();
        currentSky = (currentSky == 0) ? 1:0;   // Action Here!
    }
#endif//

 

​

The rendering of all sentences is very easy invoked here:

​​

    // 14. 2D SPRITES: 2D TEXT elements
    //----------------------------------------------------------------------------------------------------------------------

#if TUTORIAL_CHAP >= 8
    IF_NOT_RETURN_FALSE ( m_Text.Render() );
#endif//

​

​

The Shader​ that we are using on this chapter is:

​​

010TextureBlendedColor.hlsl shader ​file with a basic Vertex Shader / Pixel Shader:​

​

​////////////////////////////////////////////////////////////////////////////////
// Filename: 008TextureBlendedPixelColor.hlsl
////////////////////////////////////////////////////////////////////////////////


#include "000cbuffer.hlsl"

//////////////
// TYPEDEFS //
//////////////


// VERTEX:
struct VSIn
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
};

// PIXEL:
struct PSIn
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
};

/////////////
// GLOBALS //
/////////////

Texture2D shaderTexture;
SamplerState SampleType;

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////

PSIn MyVertexShader008TextureBlendedPixelColor(VSIn input)
{
    PSIn output;
   
    input.position.w = 1.0f;                    // Change the position vector to be 4 units for proper matrix calculations.

    output.position = mul(input.position, WVP);    // Calculate the position of the vertex against the world, view, and projection matrices.
     output.tex = input.tex;                        // Store the texture coordinates for the pixel shader.
   
    return output;
}

////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////

float4 MyPixelShader008TextureBlendedPixelColor(PSIn input) : SV_TARGET
{
    float4 color;

    // Sample the texture pixel at this location.
    color = shaderTexture.Sample(SampleType, input.tex);

    if(color.r == 0.0f && color.g == 0.0f && color.b == 0.0f)    // If the color is black on the texture then treat this pixel as transparent.
    {    clip (-1.0); return (float4)0;    }                        // Black is transparent, discard this pixel!

    //else
    {    color.rgb = pixelColor.rgb;    }    // If the color is other than black on the texture then this is a pixel in the font so draw it using the font pixel color.

    return color;
}


 

 

 

​To navigate on source code:

 

User: public

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​

​Project Code:

​

​WoMA_Chap8.zip

​

​

​What's next?

​On next chapter we go into the height maps terrains this is just a touch, only in next Part II, the terrains will be hardly covered.

bottom of page