programming4us
programming4us
MULTIMEDIA

Programming with DirectX : Optimized Drawing - Using a Sprite Object, Text Drawing

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
9/25/2012 9:33:34 PM
Allowing the DrawText function to create and use its own ID3DX10Sprite object is costly if you’re planning on drawing more than one line of text. It is more efficient for you to create the sprite object yourself, allowing it to be reused for each line of text. This keeps the number of sprite objects being created and destroyed to a minimum.

Using a Sprite Object

The first parameter to the DrawText function is a pointer to the sprite object. In the previous section, you passed NULL to this parameter; to utilize your own sprite, a valid ID3DX10Sprite object needs to be created.

The sprite object can be created anytime before the first DrawText function call is made. To keep similar functionality together, the sprite object can be created right after the font object. The InitFont function can be updated to include both tasks.

/*******************************************************************
* InitFont
* Initialize the font object
* Inputs - void
* Outputs - bool - true/success, false/failure
*******************************************************************/
bool InitFont()
{
     HRESULT hr = D3DX10CreateFont(pD3DDevice,
         35,       // the font height
         0,     // the font width
         FW_BOLD,       // the weight of the font
         1,     // number of mip levels
         FALSE,    // this is not an italic font
         DEFAULT_CHARSET,     // default character set
         OUT_DEFAULT_PRECIS,     // default size mapping
         DEFAULT_QUALITY,     // default quality mapping
         DEFAULT_PITCH | FF_DONTCARE,    // default pitch
         L"Helvetica",    // use Helvetica as the basis for this font
         &pFont);       // the output
     if (FAILED(hr))
     {
         return false;
     }
     // Create the sprite that fonts will use to draw with
     D3DX10CreateSprite(pD3DDevice, 512, &pFontSprite);
     return true;
}

					  

Remember to release both the font and sprite objects when the program ends.

// Release the font
if (pFont != NULL)
{
    pFont->Release();
    pFont = NULL;
}
// Release the font sprite
if (pFontSprite != NULL)
{
    pFontSprite->Release();
    pFontSprite = NULL;
}

Text Drawing

The DrawText function is still the workhorse of text drawing; the major difference now is the text is being drawn to objects you specify.

There are only a few changes needed to draw the text using your own sprites. The DrawText function call needs to be updated to pass in a pointer to your sprite object. Because sprites are being drawn here, the DrawText function needs to be placed between calls to the sprite object’s Begin and End calls. This prepares the system for sprite drawing. An updated Render function follows, showing which changes should be made.

/*******************************************************************
* Render
* All drawing happens in the Render function
* Inputs - void
* Outputs - void
*******************************************************************/
void Render()
{
    if (pD3DDevice != NULL)
    {
        // clear the target buffer
        pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f,
        0.0f, 0.0f, 0.0f));
        // Create and Initialize the destination rectangle
        RECT rc;
        SetRectEmpty(&rc);
        // Use the GetFontRectangle helper function to get the proper size
        // of the rectangle.
        GetFontRectangle(TEXT("This is a test string"), &rc);

        // Start font drawing
        pFontSprite->Begin(D3DX10_SPRITE_SORT_TEXTURE);

        // Draw the text to the screen
        HRESULT hr = pFont->DrawText( pFontSprite,
            TEXT("This is a test string"),
            -1,
            &rc,
            DT_LEFT,
            D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );

        pFontSprite->End();

        // display the next item in the swap chain
        pSwapChain->Present(0, 0);
    }
}

					  

While this may seem like a simple change, the results won’t quite be what you were expecting. The text being drawn shows up as a series of color-filled rectangles. Figure 1 shows the result of using your own sprites to draw text. 

Figure 1. A font that’s not quite right.


The rectangles contain an alpha channel that is not being drawn correctly. To solve this problem, the Render function needs to be updated to change the current blend state.

The Render function shown next correctly updates the blend state for font drawing.

/*******************************************************************
* Render
* All drawing happens in the Render function
* Inputs - void
* Outputs - void
*******************************************************************/
void Render()

{
    FLOAT OriginalBlendFactor[4];
    UINT   OriginalSampleMask = 0;

    if (pD3DDevice != NULL)
    {
        // clear the target buffer
        pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f,
        0.0f, 0.0f, 0.0f));
        // Create and Initialize the destination rectangle
        RECT rc;
        SetRectEmpty(&rc);
        // Use the GetFontRectangle helper function to get the proper size
        // of the rectangle.
        GetFontRectangle(TEXT("This is a test string"), &rc);
        // Start font drawing
        pFontSprite->Begin(D3DX10_SPRITE_SORT_TEXTURE);
        // Draw the text to the screen
        HRESULT hr = pFont->DrawText( pFontSprite,
            TEXT("This is a test string"),
            -1,
            &rc,
            DT_LEFT,
            D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );

        // Save the current blend state
        pD3DDevice->OMGetBlendState(&pOriginalBlendState10,
            OriginalBlendFactor,
            &OriginalSampleMask);

        // Set the blend state for font drawing
        if(pFontBlendState10)
        {
            FLOAT NewBlendFactor[4] = {0,0,0,0};
            pD3DDevice->OMSetBlendState(pFontBlendState10, NewBlendFactor,
            0xffffffff);
        }

        pFontSprite->End();

        // Restore the previous blend state
        pD3DDevice->OMSetBlendState(pOriginalBlendState10,
        OriginalBlendFactor, OriginalSampleMask);

        // display the next item in the swap chain
        pSwapChain->Present(0, 0);
    }
}

					  
Other  
 
programming4us
 
 
programming4us