Completed my text engine
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.
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?
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
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...
[edited by - Zefrieg on November 1, 2002 5:45:57 PM]
//=============================================================================// 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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement