Archived

This topic is now archived and is closed to further replies.

Zefrieg

Completed my text engine

Recommended Posts

I''m happy with it. It is for DirectX 8.0+. It allows you to load any font bitmap with characters that are in ascii sequence, and there are very few calculations in the display functions. Most of the calculations are done in the intialization, and I created a lookup table to store all the information for up to 256 characters. So, the only calculations done when calling for a string to be displayed on the screen are subtractions used to correctly align vertices, and two additions to move to next coordinate that displays a character. I filled a 1024x768 screen from top to bottom with 1200 characters, and I still got 440 fps. Not bad.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Wreakon don''t be a tool. Zefrieg, that is cool. I am working on mine right now, DirectDraw7, so now I know who run to for answers! Let me ask you this, obviously you can''t just say "move over 10 pixels" or whatever number, and draw the next letter. I mean, some fonts have fixed width for each character, but some do not. For example, after rendering an ''i'', you don''t move over as much as an ''A''. How do you figure up how much space to put between each character without storing a ton of meta data for each character?

Share this post


Link to post
Share on other sites
Anon; My font code scans the bitmap when it''s loaded to find the width of each character, and I use the first character to define the pixel spacing for the "space" character.

My original code was for dx7, so email me if you want the source.

- Matt

Share this post


Link to post
Share on other sites
These are my basic functions. I'm still going to add some things to it, but I figured I would post what I had. Hmmm.. doesn't copy that well...


        

//=============================================================================

// DXGraphics::OutputText()

// Description: Outputs an entire string to the screen

//=============================================================================


HRESULT DXGraphics::OutputText(char* pString, float left, float top, D3DCOLOR color, float z)
{
float LeftPosition;

D3DTLVERTEX* pVertices = 0;

if(FAILED(pVBTL->Lock( 0, 0, (unsigned char **)&pVertices, D3DLOCK_DISCARD)))
{
SetError("Could not lock vertex buffer");
return E_FAIL;
}

for(unsigned int cnt = 0; cnt < strlen(pString); cnt++)
{
LeftPosition = left + (AlphabetLetterWidth * cnt);
// BlitLetter(pString[cnt], LeftThing, top, (LeftThing + AlphabetLetterWidth), (top + AlphabetLetterHeight), color, z);

SetTextVertices(pString[cnt], LeftPosition, top, (LeftPosition + AlphabetLetterWidth), (top + AlphabetLetterHeight), color, pVertices, z);

pVertices += 6;
}

pVBTL->Unlock();

// set the vertex data source

pD3DDevice->SetStreamSource( 0, pVBTL, sizeof(D3DTLVERTEX));

// set the texture

pD3DDevice->SetTexture(0, TextImage);

// configure shader for vertex type

pD3DDevice->SetVertexShader(D3DFVF_TLVERTEX);

// draw the text

pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, strlen(pString)*2);


return S_OK;
}

//=============================================================================

// DXGraphics::SetTextVertices

// Description: Sets the vertices for OutputText.

//=============================================================================


HRESULT DXGraphics::SetTextVertices(char letter, float left, float top, float right, float bottom, D3DCOLOR color, D3DTLVERTEX *pVerts, float z)
{
float LeftU = OffsetXY[letter].OffsetX;
float TopV = OffsetXY[letter].OffsetY;
float RightU = OffsetXY[letter].OffsetX + AlphabetTUV;
float BottomV = OffsetXY[letter].OffsetY + AlphabetTUV;
float rhw;

if(z > 0.0f)
rhw=1.0f/(z*990.0f + 10.0f);
else
rhw=0.1f;

// set up rectangle

D3DTLVERTEX verts[6];
pVerts[0] = D3DTLVERTEX(D3DXVECTOR3(left -0.5f, top-0.5f, z), rhw, color, LeftU, TopV);
pVerts[1] = D3DTLVERTEX(D3DXVECTOR3(right-0.5f, top-0.5f, z), rhw, color, RightU, TopV);
pVerts[2] = D3DTLVERTEX(D3DXVECTOR3(left -0.5f, bottom-0.5f, z), rhw, color, LeftU, BottomV);
pVerts[3] = D3DTLVERTEX(D3DXVECTOR3(right-0.5f, top-0.5f, z), rhw, color, RightU, TopV);
pVerts[4] = D3DTLVERTEX(D3DXVECTOR3(right-0.5f, bottom-0.5f, z), rhw, color, RightU, BottomV);
pVerts[5] = D3DTLVERTEX(D3DXVECTOR3(left -0.5f, bottom-0.5f, z), rhw, color, LeftU, BottomV);

return S_OK;
}

//=============================================================================

// DXGraphics::BlitLetter

// Description: Outputs a single letter to the screen.

//=============================================================================


HRESULT DXGraphics::BlitLetter(char letter, float left, float top, float right, float bottom, D3DCOLOR color, float z)
{
if(!bAlphabetLoaded)
{
SetError("Alphabet not loaded yet!");
return E_FAIL;
}

float LeftU = OffsetXY[letter].OffsetX;
float TopV = OffsetXY[letter].OffsetY;
float RightU = OffsetXY[letter].OffsetX + AlphabetTUV;
float BottomV = OffsetXY[letter].OffsetY + AlphabetTUV;
float rhw;

// rhw

if(z > 0.0f)
rhw=1.0f/(z*990.0f + 10.0f);
else
rhw=0.1f;

// set up rectangle

D3DTLVERTEX verts[4];
verts[0] = D3DTLVERTEX(D3DXVECTOR3(left -0.5f, top-0.5f, z), rhw, color, LeftU, TopV);
verts[1] = D3DTLVERTEX(D3DXVECTOR3(right-0.5f, top-0.5f, z), rhw, color, RightU, TopV);
verts[2] = D3DTLVERTEX(D3DXVECTOR3(right-0.5f, bottom-0.5f, z), rhw, color, RightU, BottomV);
verts[3] = D3DTLVERTEX(D3DXVECTOR3(left -0.5f, bottom-0.5f, z), rhw, color, LeftU, BottomV);

// set the texture

pD3DDevice->SetTexture(0, TextImage);

// configure shader for vertex type

pD3DDevice->SetVertexShader(D3DFVF_TLVERTEX);

// draw the rectangle

pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN , 2, verts, sizeof(D3DTLVERTEX));

return S_OK;
}

//=============================================================================

// DXGraphics::LoadTextImage()

// Description: Loads the image used for the text

//=============================================================================


HRESULT DXGraphics::LoadTextImage(LPCTSTR pSrcFile, int letterWidth, int letterHeight)
{
if(!pSrcFile)
{
SetError("Could not open text bitmap");
return E_FAIL;
}
/*
if( FAILED( D3DXCreateTextureFromFile( pD3DDevice, pSrcFile, &TextImage ) ) )
{
SetError("Could not create texture from file");
return E_FAIL;
}
*/


if( FAILED( D3DXCreateTextureFromFileEx(pD3DDevice, // D3D device

pSrcFile, // File of texture

D3DX_DEFAULT, // Width

D3DX_DEFAULT, // Height

1, // MipLevels

0, // Usage

D3DFMT_A8R8G8B8, // 32-bit with Alpha

D3DPOOL_MANAGED, // Pool, D3D Managed memory

D3DX_DEFAULT, // Filter:Default filtering

D3DX_DEFAULT, // MipFilter, used for filtering mipmaps

0xffff00ff, // ColourKey

NULL, // SourceInfo

NULL, // Palette

&TextImage))) // Texture goes here

{
SetError("Could not create texture from file");
return E_FAIL;
}

D3DSURFACE_DESC d3dsd;

TextImage->GetLevelDesc(0, &d3dsd);

AlphabetWidth = d3dsd.Width;
AlphabetHeight = d3dsd.Height;
AlphabetLetterWidth = letterWidth;
AlphabetLetterHeight = letterHeight;

AlphabetLettersPerRow = AlphabetWidth / AlphabetLetterWidth;

bAlphabetLoaded = true;

return S_OK;
}

//=============================================================================

// DXGraphics::CreateTextTable()

// Description: Creates a table that has the coordinates for the ascii

// texture letters.

//=============================================================================


HRESULT DXGraphics::CreateTextTable()
{
if(!bAlphabetLoaded)
{
SetError("Alphabet not loaded yet!");
return E_FAIL;
}

div_t Result;
AlphabetTUV = (1.0f / AlphabetLettersPerRow);

for(int cnt = 0; cnt < 256; cnt++)
{
Result = div(cnt, AlphabetLettersPerRow);
OffsetXY[cnt].OffsetX = Result.rem * AlphabetTUV;
OffsetXY[cnt].OffsetY = Result.quot * AlphabetTUV;
}

return S_OK;
}






[edited by - Zefrieg on November 1, 2002 5:45:57 PM]

Share this post


Link to post
Share on other sites
Oh, and I got it to run a little faster. At 1200 characters the framerate is 490fps now. Also, I was playing around, and found that it also gets 133fps when there are 10,200 characters on the screen.

Share this post


Link to post
Share on other sites