Sign in to follow this  
Dragon_Strike

ID3DX10Font slow

Recommended Posts

im trying to render some text... and its very slow! goes from 0.008s frametime to 0.016s... and thats when go from around 30 chars to 300 chars... what am i doin wrong here?
#include "D3D10Font.hpp"
#include "D3D10Exception.hpp"

#include <iostream>

namespace drone{
    namespace d3d10{

struct Font::Implementation
{
	Implementation(	 RenderDevicePtr pRenderDevice, 
					 INT Height, 
					 UINT Width, 
					 UINT Weight, 
					 UINT MipLevels, 
					 BOOL Italic, 
					 UINT CharSet, 
					 UINT OutputPrecision,
					 UINT Quality,
					 UINT PitchAndFamily,
					 LPCWSTR pFaceName)
	{
		pRenderDevice_ = pRenderDevice;

		HRESULT hr = D3DX10CreateFont(pRenderDevice_->Device(),
									  Height,
									  Width,
									  Weight,
									  MipLevels,
									  Italic,
									  CharSet,
									  OutputPrecision,
									  Quality,
									  PitchAndFamily,
									  pFaceName,
									  &pFont_);

		if (FAILED(hr))
			throw Exception(L"Failed to Create font", hr);

		hr = pFont_->PreloadCharacters(32, 127);

		if(FAILED(hr))
			throw Exception(L"Faled to preload characters", hr);
				
		hr = D3DX10CreateSprite(pRenderDevice_->Device(),512,&pSprite_);

		if (FAILED(hr))
			throw Exception(L"Failed to Create Sprite", hr);


		D3D10_BLEND_DESC StateDesc;
		ZeroMemory(&StateDesc, sizeof(D3D10_BLEND_DESC));
		StateDesc.AlphaToCoverageEnable = FALSE;
		StateDesc.BlendEnable[0] = TRUE;
		StateDesc.SrcBlend = D3D10_BLEND_SRC_ALPHA;
		StateDesc.DestBlend = D3D10_BLEND_INV_SRC_ALPHA;
		StateDesc.BlendOp = D3D10_BLEND_OP_ADD;
		StateDesc.SrcBlendAlpha = D3D10_BLEND_ZERO;
		StateDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
		StateDesc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
		StateDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
		pRenderDevice_->Device()->CreateBlendState(&StateDesc, &pFontBlendState10);
	}	

	void GetFontRectangle(LPCWSTR text, RECT* rect)
	{
		pFont_->DrawText(NULL,
						text,
						-1,
						rect,
						DT_CALCRECT | DT_LEFT,
						D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
	}

	void Print(LPCWSTR text, vec4f color, vec2f pos = vec2f(0.0f, 0.0f))
	{
		FLOAT OriginalBlendFactor[4];
		UINT  OriginalSampleMask = 0;

		RECT rc;
		SetRectEmpty(&rc);

		GetFontRectangle(text, &rc);

		rc.bottom += (LONG)pos[1];
		rc.top += (LONG)pos[1];
		rc.left += (LONG)pos[0];
		rc.right += (LONG)pos[0];

		pSprite_->Begin(D3DX10_SPRITE_SORT_TEXTURE);

		pFont_->DrawText( pSprite_, text, -1, &rc, DT_LEFT | DT_EXPANDTABS, D3DXCOLOR( color[0], color[1], color[2], color[3] ) );
		
			pRenderDevice_->Device()->OMGetBlendState(&pOriginalBlendState10, OriginalBlendFactor, &OriginalSampleMask);

			if(pFontBlendState10)
			{
				FLOAT NewBlendFactor[4] = {0,0,0,0};
				pRenderDevice_->Device()->OMSetBlendState(pFontBlendState10, NewBlendFactor, 0xffffffff);
			}

		pSprite_->End();

		pRenderDevice_->Device()->OMSetBlendState(pOriginalBlendState10, OriginalBlendFactor, OriginalSampleMask);
	}

	RenderDevicePtr pRenderDevice_;
	
	ID3DX10FontPtr pFont_;
	ID3DX10SpritePtr pSprite_;

	ID3D10BlendStatePtr		  pOriginalBlendState10;
	ID3D10BlendStatePtr       pFontBlendState10;
};

Font::Font(	 const std::string& id, 
			 RenderDevicePtr pRenderDevice,
			 INT Height, 
			 UINT Width, 
			 UINT Weight, 
			 UINT MipLevels, 
			 BOOL Italic,
			 LPCWSTR pFaceName,
			 UINT CharSet, 
			 UINT OutputPrecision,
			 UINT Quality,
			 UINT PitchAndFamily)  : IFont(id), pImpl_(new Implementation(	pRenderDevice, 
																			 Height, 
																			 Width, 
																			 Weight, 
																			 MipLevels, 
																			 Italic, 
																			 CharSet, 
																			 OutputPrecision,
																			 Quality,
																			 PitchAndFamily,
																			 pFaceName))
{
	std::wcout << L">> Created Font: \"" << id.c_str() << L"\". (D3D10)\n";

}



void Font::Print(const std::wstring& text, vec4f color, vec2f pos)
{
	pImpl_->Print(text.c_str(), color, pos);
}






		
	} // d3d10
} // drone



EDIT:: ive profiled it and [d3dx10d_36.dll] drone::d3d10::Font::Implementation::GetFontRectangle(wchar_t const *,struct is whats takin all the cpu time..

Share this post


Link to post
Share on other sites
ID3DX10Font is meant to be convenient, not fast. You shouldn't be using it in any performance-critical areas. It works by having GDI write out text to a DIB, and then copies that to a texture. As you can imagine, getting GDI and D3D to work together in this way isn't quick.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dragon_Strike
what alternatives are there?
Implementing your own version is one. I doubt there's many font engines for DX10 yet. Alternatively, using a bitmap font would be fairly straightforward.

As MJP said, if you need performance, don't use ID3DX10Font font (And similarly for DX9's ID3DXFont), it's not up to it.

Share this post


Link to post
Share on other sites
You could roll a sprite-based system if you wanted. Write out a bunch of letters in a particular font to a texture, then change the texture coordinates based on which letter is selected.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this