Completed my text engine

Started by
7 comments, last by Zefrieg 21 years, 5 months ago
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.
Advertisement
So what''s your question?

-------
Homepage: http://students.washington.edu/andrey
-------Homepage: http://www.pclx.com
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?
and where''s some source code?
do you also lock and unlock? is yours better than CD3DFont?
http://www.dualforcesolutions.comProfessional website designs and development, customized business systems, etc.,
quote:Original post by mickey
do you also lock and unlock?

everyone does!
quote:
is yours better than CD3DFont?

that''s what i''m after as well
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
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]
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.

This topic is closed to new replies.

Advertisement